home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / GRAPHICS / JPEGSRC.V4.lzh / jwrppm.c < prev    next >
Text File  |  1993-01-14  |  10KB  |  355 lines

  1. /*
  2.  * jwrppm.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains routines to write output images in PPM/PGM format.
  9.  *
  10.  * These routines may need modification for non-Unix environments or
  11.  * specialized applications.  As they stand, they assume output to
  12.  * an ordinary stdio stream.
  13.  *
  14.  * These routines are invoked via the methods put_pixel_rows, put_color_map,
  15.  * and output_init/term.
  16.  */
  17.  
  18. #include "jinclude.h"
  19.  
  20. #ifdef PPM_SUPPORTED
  21.  
  22. /* 
  23.    OS-9 uses CR (0x0D) for the end-of-line character instead of the
  24.    UNIX LF (0x0A).  The OS-9 cc and gcc interpret \n as 0x0D.  This
  25.    confuses the program when reading PPM files which use the UNIX
  26.    convention.  This problem is the origin of the #ifdef OSK #endif
  27.    macros in the following code.
  28. */
  29.  
  30. /*
  31.  * Haven't yet got around to making this work with text-format output,
  32.  * hence cannot handle pixels wider than 8 bits.
  33.  */
  34.  
  35. #ifndef EIGHT_BIT_SAMPLES
  36.   Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
  37. #endif
  38.  
  39.  
  40. /*
  41.  * On most systems, writing individual bytes with putc() is drastically less
  42.  * efficient than buffering a row at a time for fwrite().  But we must
  43.  * allocate the row buffer in near data space on PCs, because we are assuming
  44.  * small-data memory model, wherein fwrite() can't reach far memory.  If you
  45.  * need to process very wide images on a PC, you may have to use the putc()
  46.  * approach.  Also, there are still a few systems around wherein fwrite() is
  47.  * actually implemented as a putc() loop, in which case this buffer is a waste
  48.  * of space.  So the putc() method can be used by defining USE_PUTC_OUTPUT.
  49.  */
  50.  
  51. #ifndef USE_PUTC_OUTPUT
  52. static char * row_buffer;    /* holds 1 pixel row's worth of output */
  53. #endif
  54.  
  55.  
  56. /*
  57.  * Write the file header.
  58.  */
  59.  
  60. METHODDEF void
  61. output_init (decompress_info_ptr cinfo)
  62. {
  63.   if (cinfo->out_color_space == CS_GRAYSCALE) {
  64.     /* emit header for raw PGM format */
  65. #ifdef OSK
  66.     fprintf(cinfo->output_file, "P5\l%ld %ld\l%d\l",
  67.         cinfo->image_width, cinfo->image_height, 255);
  68. #else
  69.     fprintf(cinfo->output_file, "P5\n%ld %ld\n%d\n",
  70.         cinfo->image_width, cinfo->image_height, 255);
  71. #endif /* OSK */   
  72. #ifndef USE_PUTC_OUTPUT
  73.     /* allocate space for row buffer: 1 byte/pixel */
  74.     row_buffer = (char *) (*cinfo->emethods->alloc_small)
  75.             ((size_t) (SIZEOF(char) * cinfo->image_width));
  76. #endif
  77.   } else if (cinfo->out_color_space == CS_RGB) {
  78.     /* emit header for raw PPM format */
  79. #ifdef OSK
  80.     fprintf(cinfo->output_file, "P6\l%ld %ld\l%d\l",
  81.         cinfo->image_width, cinfo->image_height, 255);
  82. #else
  83.     fprintf(cinfo->output_file, "P6\n%ld %ld\n%d\n",
  84.         cinfo->image_width, cinfo->image_height, 255);
  85. #endif /* OSK */
  86. #ifndef USE_PUTC_OUTPUT
  87.     /* allocate space for row buffer: 3 bytes/pixel */
  88.     row_buffer = (char *) (*cinfo->emethods->alloc_small)
  89.             ((size_t) (3 * SIZEOF(char) * cinfo->image_width));
  90. #endif
  91.   } else {
  92.     ERREXIT(cinfo->emethods, "PPM output must be grayscale or RGB");
  93.   }
  94. }
  95.  
  96.  
  97. /*
  98.  * Write some pixel data.
  99.  */
  100.  
  101. #ifdef USE_PUTC_OUTPUT
  102.  
  103. METHODDEF void
  104. put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
  105.         JSAMPIMAGE pixel_data)
  106. {
  107.   register FILE * outfile = cinfo->output_file;
  108.   register JSAMPROW ptr0, ptr1, ptr2;
  109.   register long col;
  110.   long width = cinfo->image_width;
  111.   int row;
  112.   
  113.   for (row = 0; row < num_rows; row++) {
  114.     ptr0 = pixel_data[0][row];
  115.     ptr1 = pixel_data[1][row];
  116.     ptr2 = pixel_data[2][row];
  117.     for (col = width; col > 0; col--) {
  118.       putc(GETJSAMPLE(*ptr0), outfile);
  119.       ptr0++;
  120.       putc(GETJSAMPLE(*ptr1), outfile);
  121.       ptr1++;
  122.       putc(GETJSAMPLE(*ptr2), outfile);
  123.       ptr2++;
  124.     }
  125.   }
  126. }
  127.  
  128. METHODDEF void
  129. put_gray_rows (decompress_info_ptr cinfo, int num_rows,
  130.            JSAMPIMAGE pixel_data)
  131. {
  132.   register FILE * outfile = cinfo->output_file;
  133.   register JSAMPROW ptr0;
  134.   register long col;
  135.   long width = cinfo->image_width;
  136.   int row;
  137.   
  138.   for (row = 0; row < num_rows; row++) {
  139.     ptr0 = pixel_data[0][row];
  140.     for (col = width; col > 0; col--) {
  141.       putc(GETJSAMPLE(*ptr0), outfile);
  142.       ptr0++;
  143.     }
  144.   }
  145. }
  146.  
  147. #else /* use row buffering */
  148.  
  149. METHODDEF void
  150. put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
  151.         JSAMPIMAGE pixel_data)
  152. {
  153.   FILE * outfile = cinfo->output_file;
  154.   register JSAMPROW ptr0, ptr1, ptr2;
  155.   register char * row_bufferptr;
  156.   register long col;
  157.   long width = cinfo->image_width;
  158.   int row;
  159.   
  160.   for (row = 0; row < num_rows; row++) {
  161.     ptr0 = pixel_data[0][row];
  162.     ptr1 = pixel_data[1][row];
  163.     ptr2 = pixel_data[2][row];
  164.     row_bufferptr = row_buffer;
  165.     for (col = width; col > 0; col--) {
  166.       *row_bufferptr++ = (char) GETJSAMPLE(*ptr0++);
  167.       *row_bufferptr++ = (char) GETJSAMPLE(*ptr1++);
  168.       *row_bufferptr++ = (char) GETJSAMPLE(*ptr2++);
  169.     }
  170.     (void) JFWRITE(outfile, row_buffer, 3*width);
  171.   }
  172. }
  173.  
  174. METHODDEF void
  175. put_gray_rows (decompress_info_ptr cinfo, int num_rows,
  176.            JSAMPIMAGE pixel_data)
  177. {
  178.   FILE * outfile = cinfo->output_file;
  179.   register JSAMPROW ptr0;
  180.   register char * row_bufferptr;
  181.   register long col;
  182.   long width = cinfo->image_width;
  183.   int row;
  184.   
  185.   for (row = 0; row < num_rows; row++) {
  186.     ptr0 = pixel_data[0][row];
  187.     row_bufferptr = row_buffer;
  188.     for (col = width; col > 0; col--) {
  189.       *row_bufferptr++ = (char) GETJSAMPLE(*ptr0++);
  190.     }
  191.     (void) JFWRITE(outfile, row_buffer, width);
  192.   }
  193. }
  194.  
  195. #endif /* USE_PUTC_OUTPUT */
  196.  
  197.  
  198. /*
  199.  * Write some pixel data when color quantization is in effect.
  200.  */
  201.  
  202. #ifdef USE_PUTC_OUTPUT
  203.  
  204. METHODDEF void
  205. put_demapped_rgb (decompress_info_ptr cinfo, int num_rows,
  206.           JSAMPIMAGE pixel_data)
  207. {
  208.   register FILE * outfile = cinfo->output_file;
  209.   register JSAMPROW ptr;
  210.   register JSAMPROW color_map0 = cinfo->colormap[0];
  211.   register JSAMPROW color_map1 = cinfo->colormap[1];
  212.   register JSAMPROW color_map2 = cinfo->colormap[2];
  213.   register int pixval;
  214.   register long col;
  215.   long width = cinfo->image_width;
  216.   int row;
  217.   
  218.   for (row = 0; row < num_rows; row++) {
  219.     ptr = pixel_data[0][row];
  220.     for (col = width; col > 0; col--) {
  221.       pixval = GETJSAMPLE(*ptr++);
  222.       putc(GETJSAMPLE(color_map0[pixval]), outfile);
  223.       putc(GETJSAMPLE(color_map1[pixval]), outfile);
  224.       putc(GETJSAMPLE(color_map2[pixval]), outfile);
  225.     }
  226.   }
  227. }
  228.  
  229. METHODDEF void
  230. put_demapped_gray (decompress_info_ptr cinfo, int num_rows,
  231.            JSAMPIMAGE pixel_data)
  232. {
  233.   register FILE * outfile = cinfo->output_file;
  234.   register JSAMPROW ptr;
  235.   register JSAMPROW color_map0 = cinfo->colormap[0];
  236.   register int pixval;
  237.   register long col;
  238.   long width = cinfo->image_width;
  239.   int row;
  240.   
  241.   for (row = 0; row < num_rows; row++) {
  242.     ptr = pixel_data[0][row];
  243.     for (col = width; col > 0; col--) {
  244.       pixval = GETJSAMPLE(*ptr++);
  245.       putc(GETJSAMPLE(color_map0[pixval]), outfile);
  246.     }
  247.   }
  248. }
  249.  
  250. #else /* use row buffering */
  251.  
  252. METHODDEF void
  253. put_demapped_rgb (decompress_info_ptr cinfo, int num_rows,
  254.           JSAMPIMAGE pixel_data)
  255. {
  256.   FILE * outfile = cinfo->output_file;
  257.   register JSAMPROW ptr;
  258.   register char * row_bufferptr;
  259.   register JSAMPROW color_map0 = cinfo->colormap[0];
  260.   register JSAMPROW color_map1 = cinfo->colormap[1];
  261.   register JSAMPROW color_map2 = cinfo->colormap[2];
  262.   register int pixval;
  263.   register long col;
  264.   long width = cinfo->image_width;
  265.   int row;
  266.   
  267.   for (row = 0; row < num_rows; row++) {
  268.     ptr = pixel_data[0][row];
  269.     row_bufferptr = row_buffer;
  270.     for (col = width; col > 0; col--) {
  271.       pixval = GETJSAMPLE(*ptr++);
  272.       *row_bufferptr++ = (char) GETJSAMPLE(color_map0[pixval]);
  273.       *row_bufferptr++ = (char) GETJSAMPLE(color_map1[pixval]);
  274.       *row_bufferptr++ = (char) GETJSAMPLE(color_map2[pixval]);
  275.     }
  276.     (void) JFWRITE(outfile, row_buffer, 3*width);
  277.   }
  278. }
  279.  
  280. METHODDEF void
  281. put_demapped_gray (decompress_info_ptr cinfo, int num_rows,
  282.            JSAMPIMAGE pixel_data)
  283. {
  284.   FILE * outfile = cinfo->output_file;
  285.   register JSAMPROW ptr;
  286.   register char * row_bufferptr;
  287.   register JSAMPROW color_map0 = cinfo->colormap[0];
  288.   register int pixval;
  289.   register long col;
  290.   long width = cinfo->image_width;
  291.   int row;
  292.   
  293.   for (row = 0; row < num_rows; row++) {
  294.     ptr = pixel_data[0][row];
  295.     row_bufferptr = row_buffer;
  296.     for (col = width; col > 0; col--) {
  297.       pixval = GETJSAMPLE(*ptr++);
  298.       *row_bufferptr++ = (char) GETJSAMPLE(color_map0[pixval]);
  299.     }
  300.     (void) JFWRITE(outfile, row_buffer, width);
  301.   }
  302. }
  303.  
  304. #endif /* USE_PUTC_OUTPUT */
  305.  
  306.  
  307. /*
  308.  * Write the color map.
  309.  * For PPM output, we just remember to demap the output data!
  310.  */
  311.  
  312. METHODDEF void
  313. put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
  314. {
  315.   if (cinfo->out_color_space == CS_RGB)
  316.     cinfo->methods->put_pixel_rows = put_demapped_rgb;
  317.   else
  318.     cinfo->methods->put_pixel_rows = put_demapped_gray;
  319. }
  320.  
  321.  
  322. /*
  323.  * Finish up at the end of the file.
  324.  */
  325.  
  326. METHODDEF void
  327. output_term (decompress_info_ptr cinfo)
  328. {
  329.   /* No work except to make sure we wrote the output file OK; */
  330.   /* we let free_all release any workspace */
  331.   fflush(cinfo->output_file);
  332.   if (ferror(cinfo->output_file))
  333.     ERREXIT(cinfo->emethods, "Output file write error");
  334. }
  335.  
  336.  
  337. /*
  338.  * The method selection routine for PPM format output.
  339.  * This should be called from d_ui_method_selection if PPM output is wanted.
  340.  */
  341.  
  342. GLOBAL void
  343. jselwppm (decompress_info_ptr cinfo)
  344. {
  345.   cinfo->methods->output_init = output_init;
  346.   cinfo->methods->put_color_map = put_color_map;
  347.   if (cinfo->out_color_space == CS_RGB)
  348.     cinfo->methods->put_pixel_rows = put_pixel_rows;
  349.   else
  350.     cinfo->methods->put_pixel_rows = put_gray_rows;
  351.   cinfo->methods->output_term = output_term;
  352. }
  353.  
  354. #endif /* PPM_SUPPORTED */
  355.