00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "cdjpeg.h"
00023
00024 #ifdef PPM_SUPPORTED
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifdef HAVE_UNSIGNED_CHAR
00043 typedef unsigned char U_CHAR;
00044 #define UCH(x) ((int) (x))
00045 #else
00046 #ifdef CHAR_IS_UNSIGNED
00047 typedef char U_CHAR;
00048 #define UCH(x) ((int) (x))
00049 #else
00050 typedef char U_CHAR;
00051 #define UCH(x) ((int) (x) & 0xFF)
00052 #endif
00053 #endif
00054
00055
00056 #define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 typedef struct {
00073 struct cjpeg_source_struct pub;
00074
00075 U_CHAR *iobuffer;
00076 JSAMPROW pixrow;
00077 size_t buffer_width;
00078 JSAMPLE *rescale;
00079 } ppm_source_struct;
00080
00081 typedef ppm_source_struct * ppm_source_ptr;
00082
00083
00084 LOCAL(int)
00085 pbm_getc (FILE * infile)
00086
00087
00088 {
00089 register int ch;
00090
00091 ch = getc(infile);
00092 if (ch == '#') {
00093 do {
00094 ch = getc(infile);
00095 } while (ch != '\n' && ch != EOF);
00096 }
00097 return ch;
00098 }
00099
00100
00101 LOCAL(unsigned int)
00102 read_pbm_integer (j_compress_ptr cinfo, FILE * infile)
00103
00104
00105
00106
00107 {
00108 register int ch;
00109 register unsigned int val;
00110
00111
00112 do {
00113 ch = pbm_getc(infile);
00114 if (ch == EOF)
00115 ERREXIT(cinfo, JERR_INPUT_EOF);
00116 } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
00117
00118 if (ch < '0' || ch > '9')
00119 ERREXIT(cinfo, JERR_PPM_NONNUMERIC);
00120
00121 val = ch - '0';
00122 while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') {
00123 val *= 10;
00124 val += ch - '0';
00125 }
00126 return val;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 METHODDEF(JDIMENSION)
00142 get_text_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00143
00144 {
00145 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00146 FILE * infile = source->pub.input_file;
00147 register JSAMPROW ptr;
00148 register JSAMPLE *rescale = source->rescale;
00149 JDIMENSION col;
00150
00151 ptr = source->pub.buffer[0];
00152 for (col = cinfo->image_width; col > 0; col--) {
00153 *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00154 }
00155 return 1;
00156 }
00157
00158
00159 METHODDEF(JDIMENSION)
00160 get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00161
00162 {
00163 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00164 FILE * infile = source->pub.input_file;
00165 register JSAMPROW ptr;
00166 register JSAMPLE *rescale = source->rescale;
00167 JDIMENSION col;
00168
00169 ptr = source->pub.buffer[0];
00170 for (col = cinfo->image_width; col > 0; col--) {
00171 *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00172 *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00173 *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00174 }
00175 return 1;
00176 }
00177
00178
00179 METHODDEF(JDIMENSION)
00180 get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00181
00182 {
00183 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00184 register JSAMPROW ptr;
00185 register U_CHAR * bufferptr;
00186 register JSAMPLE *rescale = source->rescale;
00187 JDIMENSION col;
00188
00189 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00190 ERREXIT(cinfo, JERR_INPUT_EOF);
00191 ptr = source->pub.buffer[0];
00192 bufferptr = source->iobuffer;
00193 for (col = cinfo->image_width; col > 0; col--) {
00194 *ptr++ = rescale[UCH(*bufferptr++)];
00195 }
00196 return 1;
00197 }
00198
00199
00200 METHODDEF(JDIMENSION)
00201 get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00202
00203 {
00204 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00205 register JSAMPROW ptr;
00206 register U_CHAR * bufferptr;
00207 register JSAMPLE *rescale = source->rescale;
00208 JDIMENSION col;
00209
00210 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00211 ERREXIT(cinfo, JERR_INPUT_EOF);
00212 ptr = source->pub.buffer[0];
00213 bufferptr = source->iobuffer;
00214 for (col = cinfo->image_width; col > 0; col--) {
00215 *ptr++ = rescale[UCH(*bufferptr++)];
00216 *ptr++ = rescale[UCH(*bufferptr++)];
00217 *ptr++ = rescale[UCH(*bufferptr++)];
00218 }
00219 return 1;
00220 }
00221
00222
00223 METHODDEF(JDIMENSION)
00224 get_raw_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00225
00226
00227
00228
00229 {
00230 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00231
00232 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00233 ERREXIT(cinfo, JERR_INPUT_EOF);
00234 return 1;
00235 }
00236
00237
00238 METHODDEF(JDIMENSION)
00239 get_word_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00240
00241 {
00242 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00243 register JSAMPROW ptr;
00244 register U_CHAR * bufferptr;
00245 register JSAMPLE *rescale = source->rescale;
00246 JDIMENSION col;
00247
00248 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00249 ERREXIT(cinfo, JERR_INPUT_EOF);
00250 ptr = source->pub.buffer[0];
00251 bufferptr = source->iobuffer;
00252 for (col = cinfo->image_width; col > 0; col--) {
00253 register int temp;
00254 temp = UCH(*bufferptr++) << 8;
00255 temp |= UCH(*bufferptr++);
00256 *ptr++ = rescale[temp];
00257 }
00258 return 1;
00259 }
00260
00261
00262 METHODDEF(JDIMENSION)
00263 get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00264
00265 {
00266 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00267 register JSAMPROW ptr;
00268 register U_CHAR * bufferptr;
00269 register JSAMPLE *rescale = source->rescale;
00270 JDIMENSION col;
00271
00272 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00273 ERREXIT(cinfo, JERR_INPUT_EOF);
00274 ptr = source->pub.buffer[0];
00275 bufferptr = source->iobuffer;
00276 for (col = cinfo->image_width; col > 0; col--) {
00277 register int temp;
00278 temp = UCH(*bufferptr++) << 8;
00279 temp |= UCH(*bufferptr++);
00280 *ptr++ = rescale[temp];
00281 temp = UCH(*bufferptr++) << 8;
00282 temp |= UCH(*bufferptr++);
00283 *ptr++ = rescale[temp];
00284 temp = UCH(*bufferptr++) << 8;
00285 temp |= UCH(*bufferptr++);
00286 *ptr++ = rescale[temp];
00287 }
00288 return 1;
00289 }
00290
00291
00292
00293
00294
00295
00296 METHODDEF(void)
00297 start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00298 {
00299 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00300 int c;
00301 unsigned int w, h, maxval;
00302 boolean need_iobuffer, use_raw_buffer, need_rescale;
00303
00304 if (getc(source->pub.input_file) != 'P')
00305 ERREXIT(cinfo, JERR_PPM_NOT);
00306
00307 c = getc(source->pub.input_file);
00308
00309
00310 switch (c) {
00311 case '2':
00312 case '3':
00313 case '5':
00314 case '6':
00315 break;
00316 default:
00317 ERREXIT(cinfo, JERR_PPM_NOT);
00318 break;
00319 }
00320
00321
00322 w = read_pbm_integer(cinfo, source->pub.input_file);
00323 h = read_pbm_integer(cinfo, source->pub.input_file);
00324 maxval = read_pbm_integer(cinfo, source->pub.input_file);
00325
00326 if (w <= 0 || h <= 0 || maxval <= 0)
00327 ERREXIT(cinfo, JERR_PPM_NOT);
00328
00329 cinfo->data_precision = BITS_IN_JSAMPLE;
00330 cinfo->image_width = (JDIMENSION) w;
00331 cinfo->image_height = (JDIMENSION) h;
00332
00333
00334 need_iobuffer = TRUE;
00335 use_raw_buffer = FALSE;
00336 need_rescale = TRUE;
00337
00338 switch (c) {
00339 case '2':
00340 cinfo->input_components = 1;
00341 cinfo->in_color_space = JCS_GRAYSCALE;
00342 TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h);
00343 source->pub.get_pixel_rows = get_text_gray_row;
00344 need_iobuffer = FALSE;
00345 break;
00346
00347 case '3':
00348 cinfo->input_components = 3;
00349 cinfo->in_color_space = JCS_RGB;
00350 TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h);
00351 source->pub.get_pixel_rows = get_text_rgb_row;
00352 need_iobuffer = FALSE;
00353 break;
00354
00355 case '5':
00356 cinfo->input_components = 1;
00357 cinfo->in_color_space = JCS_GRAYSCALE;
00358 TRACEMS2(cinfo, 1, JTRC_PGM, w, h);
00359 if (maxval > 255) {
00360 source->pub.get_pixel_rows = get_word_gray_row;
00361 } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) {
00362 source->pub.get_pixel_rows = get_raw_row;
00363 use_raw_buffer = TRUE;
00364 need_rescale = FALSE;
00365 } else {
00366 source->pub.get_pixel_rows = get_scaled_gray_row;
00367 }
00368 break;
00369
00370 case '6':
00371 cinfo->input_components = 3;
00372 cinfo->in_color_space = JCS_RGB;
00373 TRACEMS2(cinfo, 1, JTRC_PPM, w, h);
00374 if (maxval > 255) {
00375 source->pub.get_pixel_rows = get_word_rgb_row;
00376 } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) {
00377 source->pub.get_pixel_rows = get_raw_row;
00378 use_raw_buffer = TRUE;
00379 need_rescale = FALSE;
00380 } else {
00381 source->pub.get_pixel_rows = get_scaled_rgb_row;
00382 }
00383 break;
00384 }
00385
00386
00387 if (need_iobuffer) {
00388 source->buffer_width = (size_t) w * cinfo->input_components *
00389 ((maxval<=255) ? SIZEOF(U_CHAR) : (2*SIZEOF(U_CHAR)));
00390 source->iobuffer = (U_CHAR *)
00391 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00392 source->buffer_width);
00393 }
00394
00395
00396 if (use_raw_buffer) {
00397
00398
00399
00400 source->pixrow = (JSAMPROW) source->iobuffer;
00401 source->pub.buffer = & source->pixrow;
00402 source->pub.buffer_height = 1;
00403 } else {
00404
00405 source->pub.buffer = (*cinfo->mem->alloc_sarray)
00406 ((j_common_ptr) cinfo, JPOOL_IMAGE,
00407 (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1);
00408 source->pub.buffer_height = 1;
00409 }
00410
00411
00412 if (need_rescale) {
00413 INT32 val, half_maxval;
00414
00415
00416 source->rescale = (JSAMPLE *)
00417 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00418 (size_t) (((long) maxval + 1L) * SIZEOF(JSAMPLE)));
00419 half_maxval = maxval / 2;
00420 for (val = 0; val <= (INT32) maxval; val++) {
00421
00422 source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval);
00423 }
00424 }
00425 }
00426
00427
00428
00429
00430
00431
00432 METHODDEF(void)
00433 finish_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00434 {
00435
00436 }
00437
00438
00439
00440
00441
00442
00443 GLOBAL(cjpeg_source_ptr)
00444 jinit_read_ppm (j_compress_ptr cinfo)
00445 {
00446 ppm_source_ptr source;
00447
00448
00449 source = (ppm_source_ptr)
00450 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00451 SIZEOF(ppm_source_struct));
00452
00453 source->pub.start_input = start_input_ppm;
00454 source->pub.finish_input = finish_input_ppm;
00455
00456 return (cjpeg_source_ptr) source;
00457 }
00458
00459 #endif