| OLD | NEW |
| 1 /* | 1 /* |
| 2 * rdppm.c | 2 * rdppm.c |
| 3 * | 3 * |
| 4 * This file was part of the Independent JPEG Group's software: |
| 4 * Copyright (C) 1991-1997, Thomas G. Lane. | 5 * Copyright (C) 1991-1997, Thomas G. Lane. |
| 5 * Modified 2009 by Bill Allombert, Guido Vollbeding. | 6 * Modified 2009 by Bill Allombert, Guido Vollbeding. |
| 6 * This file is part of the Independent JPEG Group's software. | 7 * libjpeg-turbo Modifications: |
| 7 * For conditions of distribution and use, see the accompanying README file. | 8 * Copyright (C) 2015, D. R. Commander. |
| 9 * For conditions of distribution and use, see the accompanying README.ijg |
| 10 * file. |
| 8 * | 11 * |
| 9 * This file contains routines to read input images in PPM/PGM format. | 12 * This file contains routines to read input images in PPM/PGM format. |
| 10 * The extended 2-byte-per-sample raw PPM/PGM formats are supported. | 13 * The extended 2-byte-per-sample raw PPM/PGM formats are supported. |
| 11 * The PBMPLUS library is NOT required to compile this software | 14 * The PBMPLUS library is NOT required to compile this software |
| 12 * (but it is highly useful as a set of PPM image manipulation programs). | 15 * (but it is highly useful as a set of PPM image manipulation programs). |
| 13 * | 16 * |
| 14 * These routines may need modification for non-Unix environments or | 17 * These routines may need modification for non-Unix environments or |
| 15 * specialized applications. As they stand, they assume input from | 18 * specialized applications. As they stand, they assume input from |
| 16 * an ordinary stdio stream. They further assume that reading begins | 19 * an ordinary stdio stream. They further assume that reading begins |
| 17 * at the start of the file; start_input may need work if the | 20 * at the start of the file; start_input may need work if the |
| 18 * user interface has already read some data (e.g., to determine that | 21 * user interface has already read some data (e.g., to determine that |
| 19 * the file is indeed PPM format). | 22 * the file is indeed PPM format). |
| 20 */ | 23 */ |
| 21 | 24 |
| 22 #include "cdjpeg.h"» » /* Common decls for cjpeg/djpeg applications */ | 25 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ |
| 23 | 26 |
| 24 #ifdef PPM_SUPPORTED | 27 #ifdef PPM_SUPPORTED |
| 25 | 28 |
| 26 | 29 |
| 27 /* Portions of this code are based on the PBMPLUS library, which is: | 30 /* Portions of this code are based on the PBMPLUS library, which is: |
| 28 ** | 31 ** |
| 29 ** Copyright (C) 1988 by Jef Poskanzer. | 32 ** Copyright (C) 1988 by Jef Poskanzer. |
| 30 ** | 33 ** |
| 31 ** Permission to use, copy, modify, and distribute this software and its | 34 ** Permission to use, copy, modify, and distribute this software and its |
| 32 ** documentation for any purpose and without fee is hereby granted, provided | 35 ** documentation for any purpose and without fee is hereby granted, provided |
| 33 ** that the above copyright notice appear in all copies and that both that | 36 ** that the above copyright notice appear in all copies and that both that |
| 34 ** copyright notice and this permission notice appear in supporting | 37 ** copyright notice and this permission notice appear in supporting |
| 35 ** documentation. This software is provided "as is" without express or | 38 ** documentation. This software is provided "as is" without express or |
| 36 ** implied warranty. | 39 ** implied warranty. |
| 37 */ | 40 */ |
| 38 | 41 |
| 39 | 42 |
| 40 /* Macros to deal with unsigned chars as efficiently as compiler allows */ | 43 /* Macros to deal with unsigned chars as efficiently as compiler allows */ |
| 41 | 44 |
| 42 #ifdef HAVE_UNSIGNED_CHAR | 45 #ifdef HAVE_UNSIGNED_CHAR |
| 43 typedef unsigned char U_CHAR; | 46 typedef unsigned char U_CHAR; |
| 44 #define UCH(x)» ((int) (x)) | 47 #define UCH(x) ((int) (x)) |
| 45 #else /* !HAVE_UNSIGNED_CHAR */ | 48 #else /* !HAVE_UNSIGNED_CHAR */ |
| 46 #ifdef CHAR_IS_UNSIGNED | 49 #ifdef __CHAR_UNSIGNED__ |
| 47 typedef char U_CHAR; | 50 typedef char U_CHAR; |
| 48 #define UCH(x)» ((int) (x)) | 51 #define UCH(x) ((int) (x)) |
| 49 #else | 52 #else |
| 50 typedef char U_CHAR; | 53 typedef char U_CHAR; |
| 51 #define UCH(x)» ((int) (x) & 0xFF) | 54 #define UCH(x) ((int) (x) & 0xFF) |
| 52 #endif | 55 #endif |
| 53 #endif /* HAVE_UNSIGNED_CHAR */ | 56 #endif /* HAVE_UNSIGNED_CHAR */ |
| 54 | 57 |
| 55 | 58 |
| 56 #define»ReadOK(file,buffer,len)»(JFREAD(file,buffer,len) == ((size_t) (len))) | 59 #define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len))) |
| 57 | |
| 58 | |
| 59 /* | |
| 60 * On most systems, reading individual bytes with getc() is drastically less | |
| 61 * efficient than buffering a row at a time with fread(). On PCs, we must | |
| 62 * allocate the buffer in near data space, because we are assuming small-data | |
| 63 * memory model, wherein fread() can't reach far memory. If you need to | |
| 64 * process very wide images on a PC, you might have to compile in large-memory | |
| 65 * model, or else replace fread() with a getc() loop --- which will be much | |
| 66 * slower. | |
| 67 */ | |
| 68 | 60 |
| 69 | 61 |
| 70 /* Private version of data source object */ | 62 /* Private version of data source object */ |
| 71 | 63 |
| 72 typedef struct { | 64 typedef struct { |
| 73 struct cjpeg_source_struct pub; /* public fields */ | 65 struct cjpeg_source_struct pub; /* public fields */ |
| 74 | 66 |
| 75 U_CHAR *iobuffer;» » /* non-FAR pointer to I/O buffer */ | 67 /* Usually these two pointers point to the same place: */ |
| 76 JSAMPROW pixrow;» » /* FAR pointer to same */ | 68 U_CHAR *iobuffer; /* fread's I/O buffer */ |
| 77 size_t buffer_width;» » /* width of I/O buffer */ | 69 JSAMPROW pixrow; /* compressor input buffer */ |
| 78 JSAMPLE *rescale;» » /* => maxval-remapping array, or NULL */ | 70 size_t buffer_width; /* width of I/O buffer */ |
| 71 JSAMPLE *rescale; /* => maxval-remapping array, or NULL */ |
| 72 int maxval; |
| 79 } ppm_source_struct; | 73 } ppm_source_struct; |
| 80 | 74 |
| 81 typedef ppm_source_struct * ppm_source_ptr; | 75 typedef ppm_source_struct *ppm_source_ptr; |
| 82 | 76 |
| 83 | 77 |
| 84 LOCAL(int) | 78 LOCAL(int) |
| 85 pbm_getc (FILE * infile) | 79 pbm_getc (FILE *infile) |
| 86 /* Read next char, skipping over any comments */ | 80 /* Read next char, skipping over any comments */ |
| 87 /* A comment/newline sequence is returned as a newline */ | 81 /* A comment/newline sequence is returned as a newline */ |
| 88 { | 82 { |
| 89 register int ch; | 83 register int ch; |
| 90 | 84 |
| 91 ch = getc(infile); | 85 ch = getc(infile); |
| 92 if (ch == '#') { | 86 if (ch == '#') { |
| 93 do { | 87 do { |
| 94 ch = getc(infile); | 88 ch = getc(infile); |
| 95 } while (ch != '\n' && ch != EOF); | 89 } while (ch != '\n' && ch != EOF); |
| 96 } | 90 } |
| 97 return ch; | 91 return ch; |
| 98 } | 92 } |
| 99 | 93 |
| 100 | 94 |
| 101 LOCAL(unsigned int) | 95 LOCAL(unsigned int) |
| 102 read_pbm_integer (j_compress_ptr cinfo, FILE * infile) | 96 read_pbm_integer (j_compress_ptr cinfo, FILE *infile, unsigned int maxval) |
| 103 /* Read an unsigned decimal integer from the PPM file */ | 97 /* Read an unsigned decimal integer from the PPM file */ |
| 104 /* Swallows one trailing character after the integer */ | 98 /* Swallows one trailing character after the integer */ |
| 105 /* Note that on a 16-bit-int machine, only values up to 64k can be read. */ | 99 /* Note that on a 16-bit-int machine, only values up to 64k can be read. */ |
| 106 /* This should not be a problem in practice. */ | 100 /* This should not be a problem in practice. */ |
| 107 { | 101 { |
| 108 register int ch; | 102 register int ch; |
| 109 register unsigned int val; | 103 register unsigned int val; |
| 110 | 104 |
| 111 /* Skip any leading whitespace */ | 105 /* Skip any leading whitespace */ |
| 112 do { | 106 do { |
| 113 ch = pbm_getc(infile); | 107 ch = pbm_getc(infile); |
| 114 if (ch == EOF) | 108 if (ch == EOF) |
| 115 ERREXIT(cinfo, JERR_INPUT_EOF); | 109 ERREXIT(cinfo, JERR_INPUT_EOF); |
| 116 } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); | 110 } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); |
| 117 | 111 |
| 118 if (ch < '0' || ch > '9') | 112 if (ch < '0' || ch > '9') |
| 119 ERREXIT(cinfo, JERR_PPM_NONNUMERIC); | 113 ERREXIT(cinfo, JERR_PPM_NONNUMERIC); |
| 120 | 114 |
| 121 val = ch - '0'; | 115 val = ch - '0'; |
| 122 while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') { | 116 while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') { |
| 123 val *= 10; | 117 val *= 10; |
| 124 val += ch - '0'; | 118 val += ch - '0'; |
| 125 } | 119 } |
| 120 |
| 121 if (val > maxval) |
| 122 ERREXIT(cinfo, JERR_PPM_TOOLARGE); |
| 123 |
| 126 return val; | 124 return val; |
| 127 } | 125 } |
| 128 | 126 |
| 129 | 127 |
| 130 /* | 128 /* |
| 131 * Read one row of pixels. | 129 * Read one row of pixels. |
| 132 * | 130 * |
| 133 * We provide several different versions depending on input file format. | 131 * We provide several different versions depending on input file format. |
| 134 * In all cases, input is scaled to the size of JSAMPLE. | 132 * In all cases, input is scaled to the size of JSAMPLE. |
| 135 * | 133 * |
| 136 * A really fast path is provided for reading byte/sample raw files with | 134 * A really fast path is provided for reading byte/sample raw files with |
| 137 * maxval = MAXJSAMPLE, which is the normal case for 8-bit data. | 135 * maxval = MAXJSAMPLE, which is the normal case for 8-bit data. |
| 138 */ | 136 */ |
| 139 | 137 |
| 140 | 138 |
| 141 METHODDEF(JDIMENSION) | 139 METHODDEF(JDIMENSION) |
| 142 get_text_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | 140 get_text_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
| 143 /* This version is for reading text-format PGM files with any maxval */ | 141 /* This version is for reading text-format PGM files with any maxval */ |
| 144 { | 142 { |
| 145 ppm_source_ptr source = (ppm_source_ptr) sinfo; | 143 ppm_source_ptr source = (ppm_source_ptr) sinfo; |
| 146 FILE * infile = source->pub.input_file; | 144 FILE *infile = source->pub.input_file; |
| 147 register JSAMPROW ptr; | 145 register JSAMPROW ptr; |
| 148 register JSAMPLE *rescale = source->rescale; | 146 register JSAMPLE *rescale = source->rescale; |
| 149 JDIMENSION col; | 147 JDIMENSION col; |
| 148 unsigned int maxval = source->maxval; |
| 150 | 149 |
| 151 ptr = source->pub.buffer[0]; | 150 ptr = source->pub.buffer[0]; |
| 152 for (col = cinfo->image_width; col > 0; col--) { | 151 for (col = cinfo->image_width; col > 0; col--) { |
| 153 *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; | 152 *ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)]; |
| 154 } | 153 } |
| 155 return 1; | 154 return 1; |
| 156 } | 155 } |
| 157 | 156 |
| 158 | 157 |
| 159 METHODDEF(JDIMENSION) | 158 METHODDEF(JDIMENSION) |
| 160 get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | 159 get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
| 161 /* This version is for reading text-format PPM files with any maxval */ | 160 /* This version is for reading text-format PPM files with any maxval */ |
| 162 { | 161 { |
| 163 ppm_source_ptr source = (ppm_source_ptr) sinfo; | 162 ppm_source_ptr source = (ppm_source_ptr) sinfo; |
| 164 FILE * infile = source->pub.input_file; | 163 FILE *infile = source->pub.input_file; |
| 165 register JSAMPROW ptr; | 164 register JSAMPROW ptr; |
| 166 register JSAMPLE *rescale = source->rescale; | 165 register JSAMPLE *rescale = source->rescale; |
| 167 JDIMENSION col; | 166 JDIMENSION col; |
| 167 unsigned int maxval = source->maxval; |
| 168 | 168 |
| 169 ptr = source->pub.buffer[0]; | 169 ptr = source->pub.buffer[0]; |
| 170 for (col = cinfo->image_width; col > 0; col--) { | 170 for (col = cinfo->image_width; col > 0; col--) { |
| 171 *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; | 171 *ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)]; |
| 172 *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; | 172 *ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)]; |
| 173 *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; | 173 *ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)]; |
| 174 } | 174 } |
| 175 return 1; | 175 return 1; |
| 176 } | 176 } |
| 177 | 177 |
| 178 | 178 |
| 179 METHODDEF(JDIMENSION) | 179 METHODDEF(JDIMENSION) |
| 180 get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | 180 get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
| 181 /* This version is for reading raw-byte-format PGM files with any maxval */ | 181 /* This version is for reading raw-byte-format PGM files with any maxval */ |
| 182 { | 182 { |
| 183 ppm_source_ptr source = (ppm_source_ptr) sinfo; | 183 ppm_source_ptr source = (ppm_source_ptr) sinfo; |
| 184 register JSAMPROW ptr; | 184 register JSAMPROW ptr; |
| 185 register U_CHAR * bufferptr; | 185 register U_CHAR *bufferptr; |
| 186 register JSAMPLE *rescale = source->rescale; | 186 register JSAMPLE *rescale = source->rescale; |
| 187 JDIMENSION col; | 187 JDIMENSION col; |
| 188 | 188 |
| 189 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) | 189 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) |
| 190 ERREXIT(cinfo, JERR_INPUT_EOF); | 190 ERREXIT(cinfo, JERR_INPUT_EOF); |
| 191 ptr = source->pub.buffer[0]; | 191 ptr = source->pub.buffer[0]; |
| 192 bufferptr = source->iobuffer; | 192 bufferptr = source->iobuffer; |
| 193 for (col = cinfo->image_width; col > 0; col--) { | 193 for (col = cinfo->image_width; col > 0; col--) { |
| 194 *ptr++ = rescale[UCH(*bufferptr++)]; | 194 *ptr++ = rescale[UCH(*bufferptr++)]; |
| 195 } | 195 } |
| 196 return 1; | 196 return 1; |
| 197 } | 197 } |
| 198 | 198 |
| 199 | 199 |
| 200 METHODDEF(JDIMENSION) | 200 METHODDEF(JDIMENSION) |
| 201 get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | 201 get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
| 202 /* This version is for reading raw-byte-format PPM files with any maxval */ | 202 /* This version is for reading raw-byte-format PPM files with any maxval */ |
| 203 { | 203 { |
| 204 ppm_source_ptr source = (ppm_source_ptr) sinfo; | 204 ppm_source_ptr source = (ppm_source_ptr) sinfo; |
| 205 register JSAMPROW ptr; | 205 register JSAMPROW ptr; |
| 206 register U_CHAR * bufferptr; | 206 register U_CHAR *bufferptr; |
| 207 register JSAMPLE *rescale = source->rescale; | 207 register JSAMPLE *rescale = source->rescale; |
| 208 JDIMENSION col; | 208 JDIMENSION col; |
| 209 | 209 |
| 210 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) | 210 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) |
| 211 ERREXIT(cinfo, JERR_INPUT_EOF); | 211 ERREXIT(cinfo, JERR_INPUT_EOF); |
| 212 ptr = source->pub.buffer[0]; | 212 ptr = source->pub.buffer[0]; |
| 213 bufferptr = source->iobuffer; | 213 bufferptr = source->iobuffer; |
| 214 for (col = cinfo->image_width; col > 0; col--) { | 214 for (col = cinfo->image_width; col > 0; col--) { |
| 215 *ptr++ = rescale[UCH(*bufferptr++)]; | 215 *ptr++ = rescale[UCH(*bufferptr++)]; |
| 216 *ptr++ = rescale[UCH(*bufferptr++)]; | 216 *ptr++ = rescale[UCH(*bufferptr++)]; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 234 return 1; | 234 return 1; |
| 235 } | 235 } |
| 236 | 236 |
| 237 | 237 |
| 238 METHODDEF(JDIMENSION) | 238 METHODDEF(JDIMENSION) |
| 239 get_word_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | 239 get_word_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
| 240 /* This version is for reading raw-word-format PGM files with any maxval */ | 240 /* This version is for reading raw-word-format PGM files with any maxval */ |
| 241 { | 241 { |
| 242 ppm_source_ptr source = (ppm_source_ptr) sinfo; | 242 ppm_source_ptr source = (ppm_source_ptr) sinfo; |
| 243 register JSAMPROW ptr; | 243 register JSAMPROW ptr; |
| 244 register U_CHAR * bufferptr; | 244 register U_CHAR *bufferptr; |
| 245 register JSAMPLE *rescale = source->rescale; | 245 register JSAMPLE *rescale = source->rescale; |
| 246 JDIMENSION col; | 246 JDIMENSION col; |
| 247 | 247 |
| 248 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) | 248 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) |
| 249 ERREXIT(cinfo, JERR_INPUT_EOF); | 249 ERREXIT(cinfo, JERR_INPUT_EOF); |
| 250 ptr = source->pub.buffer[0]; | 250 ptr = source->pub.buffer[0]; |
| 251 bufferptr = source->iobuffer; | 251 bufferptr = source->iobuffer; |
| 252 for (col = cinfo->image_width; col > 0; col--) { | 252 for (col = cinfo->image_width; col > 0; col--) { |
| 253 register int temp; | 253 register int temp; |
| 254 temp = UCH(*bufferptr++) << 8; | 254 temp = UCH(*bufferptr++) << 8; |
| 255 temp |= UCH(*bufferptr++); | 255 temp |= UCH(*bufferptr++); |
| 256 *ptr++ = rescale[temp]; | 256 *ptr++ = rescale[temp]; |
| 257 } | 257 } |
| 258 return 1; | 258 return 1; |
| 259 } | 259 } |
| 260 | 260 |
| 261 | 261 |
| 262 METHODDEF(JDIMENSION) | 262 METHODDEF(JDIMENSION) |
| 263 get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | 263 get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
| 264 /* This version is for reading raw-word-format PPM files with any maxval */ | 264 /* This version is for reading raw-word-format PPM files with any maxval */ |
| 265 { | 265 { |
| 266 ppm_source_ptr source = (ppm_source_ptr) sinfo; | 266 ppm_source_ptr source = (ppm_source_ptr) sinfo; |
| 267 register JSAMPROW ptr; | 267 register JSAMPROW ptr; |
| 268 register U_CHAR * bufferptr; | 268 register U_CHAR *bufferptr; |
| 269 register JSAMPLE *rescale = source->rescale; | 269 register JSAMPLE *rescale = source->rescale; |
| 270 JDIMENSION col; | 270 JDIMENSION col; |
| 271 | 271 |
| 272 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) | 272 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) |
| 273 ERREXIT(cinfo, JERR_INPUT_EOF); | 273 ERREXIT(cinfo, JERR_INPUT_EOF); |
| 274 ptr = source->pub.buffer[0]; | 274 ptr = source->pub.buffer[0]; |
| 275 bufferptr = source->iobuffer; | 275 bufferptr = source->iobuffer; |
| 276 for (col = cinfo->image_width; col > 0; col--) { | 276 for (col = cinfo->image_width; col > 0; col--) { |
| 277 register int temp; | 277 register int temp; |
| 278 temp = UCH(*bufferptr++) << 8; | 278 temp = UCH(*bufferptr++) << 8; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 301 unsigned int w, h, maxval; | 301 unsigned int w, h, maxval; |
| 302 boolean need_iobuffer, use_raw_buffer, need_rescale; | 302 boolean need_iobuffer, use_raw_buffer, need_rescale; |
| 303 | 303 |
| 304 if (getc(source->pub.input_file) != 'P') | 304 if (getc(source->pub.input_file) != 'P') |
| 305 ERREXIT(cinfo, JERR_PPM_NOT); | 305 ERREXIT(cinfo, JERR_PPM_NOT); |
| 306 | 306 |
| 307 c = getc(source->pub.input_file); /* subformat discriminator character */ | 307 c = getc(source->pub.input_file); /* subformat discriminator character */ |
| 308 | 308 |
| 309 /* detect unsupported variants (ie, PBM) before trying to read header */ | 309 /* detect unsupported variants (ie, PBM) before trying to read header */ |
| 310 switch (c) { | 310 switch (c) { |
| 311 case '2':» » » /* it's a text-format PGM file */ | 311 case '2': /* it's a text-format PGM file */ |
| 312 case '3':» » » /* it's a text-format PPM file */ | 312 case '3': /* it's a text-format PPM file */ |
| 313 case '5':» » » /* it's a raw-format PGM file */ | 313 case '5': /* it's a raw-format PGM file */ |
| 314 case '6':» » » /* it's a raw-format PPM file */ | 314 case '6': /* it's a raw-format PPM file */ |
| 315 break; | 315 break; |
| 316 default: | 316 default: |
| 317 ERREXIT(cinfo, JERR_PPM_NOT); | 317 ERREXIT(cinfo, JERR_PPM_NOT); |
| 318 break; | 318 break; |
| 319 } | 319 } |
| 320 | 320 |
| 321 /* fetch the remaining header info */ | 321 /* fetch the remaining header info */ |
| 322 w = read_pbm_integer(cinfo, source->pub.input_file); | 322 w = read_pbm_integer(cinfo, source->pub.input_file, 65535); |
| 323 h = read_pbm_integer(cinfo, source->pub.input_file); | 323 h = read_pbm_integer(cinfo, source->pub.input_file, 65535); |
| 324 maxval = read_pbm_integer(cinfo, source->pub.input_file); | 324 maxval = read_pbm_integer(cinfo, source->pub.input_file, 65535); |
| 325 | 325 |
| 326 if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ | 326 if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ |
| 327 ERREXIT(cinfo, JERR_PPM_NOT); | 327 ERREXIT(cinfo, JERR_PPM_NOT); |
| 328 | 328 |
| 329 cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */ | 329 cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */ |
| 330 cinfo->image_width = (JDIMENSION) w; | 330 cinfo->image_width = (JDIMENSION) w; |
| 331 cinfo->image_height = (JDIMENSION) h; | 331 cinfo->image_height = (JDIMENSION) h; |
| 332 source->maxval = maxval; |
| 332 | 333 |
| 333 /* initialize flags to most common settings */ | 334 /* initialize flags to most common settings */ |
| 334 need_iobuffer = TRUE;»» /* do we need an I/O buffer? */ | 335 need_iobuffer = TRUE; /* do we need an I/O buffer? */ |
| 335 use_raw_buffer = FALSE;» /* do we map input buffer onto I/O buffer? */ | 336 use_raw_buffer = FALSE; /* do we map input buffer onto I/O buffer? */ |
| 336 need_rescale = TRUE;» » /* do we need a rescale array? */ | 337 need_rescale = TRUE; /* do we need a rescale array? */ |
| 337 | 338 |
| 338 switch (c) { | 339 switch (c) { |
| 339 case '2':» » » /* it's a text-format PGM file */ | 340 case '2': /* it's a text-format PGM file */ |
| 340 cinfo->input_components = 1; | 341 cinfo->input_components = 1; |
| 341 cinfo->in_color_space = JCS_GRAYSCALE; | 342 cinfo->in_color_space = JCS_GRAYSCALE; |
| 342 TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h); | 343 TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h); |
| 343 source->pub.get_pixel_rows = get_text_gray_row; | 344 source->pub.get_pixel_rows = get_text_gray_row; |
| 344 need_iobuffer = FALSE; | 345 need_iobuffer = FALSE; |
| 345 break; | 346 break; |
| 346 | 347 |
| 347 case '3':» » » /* it's a text-format PPM file */ | 348 case '3': /* it's a text-format PPM file */ |
| 348 cinfo->input_components = 3; | 349 cinfo->input_components = 3; |
| 349 cinfo->in_color_space = JCS_RGB; | 350 cinfo->in_color_space = JCS_RGB; |
| 350 TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h); | 351 TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h); |
| 351 source->pub.get_pixel_rows = get_text_rgb_row; | 352 source->pub.get_pixel_rows = get_text_rgb_row; |
| 352 need_iobuffer = FALSE; | 353 need_iobuffer = FALSE; |
| 353 break; | 354 break; |
| 354 | 355 |
| 355 case '5':» » » /* it's a raw-format PGM file */ | 356 case '5': /* it's a raw-format PGM file */ |
| 356 cinfo->input_components = 1; | 357 cinfo->input_components = 1; |
| 357 cinfo->in_color_space = JCS_GRAYSCALE; | 358 cinfo->in_color_space = JCS_GRAYSCALE; |
| 358 TRACEMS2(cinfo, 1, JTRC_PGM, w, h); | 359 TRACEMS2(cinfo, 1, JTRC_PGM, w, h); |
| 359 if (maxval > 255) { | 360 if (maxval > 255) { |
| 360 source->pub.get_pixel_rows = get_word_gray_row; | 361 source->pub.get_pixel_rows = get_word_gray_row; |
| 361 } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) { | 362 } else if (maxval == MAXJSAMPLE && sizeof(JSAMPLE) == sizeof(U_CHAR)) { |
| 362 source->pub.get_pixel_rows = get_raw_row; | 363 source->pub.get_pixel_rows = get_raw_row; |
| 363 use_raw_buffer = TRUE; | 364 use_raw_buffer = TRUE; |
| 364 need_rescale = FALSE; | 365 need_rescale = FALSE; |
| 365 } else { | 366 } else { |
| 366 source->pub.get_pixel_rows = get_scaled_gray_row; | 367 source->pub.get_pixel_rows = get_scaled_gray_row; |
| 367 } | 368 } |
| 368 break; | 369 break; |
| 369 | 370 |
| 370 case '6':» » » /* it's a raw-format PPM file */ | 371 case '6': /* it's a raw-format PPM file */ |
| 371 cinfo->input_components = 3; | 372 cinfo->input_components = 3; |
| 372 cinfo->in_color_space = JCS_RGB; | 373 cinfo->in_color_space = JCS_RGB; |
| 373 TRACEMS2(cinfo, 1, JTRC_PPM, w, h); | 374 TRACEMS2(cinfo, 1, JTRC_PPM, w, h); |
| 374 if (maxval > 255) { | 375 if (maxval > 255) { |
| 375 source->pub.get_pixel_rows = get_word_rgb_row; | 376 source->pub.get_pixel_rows = get_word_rgb_row; |
| 376 } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) { | 377 } else if (maxval == MAXJSAMPLE && sizeof(JSAMPLE) == sizeof(U_CHAR)) { |
| 377 source->pub.get_pixel_rows = get_raw_row; | 378 source->pub.get_pixel_rows = get_raw_row; |
| 378 use_raw_buffer = TRUE; | 379 use_raw_buffer = TRUE; |
| 379 need_rescale = FALSE; | 380 need_rescale = FALSE; |
| 380 } else { | 381 } else { |
| 381 source->pub.get_pixel_rows = get_scaled_rgb_row; | 382 source->pub.get_pixel_rows = get_scaled_rgb_row; |
| 382 } | 383 } |
| 383 break; | 384 break; |
| 384 } | 385 } |
| 385 | 386 |
| 386 /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */ | 387 /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */ |
| 387 if (need_iobuffer) { | 388 if (need_iobuffer) { |
| 388 source->buffer_width = (size_t) w * cinfo->input_components * | 389 source->buffer_width = (size_t) w * cinfo->input_components * |
| 389 ((maxval<=255) ? SIZEOF(U_CHAR) : (2*SIZEOF(U_CHAR))); | 390 ((maxval <= 255) ? sizeof(U_CHAR) : (2 * sizeof(U_CHAR))); |
| 390 source->iobuffer = (U_CHAR *) | 391 source->iobuffer = (U_CHAR *) |
| 391 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, | 392 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, |
| 392 » » » » source->buffer_width); | 393 source->buffer_width); |
| 393 } | 394 } |
| 394 | 395 |
| 395 /* Create compressor input buffer. */ | 396 /* Create compressor input buffer. */ |
| 396 if (use_raw_buffer) { | 397 if (use_raw_buffer) { |
| 397 /* For unscaled raw-input case, we can just map it onto the I/O buffer. */ | 398 /* For unscaled raw-input case, we can just map it onto the I/O buffer. */ |
| 398 /* Synthesize a JSAMPARRAY pointer structure */ | 399 /* Synthesize a JSAMPARRAY pointer structure */ |
| 399 /* Cast here implies near->far pointer conversion on PCs */ | |
| 400 source->pixrow = (JSAMPROW) source->iobuffer; | 400 source->pixrow = (JSAMPROW) source->iobuffer; |
| 401 source->pub.buffer = & source->pixrow; | 401 source->pub.buffer = & source->pixrow; |
| 402 source->pub.buffer_height = 1; | 402 source->pub.buffer_height = 1; |
| 403 } else { | 403 } else { |
| 404 /* Need to translate anyway, so make a separate sample buffer. */ | 404 /* Need to translate anyway, so make a separate sample buffer. */ |
| 405 source->pub.buffer = (*cinfo->mem->alloc_sarray) | 405 source->pub.buffer = (*cinfo->mem->alloc_sarray) |
| 406 ((j_common_ptr) cinfo, JPOOL_IMAGE, | 406 ((j_common_ptr) cinfo, JPOOL_IMAGE, |
| 407 (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1); | 407 (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1); |
| 408 source->pub.buffer_height = 1; | 408 source->pub.buffer_height = 1; |
| 409 } | 409 } |
| 410 | 410 |
| 411 /* Compute the rescaling array if required. */ | 411 /* Compute the rescaling array if required. */ |
| 412 if (need_rescale) { | 412 if (need_rescale) { |
| 413 INT32 val, half_maxval; | 413 long val, half_maxval; |
| 414 | 414 |
| 415 /* On 16-bit-int machines we have to be careful of maxval = 65535 */ | 415 /* On 16-bit-int machines we have to be careful of maxval = 65535 */ |
| 416 source->rescale = (JSAMPLE *) | 416 source->rescale = (JSAMPLE *) |
| 417 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, | 417 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, |
| 418 » » » » (size_t) (((long) maxval + 1L) * SIZEOF(JSAMPL
E))); | 418 (size_t) (((long) maxval + 1L) * |
| 419 sizeof(JSAMPLE))); |
| 419 half_maxval = maxval / 2; | 420 half_maxval = maxval / 2; |
| 420 for (val = 0; val <= (INT32) maxval; val++) { | 421 for (val = 0; val <= (long) maxval; val++) { |
| 421 /* The multiplication here must be done in 32 bits to avoid overflow */ | 422 /* The multiplication here must be done in 32 bits to avoid overflow */ |
| 422 source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval); | 423 source->rescale[val] = (JSAMPLE) ((val * MAXJSAMPLE + half_maxval) / |
| 424 maxval); |
| 423 } | 425 } |
| 424 } | 426 } |
| 425 } | 427 } |
| 426 | 428 |
| 427 | 429 |
| 428 /* | 430 /* |
| 429 * Finish up at the end of the file. | 431 * Finish up at the end of the file. |
| 430 */ | 432 */ |
| 431 | 433 |
| 432 METHODDEF(void) | 434 METHODDEF(void) |
| 433 finish_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | 435 finish_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
| 434 { | 436 { |
| 435 /* no work */ | 437 /* no work */ |
| 436 } | 438 } |
| 437 | 439 |
| 438 | 440 |
| 439 /* | 441 /* |
| 440 * The module selection routine for PPM format input. | 442 * The module selection routine for PPM format input. |
| 441 */ | 443 */ |
| 442 | 444 |
| 443 GLOBAL(cjpeg_source_ptr) | 445 GLOBAL(cjpeg_source_ptr) |
| 444 jinit_read_ppm (j_compress_ptr cinfo) | 446 jinit_read_ppm (j_compress_ptr cinfo) |
| 445 { | 447 { |
| 446 ppm_source_ptr source; | 448 ppm_source_ptr source; |
| 447 | 449 |
| 448 /* Create module interface object */ | 450 /* Create module interface object */ |
| 449 source = (ppm_source_ptr) | 451 source = (ppm_source_ptr) |
| 450 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, | 452 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, |
| 451 » » » » SIZEOF(ppm_source_struct)); | 453 sizeof(ppm_source_struct)); |
| 452 /* Fill in method ptrs, except get_pixel_rows which start_input sets */ | 454 /* Fill in method ptrs, except get_pixel_rows which start_input sets */ |
| 453 source->pub.start_input = start_input_ppm; | 455 source->pub.start_input = start_input_ppm; |
| 454 source->pub.finish_input = finish_input_ppm; | 456 source->pub.finish_input = finish_input_ppm; |
| 455 | 457 |
| 456 return (cjpeg_source_ptr) source; | 458 return (cjpeg_source_ptr) source; |
| 457 } | 459 } |
| 458 | 460 |
| 459 #endif /* PPM_SUPPORTED */ | 461 #endif /* PPM_SUPPORTED */ |
| OLD | NEW |