From 70a3a0f95bf2240a6ef4b1d6523c0e6614437304 Mon Sep 17 00:00:00 2001 From: malaterre Date: Mon, 24 Jan 2005 14:52:49 +0000 Subject: [PATCH] ENH: Grealty simplify the JPEg decompression, no need to differenciate based on the JPEG possible type (with/without fragment, with/without multiple frame). Everything is done throught the JPEG IO Suspension mechanism in IJG --- ChangeLog | 5 +++ src/gdcmJPEGFragment.cxx | 23 ++++++----- src/gdcmJPEGFragment.h | 19 ++++++--- src/gdcmJPEGFragmentsInfo.cxx | 31 ++++++++++++++- src/gdcmJPEGFragmentsInfo.h | 13 +++++-- src/gdcmJpeg.cxx | 73 ++++++++++++++++++++++++++--------- src/gdcmJpeg12.cxx | 7 +++- src/gdcmJpeg16.cxx | 7 +++- src/gdcmJpeg8.cxx | 7 +++- src/gdcmPixelReadConvert.cxx | 65 ++++++++++++++++--------------- src/jdatasrc.cxx | 42 +++++++++++++++++++- 11 files changed, 213 insertions(+), 79 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47756030..d77b19c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-01-24 Mathieu Malaterre + * Grealty simplify the JPEg decompression, no need to differenciate based on + the JPEG possible type (with/without fragment, with/without multiple frame). + Everything is done throught the JPEG IO Suspension mechanism in IJG + 2005-01-22 Benoit Regrain * src/gdcmDicomDirElement.h, gdcmDict.h : rename AddNewXxx methods to AddXxx. * src/gdcmDict.h : rename GetDictEntry moethod to GetEntry, to be coherent diff --git a/src/gdcmJPEGFragment.cxx b/src/gdcmJPEGFragment.cxx index 9b5733b5..ab7c1695 100644 --- a/src/gdcmJPEGFragment.cxx +++ b/src/gdcmJPEGFragment.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmJPEGFragment.cxx,v $ Language: C++ - Date: $Date: 2005/01/18 14:28:32 $ - Version: $Revision: 1.5 $ + Date: $Date: 2005/01/24 14:52:50 $ + Version: $Revision: 1.6 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -26,13 +26,13 @@ namespace gdcm bool gdcm_read_JPEG2000_file (std::ifstream* fp, void* image_buffer); // For JPEG 8 Bits, body in file gdcmJpeg8.cxx -bool gdcm_read_JPEG_file8 (std::ifstream *fp, void *image_buffer); +//bool gdcm_read_JPEG_file8 (JPEGFragment *frag, std::ifstream *fp, void *image_buffer); bool gdcm_read_JPEG_memory8 (const JOCTET *buffer, const size_t buflen, void *image_buffer, size_t *howManyRead, size_t *howManyWritten); // // For JPEG 12 Bits, body in file gdcmJpeg12.cxx -bool gdcm_read_JPEG_file12 (std::ifstream *fp, void *image_buffer); +//bool gdcm_read_JPEG_file12 (JPEGFragment *frag, std::ifstream *fp, void *image_buffer); bool gdcm_read_JPEG_memory12 (const JOCTET *buffer, const size_t buflen, void *image_buffer, size_t *howManyRead, size_t *howManyWritten); @@ -40,7 +40,7 @@ bool gdcm_read_JPEG_memory12 (const JOCTET *buffer, const size_t buflen, // For JPEG 16 Bits, body in file gdcmJpeg16.cxx // Beware this is misleading there is no 16bits DCT algorithm, only // jpeg lossless compression exist in 16bits. -bool gdcm_read_JPEG_file16 (std::ifstream *fp, void *image_buffer); +//bool gdcm_read_JPEG_file16 (JPEGFragment *frag, std::ifstream *fp, void *image_buffer); bool gdcm_read_JPEG_memory16 (const JOCTET *buffer, const size_t buflen, void* image_buffer, size_t *howManyRead, size_t *howManyWritten); @@ -52,6 +52,11 @@ JPEGFragment::JPEGFragment() { Offset = 0; Length = 0; + +// StateSuspension = 0; +// void *SampBuffer; + pimage = 0; + } /** @@ -73,7 +78,7 @@ void JPEGFragment::Print( std::ostream &os, std::string indent ) * @param buffer output (data decompress) * @param nBits 8/12 or 16 bits jpeg */ -void JPEGFragment::DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buffer, int nBits) +void JPEGFragment::DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buffer, int nBits, int & statesuspension) { // First thing need to reset file to proper position: fp->seekg( Offset, std::ios::beg); @@ -81,7 +86,7 @@ void JPEGFragment::DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buff if ( nBits == 8 ) { // JPEG Lossy : call to IJG 6b - if ( ! gdcm_read_JPEG_file8( fp, buffer) ) + if ( ! this->gdcm_read_JPEG_file8( fp, buffer, statesuspension) ) { //return false; } @@ -89,7 +94,7 @@ void JPEGFragment::DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buff else if ( nBits <= 12 ) { // Reading Fragment pixels - if ( ! gdcm_read_JPEG_file12 ( fp, buffer) ) + if ( ! this->gdcm_read_JPEG_file12 ( fp, buffer, statesuspension) ) { //return false; } @@ -97,7 +102,7 @@ void JPEGFragment::DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buff else if ( nBits <= 16 ) { // Reading Fragment pixels - if ( ! gdcm_read_JPEG_file16 ( fp, buffer) ) + if ( ! this->gdcm_read_JPEG_file16 ( fp, buffer, statesuspension) ) { //return false; } diff --git a/src/gdcmJPEGFragment.h b/src/gdcmJPEGFragment.h index 928049fc..987da56d 100644 --- a/src/gdcmJPEGFragment.h +++ b/src/gdcmJPEGFragment.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmJPEGFragment.h,v $ Language: C++ - Date: $Date: 2005/01/20 16:17:00 $ - Version: $Revision: 1.11 $ + Date: $Date: 2005/01/24 14:52:50 $ + Version: $Revision: 1.12 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -45,13 +45,20 @@ class GDCM_EXPORT JPEGFragment public: JPEGFragment(); void Print( std::ostream &os = std::cout, std::string indent = "" ); - void DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buffer, int nBits); + void DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buffer, int nBits, int & statesuspension); void DecompressJPEGSingleFrameFragmentsFromFile(JOCTET *buffer, size_t totalLength, uint8_t* raw, int nBits); void DecompressJPEGFragmentedFramesFromFile(JOCTET *buffer, uint8_t* raw, int nBits, size_t &howManyRead, size_t &howManyWritten, size_t totalLength); -private: - long Offset; - long Length; + bool gdcm_read_JPEG_file8 (std::ifstream* fp, void* image_buffer, int & statesuspension ); + bool gdcm_read_JPEG_file12 (std::ifstream* fp, void* image_buffer, int & statesuspension ); + bool gdcm_read_JPEG_file16 (std::ifstream* fp, void* image_buffer, int & statesuspension ); + +//private: + uint32_t Offset; + uint32_t Length; + + uint8_t *pimage; + friend class Document; friend class FileHelper; diff --git a/src/gdcmJPEGFragmentsInfo.cxx b/src/gdcmJPEGFragmentsInfo.cxx index ddfaaabd..f503f388 100644 --- a/src/gdcmJPEGFragmentsInfo.cxx +++ b/src/gdcmJPEGFragmentsInfo.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmJPEGFragmentsInfo.cxx,v $ Language: C++ - Date: $Date: 2005/01/23 10:12:34 $ - Version: $Revision: 1.8 $ + Date: $Date: 2005/01/24 14:52:50 $ + Version: $Revision: 1.9 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -22,6 +22,10 @@ namespace gdcm { +JPEGFragmentsInfo::JPEGFragmentsInfo() + { + StateSuspension = 0; + } /** * \brief Default destructor */ @@ -101,5 +105,28 @@ void JPEGFragmentsInfo::ReadAllFragments(std::ifstream *fp, JOCTET *buffer ) } +void JPEGFragmentsInfo::DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buffer, int nBits, int numBytes, int length) +{ + // Pointer to the Raw image + uint8_t *localRaw = buffer; + + // Loop on the fragment[s] + JPEGFragmentsList::const_iterator it; + for( it = Fragments.begin(); + it != Fragments.end(); + ++it ) + { + //(*it)->pimage = localRaw; + (*it)->DecompressJPEGFramesFromFile(fp, localRaw, nBits, StateSuspension); + // update pointer to image after some scanlines read: + localRaw = (*it)->pimage; + // Advance to next free location in Raw + // for next fragment decompression (if any) + + //localRaw += length * numBytes; + //std::cerr << "Used to increment by: " << length * numBytes << std::endl; + } +} + } // end namespace gdcm diff --git a/src/gdcmJPEGFragmentsInfo.h b/src/gdcmJPEGFragmentsInfo.h index b416f161..72b7b6e3 100644 --- a/src/gdcmJPEGFragmentsInfo.h +++ b/src/gdcmJPEGFragmentsInfo.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmJPEGFragmentsInfo.h,v $ Language: C++ - Date: $Date: 2005/01/20 16:17:00 $ - Version: $Revision: 1.11 $ + Date: $Date: 2005/01/24 14:52:50 $ + Version: $Revision: 1.12 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -42,14 +42,21 @@ namespace gdcm class GDCM_EXPORT JPEGFragmentsInfo { public: + JPEGFragmentsInfo(); ~JPEGFragmentsInfo(); void Print( std::ostream &os = std::cout, std::string const & indent = "" ); size_t GetFragmentsLength(); void ReadAllFragments(std::ifstream *fp, JOCTET *buffer ); + void DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buffer, int nBits, int numBytes, int length); private: typedef std::list< JPEGFragment* > JPEGFragmentsList; - JPEGFragmentsList Fragments; + + //Some mathieu hack: + int StateSuspension; + void *SampBuffer; + char* pimage; + JPEGFragmentsList Fragments; friend class Document; friend class FileHelper; diff --git a/src/gdcmJpeg.cxx b/src/gdcmJpeg.cxx index da708963..a5b1d6cc 100644 --- a/src/gdcmJpeg.cxx +++ b/src/gdcmJpeg.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmJpeg.cxx,v $ Language: C++ - Date: $Date: 2005/01/23 18:13:48 $ - Version: $Revision: 1.35 $ + Date: $Date: 2005/01/24 14:52:50 $ + Version: $Revision: 1.36 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -16,6 +16,7 @@ =========================================================================*/ #include "gdcmFileHelper.h" +#include "gdcmJPEGFragment.h" /* DICOM provides a mechanism for supporting the use of JPEG Image Compression @@ -347,9 +348,8 @@ struct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ }; - -//----------------------------------------------------------------------------- typedef struct my_error_mgr* my_error_ptr; +//----------------------------------------------------------------------------- /* * Here's the routine that will replace the standard error_exit method: @@ -379,15 +379,16 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo) { * @param image_buffer to receive uncompressed pixels * @return 1 on success, 0 on error */ - -bool gdcm_read_JPEG_file ( std::ifstream* fp, void* image_buffer ) +void *SampBuffer; +bool JPEGFragment::gdcm_read_JPEG_file (std::ifstream* fp, void* image_buffer , int& statesuspension) { - char* pimage; - + //static int fragimage = 0; + //std::cerr << "Image Fragment:" << fragimage++ << std::endl; + pimage = (uint8_t*)image_buffer; /* This struct contains the JPEG decompression parameters and pointers to * working space (which is allocated as needed by the JPEG library). */ - struct jpeg_decompress_struct cinfo; + static struct jpeg_decompress_struct cinfo; /* -------------- inside, we found : * JDIMENSION image_width; // input image width @@ -415,6 +416,8 @@ bool gdcm_read_JPEG_file ( std::ifstream* fp, void* image_buffer ) int row_stride;/* physical row width in output buffer */ + //std::cerr << "StateSuspension: " << statesuspension << std::endl; +//#define GDCM_JPG_DEBUG #ifdef GDCM_JPG_DEBUG printf("entree dans File::gdcm_read_JPEG_file (i.e. 8), depuis gdcmJpeg\n"); #endif //GDCM_JPG_DEBUG @@ -441,25 +444,37 @@ bool gdcm_read_JPEG_file ( std::ifstream* fp, void* image_buffer ) /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ + std::cerr << "Qu'est c'est ce bordel !!!!!" << std::endl; jpeg_destroy_decompress(&cinfo); return 0; } /* Now we can initialize the JPEG decompression object. */ + if( statesuspension == 0 ) + { jpeg_create_decompress(&cinfo); - /* Step 2: specify data source (eg, a file) */ #ifdef GDCM_JPG_DEBUG printf("Entree Step 2\n"); #endif //GDCM_JPG_DEBUG - jpeg_stdio_src(&cinfo, fp); + jpeg_stdio_src(&cinfo, fp, this, 1); + } + else + { + jpeg_stdio_src(&cinfo, fp, this, 0); + } /* Step 3: read file parameters with jpeg_read_header() */ #ifdef GDCM_JPG_DEBUG printf("Entree Step 3\n"); #endif //GDCM_JPG_DEBUG - (void) jpeg_read_header(&cinfo, TRUE); + if( statesuspension < 2 ) + { + if( jpeg_read_header(&cinfo, TRUE) == JPEG_SUSPENDED ) + { + std::cerr << "Suspension: jpeg_read_header" << std::endl; + } /* We can ignore the return value from jpeg_read_header since * (a) suspension is not possible with the stdio data source, and @@ -474,6 +489,7 @@ bool gdcm_read_JPEG_file ( std::ifstream* fp, void* image_buffer ) cinfo.out_color_space = JCS_UNKNOWN; } + } //statesuspension < 2 #ifdef GDCM_JPG_DEBUG printf("--------------Header contents :----------------\n"); @@ -508,7 +524,12 @@ bool gdcm_read_JPEG_file ( std::ifstream* fp, void* image_buffer ) printf("Entree Step 5\n"); #endif //GDCM_JPG_DEBUG - (void) jpeg_start_decompress(&cinfo); + if(statesuspension < 3 ) + { + if( jpeg_start_decompress(&cinfo) == FALSE ) + { + std::cerr << "Suspension: jpeg_start_decompress" << std::endl; + } /* We can ignore the return value since suspension is not possible * with the stdio data source. */ @@ -545,8 +566,13 @@ bool gdcm_read_JPEG_file ( std::ifstream* fp, void* image_buffer ) printf ("cinfo.output_height %d cinfo.output_width %d\n", cinfo.output_height,cinfo.output_width); #endif //GDCM_JPG_DEBUG - pimage=(char *)image_buffer; + SampBuffer = buffer; + } // statesuspension < 3 + else + { + buffer = (JSAMPARRAY)SampBuffer; + } int bufsize = cinfo.output_width * cinfo.output_components; size_t rowsize = bufsize * sizeof(JSAMPLE); @@ -557,7 +583,12 @@ bool gdcm_read_JPEG_file ( std::ifstream* fp, void* image_buffer ) */ //printf( "scanlines: %d\n",cinfo.output_scanline); - (void) jpeg_read_scanlines(&cinfo, buffer, 1); + if( jpeg_read_scanlines(&cinfo, buffer, 1) == 0 ) + { + std::cerr << "Suspension: jpeg_read_scanlines" << std::endl; + statesuspension = 3; + return true; + } // The ijg has no notion of big endian, therefore always swap the jpeg stream #if defined(GDCM_WORDS_BIGENDIAN) && (CMAKE_BITS_IN_JSAMPLE != 8) uint16_t *buffer16 = (uint16_t*)*buffer; @@ -575,7 +606,10 @@ bool gdcm_read_JPEG_file ( std::ifstream* fp, void* image_buffer ) printf("Entree Step 7\n"); #endif //GDCM_JPG_DEBUG - (void) jpeg_finish_decompress(&cinfo); + if( jpeg_finish_decompress(&cinfo) == FALSE ) + { + std::cerr << "Suspension: jpeg_finish_decompress" << std::endl; + } /* We can ignore the return value since suspension is not possible * with the stdio data source. @@ -590,6 +624,7 @@ bool gdcm_read_JPEG_file ( std::ifstream* fp, void* image_buffer ) /* This is an important step since it will release a good deal of memory. */ jpeg_destroy_decompress(&cinfo); + //std::cerr << "jpeg_destroy_decompress" << std::endl; /* After finish_decompress, we can close the input file. * Here we postpone it until after no more JPEG errors are possible, @@ -662,7 +697,7 @@ bool gdcm_read_JPEG_memory ( const JOCTET* input_buffer, const size_t buflen, void* image_buffer, size_t *howManyRead, size_t *howManyWritten) { - char* pimage=(char *)image_buffer; + volatile char * pimage=(volatile char *)image_buffer; JOCTET* input = (JOCTET*) input_buffer; /* This struct contains the JPEG decompression parameters and pointers to @@ -848,11 +883,11 @@ bool gdcm_read_JPEG_memory ( const JOCTET* input_buffer, const size_t buflen, for(unsigned int i=0;i> 8) | (buffer16[i] << 8 ); #else - memcpy( pimage, *buffer,rowsize); + memcpy( (void*)pimage, *buffer,rowsize); #endif //GDCM_WORDS_BIGENDIAN pimage+=rowsize; } - + /* Step 7: Finish decompression */ #ifdef GDCM_JPG_DEBUG printf("Entree Step 7\n"); diff --git a/src/gdcmJpeg12.cxx b/src/gdcmJpeg12.cxx index 48c36284..0478a2e3 100644 --- a/src/gdcmJpeg12.cxx +++ b/src/gdcmJpeg12.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmJpeg12.cxx,v $ Language: C++ - Date: $Date: 2005/01/20 17:17:12 $ - Version: $Revision: 1.29 $ + Date: $Date: 2005/01/24 14:52:50 $ + Version: $Revision: 1.30 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -28,6 +28,9 @@ extern "C" { #define gdcm_write_JPEG_file gdcm_write_JPEG_file12 #define gdcm_read_JPEG_file gdcm_read_JPEG_file12 #define gdcm_read_JPEG_memory gdcm_read_JPEG_memory12 +//#define StateSuspension StateSuspension12 +#define SampBuffer SampBuffer12 +//#define pimage pimage12 #include "gdcmJpeg.cxx" diff --git a/src/gdcmJpeg16.cxx b/src/gdcmJpeg16.cxx index e7b2e6c6..481d339f 100644 --- a/src/gdcmJpeg16.cxx +++ b/src/gdcmJpeg16.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmJpeg16.cxx,v $ Language: C++ - Date: $Date: 2005/01/20 17:17:12 $ - Version: $Revision: 1.8 $ + Date: $Date: 2005/01/24 14:52:50 $ + Version: $Revision: 1.9 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -28,6 +28,9 @@ extern "C" { #define gdcm_write_JPEG_file gdcm_write_JPEG_file16 #define gdcm_read_JPEG_file gdcm_read_JPEG_file16 #define gdcm_read_JPEG_memory gdcm_read_JPEG_memory16 +//#define StateSuspension StateSuspension16 +#define SampBuffer SampBuffer16 +//#define pimage pimage16 #include "gdcmJpeg.cxx" diff --git a/src/gdcmJpeg8.cxx b/src/gdcmJpeg8.cxx index 8a68f632..4c649ede 100644 --- a/src/gdcmJpeg8.cxx +++ b/src/gdcmJpeg8.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmJpeg8.cxx,v $ Language: C++ - Date: $Date: 2005/01/20 17:17:12 $ - Version: $Revision: 1.14 $ + Date: $Date: 2005/01/24 14:52:50 $ + Version: $Revision: 1.15 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -28,6 +28,9 @@ extern "C" { #define gdcm_write_JPEG_file gdcm_write_JPEG_file8 #define gdcm_read_JPEG_file gdcm_read_JPEG_file8 #define gdcm_read_JPEG_memory gdcm_read_JPEG_memory8 +//#define StateSuspension StateSuspension8 +#define SampBuffer SampBuffer8 +//#define pimage pimage8 #include "gdcmJpeg.cxx" diff --git a/src/gdcmPixelReadConvert.cxx b/src/gdcmPixelReadConvert.cxx index f2bbb902..eae74e04 100644 --- a/src/gdcmPixelReadConvert.cxx +++ b/src/gdcmPixelReadConvert.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelReadConvert.cxx,v $ Language: C++ - Date: $Date: 2005/01/23 10:12:34 $ - Version: $Revision: 1.32 $ + Date: $Date: 2005/01/24 14:52:50 $ + Version: $Revision: 1.33 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -389,25 +389,26 @@ void PixelReadConvert::ConvertReorderEndianity() bool PixelReadConvert::ReadAndDecompressJPEGFramesFromFile( std::ifstream *fp ) { // Pointer to the Raw image - uint8_t *localRaw = Raw; + //uint8_t *localRaw = Raw; // Precompute the offset localRaw will be shifted with int length = XSize * YSize * SamplesPerPixel; int numberBytes = BitsAllocated / 8; - // Loop on the fragment[s] - for( JPEGFragmentsInfo::JPEGFragmentsList::iterator - it = JPEGInfo->Fragments.begin(); - it != JPEGInfo->Fragments.end(); - ++it ) - { - (*it)->DecompressJPEGFramesFromFile(fp, localRaw, BitsStored ); - - // Advance to next free location in Raw - // for next fragment decompression (if any) - - localRaw += length * numberBytes; - } +// // Loop on the fragment[s] +// for( JPEGFragmentsInfo::JPEGFragmentsList::iterator +// it = JPEGInfo->Fragments.begin(); +// it != JPEGInfo->Fragments.end(); +// ++it ) +// { +// (*it)->DecompressJPEGFramesFromFile(fp, localRaw, BitsStored ); +// +// // Advance to next free location in Raw +// // for next fragment decompression (if any) +// +// localRaw += length * numberBytes; +// } + JPEGInfo->DecompressJPEGFramesFromFile(fp, Raw, BitsStored, numberBytes, length ); return true; } @@ -501,24 +502,24 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp ) return false; } - if ( ( ZSize == 1 ) && ( JPEGInfo->Fragments.size() > 1 ) ) - { - // we have one frame split into several fragments - // we will pack those fragments into a single buffer and - // read from it - return ReadAndDecompressJPEGSingleFrameFragmentsFromFile( fp ); - } - else if (JPEGInfo->Fragments.size() == (size_t)ZSize) - { +// if ( ( ZSize == 1 ) && ( JPEGInfo->Fragments.size() > 1 ) ) +// { +// // we have one frame split into several fragments +// // we will pack those fragments into a single buffer and +// // read from it +// return ReadAndDecompressJPEGSingleFrameFragmentsFromFile( fp ); +// } +// else if (JPEGInfo->Fragments.size() == (size_t)ZSize) +// { // suppose each fragment is a frame return ReadAndDecompressJPEGFramesFromFile( fp ); - } - else - { - // The dicom image contains frames containing fragments of images - // a more complex algorithm :-) - return ReadAndDecompressJPEGFragmentedFramesFromFile( fp ); - } +// } +// else +// { +// // The dicom image contains frames containing fragments of images +// // a more complex algorithm :-) +// return ReadAndDecompressJPEGFragmentedFramesFromFile( fp ); +// } } /** diff --git a/src/jdatasrc.cxx b/src/jdatasrc.cxx index e6c64430..199431c3 100644 --- a/src/jdatasrc.cxx +++ b/src/jdatasrc.cxx @@ -24,6 +24,9 @@ typedef struct { std::ifstream *infile; /* source stream */ JOCTET * buffer; /* start of buffer */ boolean start_of_file; /* have we gotten any data yet? */ + //PixelReadConvert *pixels; + gdcm::JPEGFragment *frag; + size_t bytes_read; } my_source_mgr; typedef my_source_mgr * my_src_ptr; @@ -87,8 +90,25 @@ fill_input_buffer (j_decompress_ptr cinfo) { my_src_ptr src = (my_src_ptr) cinfo->src; - src->infile->read( (char*)src->buffer, INPUT_BUF_SIZE); + //std::cerr << "Before comp:" << src->bytes_read << " / " << src->frag->Length << std::endl; + if( src->bytes_read == src->frag->Length ) + { + //std::cerr << "Sweet finished this fragment" << std::endl; + return FALSE; + } + + size_t input_buf_size = INPUT_BUF_SIZE; + if( (src->bytes_read + INPUT_BUF_SIZE) > src->frag->Length ) + { + //std::cerr << "Woula error:" << src->bytes_read << " / " << src->frag->Length << std::endl; + input_buf_size = src->frag->Length - src->bytes_read; + //std::cerr << "Ok only reading: " << input_buf_size << " / " << INPUT_BUF_SIZE << std::endl; + } + + //std::cerr << "infile read:" << src->pub.bytes_in_buffer << std::endl; + src->infile->read( (char*)src->buffer, input_buf_size); size_t nbytes = src->infile->gcount(); + //std::cerr << "input_buf_size=" << input_buf_size << " and nbytes=" << nbytes << std::endl; if (nbytes <= 0) { if (src->start_of_file) /* Treat empty input file as fatal error */ @@ -103,8 +123,13 @@ fill_input_buffer (j_decompress_ptr cinfo) src->pub.next_input_byte = src->buffer; src->pub.bytes_in_buffer = nbytes; src->start_of_file = FALSE; + src->bytes_read += nbytes; + return TRUE; + // otherwise cause a suspension return + //std::cerr << "fill_input_buffer" << std::endl; + //return FALSE; } @@ -123,6 +148,7 @@ fill_input_buffer (j_decompress_ptr cinfo) METHODDEF(void) skip_input_data (j_decompress_ptr cinfo, long num_bytes) { + //std::cerr << "skip_input_data:" << num_bytes << std::endl; my_src_ptr src = (my_src_ptr) cinfo->src; /* Just a dumb implementation for now. Could use fseek() except @@ -176,7 +202,7 @@ term_source (j_decompress_ptr cinfo) */ GLOBAL(void) -jpeg_stdio_src (j_decompress_ptr cinfo, std::ifstream * infile) +jpeg_stdio_src (j_decompress_ptr cinfo, std::ifstream * infile, gdcm::JPEGFragment *frag, int flag) { my_src_ptr src; @@ -204,6 +230,18 @@ jpeg_stdio_src (j_decompress_ptr cinfo, std::ifstream * infile) src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ src->pub.term_source = term_source; src->infile = infile; + + if( flag ) + { src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ src->pub.next_input_byte = NULL; /* until buffer loaded */ + src->frag = frag; + src->bytes_read = 0; + } + else + { + //only upate the new fragment + src->frag = frag; + src->bytes_read = 0; + } } -- 2.45.1