Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/libjpeg/jctrans.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 * jctrans.c | |
| 3 * | |
| 4 * Copyright (C) 1995-1998, Thomas G. Lane. | |
| 5 * Modified 2000-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 library routines for transcoding compression, | |
| 10 * that is, writing raw DCT coefficient arrays to an output JPEG file. | |
| 11 * The routines in jcapimin.c will also be needed by a transcoder. | |
| 12 */ | |
| 13 | |
| 14 #define JPEG_INTERNALS | |
| 15 #include "jinclude.h" | |
| 16 #include "jpeglib.h" | |
| 17 | |
| 18 | |
| 19 /* Forward declarations */ | |
| 20 LOCAL(void) transencode_master_selection | |
| 21 JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); | |
| 22 LOCAL(void) transencode_coef_controller | |
| 23 JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); | |
| 24 | |
| 25 | |
| 26 /* | |
| 27 * Compression initialization for writing raw-coefficient data. | |
| 28 * Before calling this, all parameters and a data destination must be set up. | |
| 29 * Call jpeg_finish_compress() to actually write the data. | |
| 30 * | |
| 31 * The number of passed virtual arrays must match cinfo->num_components. | |
| 32 * Note that the virtual arrays need not be filled or even realized at | |
| 33 * the time write_coefficients is called; indeed, if the virtual arrays | |
| 34 * were requested from this compression object's memory manager, they | |
| 35 * typically will be realized during this routine and filled afterwards. | |
| 36 */ | |
| 37 | |
| 38 GLOBAL(void) | |
| 39 jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) | |
| 40 { | |
| 41 if (cinfo->global_state != CSTATE_START) | |
| 42 ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); | |
| 43 /* Mark all tables to be written */ | |
| 44 jpeg_suppress_tables(cinfo, FALSE); | |
| 45 /* (Re)initialize error mgr and destination modules */ | |
| 46 (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); | |
| 47 (*cinfo->dest->init_destination) (cinfo); | |
| 48 /* Perform master selection of active modules */ | |
| 49 transencode_master_selection(cinfo, coef_arrays); | |
| 50 /* Wait for jpeg_finish_compress() call */ | |
| 51 cinfo->next_scanline = 0; /* so jpeg_write_marker works */ | |
| 52 cinfo->global_state = CSTATE_WRCOEFS; | |
| 53 } | |
| 54 | |
| 55 | |
| 56 /* | |
| 57 * Initialize the compression object with default parameters, | |
| 58 * then copy from the source object all parameters needed for lossless | |
| 59 * transcoding. Parameters that can be varied without loss (such as | |
| 60 * scan script and Huffman optimization) are left in their default states. | |
| 61 */ | |
| 62 | |
| 63 GLOBAL(void) | |
| 64 jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, | |
| 65 j_compress_ptr dstinfo) | |
| 66 { | |
| 67 JQUANT_TBL ** qtblptr; | |
| 68 jpeg_component_info *incomp, *outcomp; | |
| 69 JQUANT_TBL *c_quant, *slot_quant; | |
| 70 int tblno, ci, coefi; | |
| 71 | |
| 72 /* Safety check to ensure start_compress not called yet. */ | |
| 73 if (dstinfo->global_state != CSTATE_START) | |
| 74 ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state); | |
| 75 /* Copy fundamental image dimensions */ | |
| 76 dstinfo->image_width = srcinfo->image_width; | |
| 77 dstinfo->image_height = srcinfo->image_height; | |
| 78 dstinfo->input_components = srcinfo->num_components; | |
| 79 dstinfo->in_color_space = srcinfo->jpeg_color_space; | |
| 80 dstinfo->jpeg_width = srcinfo->output_width; | |
| 81 dstinfo->jpeg_height = srcinfo->output_height; | |
| 82 dstinfo->min_DCT_h_scaled_size = srcinfo->min_DCT_h_scaled_size; | |
| 83 dstinfo->min_DCT_v_scaled_size = srcinfo->min_DCT_v_scaled_size; | |
| 84 /* Initialize all parameters to default values */ | |
| 85 jpeg_set_defaults(dstinfo); | |
| 86 /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. | |
| 87 * Fix it to get the right header markers for the image colorspace. | |
| 88 * Note: Entropy table assignment in jpeg_set_colorspace | |
| 89 * depends on color_transform. | |
| 90 * Adaption is also required for setting the appropriate | |
| 91 * entropy coding mode dependent on image data precision. | |
| 92 */ | |
| 93 dstinfo->color_transform = srcinfo->color_transform; | |
| 94 jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space); | |
| 95 dstinfo->data_precision = srcinfo->data_precision; | |
| 96 dstinfo->arith_code = srcinfo->data_precision > 8 ? TRUE : FALSE; | |
| 97 dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling; | |
| 98 /* Copy the source's quantization tables. */ | |
| 99 for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { | |
| 100 if (srcinfo->quant_tbl_ptrs[tblno] != NULL) { | |
| 101 qtblptr = & dstinfo->quant_tbl_ptrs[tblno]; | |
| 102 if (*qtblptr == NULL) | |
| 103 *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo); | |
| 104 MEMCOPY((*qtblptr)->quantval, | |
| 105 srcinfo->quant_tbl_ptrs[tblno]->quantval, | |
| 106 SIZEOF((*qtblptr)->quantval)); | |
| 107 (*qtblptr)->sent_table = FALSE; | |
| 108 } | |
| 109 } | |
| 110 /* Copy the source's per-component info. | |
| 111 * Note we assume jpeg_set_defaults has allocated the dest comp_info array. | |
| 112 */ | |
| 113 dstinfo->num_components = srcinfo->num_components; | |
| 114 if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS) | |
| 115 ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components, | |
| 116 MAX_COMPONENTS); | |
| 117 for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info; | |
| 118 ci < dstinfo->num_components; ci++, incomp++, outcomp++) { | |
| 119 outcomp->component_id = incomp->component_id; | |
| 120 outcomp->h_samp_factor = incomp->h_samp_factor; | |
| 121 outcomp->v_samp_factor = incomp->v_samp_factor; | |
| 122 outcomp->quant_tbl_no = incomp->quant_tbl_no; | |
| 123 /* Make sure saved quantization table for component matches the qtable | |
| 124 * slot. If not, the input file re-used this qtable slot. | |
| 125 * IJG encoder currently cannot duplicate this. | |
| 126 */ | |
| 127 tblno = outcomp->quant_tbl_no; | |
| 128 if (tblno < 0 || tblno >= NUM_QUANT_TBLS || | |
| 129 srcinfo->quant_tbl_ptrs[tblno] == NULL) | |
| 130 ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno); | |
| 131 slot_quant = srcinfo->quant_tbl_ptrs[tblno]; | |
| 132 c_quant = incomp->quant_table; | |
| 133 if (c_quant != NULL) { | |
| 134 for (coefi = 0; coefi < DCTSIZE2; coefi++) { | |
| 135 if (c_quant->quantval[coefi] != slot_quant->quantval[coefi]) | |
| 136 ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno); | |
| 137 } | |
| 138 } | |
| 139 /* Note: we do not copy the source's entropy table assignments; | |
| 140 * instead we rely on jpeg_set_colorspace to have made a suitable choice. | |
| 141 */ | |
| 142 } | |
| 143 /* Also copy JFIF version and resolution information, if available. | |
| 144 * Strictly speaking this isn't "critical" info, but it's nearly | |
| 145 * always appropriate to copy it if available. In particular, | |
| 146 * if the application chooses to copy JFIF 1.02 extension markers from | |
| 147 * the source file, we need to copy the version to make sure we don't | |
| 148 * emit a file that has 1.02 extensions but a claimed version of 1.01. | |
| 149 */ | |
| 150 if (srcinfo->saw_JFIF_marker) { | |
| 151 if (srcinfo->JFIF_major_version == 1 || | |
| 152 srcinfo->JFIF_major_version == 2) { | |
| 153 dstinfo->JFIF_major_version = srcinfo->JFIF_major_version; | |
| 154 dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version; | |
| 155 } | |
| 156 dstinfo->density_unit = srcinfo->density_unit; | |
| 157 dstinfo->X_density = srcinfo->X_density; | |
| 158 dstinfo->Y_density = srcinfo->Y_density; | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 | |
| 163 LOCAL(void) | |
| 164 jpeg_calc_trans_dimensions (j_compress_ptr cinfo) | |
| 165 /* Do computations that are needed before master selection phase */ | |
| 166 { | |
| 167 if (cinfo->min_DCT_h_scaled_size != cinfo->min_DCT_v_scaled_size) | |
| 168 ERREXIT2(cinfo, JERR_BAD_DCTSIZE, | |
| 169 cinfo->min_DCT_h_scaled_size, cinfo->min_DCT_v_scaled_size); | |
| 170 | |
| 171 cinfo->block_size = cinfo->min_DCT_h_scaled_size; | |
| 172 } | |
| 173 | |
| 174 | |
| 175 /* | |
| 176 * Master selection of compression modules for transcoding. | |
| 177 * This substitutes for jcinit.c's initialization of the full compressor. | |
| 178 */ | |
| 179 | |
| 180 LOCAL(void) | |
| 181 transencode_master_selection (j_compress_ptr cinfo, | |
| 182 jvirt_barray_ptr * coef_arrays) | |
| 183 { | |
| 184 /* Do computations that are needed before master selection phase */ | |
| 185 jpeg_calc_trans_dimensions(cinfo); | |
| 186 | |
| 187 /* Initialize master control (includes parameter checking/processing) */ | |
| 188 jinit_c_master_control(cinfo, TRUE /* transcode only */); | |
| 189 | |
| 190 /* Entropy encoding: either Huffman or arithmetic coding. */ | |
| 191 if (cinfo->arith_code) | |
| 192 jinit_arith_encoder(cinfo); | |
| 193 else { | |
| 194 jinit_huff_encoder(cinfo); | |
| 195 } | |
| 196 | |
| 197 /* We need a special coefficient buffer controller. */ | |
| 198 transencode_coef_controller(cinfo, coef_arrays); | |
| 199 | |
| 200 jinit_marker_writer(cinfo); | |
| 201 | |
| 202 /* We can now tell the memory manager to allocate virtual arrays. */ | |
| 203 (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); | |
| 204 | |
| 205 /* Write the datastream header (SOI, JFIF) immediately. | |
| 206 * Frame and scan headers are postponed till later. | |
| 207 * This lets application insert special markers after the SOI. | |
| 208 */ | |
| 209 (*cinfo->marker->write_file_header) (cinfo); | |
| 210 } | |
| 211 | |
| 212 | |
| 213 /* | |
| 214 * The rest of this file is a special implementation of the coefficient | |
| 215 * buffer controller. This is similar to jccoefct.c, but it handles only | |
| 216 * output from presupplied virtual arrays. Furthermore, we generate any | |
| 217 * dummy padding blocks on-the-fly rather than expecting them to be present | |
| 218 * in the arrays. | |
| 219 */ | |
| 220 | |
| 221 /* Private buffer controller object */ | |
| 222 | |
| 223 typedef struct { | |
| 224 struct jpeg_c_coef_controller pub; /* public fields */ | |
| 225 | |
| 226 JDIMENSION iMCU_row_num; /* iMCU row # within image */ | |
| 227 JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ | |
| 228 int MCU_vert_offset; /* counts MCU rows within iMCU row */ | |
| 229 int MCU_rows_per_iMCU_row; /* number of such rows needed */ | |
| 230 | |
| 231 /* Virtual block array for each component. */ | |
| 232 jvirt_barray_ptr * whole_image; | |
| 233 | |
| 234 /* Workspace for constructing dummy blocks at right/bottom edges. */ | |
| 235 JBLOCK dummy_buffer[C_MAX_BLOCKS_IN_MCU]; | |
| 236 } my_coef_controller; | |
| 237 | |
| 238 typedef my_coef_controller * my_coef_ptr; | |
| 239 | |
| 240 | |
| 241 LOCAL(void) | |
| 242 start_iMCU_row (j_compress_ptr cinfo) | |
| 243 /* Reset within-iMCU-row counters for a new row */ | |
| 244 { | |
| 245 my_coef_ptr coef = (my_coef_ptr) cinfo->coef; | |
| 246 | |
| 247 /* In an interleaved scan, an MCU row is the same as an iMCU row. | |
| 248 * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. | |
| 249 * But at the bottom of the image, process only what's left. | |
| 250 */ | |
| 251 if (cinfo->comps_in_scan > 1) { | |
| 252 coef->MCU_rows_per_iMCU_row = 1; | |
| 253 } else { | |
| 254 if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) | |
| 255 coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; | |
| 256 else | |
| 257 coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; | |
| 258 } | |
| 259 | |
| 260 coef->MCU_ctr = 0; | |
| 261 coef->MCU_vert_offset = 0; | |
| 262 } | |
| 263 | |
| 264 | |
| 265 /* | |
| 266 * Initialize for a processing pass. | |
| 267 */ | |
| 268 | |
| 269 METHODDEF(void) | |
| 270 start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) | |
| 271 { | |
| 272 my_coef_ptr coef = (my_coef_ptr) cinfo->coef; | |
| 273 | |
| 274 if (pass_mode != JBUF_CRANK_DEST) | |
| 275 ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); | |
| 276 | |
| 277 coef->iMCU_row_num = 0; | |
| 278 start_iMCU_row(cinfo); | |
| 279 } | |
| 280 | |
| 281 | |
| 282 /* | |
| 283 * Process some data. | |
| 284 * We process the equivalent of one fully interleaved MCU row ("iMCU" row) | |
| 285 * per call, ie, v_samp_factor block rows for each component in the scan. | |
| 286 * The data is obtained from the virtual arrays and fed to the entropy coder. | |
| 287 * Returns TRUE if the iMCU row is completed, FALSE if suspended. | |
| 288 * | |
| 289 * NB: input_buf is ignored; it is likely to be a NULL pointer. | |
| 290 */ | |
| 291 | |
| 292 METHODDEF(boolean) | |
| 293 compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) | |
| 294 { | |
| 295 my_coef_ptr coef = (my_coef_ptr) cinfo->coef; | |
| 296 JDIMENSION MCU_col_num; /* index of current MCU within row */ | |
| 297 JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; | |
| 298 JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; | |
| 299 int blkn, ci, xindex, yindex, yoffset, blockcnt; | |
| 300 JDIMENSION start_col; | |
| 301 JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; | |
| 302 JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; | |
| 303 JBLOCKROW buffer_ptr; | |
| 304 jpeg_component_info *compptr; | |
| 305 | |
| 306 /* Align the virtual buffers for the components used in this scan. */ | |
| 307 for (ci = 0; ci < cinfo->comps_in_scan; ci++) { | |
| 308 compptr = cinfo->cur_comp_info[ci]; | |
| 309 buffer[ci] = (*cinfo->mem->access_virt_barray) | |
| 310 ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], | |
| 311 coef->iMCU_row_num * compptr->v_samp_factor, | |
| 312 (JDIMENSION) compptr->v_samp_factor, FALSE); | |
| 313 } | |
| 314 | |
| 315 /* Loop to process one whole iMCU row */ | |
| 316 for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; | |
| 317 yoffset++) { | |
| 318 for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; | |
| 319 MCU_col_num++) { | |
| 320 /* Construct list of pointers to DCT blocks belonging to this MCU */ | |
| 321 blkn = 0; /* index of current DCT block within MCU */ | |
| 322 for (ci = 0; ci < cinfo->comps_in_scan; ci++) { | |
| 323 compptr = cinfo->cur_comp_info[ci]; | |
| 324 blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width | |
| 325 : compptr->last_col_width; | |
| 326 start_col = MCU_col_num * compptr->MCU_width; | |
| 327 for (yindex = 0; yindex < compptr->MCU_height; yindex++) { | |
| 328 if (coef->iMCU_row_num < last_iMCU_row || | |
| 329 yoffset + yindex < compptr->last_row_height) { | |
| 330 /* Fill in pointers to real blocks in this row */ | |
| 331 buffer_ptr = buffer[ci][yoffset + yindex] + start_col; | |
| 332 xindex = blockcnt; | |
| 333 do { | |
| 334 MCU_buffer[blkn++] = buffer_ptr++; | |
| 335 } while (--xindex); | |
| 336 /* Dummy blocks at right edge */ | |
| 337 if ((xindex = compptr->MCU_width - blockcnt) == 0) | |
| 338 continue; | |
| 339 } else { | |
| 340 /* At bottom of image, need a whole row of dummy blocks */ | |
| 341 xindex = compptr->MCU_width; | |
| 342 } | |
| 343 /* Fill in any dummy blocks needed in this row. | |
| 344 * Dummy blocks are filled in the same way as in jccoefct.c: | |
| 345 * all zeroes in the AC entries, DC entries equal to previous | |
| 346 * block's DC value. The init routine has already zeroed the | |
| 347 * AC entries, so we need only set the DC entries correctly. | |
| 348 */ | |
| 349 buffer_ptr = coef->dummy_buffer + blkn; | |
| 350 do { | |
| 351 buffer_ptr[0][0] = MCU_buffer[blkn-1][0][0]; | |
| 352 MCU_buffer[blkn++] = buffer_ptr++; | |
| 353 } while (--xindex); | |
| 354 } | |
| 355 } | |
| 356 /* Try to write the MCU. */ | |
| 357 if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) { | |
| 358 /* Suspension forced; update state counters and exit */ | |
| 359 coef->MCU_vert_offset = yoffset; | |
| 360 coef->MCU_ctr = MCU_col_num; | |
| 361 return FALSE; | |
| 362 } | |
| 363 } | |
| 364 /* Completed an MCU row, but perhaps not an iMCU row */ | |
| 365 coef->MCU_ctr = 0; | |
| 366 } | |
| 367 /* Completed the iMCU row, advance counters for next one */ | |
| 368 coef->iMCU_row_num++; | |
| 369 start_iMCU_row(cinfo); | |
| 370 return TRUE; | |
| 371 } | |
| 372 | |
| 373 | |
| 374 /* | |
| 375 * Initialize coefficient buffer controller. | |
| 376 * | |
| 377 * Each passed coefficient array must be the right size for that | |
| 378 * coefficient: width_in_blocks wide and height_in_blocks high, | |
| 379 * with unitheight at least v_samp_factor. | |
| 380 */ | |
| 381 | |
| 382 LOCAL(void) | |
| 383 transencode_coef_controller (j_compress_ptr cinfo, | |
| 384 jvirt_barray_ptr * coef_arrays) | |
| 385 { | |
| 386 my_coef_ptr coef; | |
| 387 | |
| 388 coef = (my_coef_ptr) (*cinfo->mem->alloc_small) | |
| 389 ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_coef_controller)); | |
| 390 cinfo->coef = &coef->pub; | |
| 391 coef->pub.start_pass = start_pass_coef; | |
| 392 coef->pub.compress_data = compress_output; | |
| 393 | |
| 394 /* Save pointer to virtual arrays */ | |
| 395 coef->whole_image = coef_arrays; | |
| 396 | |
| 397 /* Pre-zero space for dummy DCT blocks */ | |
| 398 MEMZERO(coef->dummy_buffer, SIZEOF(coef->dummy_buffer)); | |
| 399 } |
