home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk1.iso / altsrc / articles / 10954 < prev    next >
Internet Message Format  |  1994-07-23  |  32KB

  1. Path: wupost!uhog.mit.edu!MathWorks.Com!europa.eng.gtefsd.com!emory!swrinde!sgiblab!a2i!flash.us.com!britt!dclunie
  2. From: dclunie@flash.us.com (David Clunie)
  3. Newsgroups: alt.graphics.pixutils,alt.sources,alt.image.medical
  4. Subject: PATCH: IJG jpegv4 12 bit mode & pgm/ppm files
  5. Date: 23 Jul 1994 17:37:52 GMT
  6. Organization: Her Master's Voice
  7. Lines: 1008
  8. Distribution: world
  9. Message-ID: <30rkhg$bq@flash.ksapax>
  10. Reply-To: dclunie@flash.us.com
  11. NNTP-Posting-Host: britt.ksapax
  12. Xref: wupost alt.graphics.pixutils:8225 alt.sources:10954 alt.image.medical:1287
  13.  
  14. Patch to use 12 bit mode and handle pgm/ppm files. Will use proposed new
  15. extended raw 16 bit pgm/ppm files if desired.
  16.  
  17. Works fine with v4 and v4a of the Independent JPEG Groups code.
  18.  
  19. Use "cd jpegv4; patch -p1 <thismessage".
  20.  
  21.  
  22. diff -r -c jpegv4a/README.pbm12bits jpegv4a.12/README.pbm12bits
  23. *** jpegv4a/README.pbm12bits    Sat Jul 23 20:10:13 1994
  24. --- jpegv4a.12/README.pbm12bits    Sat Jul 23 20:02:39 1994
  25. ***************
  26. *** 0 ****
  27. --- 1,91 ----
  28. + Sat Jul 23 19:02:07 GMT+0300 1994
  29. + Doing 8 bits, 12 bits, 16 bits and the PGM/PPM format.
  30. + The standard distribution has limited support for the PGM/PPM format:
  31. +     - it will read raw (8 bit) or text files (any maxval) and scale
  32. +       the data to the current data precision (usually 8).
  33. +     - it will write raw 8 bit files only (though passed through the
  34. +       colormaps if quantized) and if the precision is greater than
  35. +       8 bits only the low 8 bits would be used, if it weren't for the
  36. +       fact that there is a pre-processor generated compile error
  37. +       when BITS_IN_JSAMPLE is not 8.
  38. + In otherwords, though one can compile the library with 12 bits of precision
  39. + and use the standard "jrdppm.c" to read 12 bit data, there is no way to
  40. + write it out again.
  41. + This patch addresses these issues, and in addition supports the use of an
  42. + extension to the PGM/PPM format that allows >8 <16 bit values to be read
  43. + or written in raw form (little endian two byte word) based on the value
  44. + of maxval in the header ... if it is <=255 use a byte, if it is >255 but
  45. + <= 65535, use a word. Though nonstandard, there is another simple patch
  46. + floating around to patch the pbmplus and netpbm toolkits to handle such
  47. + files. These raw binary files save enormous amounts of space compared
  48. + with their text equivalents and make PGM/PPM a potentially useful file
  49. + format for handling such images.
  50. + The patched version has the following characteristics:
  51. +     - it can read any text, normal 8 bit and extended 16 bit PGM/PPM
  52. +       regardless of compile time options, and scales the data to the
  53. +       data precision.
  54. +     - if compiled with EIGHT_BIT_SAMPLES, it will write normal 8 bit
  55. +       raw PGM/PPM files, unless PPM_WRITETEXT is defined, in which
  56. +       case it will always write text files (pretty useless option).
  57. +     - if compiled with TWELVE_BIT_SAMPLES, it will write text format
  58. +       PGM/PPM files, unless PPM_WRITERAWWORDS is defined, in which
  59. +       case it will write 16 bit raw extended PGM/PPM files - this is
  60. +       the setting I use.
  61. + Note that the jwrppm.c and jrdppm.c routines are actually a little more
  62. + complicated and prepared for the day when 8 or 12 bits can be selected
  63. + at runtime rather than compile time, and they will behave properly
  64. + bases on the data_precision set in the cinfo structure. For now they just
  65. + behave the easy way.
  66. + Note that because the input is automatically scaled, you can actually
  67. + feed 8 bit files into a 12 bit "cjpeg|djpeg" and get 12 bits out, or
  68. + feed 12 bit data into an 8 bit "cjpeg|djpeg" and get 8 bits out !
  69. + On old versions of the source, one had to set the "-o" flag to cjpeg when 
  70. + using 12 bit precision, as there are no default Huffman tables for 12 bit 
  71. + mode, but you didn't know until you get a "Corrupted data in JPEG file" 
  72. + message from djpeg! This is now set automatically in more recent versions 
  73. + when a precision other than 8 is set.
  74. + Also if you do define TWELVE_BIT_SAMPLES, remember to undefine 
  75. + TARGA_SUPPORTED  and RLE_SUPPORTED as neither of these can handle 12 bits
  76. + and bitch if they have to. Intrestingly the gif routines have a little
  77. + shift in there to take care of data precisions > 8 ! In fact ...
  78. +     cjpeg12 < test.grey.12.raw.pgm | djpeg12 -gif >test.gif
  79. + works just fine, amazingly enough.
  80. + Once you have versions for 12 bits compiled, and if you have defined 
  81. + PPM_WRITERAWWORDS at compile time, and have updated your pbmplus library 
  82. + but not your X viewer to handle the "extended 16 bit raw" format, one 
  83. + can do things like this ...
  84. +     cjpeg12 < test.grey.12.raw.pgm | djpeg12 | pnmnoraw | xv -
  85. + and actually see an image ! (Although you will have to mess with the 
  86. + color editor of xv to window the image if your data is all squashed 
  87. + down the bottom of the dynamic range like MRI data usually is).
  88. + You don't HAVE to use the extended format ... if you want your images 
  89. + to be compatible and transportable (at least until the known universe 
  90. + fully adopts this wonderful new format) you can always leave out 
  91. + PPM_WRITERAWWORDS, still use the 12 bit mode and produce huge, but 
  92. + functional text files ... well it works, and is better than nothing.
  93. + Finally thanks to whoever wrote the JPEG stuff to handle 12 bits in the 
  94. + first place even though hardly anyone wants it ... those of us who do 
  95. + are very grateful !
  96. + David A. Clunie (dclunie@flash.us.com)
  97. diff -r -c jpegv4a/jconfig.h jpegv4a.12/jconfig.h
  98. *** jpegv4a/jconfig.h    Fri Apr 23 04:32:38 1993
  99. --- jpegv4a.12/jconfig.h    Sat Jul 23 18:50:11 1994
  100. ***************
  101. *** 200,206 ****
  102.   #define GIF_SUPPORTED        /* GIF image file format */
  103.   /* #define RLE_SUPPORTED */    /* RLE image file format (by default, no) */
  104.   #define PPM_SUPPORTED        /* PPM/PGM image file format */
  105. ! #define TARGA_SUPPORTED        /* Targa image file format */
  106.   #undef  TIFF_SUPPORTED        /* TIFF image file format (not yet impl.) */
  107.   
  108.   /* more capability options later, no doubt */
  109. --- 200,207 ----
  110.   #define GIF_SUPPORTED        /* GIF image file format */
  111.   /* #define RLE_SUPPORTED */    /* RLE image file format (by default, no) */
  112.   #define PPM_SUPPORTED        /* PPM/PGM image file format */
  113. ! #define PPM_WRITERAWWORDS       /* If 12 bits, write extended raw word format */
  114. ! #undef  TARGA_SUPPORTED        /* Targa image file format */
  115.   #undef  TIFF_SUPPORTED        /* TIFF image file format (not yet impl.) */
  116.   
  117.   /* more capability options later, no doubt */
  118. ***************
  119. *** 221,228 ****
  120.    * you'll have to supply different default Huffman tables.
  121.    */
  122.   
  123. ! #define EIGHT_BIT_SAMPLES
  124. ! #undef  TWELVE_BIT_SAMPLES
  125.   #undef  SIXTEEN_BIT_SAMPLES
  126.   
  127.   
  128. --- 222,229 ----
  129.    * you'll have to supply different default Huffman tables.
  130.    */
  131.   
  132. ! #undef EIGHT_BIT_SAMPLES
  133. ! #define  TWELVE_BIT_SAMPLES
  134.   #undef  SIXTEEN_BIT_SAMPLES
  135.   
  136.   
  137. diff -r -c jpegv4a/jrdppm.c jpegv4a.12/jrdppm.c
  138. *** jpegv4a/jrdppm.c    Fri Apr 23 04:32:36 1993
  139. --- jpegv4a.12/jrdppm.c    Sat Jul 23 19:15:21 1994
  140. ***************
  141. *** 119,124 ****
  142. --- 119,138 ----
  143.   }
  144.   
  145.   
  146. + LOCAL unsigned int
  147. + read_raw_integer (compress_info_ptr cinfo)
  148. + /* Read a little-endian binary 16 bit value from the PPM file */
  149. + {
  150. +   register unsigned int ch1;
  151. +   register unsigned int ch2;
  152. +   register unsigned int val;
  153. +   
  154. +   ch1 = getc(cinfo->input_file);
  155. +   ch2 = getc(cinfo->input_file);
  156. +   val = (ch2<<8)|ch1;
  157. +   return val;
  158. + }
  159.   /*
  160.    * Read one row of pixels.
  161.    *
  162. ***************
  163. *** 334,339 ****
  164. --- 348,417 ----
  165.   #endif /* USE_GETC_INPUT */
  166.   
  167.   
  168. + METHODDEF void
  169. + get_scaled_word_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  170. + /* This version is for reading raw-format word PGM files with scaling */
  171. + {
  172. +   register JSAMPROW ptr0;
  173. +   register long col;
  174. +   
  175. +   ptr0 = pixel_row[0];
  176. +   for (col = cinfo->image_width; col > 0; col--) {
  177. +     *ptr0++ = rescale[read_raw_integer(cinfo)];
  178. +   }
  179. + }
  180. + METHODDEF void
  181. + get_scaled_word_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  182. + /* This version is for reading raw-format word PPM files with scaling */
  183. + {
  184. +   register JSAMPROW ptr0, ptr1, ptr2;
  185. +   register long col;
  186. +   
  187. +   ptr0 = pixel_row[0];
  188. +   ptr1 = pixel_row[1];
  189. +   ptr2 = pixel_row[2];
  190. +   for (col = cinfo->image_width; col > 0; col--) {
  191. +     *ptr0++ = rescale[read_raw_integer(cinfo)];
  192. +     *ptr1++ = rescale[read_raw_integer(cinfo)];
  193. +     *ptr2++ = rescale[read_raw_integer(cinfo)];
  194. +   }
  195. + }
  196. + METHODDEF void
  197. + get_raw_word_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  198. + /* This version is for reading raw-format word PGM files without scaling */
  199. + {
  200. +   register JSAMPROW ptr0;
  201. +   register long col;
  202. +   
  203. +   ptr0 = pixel_row[0];
  204. +   for (col = cinfo->image_width; col > 0; col--) {
  205. +     *ptr0++ = (JSAMPLE) read_raw_integer(cinfo);
  206. +   }
  207. + }
  208. + METHODDEF void
  209. + get_raw_word_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  210. + /* This version is for reading raw-format word PPM files without scaling */
  211. + {
  212. +   register JSAMPROW ptr0, ptr1, ptr2;
  213. +   register long col;
  214. +   
  215. +   ptr0 = pixel_row[0];
  216. +   ptr1 = pixel_row[1];
  217. +   ptr2 = pixel_row[2];
  218. +   for (col = cinfo->image_width; col > 0; col--) {
  219. +     *ptr0++ = (JSAMPLE) read_raw_integer(cinfo);
  220. +     *ptr1++ = (JSAMPLE) read_raw_integer(cinfo);
  221. +     *ptr2++ = (JSAMPLE) read_raw_integer(cinfo);
  222. +   }
  223. + }
  224.   /*
  225.    * Read the file header; return image size and component count.
  226.    */
  227. ***************
  228. *** 343,351 ****
  229.   {
  230.     int c;
  231.     unsigned int w, h, maxval;
  232.   
  233.     if (getc(cinfo->input_file) != 'P')
  234. !     ERREXIT(cinfo->emethods, "Not a PPM file");
  235.   
  236.     c = getc(cinfo->input_file);    /* save format discriminator for a sec */
  237.   
  238. --- 421,430 ----
  239.   {
  240.     int c;
  241.     unsigned int w, h, maxval;
  242. +   int scaling;
  243.   
  244.     if (getc(cinfo->input_file) != 'P')
  245. !     ERREXIT(cinfo->emethods, "Not a PGM or PPM file");
  246.   
  247.     c = getc(cinfo->input_file);    /* save format discriminator for a sec */
  248.   
  249. ***************
  250. *** 354,361 ****
  251.     maxval = read_pbm_integer(cinfo);
  252.   
  253.     if (w <= 0 || h <= 0 || maxval <= 0) /* error check */
  254. !     ERREXIT(cinfo->emethods, "Not a PPM file");
  255.   
  256.     switch (c) {
  257.     case '2':            /* it's a text-format PGM file */
  258.       cinfo->methods->get_input_row = get_text_gray_row;
  259. --- 433,459 ----
  260.     maxval = read_pbm_integer(cinfo);
  261.   
  262.     if (w <= 0 || h <= 0 || maxval <= 0) /* error check */
  263. !     ERREXIT(cinfo->emethods, "Not a PGM or PPM file");
  264.   
  265. + #ifdef MULTIPLEPRECISIONSCANCOEXIST    /* Nice fantasy */
  266. +   if (maxval > MAXJSAMPLE) {
  267. +     scaling=1;
  268. +     cinfo->data_precision = BITS_IN_JSAMPLE;
  269. +   } else if (maxval <= 255) {
  270. +     scaling=0;
  271. +     cinfo->data_precision = 8;
  272. +   } else if (maxval <= 4095) {
  273. +     scaling=0;
  274. +     cinfo->data_precision = 12;
  275. +   } else {
  276. +     cinfo->data_precision = BITS_IN_JSAMPLE;    /* optimistic or what ? */
  277. +   }
  278. + #else  /*MULTIPLEPRECISIONSCANCOEXIST*/
  279. +   cinfo->data_precision = BITS_IN_JSAMPLE;
  280. +   if (maxval != MAXJSAMPLE) scaling=1;
  281. +   else scaling=0;
  282. + #endif /*MULTIPLEPRECISIONSCANCOEXIST*/
  283.     switch (c) {
  284.     case '2':            /* it's a text-format PGM file */
  285.       cinfo->methods->get_input_row = get_text_gray_row;
  286. ***************
  287. *** 372,414 ****
  288.       break;
  289.   
  290.     case '5':            /* it's a raw-format PGM file */
  291. !     if (maxval == MAXJSAMPLE)
  292. !       cinfo->methods->get_input_row = get_raw_gray_row;
  293. !     else
  294. !       cinfo->methods->get_input_row = get_scaled_gray_row;
  295. !     cinfo->input_components = 1;
  296. !     cinfo->in_color_space = CS_GRAYSCALE;
  297.   #ifndef USE_GETC_INPUT
  298. !     /* allocate space for row buffer: 1 byte/pixel */
  299. !     row_buffer = (U_CHAR *) (*cinfo->emethods->alloc_small)
  300.               ((size_t) (SIZEOF(U_CHAR) * (long) w));
  301.   #endif
  302.       TRACEMS2(cinfo->emethods, 1, "%ux%u PGM image", w, h);
  303.       break;
  304.   
  305.     case '6':            /* it's a raw-format PPM file */
  306. !     if (maxval == MAXJSAMPLE)
  307. !       cinfo->methods->get_input_row = get_raw_rgb_row;
  308. !     else
  309. !       cinfo->methods->get_input_row = get_scaled_rgb_row;
  310. !     cinfo->input_components = 3;
  311. !     cinfo->in_color_space = CS_RGB;
  312.   #ifndef USE_GETC_INPUT
  313. !     /* allocate space for row buffer: 3 bytes/pixel */
  314. !     row_buffer = (U_CHAR *) (*cinfo->emethods->alloc_small)
  315.               ((size_t) (3 * SIZEOF(U_CHAR) * (long) w));
  316.   #endif
  317.       TRACEMS2(cinfo->emethods, 1, "%ux%u PPM image", w, h);
  318.       break;
  319.   
  320.     default:
  321. !     ERREXIT(cinfo->emethods, "Not a PPM file");
  322.       break;
  323.     }
  324.   
  325.     /* Compute the rescaling array if necessary */
  326.     /* This saves per-pixel calculation */
  327. !   if (maxval == MAXJSAMPLE)
  328.       rescale = NULL;        /* no rescaling required */
  329.     else {
  330.       INT32 val, half_maxval;
  331. --- 470,528 ----
  332.       break;
  333.   
  334.     case '5':            /* it's a raw-format PGM file */
  335. !     if (maxval <= 255)
  336. !     {
  337.   #ifndef USE_GETC_INPUT
  338. !         /* allocate space for row buffer: 1 byte/pixel */
  339. !         row_buffer = (U_CHAR *) (*cinfo->emethods->alloc_small)
  340.               ((size_t) (SIZEOF(U_CHAR) * (long) w));
  341.   #endif
  342. +         if (!scaling)
  343. +             cinfo->methods->get_input_row = get_raw_gray_row;
  344. +         else
  345. +             cinfo->methods->get_input_row = get_scaled_gray_row;
  346. +     } else {
  347. +         if (!scaling)
  348. +             cinfo->methods->get_input_row = get_raw_word_gray_row;
  349. +         else
  350. +             cinfo->methods->get_input_row = get_scaled_word_gray_row;
  351. +     }
  352. +     cinfo->input_components = 1;
  353. +     cinfo->in_color_space = CS_GRAYSCALE;
  354.       TRACEMS2(cinfo->emethods, 1, "%ux%u PGM image", w, h);
  355.       break;
  356.   
  357.     case '6':            /* it's a raw-format PPM file */
  358. !     if (maxval <= 255)
  359. !     {
  360.   #ifndef USE_GETC_INPUT
  361. !         /* allocate space for row buffer: 3 bytes/pixel */
  362. !         row_buffer = (U_CHAR *) (*cinfo->emethods->alloc_small)
  363.               ((size_t) (3 * SIZEOF(U_CHAR) * (long) w));
  364.   #endif
  365. +         if (!scaling)
  366. +             cinfo->methods->get_input_row = get_raw_rgb_row;
  367. +         else
  368. +             cinfo->methods->get_input_row = get_scaled_rgb_row;
  369. +     } else {
  370. +         if (!scaling)
  371. +             cinfo->methods->get_input_row = get_raw_word_rgb_row;
  372. +         else
  373. +             cinfo->methods->get_input_row = get_scaled_word_rgb_row;
  374. +     }
  375. +     cinfo->input_components = 3;
  376. +     cinfo->in_color_space = CS_RGB;
  377.       TRACEMS2(cinfo->emethods, 1, "%ux%u PPM image", w, h);
  378.       break;
  379.   
  380.     default:
  381. !     ERREXIT(cinfo->emethods, "Not a PGM or PPM file");
  382.       break;
  383.     }
  384.   
  385.     /* Compute the rescaling array if necessary */
  386.     /* This saves per-pixel calculation */
  387. !   if (!scaling)
  388.       rescale = NULL;        /* no rescaling required */
  389.     else {
  390.       INT32 val, half_maxval;
  391. ***************
  392. *** 425,431 ****
  393.   
  394.     cinfo->image_width = w;
  395.     cinfo->image_height = h;
  396. -   cinfo->data_precision = BITS_IN_JSAMPLE;
  397.   }
  398.   
  399.   
  400. --- 539,544 ----
  401. diff -r -c jpegv4a/jwrppm.c jpegv4a.12/jwrppm.c
  402. *** jpegv4a/jwrppm.c    Fri Apr 23 04:32:37 1993
  403. --- jpegv4a.12/jwrppm.c    Sat Jul 23 20:12:08 1994
  404. ***************
  405. *** 19,36 ****
  406.   
  407.   #ifdef PPM_SUPPORTED
  408.   
  409.   /*
  410. -  * Haven't yet got around to making this work with text-format output,
  411. -  * hence cannot handle pixels wider than 8 bits.
  412. -  */
  413. - #ifndef EIGHT_BIT_SAMPLES
  414. -   Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
  415. - #endif
  416. - /*
  417.    * On most systems, writing individual bytes with putc() is drastically less
  418.    * efficient than buffering a row at a time for fwrite().  But we must
  419.    * allocate the row buffer in near data space on PCs, because we are assuming
  420. --- 19,25 ----
  421. ***************
  422. *** 53,79 ****
  423.   METHODDEF void
  424.   output_init (decompress_info_ptr cinfo)
  425.   {
  426. !   if (cinfo->out_color_space == CS_GRAYSCALE) {
  427.       /* emit header for raw PGM format */
  428.       fprintf(cinfo->output_file, "P5\n%ld %ld\n%d\n",
  429. !         cinfo->image_width, cinfo->image_height, 255);
  430. ! #ifndef USE_PUTC_OUTPUT
  431. !     /* allocate space for row buffer: 1 byte/pixel */
  432. !     row_buffer = (char *) (*cinfo->emethods->alloc_small)
  433. !             ((size_t) (SIZEOF(char) * cinfo->image_width));
  434. ! #endif
  435. !   } else if (cinfo->out_color_space == CS_RGB) {
  436.       /* emit header for raw PPM format */
  437.       fprintf(cinfo->output_file, "P6\n%ld %ld\n%d\n",
  438. !         cinfo->image_width, cinfo->image_height, 255);
  439.   #ifndef USE_PUTC_OUTPUT
  440. !     /* allocate space for row buffer: 3 bytes/pixel */
  441. !     row_buffer = (char *) (*cinfo->emethods->alloc_small)
  442.               ((size_t) (3 * SIZEOF(char) * cinfo->image_width));
  443. ! #endif
  444. !   } else {
  445. !     ERREXIT(cinfo->emethods, "PPM output must be grayscale or RGB");
  446. !   }
  447.   }
  448.   
  449.   
  450. --- 42,118 ----
  451.   METHODDEF void
  452.   output_init (decompress_info_ptr cinfo)
  453.   {
  454. !   unsigned maxval;
  455. !   /* don't need to check MAXJSAMPLE etc. because couldn't get this far */
  456. !   /* with any other value of cinfo->data_precision than 8 if only 8 bits */
  457. !   if (cinfo->data_precision == 8) {
  458. !     maxval=255;
  459. !   } else if (cinfo->data_precision == 12) {
  460. !     maxval=4095;
  461. !   } else {
  462. !     ERREXIT(cinfo->emethods, "PPM output - only 8 or 12 bits supported");
  463. !   }
  464. ! #ifdef PPM_WRITETEXT
  465. !   if (cinfo->out_color_space == CS_GRAYSCALE)
  466. !     /* emit header for text PGM format */
  467. !     fprintf(cinfo->output_file, "P2\n%ld %ld\n%d\n",
  468. !         cinfo->image_width, cinfo->image_height, maxval);
  469. !   else if (cinfo->out_color_space == CS_RGB)
  470. !     /* emit header for text PPM format */
  471. !     fprintf(cinfo->output_file, "P3\n%ld %ld\n%d\n",
  472. !         cinfo->image_width, cinfo->image_height, maxval);
  473. ! #else  /*PPM_WRITETEXT*/
  474. !   if (cinfo->out_color_space == CS_GRAYSCALE)
  475. ! #ifdef PPM_WRITERAWWORDS
  476.       /* emit header for raw PGM format */
  477.       fprintf(cinfo->output_file, "P5\n%ld %ld\n%d\n",
  478. !         cinfo->image_width, cinfo->image_height, maxval);
  479. ! #else  /*PPM_WRITERAWWORDS*/
  480. !     if (cinfo->data_precision == 8)
  481. !       /* emit header for raw PGM format */
  482. !       fprintf(cinfo->output_file, "P5\n%ld %ld\n%d\n",
  483. !           cinfo->image_width, cinfo->image_height, maxval);
  484. !     else
  485. !       /* emit header for text PGM format */
  486. !       fprintf(cinfo->output_file, "P2\n%ld %ld\n%d\n",
  487. !           cinfo->image_width, cinfo->image_height, maxval);
  488. ! #endif /*PPM_WRITERAWWORDS*/
  489. !   else if (cinfo->out_color_space == CS_RGB)
  490. ! #ifdef PPM_WRITERAWWORDS
  491.       /* emit header for raw PPM format */
  492.       fprintf(cinfo->output_file, "P6\n%ld %ld\n%d\n",
  493. !         cinfo->image_width, cinfo->image_height, maxval);
  494. ! #else  /*PPM_WRITERAWWORDS*/
  495. !     if (cinfo->data_precision == 8)
  496. !       /* emit header for raw PPM format */
  497. !       fprintf(cinfo->output_file, "P6\n%ld %ld\n%d\n",
  498. !           cinfo->image_width, cinfo->image_height, maxval);
  499. !     else
  500. !       /* emit header for text PPM format */
  501. !       fprintf(cinfo->output_file, "P3\n%ld %ld\n%d\n",
  502. !           cinfo->image_width, cinfo->image_height, maxval);
  503. ! #endif /*PPM_WRITERAWWORDS*/
  504. ! #endif /*PPM_WRITETEXT*/
  505. !   else
  506. !     ERREXIT(cinfo->emethods, "PPM output must be grayscale or RGB");
  507. ! #ifndef PPM_WRITETEXT
  508.   #ifndef USE_PUTC_OUTPUT
  509. !     if (cinfo->data_precision == 8) {
  510. !       if (cinfo->out_color_space == CS_GRAYSCALE)
  511. !         /* allocate space for row buffer: 1 byte/pixel */
  512. !         row_buffer = (char *) (*cinfo->emethods->alloc_small)
  513. !             ((size_t) (SIZEOF(char) * cinfo->image_width));
  514. !       else
  515. !         /* allocate space for row buffer: 3 bytes/pixel */
  516. !         row_buffer = (char *) (*cinfo->emethods->alloc_small)
  517.               ((size_t) (3 * SIZEOF(char) * cinfo->image_width));
  518. !     }
  519. ! #endif /*USE_PUTC_OUTPUT*/
  520. ! #endif /*PPM_WRITETEXT*/
  521.   }
  522.   
  523.   
  524. ***************
  525. *** 81,90 ****
  526.    * Write some pixel data.
  527.    */
  528.   
  529.   #ifdef USE_PUTC_OUTPUT
  530.   
  531.   METHODDEF void
  532. ! put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
  533.           JSAMPIMAGE pixel_data)
  534.   {
  535.     register FILE * outfile = cinfo->output_file;
  536. --- 120,227 ----
  537.    * Write some pixel data.
  538.    */
  539.   
  540. + METHODDEF void
  541. + put_rgb_text_rows (decompress_info_ptr cinfo, int num_rows,
  542. +         JSAMPIMAGE pixel_data)
  543. + {
  544. +   register FILE * outfile = cinfo->output_file;
  545. +   register JSAMPROW ptr0, ptr1, ptr2;
  546. +   register long col;
  547. +   long width = cinfo->image_width;
  548. +   int row;
  549. +   
  550. +   for (row = 0; row < num_rows; row++) {
  551. +     ptr0 = pixel_data[0][row];
  552. +     ptr1 = pixel_data[1][row];
  553. +     ptr2 = pixel_data[2][row];
  554. +     for (col = width; col > 0; col--) {
  555. +       fprintf(outfile,"%u\n",(unsigned)GETJSAMPLE(*ptr0));
  556. +       ptr0++;
  557. +       fprintf(outfile,"%u\n",(unsigned)GETJSAMPLE(*ptr1));
  558. +       ptr1++;
  559. +       fprintf(outfile,"%u\n",(unsigned)GETJSAMPLE(*ptr2));
  560. +       ptr2++;
  561. +     }
  562. +   }
  563. + }
  564. + METHODDEF void
  565. + put_gray_text_rows (decompress_info_ptr cinfo, int num_rows,
  566. +            JSAMPIMAGE pixel_data)
  567. + {
  568. +   register FILE * outfile = cinfo->output_file;
  569. +   register JSAMPROW ptr0;
  570. +   register long col;
  571. +   long width = cinfo->image_width;
  572. +   int row;
  573. +   
  574. +   for (row = 0; row < num_rows; row++) {
  575. +     ptr0 = pixel_data[0][row];
  576. +     for (col = width; col > 0; col--) {
  577. +       fprintf(outfile,"%u\n",(unsigned)GETJSAMPLE(*ptr0));
  578. +       ptr0++;
  579. +     }
  580. +   }
  581. + }
  582. + METHODDEF void
  583. + put_rgb_raw_word_rows (decompress_info_ptr cinfo, int num_rows,
  584. +         JSAMPIMAGE pixel_data)
  585. + {
  586. +   register FILE * outfile = cinfo->output_file;
  587. +   register JSAMPROW ptr0, ptr1, ptr2;
  588. +   register long col;
  589. +   long width = cinfo->image_width;
  590. +   int row;
  591. +   
  592. +   for (row = 0; row < num_rows; row++) {
  593. +     ptr0 = pixel_data[0][row];
  594. +     ptr1 = pixel_data[1][row];
  595. +     ptr2 = pixel_data[2][row];
  596. +     for (col = width; col > 0; col--) {
  597. +       JSAMPLE value;
  598. +       value=GETJSAMPLE(*ptr0);
  599. +       putc(value&0xff, outfile);
  600. +       putc((value>>8)&0xff, outfile);
  601. +       ptr0++;
  602. +       value=GETJSAMPLE(*ptr1);
  603. +       putc(value&0xff, outfile);
  604. +       putc((value>>8)&0xff, outfile);
  605. +       ptr1++;
  606. +       value=GETJSAMPLE(*ptr2);
  607. +       putc(value&0xff, outfile);
  608. +       putc((value>>8)&0xff, outfile);
  609. +       ptr2++;
  610. +     }
  611. +   }
  612. + }
  613. + METHODDEF void
  614. + put_gray_raw_word_rows (decompress_info_ptr cinfo, int num_rows,
  615. +            JSAMPIMAGE pixel_data)
  616. + {
  617. +   register FILE * outfile = cinfo->output_file;
  618. +   register JSAMPROW ptr0;
  619. +   register long col;
  620. +   long width = cinfo->image_width;
  621. +   int row;
  622. +   for (row = 0; row < num_rows; row++) {
  623. +     ptr0 = pixel_data[0][row];
  624. +     for (col = width; col > 0; col--) {
  625. +       JSAMPLE value;
  626. +       value=GETJSAMPLE(*ptr0);
  627. +       putc(value&0xff, outfile);
  628. +       putc((value>>8)&0xff, outfile);
  629. +       ptr0++;
  630. +     }
  631. +   }
  632. + }
  633.   #ifdef USE_PUTC_OUTPUT
  634.   
  635.   METHODDEF void
  636. ! put_rgb_raw_byte_rows (decompress_info_ptr cinfo, int num_rows,
  637.           JSAMPIMAGE pixel_data)
  638.   {
  639.     register FILE * outfile = cinfo->output_file;
  640. ***************
  641. *** 109,115 ****
  642.   }
  643.   
  644.   METHODDEF void
  645. ! put_gray_rows (decompress_info_ptr cinfo, int num_rows,
  646.              JSAMPIMAGE pixel_data)
  647.   {
  648.     register FILE * outfile = cinfo->output_file;
  649. --- 246,252 ----
  650.   }
  651.   
  652.   METHODDEF void
  653. ! put_gray_raw_byte_rows (decompress_info_ptr cinfo, int num_rows,
  654.              JSAMPIMAGE pixel_data)
  655.   {
  656.     register FILE * outfile = cinfo->output_file;
  657. ***************
  658. *** 130,136 ****
  659.   #else /* use row buffering */
  660.   
  661.   METHODDEF void
  662. ! put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
  663.           JSAMPIMAGE pixel_data)
  664.   {
  665.     FILE * outfile = cinfo->output_file;
  666. --- 267,273 ----
  667.   #else /* use row buffering */
  668.   
  669.   METHODDEF void
  670. ! put_rgb_raw_byte_rows (decompress_info_ptr cinfo, int num_rows,
  671.           JSAMPIMAGE pixel_data)
  672.   {
  673.     FILE * outfile = cinfo->output_file;
  674. ***************
  675. *** 155,161 ****
  676.   }
  677.   
  678.   METHODDEF void
  679. ! put_gray_rows (decompress_info_ptr cinfo, int num_rows,
  680.              JSAMPIMAGE pixel_data)
  681.   {
  682.     FILE * outfile = cinfo->output_file;
  683. --- 292,298 ----
  684.   }
  685.   
  686.   METHODDEF void
  687. ! put_gray_raw_byte_rows (decompress_info_ptr cinfo, int num_rows,
  688.              JSAMPIMAGE pixel_data)
  689.   {
  690.     FILE * outfile = cinfo->output_file;
  691. ***************
  692. *** 182,191 ****
  693.    * Write some pixel data when color quantization is in effect.
  694.    */
  695.   
  696.   #ifdef USE_PUTC_OUTPUT
  697.   
  698.   METHODDEF void
  699. ! put_demapped_rgb (decompress_info_ptr cinfo, int num_rows,
  700.             JSAMPIMAGE pixel_data)
  701.   {
  702.     register FILE * outfile = cinfo->output_file;
  703. --- 319,430 ----
  704.    * Write some pixel data when color quantization is in effect.
  705.    */
  706.   
  707. + METHODDEF void
  708. + put_demapped_rgb_text_rows (decompress_info_ptr cinfo, int num_rows,
  709. +           JSAMPIMAGE pixel_data)
  710. + {
  711. +   register FILE * outfile = cinfo->output_file;
  712. +   register JSAMPROW ptr;
  713. +   register JSAMPROW color_map0 = cinfo->colormap[0];
  714. +   register JSAMPROW color_map1 = cinfo->colormap[1];
  715. +   register JSAMPROW color_map2 = cinfo->colormap[2];
  716. +   register int pixval;
  717. +   register long col;
  718. +   long width = cinfo->image_width;
  719. +   int row;
  720. +   
  721. +   for (row = 0; row < num_rows; row++) {
  722. +     ptr = pixel_data[0][row];
  723. +     for (col = width; col > 0; col--) {
  724. +       pixval = GETJSAMPLE(*ptr++);
  725. +       fprintf(outfile,"%u\n",(unsigned)GETJSAMPLE(color_map0[pixval]));
  726. +       fprintf(outfile,"%u\n",(unsigned)GETJSAMPLE(color_map1[pixval]));
  727. +       fprintf(outfile,"%u\n",(unsigned)GETJSAMPLE(color_map2[pixval]));
  728. +     }
  729. +   }
  730. + }
  731. + METHODDEF void
  732. + put_demapped_gray_text_rows (decompress_info_ptr cinfo, int num_rows,
  733. +            JSAMPIMAGE pixel_data)
  734. + {
  735. +   register FILE * outfile = cinfo->output_file;
  736. +   register JSAMPROW ptr;
  737. +   register JSAMPROW color_map0 = cinfo->colormap[0];
  738. +   register int pixval;
  739. +   register long col;
  740. +   long width = cinfo->image_width;
  741. +   int row;
  742. +   
  743. +   for (row = 0; row < num_rows; row++) {
  744. +     ptr = pixel_data[0][row];
  745. +     for (col = width; col > 0; col--) {
  746. +       pixval = GETJSAMPLE(*ptr++);
  747. +       fprintf(outfile,"%u\n",(unsigned)GETJSAMPLE(color_map0[pixval]));
  748. +     }
  749. +   }
  750. + }
  751. + METHODDEF void
  752. + put_demapped_rgb_raw_word_rows (decompress_info_ptr cinfo, int num_rows,
  753. +           JSAMPIMAGE pixel_data)
  754. + {
  755. +   register FILE * outfile = cinfo->output_file;
  756. +   register JSAMPROW ptr;
  757. +   register JSAMPROW color_map0 = cinfo->colormap[0];
  758. +   register JSAMPROW color_map1 = cinfo->colormap[1];
  759. +   register JSAMPROW color_map2 = cinfo->colormap[2];
  760. +   register int pixval;
  761. +   register long col;
  762. +   long width = cinfo->image_width;
  763. +   int row;
  764. +   
  765. +   for (row = 0; row < num_rows; row++) {
  766. +     ptr = pixel_data[0][row];
  767. +     for (col = width; col > 0; col--) {
  768. +       JSAMPLE value;
  769. +       pixval = GETJSAMPLE(*ptr++);
  770. +       value=GETJSAMPLE(color_map0[pixval]);
  771. +       putc(value&0xff, outfile);
  772. +       putc((value>>8)&0xff, outfile);
  773. +       value=GETJSAMPLE(color_map1[pixval]);
  774. +       putc(value&0xff, outfile);
  775. +       putc((value>>8)&0xff, outfile);
  776. +       value=GETJSAMPLE(color_map2[pixval]);
  777. +       putc(value&0xff, outfile);
  778. +       putc((value>>8)&0xff, outfile);
  779. +     }
  780. +   }
  781. + }
  782. + METHODDEF void
  783. + put_demapped_gray_raw_word_rows (decompress_info_ptr cinfo, int num_rows,
  784. +            JSAMPIMAGE pixel_data)
  785. + {
  786. +   register FILE * outfile = cinfo->output_file;
  787. +   register JSAMPROW ptr;
  788. +   register JSAMPROW color_map0 = cinfo->colormap[0];
  789. +   register int pixval;
  790. +   register long col;
  791. +   long width = cinfo->image_width;
  792. +   int row;
  793. +   
  794. +   for (row = 0; row < num_rows; row++) {
  795. +     ptr = pixel_data[0][row];
  796. +     for (col = width; col > 0; col--) {
  797. +       JSAMPLE value;
  798. +       pixval = GETJSAMPLE(*ptr++);
  799. +       value=GETJSAMPLE(color_map0[pixval]);
  800. +       putc(value&0xff, outfile);
  801. +       putc((value>>8)&0xff, outfile);
  802. +     }
  803. +   }
  804. + }
  805.   #ifdef USE_PUTC_OUTPUT
  806.   
  807.   METHODDEF void
  808. ! put_demapped_rgb_raw_byte_rows (decompress_info_ptr cinfo, int num_rows,
  809.             JSAMPIMAGE pixel_data)
  810.   {
  811.     register FILE * outfile = cinfo->output_file;
  812. ***************
  813. *** 210,216 ****
  814.   }
  815.   
  816.   METHODDEF void
  817. ! put_demapped_gray (decompress_info_ptr cinfo, int num_rows,
  818.              JSAMPIMAGE pixel_data)
  819.   {
  820.     register FILE * outfile = cinfo->output_file;
  821. --- 449,455 ----
  822.   }
  823.   
  824.   METHODDEF void
  825. ! put_demapped_gray_raw_byte_rows (decompress_info_ptr cinfo, int num_rows,
  826.              JSAMPIMAGE pixel_data)
  827.   {
  828.     register FILE * outfile = cinfo->output_file;
  829. ***************
  830. *** 233,239 ****
  831.   #else /* use row buffering */
  832.   
  833.   METHODDEF void
  834. ! put_demapped_rgb (decompress_info_ptr cinfo, int num_rows,
  835.             JSAMPIMAGE pixel_data)
  836.   {
  837.     FILE * outfile = cinfo->output_file;
  838. --- 472,478 ----
  839.   #else /* use row buffering */
  840.   
  841.   METHODDEF void
  842. ! put_demapped_rgb_raw_byte_rows (decompress_info_ptr cinfo, int num_rows,
  843.             JSAMPIMAGE pixel_data)
  844.   {
  845.     FILE * outfile = cinfo->output_file;
  846. ***************
  847. *** 261,267 ****
  848.   }
  849.   
  850.   METHODDEF void
  851. ! put_demapped_gray (decompress_info_ptr cinfo, int num_rows,
  852.              JSAMPIMAGE pixel_data)
  853.   {
  854.     FILE * outfile = cinfo->output_file;
  855. --- 500,506 ----
  856.   }
  857.   
  858.   METHODDEF void
  859. ! put_demapped_gray_raw_byte_rows (decompress_info_ptr cinfo, int num_rows,
  860.              JSAMPIMAGE pixel_data)
  861.   {
  862.     FILE * outfile = cinfo->output_file;
  863. ***************
  864. *** 295,304 ****
  865.   METHODDEF void
  866.   put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
  867.   {
  868. !   if (cinfo->out_color_space == CS_RGB)
  869. !     cinfo->methods->put_pixel_rows = put_demapped_rgb;
  870. !   else
  871. !     cinfo->methods->put_pixel_rows = put_demapped_gray;
  872.   }
  873.   
  874.   
  875. --- 534,568 ----
  876.   METHODDEF void
  877.   put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
  878.   {
  879. !   if (cinfo->out_color_space == CS_RGB) {
  880. ! #ifdef PPM_WRITETEXT
  881. !     cinfo->methods->put_pixel_rows = put_demapped_rgb_text_rows;
  882. ! #else  /*PPM_WRITETEXT*/
  883. !     if (cinfo->data_precision == 8) {
  884. !       cinfo->methods->put_pixel_rows = put_demapped_rgb_raw_byte_rows;
  885. !     } else {
  886. ! #ifdef PPM_WRITERAWWORDS
  887. !       cinfo->methods->put_pixel_rows = put_demapped_rgb_raw_word_rows;
  888. ! #else  /*PPM_WRITERAWWORDS*/
  889. !       cinfo->methods->put_pixel_rows = put_demapped_rgb_text_rows;
  890. ! #endif /*PPM_WRITERAWWORDS*/
  891. !     }
  892. ! #endif /*PPM_WRITETEXT*/
  893. !   } else {
  894. ! #ifdef PPM_WRITETEXT
  895. !     cinfo->methods->put_pixel_rows = put_demapped_gray_text_rows;
  896. ! #else  /*PPM_WRITETEXT*/
  897. !     if (cinfo->data_precision == 8) {
  898. !       cinfo->methods->put_pixel_rows = put_demapped_gray_raw_byte_rows;
  899. !     } else {
  900. ! #ifdef PPM_WRITERAWWORDS
  901. !       cinfo->methods->put_pixel_rows = put_demapped_gray_raw_word_rows;
  902. ! #else  /*PPM_WRITERAWWORDS*/
  903. !       cinfo->methods->put_pixel_rows = put_demapped_gray_text_rows;
  904. ! #endif /*PPM_WRITERAWWORDS*/
  905. !     }
  906. ! #endif /*PPM_WRITETEXT*/
  907. !   }
  908.   }
  909.   
  910.   
  911. ***************
  912. *** 327,337 ****
  913.   {
  914.     cinfo->methods->output_init = output_init;
  915.     cinfo->methods->put_color_map = put_color_map;
  916. !   if (cinfo->out_color_space == CS_RGB)
  917. !     cinfo->methods->put_pixel_rows = put_pixel_rows;
  918. !   else
  919. !     cinfo->methods->put_pixel_rows = put_gray_rows;
  920.     cinfo->methods->output_term = output_term;
  921.   }
  922.   
  923.   #endif /* PPM_SUPPORTED */
  924. --- 591,631 ----
  925.   {
  926.     cinfo->methods->output_init = output_init;
  927.     cinfo->methods->put_color_map = put_color_map;
  928. !   if (cinfo->out_color_space == CS_RGB) {
  929. ! #ifdef PPM_WRITETEXT
  930. !     cinfo->methods->put_pixel_rows = put_rgb_text_rows;
  931. ! #else  /*PPM_WRITETEXT*/
  932. !     if (cinfo->data_precision == 8) {
  933. !       cinfo->methods->put_pixel_rows = put_rgb_raw_byte_rows;
  934. !     } else {
  935. ! #ifdef PPM_WRITERAWWORDS
  936. !       cinfo->methods->put_pixel_rows = put_rgb_raw_word_rows;
  937. ! #else  /*PPM_WRITERAWWORDS*/
  938. !       cinfo->methods->put_pixel_rows = put_rgb_text_rows;
  939. ! #endif /*PPM_WRITERAWWORDS*/
  940. !     }
  941. ! #endif /*PPM_WRITETEXT*/
  942. !   } else {
  943. ! #ifdef PPM_WRITETEXT
  944. !     cinfo->methods->put_pixel_rows = put_gray_text_rows;
  945. ! #else  /*PPM_WRITETEXT*/
  946. !     if (cinfo->data_precision == 8) {
  947. !       cinfo->methods->put_pixel_rows = put_gray_raw_byte_rows;
  948. !     } else {
  949. ! #ifdef PPM_WRITERAWWORDS
  950. !       cinfo->methods->put_pixel_rows = put_gray_raw_word_rows;
  951. ! #else  /*PPM_WRITERAWWORDS*/
  952. !       cinfo->methods->put_pixel_rows = put_gray_text_rows;
  953. ! #endif /*PPM_WRITERAWWORDS*/
  954. !     }
  955. ! #endif /*PPM_WRITETEXT*/
  956. !   }
  957.     cinfo->methods->output_term = output_term;
  958.   }
  959.   
  960.   #endif /* PPM_SUPPORTED */
  961.  
  962. ---
  963. David A. Clunie (dclunie@flash.us.com)
  964. In sunny Riyadh, Saudi Arabia.
  965.  
  966. "I must see your DICOM 3 conformance statement before I buy."
  967.  
  968.