Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/libjpeg/wrppm.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * wrppm.c | |
| 3 * | |
| 4 * Copyright (C) 1991-1996, Thomas G. Lane. | |
| 5 * Modified 2009-2020 by Guido Vollbeding. | |
| 6 * This file is part of the Independent JPEG Group's software. | |
| 7 * For conditions of distribution and use, see the accompanying README file. | |
| 8 * | |
| 9 * This file contains routines to write output images in PPM/PGM format. | |
| 10 * The extended 2-byte-per-sample raw PPM/PGM formats are supported. | |
| 11 * The PBMPLUS library is NOT required to compile this software | |
| 12 * (but it is highly useful as a set of PPM image manipulation programs). | |
| 13 * | |
| 14 * These routines may need modification for non-Unix environments or | |
| 15 * specialized applications. As they stand, they assume output to | |
| 16 * an ordinary stdio stream. | |
| 17 */ | |
| 18 | |
| 19 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ | |
| 20 | |
| 21 #ifdef PPM_SUPPORTED | |
| 22 | |
| 23 | |
| 24 /* | |
| 25 * For 12-bit JPEG data, we either downscale the values to 8 bits | |
| 26 * (to write standard byte-per-sample PPM/PGM files), or output | |
| 27 * nonstandard word-per-sample PPM/PGM files. Downscaling is done | |
| 28 * if PPM_NORAWWORD is defined (this can be done in the Makefile | |
| 29 * or in jconfig.h). | |
| 30 * (When the core library supports data precision reduction, a cleaner | |
| 31 * implementation will be to ask for that instead.) | |
| 32 */ | |
| 33 | |
| 34 #if BITS_IN_JSAMPLE == 8 | |
| 35 #define PUTPPMSAMPLE(ptr,v) *ptr++ = (char) (v) | |
| 36 #define BYTESPERSAMPLE 1 | |
| 37 #define PPM_MAXVAL 255 | |
| 38 #else | |
| 39 #ifdef PPM_NORAWWORD | |
| 40 #define PUTPPMSAMPLE(ptr,v) *ptr++ = (char) ((v) >> (BITS_IN_JSAMPLE-8)) | |
| 41 #define BYTESPERSAMPLE 1 | |
| 42 #define PPM_MAXVAL 255 | |
| 43 #else | |
| 44 /* The word-per-sample format always puts the MSB first. */ | |
| 45 #define PUTPPMSAMPLE(ptr,v) \ | |
| 46 { register int val_ = v; \ | |
| 47 *ptr++ = (char) ((val_ >> 8) & 0xFF); \ | |
| 48 *ptr++ = (char) (val_ & 0xFF); \ | |
| 49 } | |
| 50 #define BYTESPERSAMPLE 2 | |
| 51 #define PPM_MAXVAL ((1<<BITS_IN_JSAMPLE)-1) | |
| 52 #endif | |
| 53 #endif | |
| 54 | |
| 55 | |
| 56 /* | |
| 57 * When JSAMPLE is the same size as char, we can just fwrite() the | |
| 58 * decompressed data to the PPM or PGM file. On PCs, in order to make this | |
| 59 * work the output buffer must be allocated in near data space, because we are | |
| 60 * assuming small-data memory model wherein fwrite() can't reach far memory. | |
| 61 * If you need to process very wide images on a PC, you might have to compile | |
| 62 * in large-memory model, or else replace fwrite() with a putc() loop --- | |
| 63 * which will be much slower. | |
| 64 */ | |
| 65 | |
| 66 | |
| 67 /* Private version of data destination object */ | |
| 68 | |
| 69 typedef struct { | |
| 70 struct djpeg_dest_struct pub; /* public fields */ | |
| 71 | |
| 72 /* Usually these two pointers point to the same place: */ | |
| 73 char *iobuffer; /* fwrite's I/O buffer */ | |
| 74 JSAMPROW pixrow; /* decompressor output buffer */ | |
| 75 size_t buffer_width; /* width of I/O buffer */ | |
| 76 JDIMENSION samples_per_row; /* JSAMPLEs per output row */ | |
| 77 } ppm_dest_struct; | |
| 78 | |
| 79 typedef ppm_dest_struct * ppm_dest_ptr; | |
| 80 | |
| 81 | |
| 82 /* | |
| 83 * Write some pixel data. | |
| 84 * In this module rows_supplied will always be 1. | |
| 85 * | |
| 86 * put_pixel_rows handles the "normal" 8-bit case where the decompressor | |
| 87 * output buffer is physically the same as the fwrite buffer. | |
| 88 */ | |
| 89 | |
| 90 METHODDEF(void) | |
| 91 put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, | |
| 92 JDIMENSION rows_supplied) | |
| 93 { | |
| 94 ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; | |
| 95 | |
| 96 (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); | |
| 97 } | |
| 98 | |
| 99 | |
| 100 /* | |
| 101 * This code is used when we have to copy the data and apply a pixel | |
| 102 * format translation. Typically this only happens in 12-bit mode. | |
| 103 */ | |
| 104 | |
| 105 METHODDEF(void) | |
| 106 copy_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, | |
| 107 JDIMENSION rows_supplied) | |
| 108 { | |
| 109 ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; | |
| 110 register char * bufferptr; | |
| 111 register JSAMPROW ptr; | |
| 112 register JDIMENSION col; | |
| 113 | |
| 114 ptr = dest->pixrow; | |
| 115 bufferptr = dest->iobuffer; | |
| 116 for (col = dest->samples_per_row; col > 0; col--) { | |
| 117 PUTPPMSAMPLE(bufferptr, GETJSAMPLE(*ptr++)); | |
| 118 } | |
| 119 (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); | |
| 120 } | |
| 121 | |
| 122 | |
| 123 /* | |
| 124 * Write some pixel data when color quantization is in effect. | |
| 125 * We have to demap the color index values to straight data. | |
| 126 */ | |
| 127 | |
| 128 METHODDEF(void) | |
| 129 put_demapped_rgb (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, | |
| 130 JDIMENSION rows_supplied) | |
| 131 { | |
| 132 ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; | |
| 133 register char * bufferptr; | |
| 134 register int pixval; | |
| 135 register JSAMPROW ptr; | |
| 136 register JSAMPROW color_map0 = cinfo->colormap[0]; | |
| 137 register JSAMPROW color_map1 = cinfo->colormap[1]; | |
| 138 register JSAMPROW color_map2 = cinfo->colormap[2]; | |
| 139 register JDIMENSION col; | |
| 140 | |
| 141 ptr = dest->pixrow; | |
| 142 bufferptr = dest->iobuffer; | |
| 143 for (col = cinfo->output_width; col > 0; col--) { | |
| 144 pixval = GETJSAMPLE(*ptr++); | |
| 145 PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map0[pixval])); | |
| 146 PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map1[pixval])); | |
| 147 PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map2[pixval])); | |
| 148 } | |
| 149 (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); | |
| 150 } | |
| 151 | |
| 152 METHODDEF(void) | |
| 153 put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, | |
| 154 JDIMENSION rows_supplied) | |
| 155 { | |
| 156 ppm_dest_ptr dest = (ppm_dest_ptr) dinfo; | |
| 157 register char * bufferptr; | |
| 158 register JSAMPROW ptr; | |
| 159 register JSAMPROW color_map0 = cinfo->colormap[0]; | |
| 160 register JDIMENSION col; | |
| 161 | |
| 162 ptr = dest->pixrow; | |
| 163 bufferptr = dest->iobuffer; | |
| 164 for (col = cinfo->output_width; col > 0; col--) { | |
| 165 PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map0[GETJSAMPLE(*ptr++)])); | |
| 166 } | |
| 167 (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); | |
| 168 } | |
| 169 | |
| 170 | |
| 171 /* | |
| 172 * Startup: write the file header. | |
| 173 */ | |
| 174 | |
| 175 METHODDEF(void) | |
| 176 start_output_ppm (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) | |
| 177 { | |
| 178 /* Emit file header */ | |
| 179 switch (cinfo->out_color_space) { | |
| 180 case JCS_GRAYSCALE: | |
| 181 /* emit header for raw PGM format */ | |
| 182 fprintf(dinfo->output_file, "P5\n%ld %ld\n%d\n", | |
| 183 (long) cinfo->output_width, (long) cinfo->output_height, | |
| 184 PPM_MAXVAL); | |
| 185 break; | |
| 186 case JCS_RGB: | |
| 187 /* emit header for raw PPM format */ | |
| 188 fprintf(dinfo->output_file, "P6\n%ld %ld\n%d\n", | |
| 189 (long) cinfo->output_width, (long) cinfo->output_height, | |
| 190 PPM_MAXVAL); | |
| 191 break; | |
| 192 default: | |
| 193 ERREXIT(cinfo, JERR_PPM_COLORSPACE); | |
| 194 } | |
| 195 } | |
| 196 | |
| 197 | |
| 198 /* | |
| 199 * Finish up at the end of the file. | |
| 200 */ | |
| 201 | |
| 202 METHODDEF(void) | |
| 203 finish_output_ppm (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo) | |
| 204 { | |
| 205 /* Make sure we wrote the output file OK */ | |
| 206 JFFLUSH(dinfo->output_file); | |
| 207 if (JFERROR(dinfo->output_file)) | |
| 208 ERREXIT(cinfo, JERR_FILE_WRITE); | |
| 209 } | |
| 210 | |
| 211 | |
| 212 /* | |
| 213 * The module selection routine for PPM format output. | |
| 214 */ | |
| 215 | |
| 216 GLOBAL(djpeg_dest_ptr) | |
| 217 jinit_write_ppm (j_decompress_ptr cinfo) | |
| 218 { | |
| 219 ppm_dest_ptr dest; | |
| 220 | |
| 221 /* Create module interface object, fill in method pointers */ | |
| 222 dest = (ppm_dest_ptr) (*cinfo->mem->alloc_small) | |
| 223 ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(ppm_dest_struct)); | |
| 224 dest->pub.start_output = start_output_ppm; | |
| 225 dest->pub.finish_output = finish_output_ppm; | |
| 226 | |
| 227 /* Calculate output image dimensions so we can allocate space */ | |
| 228 jpeg_calc_output_dimensions(cinfo); | |
| 229 | |
| 230 /* Create physical I/O buffer. Note we make this near on a PC. */ | |
| 231 dest->samples_per_row = cinfo->output_width * cinfo->out_color_components; | |
| 232 dest->buffer_width = dest->samples_per_row * (BYTESPERSAMPLE * SIZEOF(char)); | |
| 233 dest->iobuffer = (char *) (*cinfo->mem->alloc_small) | |
| 234 ((j_common_ptr) cinfo, JPOOL_IMAGE, dest->buffer_width); | |
| 235 | |
| 236 if (cinfo->quantize_colors || BITS_IN_JSAMPLE != 8 || | |
| 237 SIZEOF(JSAMPLE) != SIZEOF(char)) { | |
| 238 /* When quantizing, we need an output buffer for colormap indexes | |
| 239 * that's separate from the physical I/O buffer. We also need a | |
| 240 * separate buffer if pixel format translation must take place. | |
| 241 */ | |
| 242 dest->pixrow = (JSAMPROW) (*cinfo->mem->alloc_large) | |
| 243 ((j_common_ptr) cinfo, JPOOL_IMAGE, (size_t) cinfo->output_width * | |
| 244 (size_t) cinfo->output_components * SIZEOF(JSAMPLE)); | |
| 245 if (! cinfo->quantize_colors) | |
| 246 dest->pub.put_pixel_rows = copy_pixel_rows; | |
| 247 else if (cinfo->out_color_space == JCS_GRAYSCALE) | |
| 248 dest->pub.put_pixel_rows = put_demapped_gray; | |
| 249 else | |
| 250 dest->pub.put_pixel_rows = put_demapped_rgb; | |
| 251 } else { | |
| 252 /* We will fwrite() directly from decompressor output buffer. */ | |
| 253 /* Cast here implies near->far pointer conversion on PCs */ | |
| 254 dest->pixrow = (JSAMPROW) dest->iobuffer; | |
| 255 dest->pub.put_pixel_rows = put_pixel_rows; | |
| 256 } | |
| 257 /* Synthesize a JSAMPARRAY pointer structure */ | |
| 258 dest->pub.buffer = & dest->pixrow; | |
| 259 dest->pub.buffer_height = 1; | |
| 260 | |
| 261 return &dest->pub; | |
| 262 } | |
| 263 | |
| 264 #endif /* PPM_SUPPORTED */ |
