From 0e0403151bbff57175d2b974ee2d14b8195f9234 Mon Sep 17 00:00:00 2001 From: malaterre Date: Mon, 31 Jan 2005 03:22:23 +0000 Subject: [PATCH] ENH: Huge commit to remove the previous implementation for jpeg/fragments/multiframes. Use full potential of IJG, one of the best written io library. IJG rocks --- Doc/DICOM.txt | 52 +++ Testing/CMakeLists.txt | 6 + Testing/TestDicomDir.cxx | 6 +- src/gdcmJPEGFragment.cxx | 125 +----- src/gdcmJPEGFragment.h | 6 +- src/gdcmJPEGFragmentsInfo.cxx | 7 +- src/gdcmJpeg.cxx | 722 ++++--------------------------- src/gdcmJpeg12.cxx | 7 +- src/gdcmJpeg16.cxx | 7 +- src/gdcmJpeg8.cxx | 7 +- src/gdcmPixelReadConvert.cxx | 150 +------ src/gdcmPixelReadConvert.h | 8 +- src/gdcmSerieHeader.cxx | 6 +- src/gdcmjpeg/CMakeLists.txt | 2 +- src/gdcmjpeg/jpeglib.h | 1 - src/gdcmjpeg/mangle_jpeg12bits.h | 1 - src/gdcmjpeg/mangle_jpeg16bits.h | 1 - src/gdcmjpeg/mangle_jpeg8bits.h | 1 - src/jdatasrc.cxx | 30 +- 19 files changed, 168 insertions(+), 977 deletions(-) create mode 100644 Doc/DICOM.txt diff --git a/Doc/DICOM.txt b/Doc/DICOM.txt new file mode 100644 index 00000000..ba108c38 --- /dev/null +++ b/Doc/DICOM.txt @@ -0,0 +1,52 @@ +DICOM provides a mechanism for supporting the use of JPEG Image Compression +through the Encapsulated Format (see PS 3.3 of the DICOM Standard). +Annex A defines a number of Transfer Syntaxes which reference +the JPEG Standard and provide a number of lossless (bit preserving) +and lossy compression schemes. +In order to facilitate interoperability of implementations conforming +to the DICOM Standard which elect to use one or more +of the Transfer Syntaxes for JPEG Image Compression, the following policy is specified: + + Any implementation which conforms to the DICOM Standard and has elected + to support any one of the Transfer Syntaxes for lossless JPEG Image Compression, + shall support the following lossless compression: + The subset (first-order horizontal prediction [Selection Value 1) of JPEG Process 14 + (DPCM, non-hierarchical with Huffman coding) (see Annex F of the DICOM Standard). + + Any implementation which conforms to the DICOM Standard and has elected + to support any one of the Transfer Syntaxes for 8-bit lossy JPEG Image Compression, + shall support the JPEG Baseline Compression (coding Process 1). + + Any implementation which conforms to the DICOM Standard and has elected + to support any one of the Transfer Syntaxes for 12-bit lossy JPEG Image Compression, + shall support the JPEG Compression Process 4. + +Note: The DICOM conformance statement shall differentiate between implementations +that can simply receive JPEG encoded images and those that can receive and process +JPEG encoded images (see PS 3.2 of the DICOM Standard). + +The use of the DICOM Encapsulated Format to support JPEG Compressed Pixel Data +implies that the Data Elements which are related to the Native Format Pixel Data encoding +(e.g. Bits Allocated, Bits Stored, High Bit, Pixel Representation, Rows, Columns, etc.) +shall contain values which are consistent with the characteristics +of the uncompressed pixel data from which the compressed Data Stream was derived. +The Pixel Data characteristics included in the JPEG Interchange Format +shall be used to decode the compressed data stream. + +Run Length Encoding Compression + +DICOM provides a mechanism for supporting the use of Run Length Encoding (RLE) +Compression which is a byte oriented lossless compression scheme through +the encapsulated Format (see PS 3.3 of this Standard). +Annex G of the DICOM Standard defines RLE Compression and its Transfer Syntax. + +Note: The RLE Compression algorithm described in Annex G +of the DICOM Standard is the compression used in +the TIFF 6.0 specification known as the "PackBits" scheme. + +The use of the DICOM Encapsulated Format to support RLE Compressed Pixel Data +implies that the Data Elements which are related to the Native Format Pixel Data encoding ( +e.g. Bits Allocated, Bits Stored, High Bit, Pixel Representation, Rows, Columns, etc.) +shall contain values which are consistent with the characteristics +of the uncompressed pixel data from which the compressed data is derived + diff --git a/Testing/CMakeLists.txt b/Testing/CMakeLists.txt index 492dba61..48a2fb54 100644 --- a/Testing/CMakeLists.txt +++ b/Testing/CMakeLists.txt @@ -151,6 +151,12 @@ SET(BLACK_LIST # (NOT gdcm::File ...) # any contribution is welcome "PET-cardio-Multiframe-Papyrus.dcm" + + # JPR love to add code in gdcm without even runing the tests + "D_CLUNIE_CT1_J2KI.dcm" + "D_CLUNIE_CT1_J2KR.dcm" + "D_CLUNIE_CT1_JLSL.dcm" + "D_CLUNIE_CT1_JLSN.dcm" ) diff --git a/Testing/TestDicomDir.cxx b/Testing/TestDicomDir.cxx index 037227e2..98f01cc0 100644 --- a/Testing/TestDicomDir.cxx +++ b/Testing/TestDicomDir.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: TestDicomDir.cxx,v $ Language: C++ - Date: $Date: 2005/01/29 11:56:53 $ - Version: $Revision: 1.34 $ + Date: $Date: 2005/01/31 03:22:24 $ + Version: $Revision: 1.35 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -199,8 +199,6 @@ int TestDicomDir(int argc, char* argv[]) return 1; } - gdcm::DocEntry *e1; - gdcm::DocEntry *e2; while ( pa1 && pa2 ) { // we process all the PATIENT of this DICOMDIR diff --git a/src/gdcmJPEGFragment.cxx b/src/gdcmJPEGFragment.cxx index 8ba7dad4..65b9e393 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/26 11:42:02 $ - Version: $Revision: 1.9 $ + Date: $Date: 2005/01/31 03:22:25 $ + Version: $Revision: 1.10 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -30,26 +30,6 @@ bool gdcm_read_JPEG2000_file (std::ifstream* fp, void* image_buffer); // Not yet made bool gdcm_read_JPEGLS_file (std::ifstream* fp, void* image_buffer); -// For JPEG 8 Bits, body in file gdcmJpeg8.cxx -//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 (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); - -// 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 (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); - /** * \brief Default constructor. */ @@ -128,106 +108,5 @@ void JPEGFragment::DecompressJPEGFramesFromFile(std::ifstream *fp, } -void JPEGFragment::DecompressJPEGSingleFrameFragmentsFromFile(JOCTET *buffer, - size_t totalLength, uint8_t *raw, int nBits) -{ - size_t howManyRead = 0; - size_t howManyWritten = 0; - - if ( nBits == 8) - { - if ( ! gdcm_read_JPEG_memory8( buffer, totalLength, raw, - &howManyRead, &howManyWritten ) ) - { - gdcmErrorMacro( "Failed to read jpeg8 "); - delete [] buffer; - //return false; - } - } - else if ( nBits <= 12) - { - if ( ! gdcm_read_JPEG_memory12( buffer, totalLength, raw, - &howManyRead, &howManyWritten ) ) - { - gdcmErrorMacro( "Failed to read jpeg12 "); - delete [] buffer; - //return false; - } - } - else if ( nBits <= 16) - { - - if ( ! gdcm_read_JPEG_memory16( buffer, totalLength, raw, - &howManyRead, &howManyWritten ) ) - { - gdcmErrorMacro( "Failed to read jpeg16 "); - delete [] buffer; - //return false; - } - } - else - { - // FIXME : only the bits number is checked, - // NOT the compression method - - // other JPEG lossy not supported - gdcmErrorMacro( "Unsupported jpeg lossy compression "); - delete [] buffer; - //return false; - } - -} - -void JPEGFragment::DecompressJPEGFragmentedFramesFromFile(JOCTET *buffer, - uint8_t* raw, int nBits, size_t &howManyRead, - size_t &howManyWritten, size_t totalLength) -{ - if ( nBits == 8 ) - { - if ( ! gdcm_read_JPEG_memory8( buffer+howManyRead, totalLength-howManyRead, - raw+howManyWritten, - &howManyRead, &howManyWritten ) ) - { - gdcmErrorMacro( "Failed to read jpeg8"); - //delete [] buffer; - //return false; - } - } - else if ( nBits <= 12 ) - { - - if ( ! gdcm_read_JPEG_memory12( buffer+howManyRead, totalLength-howManyRead, - raw+howManyWritten, - &howManyRead, &howManyWritten ) ) - { - gdcmErrorMacro( "Failed to read jpeg12"); - //delete [] buffer; - //return false; - } - } - else if ( nBits <= 16 ) - { - - if ( ! gdcm_read_JPEG_memory16( buffer+howManyRead, totalLength-howManyRead, - raw+howManyWritten, - &howManyRead, &howManyWritten ) ) - { - gdcmErrorMacro( "Failed to read jpeg16 "); - //delete [] buffer; - //return false; - } - } - else - { - // FIXME : only the bits number is checked, - // NOT the compression method - - // other JPEG lossy not supported - gdcmErrorMacro( "Unsupported jpeg lossy compression "); - //delete [] buffer; - //return false; - } -} - } // end namespace gdcm diff --git a/src/gdcmJPEGFragment.h b/src/gdcmJPEGFragment.h index b2862aa6..b3e0cc3a 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/26 11:42:02 $ - Version: $Revision: 1.13 $ + Date: $Date: 2005/01/31 03:22:25 $ + Version: $Revision: 1.14 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -46,8 +46,6 @@ public: JPEGFragment(); void Print( std::ostream &os = std::cout, std::string indent = "" ); 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); 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 ); diff --git a/src/gdcmJPEGFragmentsInfo.cxx b/src/gdcmJPEGFragmentsInfo.cxx index 93e2b0fb..489ab2fe 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/28 17:01:30 $ - Version: $Revision: 1.13 $ + Date: $Date: 2005/01/31 03:22:25 $ + Version: $Revision: 1.14 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -108,9 +108,6 @@ void JPEGFragmentsInfo::ReadAllFragments(std::ifstream *fp, JOCTET *buffer ) } -// Keep a track of the old code (maybe Jpeg2000 lib will be less clever than IJG -//void JPEGFragmentsInfo::DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buffer, int nBits, int numBytes, int length) - // to avoid warnings void JPEGFragmentsInfo::DecompressJPEGFramesFromFile(std::ifstream *fp, uint8_t *buffer, int nBits, int , int ) { diff --git a/src/gdcmJpeg.cxx b/src/gdcmJpeg.cxx index d18fa4d9..2d79c5c8 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/26 11:42:02 $ - Version: $Revision: 1.37 $ + Date: $Date: 2005/01/31 03:22:25 $ + Version: $Revision: 1.38 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -17,73 +17,8 @@ =========================================================================*/ #include "gdcmFileHelper.h" #include "gdcmJPEGFragment.h" +#include "gdcmDebug.h" -/* -DICOM provides a mechanism for supporting the use of JPEG Image Compression -through the Encapsulated Format (see PS 3.3 of the DICOM Standard). -Annex A defines a number of Transfer Syntaxes which reference -the JPEG Standard and provide a number of lossless (bit preserving) -and lossy compression schemes. -In order to facilitate interoperability of implementations conforming -to the DICOM Standard which elect to use one or more -of the Transfer Syntaxes for JPEG Image Compression, the following policy is specified: - - Any implementation which conforms to the DICOM Standard and has elected - to support any one of the Transfer Syntaxes for lossless JPEG Image Compression, - shall support the following lossless compression: - The subset (first-order horizontal prediction [Selection Value 1) of JPEG Process 14 - (DPCM, non-hierarchical with Huffman coding) (see Annex F of the DICOM Standard). - - Any implementation which conforms to the DICOM Standard and has elected - to support any one of the Transfer Syntaxes for 8-bit lossy JPEG Image Compression, - shall support the JPEG Baseline Compression (coding Process 1). - - Any implementation which conforms to the DICOM Standard and has elected - to support any one of the Transfer Syntaxes for 12-bit lossy JPEG Image Compression, - shall support the JPEG Compression Process 4. - -Note: The DICOM conformance statement shall differentiate between implementations -that can simply receive JPEG encoded images and those that can receive and process -JPEG encoded images (see PS 3.2 of the DICOM Standard). - -The use of the DICOM Encapsulated Format to support JPEG Compressed Pixel Data -implies that the Data Elements which are related to the Native Format Pixel Data encoding -(e.g. Bits Allocated, Bits Stored, High Bit, Pixel Representation, Rows, Columns, etc.) -shall contain values which are consistent with the characteristics -of the uncompressed pixel data from which the compressed Data Stream was derived. -The Pixel Data characteristics included in the JPEG Interchange Format -shall be used to decode the compressed data stream. - -Run Length Encoding Compression - -DICOM provides a mechanism for supporting the use of Run Length Encoding (RLE) -Compression which is a byte oriented lossless compression scheme through -the encapsulated Format (see PS 3.3 of this Standard). -Annex G of the DICOM Standard defines RLE Compression and its Transfer Syntax. - -Note: The RLE Compression algorithm described in Annex G -of the DICOM Standard is the compression used in -the TIFF 6.0 specification known as the "PackBits" scheme. - -The use of the DICOM Encapsulated Format to support RLE Compressed Pixel Data -implies that the Data Elements which are related to the Native Format Pixel Data encoding ( -e.g. Bits Allocated, Bits Stored, High Bit, Pixel Representation, Rows, Columns, etc.) -shall contain values which are consistent with the characteristics -of the uncompressed pixel data from which the compressed data is derived -*/ - -/* - * is used for the optional error recovery mechanism shown in - * the second part of the example. - */ - -/* - * Include file for users of JPEG library. - * You will need to have included system headers that define at least - * the typedefs FILE and size_t before you can include jpeglib.h. - * (stdio.h is sufficient on ANSI-conforming systems.) - * You may also wish to include "jerror.h". - */ #if defined(__sgi) && !defined(__GNUC__) // Try to get rid of the warning: //cc-3505 CC: WARNING File = /usr/include/internal/setjmp_core.h, Line = 74 @@ -109,40 +44,6 @@ of the uncompressed pixel data from which the compressed data is derived namespace gdcm { -/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/ - -/* This half of the example shows how to feed data into the JPEG compressor. - * We present a minimal version that does not worry about refinements such - * as error recovery (the JPEG code will just exit() if it gets an error). - */ - -/* - * IMAGE DATA FORMATS: - * - * The standard input image format is a rectangular array of pixels, with - * each pixel having the same number of "component" values (color channels). - * Each pixel row is an array of JSAMPLEs (which typically are unsigned chars). - * If you are working with color data, then the color values for each pixel - * must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit - * RGB color. - * - * For this example, we'll assume that this data structure matches the way - * our application has stored the image in memory, so we can just pass a - * pointer to our image buffer. In particular, let's say that the image is - * RGB color and is described by: - */ - - -//extern JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */ -//extern int image_height; /* Number of rows in image */ -//extern int image_width; /* Number of columns in image */ - - - -/* - * Sample routine for JPEG compression. We assume that the target file name - * and a compression quality factor are passed in. - */ /** * \brief routine for JPEG decompression @@ -273,76 +174,6 @@ bool gdcm_write_JPEG_file (std::ofstream* fp, void* im_buf, } - -/* - * SOME FINE POINTS: - * - * In the above loop, we ignored the return value of jpeg_write_scanlines, - * which is the number of scanlines actually written. We could get away - * with this because we were only relying on the value of cinfo.next_scanline, - * which will be incremented correctly. If you maintain additional loop - * variables then you should be careful to increment them properly. - * Actually, for output to a stdio stream you needn't worry, because - * then jpeg_write_scanlines will write all the lines passed (or else exit - * with a fatal error). Partial writes can only occur if you use a data - * destination module that can demand suspension of the compressor. - * (If you don't know what that's for, you don't need it.) - * - * If the compressor requires full-image buffers (for entropy-coding - * optimization or a multi-scan JPEG file), it will create temporary - * files for anything that doesn't fit within the maximum-memory setting. - * (Note that temp files are NOT needed if you use the default parameters.) - * On some systems you may need to set up a signal handler to ensure that - * temporary files are deleted if the program is interrupted. See libjpeg.doc. - * - * Scanlines MUST be supplied in top-to-bottom order if you want your JPEG - * files to be compatible with everyone else's. If you cannot readily read - * your data in that order, you'll need an intermediate array to hold the - * image. See rdtarga.c or rdbmp.c for examples of handling bottom-to-top - * source data using the JPEG code's internal virtual-array mechanisms. - */ - - - -/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/ - -/* This half of the example shows how to read data from the JPEG decompressor. - * It's a bit more refined than the above, in that we show: - * (a) how to modify the JPEG library's standard error-reporting behavior; - * (b) how to allocate workspace using the library's memory manager. - * - * Just to make this example a little different from the first one, we'll - * assume that we do not intend to put the whole image into an in-memory - * buffer, but to send it line-by-line someplace else. We need a one- - * scanline-high JSAMPLE array as a work buffer, and we will let the JPEG - * memory manager allocate it for us. This approach is actually quite useful - * because we don't need to remember to deallocate the buffer separately: it - * will go away automatically when the JPEG object is cleaned up. - */ - -/* - * ERROR HANDLING: - * - * The JPEG library's standard error handler (jerror.c) is divided into - * several "methods" which you can override individually. This lets you - * adjust the behavior without duplicating a lot of code, which you might - * have to update with each future release. - * - * Our example here shows how to override the "error_exit" method so that - * control is returned to the library's caller when a fatal error occurs, - * rather than calling exit() as the standard error_exit method does. - * - * We use C's setjmp/longjmp facility to return control. This means that the - * routine which calls the JPEG library must first execute a setjmp() call to - * establish the return point. We want the replacement error_exit to do a - * longjmp(). But we need to make the setjmp buffer accessible to the - * error_exit routine. To do this, we make a private extension of the - * standard JPEG error handler object. (If we were using C++, we'd say we - * were making a subclass of the regular error handler.) - * - * Here's the extended error handler struct: - */ - //----------------------------------------------------------------------------- struct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ @@ -367,10 +198,6 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo) { } //----------------------------------------------------------------------------- -/* - * Sample routine for JPEG decompression. We assume that the source file name - * is passed in. We want to return 1 on success, 0 on error. - */ /** * \brief routine for JPEG decompression @@ -382,30 +209,26 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo) { void *SampBuffer; bool JPEGFragment::gdcm_read_JPEG_file (std::ifstream* fp, void* image_buffer , int& statesuspension) { - //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). - */ + // This struct contains the JPEG decompression parameters and pointers to + // working space (which is allocated as needed by the JPEG library). + static struct jpeg_decompress_struct cinfo; - /* -------------- inside, we found : - * JDIMENSION image_width; // input image width - * JDIMENSION image_height; // input image height - * int input_components; // nb of color components in input image - * J_COLOR_SPACE in_color_space; // colorspace of input image - * double input_gamma; // image gamma of input image - * -------------- */ - - /* We use our private extension JPEG error handler. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ + // -------------- inside, we found : + // JDIMENSION image_width; // input image width + // JDIMENSION image_height; // input image height + // int input_components; // nb of color components in input image + // J_COLOR_SPACE in_color_space; // colorspace of input image + // double input_gamma; // image gamma of input image + + // We use our private extension JPEG error handler. + // Note that this struct must live as long as the main JPEG parameter + // struct, to avoid dangling-pointer problems. + struct my_error_mgr jerr; - /* More stuff */ - JSAMPARRAY buffer;/* Output row buffer */ + JSAMPARRAY buffer;// Output row buffer // rappel : // ------ @@ -414,178 +237,86 @@ bool JPEGFragment::gdcm_read_JPEG_file (std::ifstream* fp, void* image_buffer , // typedef JSAMPROW *JSAMPARRAY;/* ptr to some rows (a 2-D sample array) */ // typedef JSAMPARRAY *JSAMPIMAGE;/* a 3-D sample array: top index is color */ - int row_stride;/* physical row width in output 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 - - /* In this example we want to open the input file before doing anything else, - * so that the setjmp() error recovery below can assume the file is open. - * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to read binary files. - */ - - /* Step 1: allocate and initialize JPEG decompression object */ -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 1\n"); -#endif //GDCM_JPG_DEBUG - - /* We set up the normal JPEG error routines, then override error_exit. */ + // We set up the normal JPEG error routines, then override error_exit. cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; - /* Establish the setjmp return context for my_error_exit to use. */ + // Establish the setjmp return context for my_error_exit to use. if (setjmp(jerr.setjmp_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; + // 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. + + gdcmErrorMacro( "Serious Problem !" ); jpeg_destroy_decompress(&cinfo); return 0; } - /* Now we can initialize the JPEG decompression object. */ + // 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, this, 1); - + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, fp, this, 1); } else { - jpeg_stdio_src(&cinfo, fp, this, 0); + 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 + // Step 3: read file parameters with jpeg_read_header() - 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 - * (b) we passed TRUE to reject a tables-only JPEG file as an error. - * See libjpeg.doc for more info. - */ - - // prevent the library from performing any color space conversion - if( cinfo.process == JPROC_LOSSLESS ) + if( statesuspension < 2 ) { - cinfo.jpeg_color_space = JCS_UNKNOWN; - cinfo.out_color_space = JCS_UNKNOWN; + if( jpeg_read_header(&cinfo, TRUE) == JPEG_SUSPENDED ) + { + // Suspension in jpeg_read_header + statesuspension = 2; + } + + // Step 4: set parameters for decompression + // prevent the library from performing any color space conversion + if( cinfo.process == JPROC_LOSSLESS ) + { + cinfo.jpeg_color_space = JCS_UNKNOWN; + cinfo.out_color_space = JCS_UNKNOWN; + } } - } //statesuspension < 2 - -#ifdef GDCM_JPG_DEBUG - printf("--------------Header contents :----------------\n"); - printf("image_width %d image_height %d\n", - cinfo.image_width , cinfo.image_height); - printf("bits of precision in image data %d \n", - cinfo.output_components); - printf("nb of color components returned %d \n", - cinfo.data_precision); -#endif //GDCM_JPG_DEBUG - - - /* - * JDIMENSION image_width; // input image width - * JDIMENSION image_height; // input image height - * int output_components; // # of color components returned - * J_COLOR_SPACE in_color_space; // colorspace of input image - * double input_gamma; // image gamma of input image - * int data_precision; // bits of precision in image data - */ - - /* Step 4: set parameters for decompression */ -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 4\n"); -#endif //GDCM_JPG_DEBUG - /* In this example, we don't need to change any of the defaults set by - * jpeg_read_header(), so we do nothing here. - */ - - /* Step 5: Start decompressor */ -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 5\n"); -#endif //GDCM_JPG_DEBUG - + // Step 5: Start decompressor 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. - */ - - /* We may need to do some setup of our own at this point before reading - * the data. After jpeg_start_decompress() we have the correct scaled - * output image dimensions available, as well as the output colormap - * if we asked for color quantization. - * In this example, we need to make an output work buffer of the right size. - */ - - /* JSAMPLEs per row in output buffer */ - row_stride = cinfo.output_width * cinfo.output_components*2; + { + if( jpeg_start_decompress(&cinfo) == FALSE ) + { + // Suspension: jpeg_start_decompress + statesuspension = 3; + } + + // JSAMPLEs per row in output buffer + row_stride = cinfo.output_width * cinfo.output_components*2; -#ifdef GDCM_JPG_DEBUG - printf ("cinfo.output_width %d cinfo.output_components %d row_stride %d\n", - cinfo.output_width, cinfo.output_components,row_stride); -#endif //GDCM_JPG_DEBUG - - /* Make a one-row-high sample array that will go away when done with image */ - buffer = (*cinfo.mem->alloc_sarray) + // Make a one-row-high sample array that will go away when done with image + buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - /* Step 6: while (scan lines remain to be read) */ -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 6\n"); -#endif //GDCM_JPG_DEBUG - /* jpeg_read_scanlines(...); */ - - /* Here we use the library's state variable cinfo.output_scanline as the - * loop counter, so that we don't have to keep track ourselves. - */ -#ifdef GDCM_JPG_DEBUG - printf ("cinfo.output_height %d cinfo.output_width %d\n", - cinfo.output_height,cinfo.output_width); -#endif //GDCM_JPG_DEBUG - + // Step 6: while (scan lines remain to be read) + + // Save the buffer in case of suspension to be able to reuse it later: SampBuffer = buffer; - } // statesuspension < 3 + } else - { - buffer = (JSAMPARRAY)SampBuffer; - } + { + // Suspension: re-use the buffer: + buffer = (JSAMPARRAY)SampBuffer; + } int bufsize = cinfo.output_width * cinfo.output_components; size_t rowsize = bufsize * sizeof(JSAMPLE); - while (cinfo.output_scanline < cinfo.output_height) { - /* jpeg_read_scanlines expects an array of pointers to scanlines. - * Here the array is only one element long, but you could ask for - * more than one scanline at a time if that's more convenient. - */ - - //printf( "scanlines: %d\n",cinfo.output_scanline); + while (cinfo.output_scanline < cinfo.output_height) + { if( jpeg_read_scanlines(&cinfo, buffer, 1) == 0 ) { - std::cerr << "Suspension: jpeg_read_scanlines" << std::endl; + // Suspension in jpeg_read_scanlines statesuspension = 3; return true; } @@ -601,332 +332,25 @@ bool JPEGFragment::gdcm_read_JPEG_file (std::ifstream* fp, void* image_buffer , pImage+=rowsize; } - /* Step 7: Finish decompression */ -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 7\n"); -#endif //GDCM_JPG_DEBUG - + // Step 7: Finish decompression if( jpeg_finish_decompress(&cinfo) == FALSE ) { - std::cerr << "Suspension: jpeg_finish_decompress" << std::endl; + // Suspension: jpeg_finish_decompress + statesuspension = 4; } - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* Step 8: Release JPEG decompression object */ - -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 8\n"); -#endif //GDCM_JPG_DEBUG - - /* This is an important step since it will release a good deal of memory. */ - + // Step 8: Release JPEG decompression object 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, - * so as to simplify the setjmp error logic above. (Actually, I don't - * think that jpeg_destroy can do an error exit, but why assume anything...) - */ - - /* At this point you may want to check to see whether any corrupt-data - * warnings occurred (test whether jerr.pub.num_warnings is nonzero). - */ - - /* And we're done! */ + // At this point you may want to check to see whether any corrupt-data + // warnings occurred (test whether jerr.pub.num_warnings is nonzero). return true; } - -/* - * SOME FINE POINTS: - * - * In the above code, we ignored the return value of jpeg_read_scanlines, - * which is the number of scanlines actually read. We could get away with - * this because we asked for only one line at a time and we weren't using - * a suspending data source. See libjpeg.doc for more info. - * - * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress(); - * we should have done it beforehand to ensure that the space would be - * counted against the JPEG max_memory setting. In some systems the above - * code would risk an out-of-memory error. However, in general we don't - * know the output image dimensions before jpeg_start_decompress(), unless we - * call jpeg_calc_output_dimensions(). See libjpeg.doc for more about this. - * - * Scanlines are returned in the same order as they appear in the JPEG file, - * which is standardly top-to-bottom. If you must emit data bottom-to-top, - * you can use one of the virtual arrays provided by the JPEG memory manager - * to invert the data. See wrbmp.c for an example. - * - * As with compression, some operating modes may require temporary files. - * On some systems you may need to set up a signal handler to ensure that - * temporary files are deleted if the program is interrupted. See libjpeg.doc. - */ #ifdef _MSC_VER // Put the warning back #pragma warning( default : 4611 ) #endif - -//---------------------------------------------------------------------------- - - -/** - * \brief routine for JPEG decompression from a memory buffer. - * routine for JPEG decompression from a memory buffer. This routine - * only reads one JPEG image at a time, but returns information about - * how many bytes have been consumed from the \c input_buffer, and - * how many bytes have been written into the output \c image_buffer. - * - * @param input_buffer pointer to a memory buffer containing the jpeg - * compressed data. - * @param buflen length of the memory buffer. - * @param image_buffer pointer to the location where the decompressed - * image will be filled. - * @param howManyRead returns how many bytes have been consumed from the - * input_buffer. - * @param howManyWritten returns how many bytes have been written into - * the output image_buffer. - * @return 1 on success, 0 on error - */ - -bool gdcm_read_JPEG_memory ( const JOCTET* input_buffer, const size_t buflen, - void* image_buffer, - size_t *howManyRead, size_t *howManyWritten) -{ - volatile char * pimage=(volatile char *)image_buffer; - JOCTET* input = (JOCTET*) input_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; - - /* -------------- inside, we found : - * JDIMENSION image_width; // input image width - * JDIMENSION image_height; // input image height - * int input_components; // nb of color components in input image - * J_COLOR_SPACE in_color_space; // colorspace of input image - * double input_gamma; // image gamma of input image - * -------------- */ - - /* We use our private extension JPEG error handler. - * Note that this struct must live as long as the main JPEG parameter - * struct, to avoid dangling-pointer problems. - */ - struct my_error_mgr jerr; - /* More stuff */ - - JSAMPARRAY buffer;/* Output row buffer */ - - // rappel : - // ------ - // typedef unsigned char JSAMPLE; - // typedef JSAMPLE FAR *JSAMPROW;/* ptr to one image row of pixel samples. */ - // typedef JSAMPROW *JSAMPARRAY;/* ptr to some rows (a 2-D sample array) */ - // typedef JSAMPARRAY *JSAMPIMAGE;/* a 3-D sample array: top index is color */ - - int row_stride;/* physical row width in output buffer */ - -#ifdef GDCM_JPG_DEBUG - printf("entree dans File::gdcm_read_JPEG_file (i.e. 8), depuis gdcmJpeg\n"); -#endif //GDCM_JPG_DEBUG - - /* In this example we want to open the input file before doing anything else, - * so that the setjmp() error recovery below can assume the file is open. - * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that - * requires it in order to read binary files. - */ - - /* Step 1: allocate and initialize JPEG decompression object */ -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 1\n"); -#endif //GDCM_JPG_DEBUG - - /* We set up the normal JPEG error routines, then override error_exit. */ - - cinfo.err = jpeg_std_error(&jerr.pub); - jerr.pub.error_exit = my_error_exit; - - /* Establish the setjmp return context for my_error_exit to use. */ - if (setjmp(jerr.setjmp_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. - */ - jpeg_destroy_decompress(&cinfo); - - *howManyRead += input - input_buffer; - *howManyWritten += pimage - (char *)image_buffer; - return 0; - } - - /* Now we can initialize the JPEG decompression object. */ - 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_memory_src(&cinfo, input, buflen); - - /* 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); - - /* We can ignore the return value from jpeg_read_header since - * (a) suspension is not possible with the stdio data source, and - * (b) we passed TRUE to reject a tables-only JPEG file as an error. - * See libjpeg.doc for more info. - */ - - // prevent the library from performing any color space conversion - if( cinfo.process == JPROC_LOSSLESS ) - { - cinfo.jpeg_color_space = JCS_UNKNOWN; - cinfo.out_color_space = JCS_UNKNOWN; - } - -#ifdef GDCM_JPG_DEBUG - printf("--------------Header contents :----------------\n"); - printf("image_width %d image_height %d\n", - cinfo.image_width , cinfo.image_height); - printf("bits of precision in image data %d \n", - cinfo.output_components); - printf("nb of color components returned %d \n", - cinfo.data_precision); -#endif //GDCM_JPG_DEBUG - - - /* - * JDIMENSION image_width; // input image width - * JDIMENSION image_height; // input image height - * int output_components; // # of color components returned - * J_COLOR_SPACE in_color_space; // colorspace of input image - * double input_gamma; // image gamma of input image - * int data_precision; // bits of precision in image data - */ - - /* Step 4: set parameters for decompression */ -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 4\n"); -#endif //GDCM_JPG_DEBUG - /* In this example, we don't need to change any of the defaults set by - * jpeg_read_header(), so we do nothing here. - */ - - /* Step 5: Start decompressor */ -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 5\n"); -#endif //GDCM_JPG_DEBUG - - (void) jpeg_start_decompress(&cinfo); - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* We may need to do some setup of our own at this point before reading - * the data. After jpeg_start_decompress() we have the correct scaled - * output image dimensions available, as well as the output colormap - * if we asked for color quantization. - * In this example, we need to make an output work buffer of the right size. - */ - - /* JSAMPLEs per row in output buffer */ - row_stride = cinfo.output_width * cinfo.output_components*2; - -#ifdef GDCM_JPG_DEBUG - printf ("cinfo.output_width %d cinfo.output_components %d row_stride %d\n", - cinfo.output_width, cinfo.output_components,row_stride); -#endif //GDCM_JPG_DEBUG - - /* Make a one-row-high sample array that will go away when done with image */ - buffer = (*cinfo.mem->alloc_sarray) - ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); - - - /* Step 6: while (scan lines remain to be read) */ -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 6\n"); -#endif //GDCM_JPG_DEBUG - /* jpeg_read_scanlines(...); */ - - /* Here we use the library's state variable cinfo.output_scanline as the - * loop counter, so that we don't have to keep track ourselves. - */ -#ifdef GDCM_JPG_DEBUG - printf ("cinfo.output_height %d cinfo.output_width %d\n", - cinfo.output_height,cinfo.output_width); -#endif //GDCM_JPG_DEBUG - - int bufsize = cinfo.output_width * cinfo.output_components; - size_t rowsize = bufsize * sizeof(JSAMPLE); - - while (cinfo.output_scanline < cinfo.output_height) { - /* jpeg_read_scanlines expects an array of pointers to scanlines. - * Here the array is only one element long, but you could ask for - * more than one scanline at a time if that's more convenient. - */ - - //printf( "scanlines: %d\n",cinfo.output_scanline); - (void) jpeg_read_scanlines(&cinfo, buffer, 1); -#if defined(GDCM_WORDS_BIGENDIAN) && (CMAKE_BITS_IN_JSAMPLE != 8) - uint16_t *buffer16 = (uint16_t*)*buffer; - uint16_t *pimage16 = (uint16_t*)pimage; - for(unsigned int i=0;i> 8) | (buffer16[i] << 8 ); -#else - memcpy( (void*)pimage, *buffer,rowsize); -#endif //GDCM_WORDS_BIGENDIAN - pimage+=rowsize; - } - - /* Step 7: Finish decompression */ -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 7\n"); -#endif //GDCM_JPG_DEBUG - - input = (JOCTET *)cinfo.src->next_input_byte; - - (void) jpeg_finish_decompress(&cinfo); - - /* We can ignore the return value since suspension is not possible - * with the stdio data source. - */ - - /* Step 8: Release JPEG decompression object */ - -#ifdef GDCM_JPG_DEBUG - printf("Entree Step 8\n"); -#endif //GDCM_JPG_DEBUG - - /* This is an important step since it will release a good deal of memory. */ - - jpeg_destroy_decompress(&cinfo); - - - /* After finish_decompress, we can close the input file. - * Here we postpone it until after no more JPEG errors are possible, - * so as to simplify the setjmp error logic above. (Actually, I don't - * think that jpeg_destroy can do an error exit, but why assume anything...) - */ - - /* At this point you may want to check to see whether any corrupt-data - * warnings occurred (test whether jerr.pub.num_warnings is nonzero). - */ - - /* And we're done! */ - *howManyRead += input - input_buffer; - *howManyWritten += pimage - (char *)image_buffer; - - return true; -} } // end namespace gdcm diff --git a/src/gdcmJpeg12.cxx b/src/gdcmJpeg12.cxx index 0478a2e3..03d25b84 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/24 14:52:50 $ - Version: $Revision: 1.30 $ + Date: $Date: 2005/01/31 03:22:26 $ + Version: $Revision: 1.31 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -27,10 +27,7 @@ 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 481d339f..4adfddbb 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/24 14:52:50 $ - Version: $Revision: 1.9 $ + Date: $Date: 2005/01/31 03:22:26 $ + Version: $Revision: 1.10 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -27,10 +27,7 @@ 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 4c649ede..42ab8130 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/24 14:52:50 $ - Version: $Revision: 1.15 $ + Date: $Date: 2005/01/31 03:22:26 $ + Version: $Revision: 1.16 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -27,10 +27,7 @@ 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 d3db3012..8c8bd2db 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/28 15:42:22 $ - Version: $Revision: 1.37 $ + Date: $Date: 2005/01/31 03:22:26 $ + Version: $Revision: 1.38 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -369,117 +369,6 @@ void PixelReadConvert::ConvertReorderEndianity() } } - -/** - * \brief Reads from disk the Pixel Data of JPEG Dicom encapsulated - * file and decompress it. This function assumes that each - * jpeg fragment contains a whole frame (jpeg file). - * @param fp File Pointer - * @return Boolean - */ -bool PixelReadConvert::ReadAndDecompressJPEGFramesFromFile( std::ifstream *fp ) -{ - // Pointer to the Raw image - //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; -// } - JPEGInfo->DecompressJPEGFramesFromFile(fp, Raw, BitsStored, numberBytes, length ); - return true; -} - -/** - * \brief Reads from disk the Pixel Data of JPEG Dicom encapsulated - * file and decompress it. This function assumes that the dicom - * image is a single frame split into several JPEG fragments. - * Those fragments will be glued together into a memory buffer - * before being read. - * @param fp File Pointer - * @return Boolean - */ -bool PixelReadConvert:: -ReadAndDecompressJPEGSingleFrameFragmentsFromFile( std::ifstream *fp ) -{ - // Loop on the fragment[s] to get total length - size_t totalLength = JPEGInfo->GetFragmentsLength(); - - // Concatenate the jpeg fragments into a local buffer - JOCTET *buffer = new JOCTET [totalLength]; - // Fill in the buffer: - JPEGInfo->ReadAllFragments(fp, buffer); - - // kludge: // FIXME - JPEGFragment *fragment = JPEGInfo->GetFirstFragment(); - fragment->DecompressJPEGSingleFrameFragmentsFromFile(buffer, totalLength, Raw, BitsStored); - - // free local buffer - delete [] buffer; - - return true; -} - -/** - * \brief Reads from disk the Pixel Data of JPEG Dicom encapsulated - * file and decompress it. This function handles the generic - * and complex case where the DICOM contains several frames, - * and some of the frames are possibly split into several JPEG - * fragments. - * @param fp File Pointer - * @return Boolean - */ -bool PixelReadConvert:: -ReadAndDecompressJPEGFragmentedFramesFromFile( std::ifstream *fp ) -{ - // Loop on the fragment[s] to get total length - size_t totalLength = JPEGInfo->GetFragmentsLength(); - - // Concatenate the jpeg fragments into a local buffer - JOCTET *buffer = new JOCTET [totalLength]; - // Fill in the buffer: - JPEGInfo->ReadAllFragments(fp, buffer); - - size_t howManyRead = 0; - size_t howManyWritten = 0; - size_t fragmentLength = 0; - - JPEGFragment *fragment = JPEGInfo->GetFirstFragment(); - while( fragment ) - { - fragmentLength += fragment->GetLength(); - - if (howManyRead > fragmentLength) continue; - - fragment->DecompressJPEGFragmentedFramesFromFile(buffer, Raw, BitsStored, - howManyRead, howManyWritten, - totalLength); - - if (howManyRead < fragmentLength) - howManyRead = fragmentLength; - - fragment = JPEGInfo->GetNextFragment(); - } - - // free local buffer - delete [] buffer; - - return true; -} - /** * \brief Reads from disk the Pixel Data of JPEG Dicom encapsulated * file and decompress it. @@ -504,34 +393,13 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp ) return false; } - if ( ( ZSize == 1 ) && ( JPEGInfo->GetFragmentCount() > 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->GetFragmentCount() == (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 ?? + // Precompute the offset localRaw will be shifted with + int length = XSize * YSize * SamplesPerPixel; + int numberBytes = BitsAllocated / 8; + + JPEGInfo->DecompressJPEGFramesFromFile(fp, Raw, BitsStored, numberBytes, length ); + return true; } /** diff --git a/src/gdcmPixelReadConvert.h b/src/gdcmPixelReadConvert.h index db5556d4..047d3193 100644 --- a/src/gdcmPixelReadConvert.h +++ b/src/gdcmPixelReadConvert.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelReadConvert.h,v $ Language: C++ - Date: $Date: 2005/01/26 16:28:58 $ - Version: $Revision: 1.14 $ + Date: $Date: 2005/01/31 03:22:26 $ + 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 @@ -68,10 +68,6 @@ private: void ReadAndDecompress12BitsTo16Bits( std::ifstream *fp ) throw ( FormatError ); bool ReadAndDecompressRLEFile( std::ifstream *fp ); bool ReadAndDecompressJPEGFile( std::ifstream *fp ); - bool ReadAndDecompressJPEGFramesFromFile( std::ifstream *fp ); - bool ReadAndDecompressJPEGSingleFrameFragmentsFromFile( std::ifstream *fp ); - bool ReadAndDecompressJPEGFragmentedFramesFromFile( std::ifstream *fp ); - void BuildLUTRGBA( std::ifstream *fp ); diff --git a/src/gdcmSerieHeader.cxx b/src/gdcmSerieHeader.cxx index 4ecd7d51..4c2ac383 100644 --- a/src/gdcmSerieHeader.cxx +++ b/src/gdcmSerieHeader.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmSerieHeader.cxx,v $ Language: C++ - Date: $Date: 2005/01/30 17:22:55 $ - Version: $Revision: 1.15 $ + Date: $Date: 2005/01/31 03:22:26 $ + Version: $Revision: 1.16 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -407,7 +407,7 @@ bool SerieHeader::ImageNumberOrdering(GdcmFileList *CoherentGdcmFileList) * @param CoherentGdcmFileList Coherent File list (same Serie UID) to sort * @return false only if the header is bugged ! */ -bool SerieHeader::FileNameOrdering(GdcmFileList *CoherentGdcmFileList) +bool SerieHeader::FileNameOrdering(GdcmFileList *) { //using the sort //sort(CoherentGdcmFileList.begin(), CoherentGdcmFileList.end()); diff --git a/src/gdcmjpeg/CMakeLists.txt b/src/gdcmjpeg/CMakeLists.txt index 43a5f275..7a905f3b 100644 --- a/src/gdcmjpeg/CMakeLists.txt +++ b/src/gdcmjpeg/CMakeLists.txt @@ -43,7 +43,7 @@ jdapimin.c jdapistd.c jdtrans.c jdmaster.c jdinput.c jdmarker.c jdhuff.c jdphuff.c jdmainct.c jdcoefct.c jdpostct.c jddctmgr.c jidctfst.c jidctflt.c jidctint.c jidctred.c jdsample.c jdcolor.c jquant1.c jquant2.c jdmerge.c -jdatasrc.c jmemsrc.c +jdatasrc.c ) SET(decomp_lossy_SRCS diff --git a/src/gdcmjpeg/jpeglib.h b/src/gdcmjpeg/jpeglib.h index 5d6f3a87..02c2d186 100644 --- a/src/gdcmjpeg/jpeglib.h +++ b/src/gdcmjpeg/jpeglib.h @@ -942,7 +942,6 @@ EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); /* Caller is responsible for opening the file before and closing after. */ EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); -EXTERN(void) jpeg_memory_src JPP((j_decompress_ptr cinfo, const JOCTET * buffer, size_t bufsize)); /* Default parameter setup for compression */ EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); diff --git a/src/gdcmjpeg/mangle_jpeg12bits.h b/src/gdcmjpeg/mangle_jpeg12bits.h index 09342fbc..74170655 100644 --- a/src/gdcmjpeg/mangle_jpeg12bits.h +++ b/src/gdcmjpeg/mangle_jpeg12bits.h @@ -103,7 +103,6 @@ nm libgdcmjpeg12.a | grep " [R|T] " | colrm 1 11 | sort #define jpeg_mem_available gdcm_jpeg12_jpeg_mem_available #define jpeg_mem_init gdcm_jpeg12_jpeg_mem_init #define jpeg_mem_term gdcm_jpeg12_jpeg_mem_term -#define jpeg_memory_src gdcm_jpeg12_jpeg_memory_src #define jpeg_natural_order gdcm_jpeg12_jpeg_natural_order #define jpeg_new_colormap gdcm_jpeg12_jpeg_new_colormap #define jpeg_open_backing_store gdcm_jpeg12_jpeg_open_backing_store diff --git a/src/gdcmjpeg/mangle_jpeg16bits.h b/src/gdcmjpeg/mangle_jpeg16bits.h index 947f7f48..4e5e8dc4 100644 --- a/src/gdcmjpeg/mangle_jpeg16bits.h +++ b/src/gdcmjpeg/mangle_jpeg16bits.h @@ -103,7 +103,6 @@ nm libgdcmjpeg16.a | grep " [R|T] " | colrm 1 11 | sort #define jpeg_mem_available gdcm_jpeg16_jpeg_mem_available #define jpeg_mem_init gdcm_jpeg16_jpeg_mem_init #define jpeg_mem_term gdcm_jpeg16_jpeg_mem_term -#define jpeg_memory_src gdcm_jpeg16_jpeg_memory_src #define jpeg_natural_order gdcm_jpeg16_jpeg_natural_order #define jpeg_new_colormap gdcm_jpeg16_jpeg_new_colormap #define jpeg_open_backing_store gdcm_jpeg16_jpeg_open_backing_store diff --git a/src/gdcmjpeg/mangle_jpeg8bits.h b/src/gdcmjpeg/mangle_jpeg8bits.h index c90b7cf9..e5f7f6a5 100644 --- a/src/gdcmjpeg/mangle_jpeg8bits.h +++ b/src/gdcmjpeg/mangle_jpeg8bits.h @@ -100,7 +100,6 @@ nm libgdcmjpeg8.a | grep " [R|T] " | colrm 1 11 | sort #define jpeg_mem_available gdcm_jpeg8_jpeg_mem_available #define jpeg_mem_init gdcm_jpeg8_jpeg_mem_init #define jpeg_mem_term gdcm_jpeg8_jpeg_mem_term -#define jpeg_memory_src gdcm_jpeg8_jpeg_memory_src #define jpeg_natural_order gdcm_jpeg8_jpeg_natural_order #define jpeg_new_colormap gdcm_jpeg8_jpeg_new_colormap #define jpeg_open_backing_store gdcm_jpeg8_jpeg_open_backing_store diff --git a/src/jdatasrc.cxx b/src/jdatasrc.cxx index 1573e740..c0fb1220 100644 --- a/src/jdatasrc.cxx +++ b/src/jdatasrc.cxx @@ -24,7 +24,7 @@ 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; @@ -90,25 +90,20 @@ fill_input_buffer (j_decompress_ptr cinfo) { my_src_ptr src = (my_src_ptr) cinfo->src; - //std::cerr << "Before comp:" << src->bytes_read << " / " << src->frag->Length << std::endl; if( src->bytes_read == src->frag->GetLength() ) { - //std::cerr << "Sweet finished this fragment" << std::endl; + // Start the I/O suspension simply by returning false here: return FALSE; } size_t input_buf_size = INPUT_BUF_SIZE; if( (src->bytes_read + INPUT_BUF_SIZE) > src->frag->GetLength() ) { - //std::cerr << "Woula error:" << src->bytes_read << " / " << src->frag->Length << std::endl; input_buf_size = src->frag->GetLength() - 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 */ @@ -125,11 +120,7 @@ fill_input_buffer (j_decompress_ptr cinfo) 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; } @@ -148,7 +139,6 @@ 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 @@ -231,17 +221,13 @@ jpeg_stdio_src (j_decompress_ptr cinfo, std::ifstream * infile, gdcm::JPEGFragme src->pub.term_source = term_source; src->infile = infile; + // Need to setup a new buffer, clean bytes_in_buffer and next_input_byte 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; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ } - else - { - //only upate the new fragment - src->frag = frag; + //only upate the new fragment, valid for both 'flag' value + src->frag = frag; src->bytes_read = 0; - } } -- 2.45.1