/src/libjpeg-turbo.main/jdlhuff.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * jdlhuff.c | 
| 3 |  |  * | 
| 4 |  |  * This file was part of the Independent JPEG Group's software: | 
| 5 |  |  * Copyright (C) 1991-1997, Thomas G. Lane. | 
| 6 |  |  * Lossless JPEG Modifications: | 
| 7 |  |  * Copyright (C) 1999, Ken Murchison. | 
| 8 |  |  * libjpeg-turbo Modifications: | 
| 9 |  |  * Copyright (C) 2022, D. R. Commander. | 
| 10 |  |  * For conditions of distribution and use, see the accompanying README.ijg | 
| 11 |  |  * file. | 
| 12 |  |  * | 
| 13 |  |  * This file contains Huffman entropy decoding routines for lossless JPEG. | 
| 14 |  |  * | 
| 15 |  |  * Much of the complexity here has to do with supporting input suspension. | 
| 16 |  |  * If the data source module demands suspension, we want to be able to back | 
| 17 |  |  * up to the start of the current MCU.  To do this, we copy state variables | 
| 18 |  |  * into local working storage, and update them back to the permanent | 
| 19 |  |  * storage only upon successful completion of an MCU. | 
| 20 |  |  */ | 
| 21 |  |  | 
| 22 |  | #define JPEG_INTERNALS | 
| 23 |  | #include "jinclude.h" | 
| 24 |  | #include "jpeglib.h" | 
| 25 |  | #include "jlossls.h"            /* Private declarations for lossless codec */ | 
| 26 |  | #include "jdhuff.h"             /* Declarations shared with jd*huff.c */ | 
| 27 |  |  | 
| 28 |  |  | 
| 29 |  | #ifdef D_LOSSLESS_SUPPORTED | 
| 30 |  |  | 
| 31 |  | typedef struct { | 
| 32 |  |   int ci, yoffset, MCU_width; | 
| 33 |  | } lhd_output_ptr_info; | 
| 34 |  |  | 
| 35 |  | /* | 
| 36 |  |  * Expanded entropy decoder object for Huffman decoding in lossless mode. | 
| 37 |  |  */ | 
| 38 |  |  | 
| 39 |  | typedef struct { | 
| 40 |  |   struct jpeg_entropy_decoder pub; /* public fields */ | 
| 41 |  |  | 
| 42 |  |   /* These fields are loaded into local variables at start of each MCU. | 
| 43 |  |    * In case of suspension, we exit WITHOUT updating them. | 
| 44 |  |    */ | 
| 45 |  |   bitread_perm_state bitstate;  /* Bit buffer at start of MCU */ | 
| 46 |  |  | 
| 47 |  |   /* Pointers to derived tables (these workspaces have image lifespan) */ | 
| 48 |  |   d_derived_tbl *derived_tbls[NUM_HUFF_TBLS]; | 
| 49 |  |  | 
| 50 |  |   /* Precalculated info set up by start_pass for use in decode_mcus: */ | 
| 51 |  |  | 
| 52 |  |   /* Pointers to derived tables to be used for each data unit within an MCU */ | 
| 53 |  |   d_derived_tbl *cur_tbls[D_MAX_BLOCKS_IN_MCU]; | 
| 54 |  |  | 
| 55 |  |   /* Pointers to the proper output difference row for each group of data units | 
| 56 |  |    * within an MCU.  For each component, there are Vi groups of Hi data units. | 
| 57 |  |    */ | 
| 58 |  |   JDIFFROW output_ptr[D_MAX_BLOCKS_IN_MCU]; | 
| 59 |  |  | 
| 60 |  |   /* Number of output pointers in use for the current MCU.  This is the sum | 
| 61 |  |    * of all Vi in the MCU. | 
| 62 |  |    */ | 
| 63 |  |   int num_output_ptrs; | 
| 64 |  |  | 
| 65 |  |   /* Information used for positioning the output pointers within the output | 
| 66 |  |    * difference rows. | 
| 67 |  |    */ | 
| 68 |  |   lhd_output_ptr_info output_ptr_info[D_MAX_BLOCKS_IN_MCU]; | 
| 69 |  |  | 
| 70 |  |   /* Index of the proper output pointer for each data unit within an MCU */ | 
| 71 |  |   int output_ptr_index[D_MAX_BLOCKS_IN_MCU]; | 
| 72 |  |  | 
| 73 |  | } lhuff_entropy_decoder; | 
| 74 |  |  | 
| 75 |  | typedef lhuff_entropy_decoder *lhuff_entropy_ptr; | 
| 76 |  |  | 
| 77 |  |  | 
| 78 |  | /* | 
| 79 |  |  * Initialize for a Huffman-compressed scan. | 
| 80 |  |  */ | 
| 81 |  |  | 
| 82 |  | METHODDEF(void) | 
| 83 |  | start_pass_lhuff_decoder(j_decompress_ptr cinfo) | 
| 84 | 4.57k | { | 
| 85 | 4.57k |   lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy; | 
| 86 | 4.57k |   int ci, dctbl, sampn, ptrn, yoffset, xoffset; | 
| 87 | 4.57k |   jpeg_component_info *compptr; | 
| 88 |  |  | 
| 89 | 11.1k |   for (ci = 0; ci < cinfo->comps_in_scan; ci++) { | 
| 90 | 6.61k |     compptr = cinfo->cur_comp_info[ci]; | 
| 91 | 6.61k |     dctbl = compptr->dc_tbl_no; | 
| 92 |  |     /* Make sure requested tables are present */ | 
| 93 | 6.61k |     if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS || | 
| 94 | 6.61k |         cinfo->dc_huff_tbl_ptrs[dctbl] == NULL) | 
| 95 | 105 |       ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); | 
| 96 |  |     /* Compute derived values for Huffman tables */ | 
| 97 |  |     /* We may do this more than once for a table, but it's not expensive */ | 
| 98 | 6.61k |     jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, | 
| 99 | 6.61k |                             &entropy->derived_tbls[dctbl]); | 
| 100 | 6.61k |   } | 
| 101 |  |  | 
| 102 |  |   /* Precalculate decoding info for each sample in an MCU of this scan */ | 
| 103 | 11.0k |   for (sampn = 0, ptrn = 0; sampn < cinfo->blocks_in_MCU;) { | 
| 104 | 6.49k |     compptr = cinfo->cur_comp_info[cinfo->MCU_membership[sampn]]; | 
| 105 | 6.49k |     ci = compptr->component_index; | 
| 106 | 14.6k |     for (yoffset = 0; yoffset < compptr->MCU_height; yoffset++, ptrn++) { | 
| 107 |  |       /* Precalculate the setup info for each output pointer */ | 
| 108 | 8.16k |       entropy->output_ptr_info[ptrn].ci = ci; | 
| 109 | 8.16k |       entropy->output_ptr_info[ptrn].yoffset = yoffset; | 
| 110 | 8.16k |       entropy->output_ptr_info[ptrn].MCU_width = compptr->MCU_width; | 
| 111 | 19.4k |       for (xoffset = 0; xoffset < compptr->MCU_width; xoffset++, sampn++) { | 
| 112 |  |         /* Precalculate the output pointer index for each sample */ | 
| 113 | 11.2k |         entropy->output_ptr_index[sampn] = ptrn; | 
| 114 |  |         /* Precalculate which table to use for each sample */ | 
| 115 | 11.2k |         entropy->cur_tbls[sampn] = entropy->derived_tbls[compptr->dc_tbl_no]; | 
| 116 | 11.2k |       } | 
| 117 | 8.16k |     } | 
| 118 | 6.49k |   } | 
| 119 | 4.57k |   entropy->num_output_ptrs = ptrn; | 
| 120 |  |  | 
| 121 |  |   /* Initialize bitread state variables */ | 
| 122 | 4.57k |   entropy->bitstate.bits_left = 0; | 
| 123 | 4.57k |   entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ | 
| 124 | 4.57k |   entropy->pub.insufficient_data = FALSE; | 
| 125 | 4.57k | } | 
| 126 |  |  | 
| 127 |  |  | 
| 128 |  | /* | 
| 129 |  |  * Figure F.12: extend sign bit. | 
| 130 |  |  * On some machines, a shift and add will be faster than a table lookup. | 
| 131 |  |  */ | 
| 132 |  |  | 
| 133 |  | #define AVOID_TABLES | 
| 134 |  | #ifdef AVOID_TABLES | 
| 135 |  |  | 
| 136 | 6.25M | #define NEG_1  ((unsigned int)-1) | 
| 137 |  | #define HUFF_EXTEND(x, s) \ | 
| 138 | 6.25M |   ((x) + ((((x) - (1 << ((s) - 1))) >> 31) & (((NEG_1) << (s)) + 1))) | 
| 139 |  |  | 
| 140 |  | #else | 
| 141 |  |  | 
| 142 |  | #define HUFF_EXTEND(x, s) \ | 
| 143 |  |   ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) | 
| 144 |  |  | 
| 145 |  | static const int extend_test[16] = {   /* entry n is 2**(n-1) */ | 
| 146 |  |   0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, | 
| 147 |  |   0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 | 
| 148 |  | }; | 
| 149 |  |  | 
| 150 |  | static const int extend_offset[16] = { /* entry n is (-1 << n) + 1 */ | 
| 151 |  |   0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1, | 
| 152 |  |   ((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1, | 
| 153 |  |   ((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1, | 
| 154 |  |   ((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1 | 
| 155 |  | }; | 
| 156 |  |  | 
| 157 |  | #endif /* AVOID_TABLES */ | 
| 158 |  |  | 
| 159 |  |  | 
| 160 |  | /* | 
| 161 |  |  * Check for a restart marker & resynchronize decoder. | 
| 162 |  |  * Returns FALSE if must suspend. | 
| 163 |  |  */ | 
| 164 |  |  | 
| 165 |  | LOCAL(boolean) | 
| 166 |  | process_restart(j_decompress_ptr cinfo) | 
| 167 | 112k | { | 
| 168 | 112k |   lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy; | 
| 169 |  |  | 
| 170 |  |   /* Throw away any unused bits remaining in bit buffer; */ | 
| 171 |  |   /* include any full bytes in next_marker's count of discarded bytes */ | 
| 172 | 112k |   cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; | 
| 173 | 112k |   entropy->bitstate.bits_left = 0; | 
| 174 |  |  | 
| 175 |  |   /* Advance past the RSTn marker */ | 
| 176 | 112k |   if (!(*cinfo->marker->read_restart_marker) (cinfo)) | 
| 177 | 0 |     return FALSE; | 
| 178 |  |  | 
| 179 |  |   /* Reset out-of-data flag, unless read_restart_marker left us smack up | 
| 180 |  |    * against a marker.  In that case we will end up treating the next data | 
| 181 |  |    * segment as empty, and we can avoid producing bogus output pixels by | 
| 182 |  |    * leaving the flag set. | 
| 183 |  |    */ | 
| 184 | 112k |   if (cinfo->unread_marker == 0) | 
| 185 | 549 |     entropy->pub.insufficient_data = FALSE; | 
| 186 |  |  | 
| 187 | 112k |   return TRUE; | 
| 188 | 112k | } | 
| 189 |  |  | 
| 190 |  |  | 
| 191 |  | /* | 
| 192 |  |  * Decode and return nMCU MCUs' worth of Huffman-compressed differences. | 
| 193 |  |  * Each MCU is also disassembled and placed accordingly in diff_buf. | 
| 194 |  |  * | 
| 195 |  |  * MCU_col_num specifies the column of the first MCU being requested within | 
| 196 |  |  * the MCU row.  This tells us where to position the output row pointers in | 
| 197 |  |  * diff_buf. | 
| 198 |  |  * | 
| 199 |  |  * Returns the number of MCUs decoded.  This may be less than nMCU MCUs if | 
| 200 |  |  * data source requested suspension.  In that case no changes have been made | 
| 201 |  |  * to permanent state.  (Exception: some output differences may already have | 
| 202 |  |  * been assigned.  This is harmless for this module, since we'll just | 
| 203 |  |  * re-assign them on the next call.) | 
| 204 |  |  */ | 
| 205 |  |  | 
| 206 |  | METHODDEF(JDIMENSION) | 
| 207 |  | decode_mcus(j_decompress_ptr cinfo, JDIFFIMAGE diff_buf, | 
| 208 |  |             JDIMENSION MCU_row_num, JDIMENSION MCU_col_num, JDIMENSION nMCU) | 
| 209 | 36.7M | { | 
| 210 | 36.7M |   lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy; | 
| 211 | 36.7M |   int sampn, ci, yoffset, MCU_width, ptrn; | 
| 212 | 36.7M |   JDIMENSION mcu_num; | 
| 213 | 36.7M |   BITREAD_STATE_VARS; | 
| 214 |  |  | 
| 215 |  |   /* Set output pointer locations based on MCU_col_num */ | 
| 216 | 97.6M |   for (ptrn = 0; ptrn < entropy->num_output_ptrs; ptrn++) { | 
| 217 | 60.9M |     ci = entropy->output_ptr_info[ptrn].ci; | 
| 218 | 60.9M |     yoffset = entropy->output_ptr_info[ptrn].yoffset; | 
| 219 | 60.9M |     MCU_width = entropy->output_ptr_info[ptrn].MCU_width; | 
| 220 | 60.9M |     entropy->output_ptr[ptrn] = | 
| 221 | 60.9M |       diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width); | 
| 222 | 60.9M |   } | 
| 223 |  |  | 
| 224 |  |   /* | 
| 225 |  |    * If we've run out of data, zero out the buffers and return. | 
| 226 |  |    * By resetting the undifferencer, the output samples will be CENTERJSAMPLE. | 
| 227 |  |    * | 
| 228 |  |    * NB: We should find a way to do this without interacting with the | 
| 229 |  |    * undifferencer module directly. | 
| 230 |  |    */ | 
| 231 | 36.7M |   if (entropy->pub.insufficient_data) { | 
| 232 | 97.6M |     for (ptrn = 0; ptrn < entropy->num_output_ptrs; ptrn++) | 
| 233 | 60.9M |       jzero_far((void FAR *)entropy->output_ptr[ptrn], | 
| 234 | 60.9M |                 nMCU * entropy->output_ptr_info[ptrn].MCU_width * | 
| 235 | 60.9M |                 sizeof(JDIFF)); | 
| 236 |  |  | 
| 237 | 36.7M |     (*cinfo->idct->start_pass) (cinfo); | 
| 238 |  |  | 
| 239 | 36.7M |   } else { | 
| 240 |  |  | 
| 241 |  |     /* Load up working state */ | 
| 242 | 26.2k |     BITREAD_LOAD_STATE(cinfo, entropy->bitstate); | 
| 243 |  |  | 
| 244 |  |     /* Outer loop handles the number of MCUs requested */ | 
| 245 |  |  | 
| 246 | 19.7M |     for (mcu_num = 0; mcu_num < nMCU; mcu_num++) { | 
| 247 |  |  | 
| 248 |  |       /* Inner loop handles the samples in the MCU */ | 
| 249 | 44.4M |       for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) { | 
| 250 | 24.7M |         d_derived_tbl *dctbl = entropy->cur_tbls[sampn]; | 
| 251 | 24.7M |         register int s, r; | 
| 252 |  |  | 
| 253 |  |         /* Section H.2.2: decode the sample difference */ | 
| 254 | 24.7M |         HUFF_DECODE(s, br_state, dctbl, return mcu_num, label1); | 
| 255 | 24.7M |         if (s) { | 
| 256 | 12.4M |           if (s == 16)  /* special case: always output 32768 */ | 
| 257 | 6.14M |             s = 32768; | 
| 258 | 6.25M |           else {        /* normal case: fetch subsequent bits */ | 
| 259 | 6.25M |             CHECK_BIT_BUFFER(br_state, s, return mcu_num); | 
| 260 | 6.25M |             r = GET_BITS(s); | 
| 261 | 6.25M |             s = HUFF_EXTEND(r, s); | 
| 262 | 6.25M |           } | 
| 263 | 12.4M |         } | 
| 264 |  |  | 
| 265 |  |         /* Output the sample difference */ | 
| 266 | 24.7M |         *entropy->output_ptr[entropy->output_ptr_index[sampn]]++ = (JDIFF)s; | 
| 267 | 24.7M |       } | 
| 268 |  |  | 
| 269 |  |       /* Completed MCU, so update state */ | 
| 270 | 19.6M |       BITREAD_SAVE_STATE(cinfo, entropy->bitstate); | 
| 271 | 19.6M |     } | 
| 272 | 26.2k |   } | 
| 273 |  |  | 
| 274 | 36.7M |  return nMCU; | 
| 275 | 36.7M | } | 
| 276 |  |  | 
| 277 |  |  | 
| 278 |  | /* | 
| 279 |  |  * Module initialization routine for lossless mode Huffman entropy decoding. | 
| 280 |  |  */ | 
| 281 |  |  | 
| 282 |  | GLOBAL(void) | 
| 283 |  | jinit_lhuff_decoder(j_decompress_ptr cinfo) | 
| 284 | 1.13k | { | 
| 285 | 1.13k |   lhuff_entropy_ptr entropy; | 
| 286 | 1.13k |   int i; | 
| 287 |  |  | 
| 288 | 1.13k |   entropy = (lhuff_entropy_ptr) | 
| 289 | 1.13k |     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, | 
| 290 | 1.13k |                                 sizeof(lhuff_entropy_decoder)); | 
| 291 | 1.13k |   cinfo->entropy = (struct jpeg_entropy_decoder *)entropy; | 
| 292 | 1.13k |   entropy->pub.start_pass = start_pass_lhuff_decoder; | 
| 293 | 1.13k |   entropy->pub.decode_mcus = decode_mcus; | 
| 294 | 1.13k |   entropy->pub.process_restart = process_restart; | 
| 295 |  |  | 
| 296 |  |   /* Mark tables unallocated */ | 
| 297 | 5.68k |   for (i = 0; i < NUM_HUFF_TBLS; i++) { | 
| 298 | 4.54k |     entropy->derived_tbls[i] = NULL; | 
| 299 | 4.54k |   } | 
| 300 | 1.13k | } | 
| 301 |  |  | 
| 302 |  | #endif /* D_LOSSLESS_SUPPORTED */ |