]> Creatis software - gdcm.git/blobdiff - src/gdcmJpeg.cxx
* To remove warnings
[gdcm.git] / src / gdcmJpeg.cxx
index d82ce565f7b9595b616d5b9f76fd87136c1499e2..15bdd1a17b3926d1fc14b29bc3766f6eb79a435c 100644 (file)
@@ -1,8 +1,66 @@
-#include <gdcmFile.h>
+// gdcmJpeg.cxx
+//-----------------------------------------------------------------------------
 #include <stdio.h>
+#include "gdcmFile.h"
+
+#define BITS_IN_JSAMPLE 8
 
 #define DEBUG 0
 
+/*
+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
+*/
+
 /*
  * <setjmp.h> is used for the optional error recovery mechanism shown in
  * the second part of the example.
@@ -60,76 +118,70 @@ extern "C" {
  * Here's the extended error handler struct:
  */
 
+//-----------------------------------------------------------------------------
 struct my_error_mgr {
-  struct jpeg_error_mgr pub;   /* "public" fields */
-  jmp_buf setjmp_buffer;       /* for return to caller */
+   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:
  */
+METHODDEF(void) my_error_exit (j_common_ptr cinfo) {
+   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
+   my_error_ptr myerr = (my_error_ptr) cinfo->err;
 
-METHODDEF(void)
-my_error_exit (j_common_ptr cinfo) {
-  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
-  my_error_ptr myerr = (my_error_ptr) cinfo->err;
-
-  /* Always display the message. */
-  /* We could postpone this until after returning, if we chose. */
-  (*cinfo->err->output_message) (cinfo);
+   /* Always display the message. */
+   /* We could postpone this until after returning, if we chose. */
+   (*cinfo->err->output_message) (cinfo);
 
-  /* Return control to the setjmp point */
-  longjmp(myerr->setjmp_buffer, 1);
+   /* Return control to the setjmp point */
+   longjmp(myerr->setjmp_buffer, 1);
 }
 
-
+//-----------------------------------------------------------------------------
 /*
  * 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.
  */
+//GLOBAL(bool)
+bool gdcmFile::gdcm_read_JPEG_file (FILE *fp,void * image_buffer) {
+   char *pimage;
 
-
-//GLOBAL(int)
-int
-gdcmFile::gdcm_read_JPEG_file (void * image_buffer) {
-
-char *pimage;
-
-  /* This struct contains the JPEG decompression parameters and pointers to
+   /* 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 
+   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.
+
+   /* 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 */
+   struct my_error_mgr jerr;
+   /* More stuff */
+
+   JSAMPARRAY buffer;          /* Output row buffer */
   
-  int row_stride;              /* physical row width in output 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 */
   
- if (DEBUG) printf("entree dans gdcmFile::gdcm_read_JPEG_file, depuis gdcmJpeg\n");
  if (DEBUG) printf("entree dans gdcmFile::gdcm_read_JPEG_file, depuis gdcmJpeg\n");
 
 
   /* In this example we want to open the input file before doing anything else,
@@ -159,33 +211,31 @@ char *pimage;
   /* Now we can initialize the JPEG decompression object. */
   jpeg_create_decompress(&cinfo);
 
-  /* Step 2: specify data source (eg, a file) */
-  
-if (DEBUG) printf("Entree Step 2\n");
-
-  jpeg_stdio_src(&cinfo, fp);
+   /* Step 2: specify data source (eg, a file) */
+   if (DEBUG) printf("Entree Step 2\n");
 
-  /* Step 3: read file parameters with jpeg_read_header() */
+   jpeg_stdio_src(&cinfo, fp);
 
- if (DEBUG) printf("Entree Step 3\n");
+   /* Step 3: read file parameters with jpeg_read_header() */
+   if (DEBUG) printf("Entree Step 3\n");
 
-  (void) jpeg_read_header(&cinfo, TRUE);
+   (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.
-   */
-
-if (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);
-}
+   /* 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.
+    */
+
+   if (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);
+   }
 
 
 /*
@@ -198,17 +248,14 @@ if (DEBUG) {
  
 */
 
-  /* Step 4: set parameters for decompression */
-  
- if (DEBUG) printf("Entree Step 4\n");
-
-  /* In this example, we don't need to change any of the defaults set by
-   * jpeg_read_header(), so we do nothing here.
-   */
+   /* Step 4: set parameters for decompression */
+   if (DEBUG) printf("Entree Step 4\n");
+   /* 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 */
-  
- if (DEBUG) printf("Entree Step 5\n");
+   /* Step 5: Start decompressor */
+   if (DEBUG) printf("Entree Step 5\n");
 
   (void) jpeg_start_decompress(&cinfo);
   /* We can ignore the return value since suspension is not possible
@@ -221,33 +268,32 @@ if (DEBUG) {
    * 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;
   
- if (DEBUG) printf ("cinfo.output_width %d cinfo.output_components %d  row_stride %d\n",
-       cinfo.output_width, cinfo.output_components,row_stride);
  if (DEBUG) printf ("cinfo.output_width %d cinfo.output_components %d  row_stride %d\n",
+      cinfo.output_width, cinfo.output_components,row_stride);
        
-  /* 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);
+   /* 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) */
-  
- if (DEBUG)  printf("Entree Step 6\n"); 
+   /* Step 6: while (scan lines remain to be read) */
+   if (DEBUG)  printf("Entree Step 6\n"); 
 
-  /*           jpeg_read_scanlines(...); */
+   /*           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.
-   */
-   
if (DEBUG)  printf ("cinfo.output_height %d  cinfo.output_width %d\n",
-                       cinfo.output_height,cinfo.output_width);
+   /* 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.
+    */
+   if (DEBUG)  
     printf ("cinfo.output_height %d  cinfo.output_width %d\n",
+               cinfo.output_height,cinfo.output_width);
  
-  pimage=(char *)image_buffer;
+   pimage=(char *)image_buffer;
   
-  
-  while (cinfo.output_scanline < cinfo.output_height) {
+   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.
@@ -259,42 +305,46 @@ if (DEBUG) {
     
     //(void) jpeg_read_scanlines(&cinfo, pimage, 1);
     
-     (void) jpeg_read_scanlines(&cinfo, buffer, 1); 
-     memcpy( pimage, buffer[0],row_stride*2 ); // FIXME : *2  car 16 bits?!?
-     
-    pimage+=row_stride*2;  // FIXME : *2 car 16 bits?!?
+     (void) jpeg_read_scanlines(&cinfo, buffer, 1);
+      
+     if ( BITS_IN_JSAMPLE == 8) {
+         memcpy( pimage, buffer[0],row_stride); 
+         pimage+=row_stride;
+     } else {
+         memcpy( pimage, buffer[0],row_stride*2 ); // FIXME : *2  car 16 bits?!?
+         pimage+=row_stride*2;                     // FIXME : *2 car 16 bits?!?     
+     }
   }
  
   /* Step 7: Finish decompression */
-  
-if (DEBUG)  printf("Entree Step 7\n");
+   if (DEBUG)  printf("Entree Step 7\n");
 
-  (void) jpeg_finish_decompress(&cinfo);
-  /* We can ignore the return value since suspension is not possible
-   * with the stdio data source.
-   */
+   (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 */
-  
-if (DEBUG) printf("Entree Step 8\n");
+   /* Step 8: Release JPEG decompression object */
 
-  /* This is an important step since it will release a good deal of memory. */
-  
-  jpeg_destroy_decompress(&cinfo);
+   if (DEBUG) printf("Entree Step 8\n");
 
-  /* 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...)
-   */
+   /* This is an important step since it will release a good deal of memory. */
 
-  /* At this point you may want to check to see whether any corrupt-data
-   * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
-   */
+   jpeg_destroy_decompress(&cinfo);
 
-  /* And we're done! */
-  
-  return 1;
+   /* 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! */
+
+   return 1;
 }
 
 /*
@@ -322,4 +372,4 @@ if (DEBUG) printf("Entree Step 8\n");
  * temporary files are deleted if the program is interrupted.  See libjpeg.doc.
  */
  
-
+//-----------------------------------------------------------------------------