home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / GRAPHICS / jpegsrc.v3.lzh / jrdppm.c < prev    next >
Text File  |  1992-07-03  |  9KB  |  339 lines

  1. /*
  2.  * jrdppm.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 read input images in PPM format.
  9.  * The PBMPLUS library is NOT required to compile this software,
  10.  * but it is highly useful as a set of PPM image manipulation programs.
  11.  *
  12.  * These routines may need modification for non-Unix environments or
  13.  * specialized applications.  As they stand, they assume input from
  14.  * an ordinary stdio stream.  They further assume that reading begins
  15.  * at the start of the file; input_init may need work if the
  16.  * user interface has already read some data (e.g., to determine that
  17.  * the file is indeed PPM format).
  18.  *
  19.  * These routines are invoked via the methods get_input_row
  20.  * and input_init/term.
  21.  */
  22.  
  23. #include "jinclude.h"
  24.  
  25. #ifdef PPM_SUPPORTED
  26.  
  27. /* 
  28.    OS-9 uses CR (0x0D) for the end-of-line character instead of the
  29.    UNIX LF (0x0A).  The OS-9 cc and gcc interpret \n as 0x0D.  This
  30.    confuses the program when reading PPM files which use the UNIX
  31.    convention.  This problem is the origin of the #ifdef OSK #endif
  32.    macros in the following code.
  33. */
  34.  
  35. static JSAMPLE * rescale;    /* => maxval-remapping array, or NULL */
  36.  
  37.  
  38. /* Portions of this code are based on the PBMPLUS library, which is:
  39. **
  40. ** Copyright (C) 1988 by Jef Poskanzer.
  41. **
  42. ** Permission to use, copy, modify, and distribute this software and its
  43. ** documentation for any purpose and without fee is hereby granted, provided
  44. ** that the above copyright notice appear in all copies and that both that
  45. ** copyright notice and this permission notice appear in supporting
  46. ** documentation.  This software is provided "as is" without express or
  47. ** implied warranty.
  48. */
  49.  
  50.  
  51. LOCAL int
  52. pbm_getc (FILE * file)
  53. /* Read next char, skipping over any comments */
  54. /* A comment/newline sequence is returned as a newline */
  55. {
  56.   register int ch;
  57.   
  58.   ch = getc(file);
  59.   if (ch == '#') {
  60.     do {
  61.       ch = getc(file);
  62. #ifdef OSK
  63.     } while (ch != '\l' && ch != EOF);
  64. #else
  65.     } while (ch != '\n' && ch != EOF);
  66. #endif /* OSK */
  67.   }
  68.   return ch;
  69. }
  70.  
  71.  
  72. LOCAL unsigned int
  73. read_pbm_integer (compress_info_ptr cinfo)
  74. /* Read an unsigned decimal integer from the PPM file */
  75. /* Swallows one trailing character after the integer */
  76. /* Note that on a 16-bit-int machine, only values up to 64k can be read. */
  77. /* This should not be a problem in practice. */
  78. {
  79.   register int ch;
  80.   register unsigned int val;
  81.   
  82.   /* Skip any leading whitespace */
  83.   do {
  84.     ch = pbm_getc(cinfo->input_file);
  85.     if (ch == EOF)
  86.       ERREXIT(cinfo->emethods, "Premature EOF in PPM file");
  87. #ifdef OSK
  88.   } while (ch == ' ' || ch == '\t' || ch == '\l');
  89. #else
  90.   } while (ch == ' ' || ch == '\t' || ch == '\n');
  91. #endif /* OSK */  
  92.   if (ch < '0' || ch > '9')
  93.     ERREXIT(cinfo->emethods, "Bogus data in PPM file");
  94.   
  95.   val = ch - '0';
  96.   while ((ch = pbm_getc(cinfo->input_file)) >= '0' && ch <= '9') {
  97.     val *= 10;
  98.     val += ch - '0';
  99.   }
  100.   return val;
  101. }
  102.  
  103.  
  104. /*
  105.  * Read one row of pixels.
  106.  *
  107.  * We provide several different versions depending on input file format.
  108.  * In all cases, input is scaled to the size of JSAMPLE; it's possible that
  109.  * when JSAMPLE is 12 bits, this would not really be desirable.
  110.  *
  111.  * Note that a really fast path is provided for reading raw files with
  112.  * maxval = MAXJSAMPLE, which is the normal case (at least for 8-bit JSAMPLEs).
  113.  */
  114.  
  115.  
  116. METHODDEF void
  117. get_text_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  118. /* This version is for reading text-format PGM files with any maxval */
  119. {
  120.   register JSAMPROW ptr0;
  121.   register unsigned int val;
  122.   register long col;
  123.   
  124.   ptr0 = pixel_row[0];
  125.   for (col = cinfo->image_width; col > 0; col--) {
  126.     val = read_pbm_integer(cinfo);
  127.     if (rescale != NULL)
  128.       val = rescale[val];
  129.     *ptr0++ = (JSAMPLE) val;
  130.   }
  131. }
  132.  
  133.  
  134. METHODDEF void
  135. get_text_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  136. /* This version is for reading text-format PPM files with any maxval */
  137. {
  138.   register JSAMPROW ptr0, ptr1, ptr2;
  139.   register unsigned int val;
  140.   register long col;
  141.   
  142.   ptr0 = pixel_row[0];
  143.   ptr1 = pixel_row[1];
  144.   ptr2 = pixel_row[2];
  145.   for (col = cinfo->image_width; col > 0; col--) {
  146.     val = read_pbm_integer(cinfo);
  147.     if (rescale != NULL)
  148.       val = rescale[val];
  149.     *ptr0++ = (JSAMPLE) val;
  150.     val = read_pbm_integer(cinfo);
  151.     if (rescale != NULL)
  152.       val = rescale[val];
  153.     *ptr1++ = (JSAMPLE) val;
  154.     val = read_pbm_integer(cinfo);
  155.     if (rescale != NULL)
  156.       val = rescale[val];
  157.     *ptr2++ = (JSAMPLE) val;
  158.   }
  159. }
  160.  
  161.  
  162. METHODDEF void
  163. get_scaled_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  164. /* This version is for reading raw-format PGM files with any maxval */
  165. {
  166.   register FILE * infile = cinfo->input_file;
  167.   register JSAMPROW ptr0;
  168.   register long col;
  169.   
  170.   ptr0 = pixel_row[0];
  171.   for (col = cinfo->image_width; col > 0; col--) {
  172.     *ptr0++ = rescale[getc(infile)];
  173.   }
  174. }
  175.  
  176.  
  177. METHODDEF void
  178. get_scaled_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  179. /* This version is for reading raw-format PPM files with any maxval */
  180. {
  181.   register FILE * infile = cinfo->input_file;
  182.   register JSAMPROW ptr0, ptr1, ptr2;
  183.   register long col;
  184.   
  185.   ptr0 = pixel_row[0];
  186.   ptr1 = pixel_row[1];
  187.   ptr2 = pixel_row[2];
  188.   for (col = cinfo->image_width; col > 0; col--) {
  189.     *ptr0++ = rescale[getc(infile)];
  190.     *ptr1++ = rescale[getc(infile)];
  191.     *ptr2++ = rescale[getc(infile)];
  192.   }
  193. }
  194.  
  195.  
  196. METHODDEF void
  197. get_raw_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  198. /* This version is for reading raw-format PGM files with maxval = MAXJSAMPLE */
  199. {
  200.   register FILE * infile = cinfo->input_file;
  201.   register JSAMPROW ptr0;
  202.   register long col;
  203.   
  204.   ptr0 = pixel_row[0];
  205.   for (col = cinfo->image_width; col > 0; col--) {
  206.     *ptr0++ = (JSAMPLE) getc(infile);
  207.   }
  208. }
  209.  
  210.  
  211. METHODDEF void
  212. get_raw_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  213. /* This version is for reading raw-format PPM files with maxval = MAXJSAMPLE */
  214. {
  215.   register FILE * infile = cinfo->input_file;
  216.   register JSAMPROW ptr0, ptr1, ptr2;
  217.   register long col;
  218.   
  219.   ptr0 = pixel_row[0];
  220.   ptr1 = pixel_row[1];
  221.   ptr2 = pixel_row[2];
  222.   for (col = cinfo->image_width; col > 0; col--) {
  223.     *ptr0++ = (JSAMPLE) getc(infile);
  224.     *ptr1++ = (JSAMPLE) getc(infile);
  225.     *ptr2++ = (JSAMPLE) getc(infile);
  226.   }
  227. }
  228.  
  229.  
  230. /*
  231.  * Read the file header; return image size and component count.
  232.  */
  233.  
  234. METHODDEF void
  235. input_init (compress_info_ptr cinfo)
  236. {
  237.   int c;
  238.   unsigned int w, h, maxval;
  239.  
  240.   if (getc(cinfo->input_file) != 'P')
  241.     ERREXIT(cinfo->emethods, "Not a PPM file");
  242.  
  243.   c = getc(cinfo->input_file);    /* save format discriminator for a sec */
  244.  
  245.   w = read_pbm_integer(cinfo);    /* while we fetch the header info */
  246.   h = read_pbm_integer(cinfo);
  247.   maxval = read_pbm_integer(cinfo);
  248.  
  249.   switch (c) {
  250.   case '2':            /* it's a text-format PGM file */
  251.     cinfo->methods->get_input_row = get_text_gray_row;
  252.     cinfo->input_components = 1;
  253.     cinfo->in_color_space = CS_GRAYSCALE;
  254.     break;
  255.  
  256.   case '3':            /* it's a text-format PPM file */
  257.     cinfo->methods->get_input_row = get_text_rgb_row;
  258.     cinfo->input_components = 3;
  259.     cinfo->in_color_space = CS_RGB;
  260.     break;
  261.  
  262.   case '5':            /* it's a raw-format PGM file */
  263.     if (maxval == MAXJSAMPLE)
  264.       cinfo->methods->get_input_row = get_raw_gray_row;
  265.     else
  266.       cinfo->methods->get_input_row = get_scaled_gray_row;
  267.     cinfo->input_components = 1;
  268.     cinfo->in_color_space = CS_GRAYSCALE;
  269.     break;
  270.  
  271.   case '6':            /* it's a raw-format PPM file */
  272.     if (maxval == MAXJSAMPLE)
  273.       cinfo->methods->get_input_row = get_raw_rgb_row;
  274.     else
  275.       cinfo->methods->get_input_row = get_scaled_rgb_row;
  276.     cinfo->input_components = 3;
  277.     cinfo->in_color_space = CS_RGB;
  278.     break;
  279.  
  280.   default:
  281.     ERREXIT(cinfo->emethods, "Not a PPM file");
  282.     break;
  283.   }
  284.  
  285.   if (w <= 0 || h <= 0 || maxval <= 0) /* error check */
  286.     ERREXIT(cinfo->emethods, "Not a PPM file");
  287.  
  288.   /* Compute the rescaling array if necessary */
  289.   /* This saves per-pixel calculation */
  290.   if (maxval == MAXJSAMPLE)
  291.     rescale = NULL;        /* no rescaling required */
  292.   else {
  293.     INT32 val, half_maxval;
  294.  
  295.     /* On 16-bit-int machines we have to be careful of maxval = 65535 */
  296.     rescale = (JSAMPLE *) (*cinfo->emethods->alloc_small)
  297.             ((size_t) (((long) maxval + 1L) * SIZEOF(JSAMPLE)));
  298.     half_maxval = maxval / 2;
  299.     for (val = 0; val <= (INT32) maxval; val++) {
  300.       /* The multiplication here must be done in 32 bits to avoid overflow */
  301.       rescale[val] = (JSAMPLE) ((val * MAXJSAMPLE + half_maxval) / maxval);
  302.     }
  303.   }
  304.  
  305.   cinfo->image_width = w;
  306.   cinfo->image_height = h;
  307.   cinfo->data_precision = BITS_IN_JSAMPLE;
  308. }
  309.  
  310.  
  311. /*
  312.  * Finish up at the end of the file.
  313.  */
  314.  
  315. METHODDEF void
  316. input_term (compress_info_ptr cinfo)
  317. {
  318.   /* no work (we let free_all release the workspace) */
  319. }
  320.  
  321.  
  322. /*
  323.  * The method selection routine for PPM format input.
  324.  * Note that this must be called by the user interface before calling
  325.  * jpeg_compress.  If multiple input formats are supported, the
  326.  * user interface is responsible for discovering the file format and
  327.  * calling the appropriate method selection routine.
  328.  */
  329.  
  330. GLOBAL void
  331. jselrppm (compress_info_ptr cinfo)
  332. {
  333.   cinfo->methods->input_init = input_init;
  334.   /* cinfo->methods->get_input_row is set by input_init */
  335.   cinfo->methods->input_term = input_term;
  336. }
  337.  
  338. #endif /* PPM_SUPPORTED */
  339.