tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

jdmainct.c (20170B)


      1 /*
      2 * jdmainct.c
      3 *
      4 * This file was part of the Independent JPEG Group's software:
      5 * Copyright (C) 1994-1996, Thomas G. Lane.
      6 * libjpeg-turbo Modifications:
      7 * Copyright (C) 2010, 2016, 2022, D. R. Commander.
      8 * For conditions of distribution and use, see the accompanying README.ijg
      9 * file.
     10 *
     11 * This file contains the main buffer controller for decompression.
     12 * The main buffer lies between the JPEG decompressor proper and the
     13 * post-processor; it holds downsampled data in the JPEG colorspace.
     14 *
     15 * Note that this code is bypassed in raw-data mode, since the application
     16 * supplies the equivalent of the main buffer in that case.
     17 */
     18 
     19 #include "jinclude.h"
     20 #include "jdmainct.h"
     21 
     22 
     23 #if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
     24 
     25 /*
     26 * In the current system design, the main buffer need never be a full-image
     27 * buffer; any full-height buffers will be found inside the coefficient,
     28 * difference, or postprocessing controllers.  Nonetheless, the main controller
     29 * is not trivial.  Its responsibility is to provide context rows for
     30 * upsampling/rescaling, and doing this in an efficient fashion is a bit
     31 * tricky.
     32 *
     33 * Postprocessor input data is counted in "row groups".  A row group
     34 * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
     35 * sample rows of each component.  (We require DCT_scaled_size values to be
     36 * chosen such that these numbers are integers.  In practice DCT_scaled_size
     37 * values will likely be powers of two, so we actually have the stronger
     38 * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
     39 * Upsampling will typically produce max_v_samp_factor pixel rows from each
     40 * row group (times any additional scale factor that the upsampler is
     41 * applying).
     42 *
     43 * The coefficient or difference controller will deliver data to us one iMCU
     44 * row at a time; each iMCU row contains v_samp_factor * DCT_scaled_size sample
     45 * rows, or exactly min_DCT_scaled_size row groups.  (This amount of data
     46 * corresponds to one row of MCUs when the image is fully interleaved.)  Note
     47 * that the number of sample rows varies across components, but the number of
     48 * row groups does not.  Some garbage sample rows may be included in the last
     49 * iMCU row at the bottom of the image.
     50 *
     51 * Depending on the vertical scaling algorithm used, the upsampler may need
     52 * access to the sample row(s) above and below its current input row group.
     53 * The upsampler is required to set need_context_rows TRUE at global selection
     54 * time if so.  When need_context_rows is FALSE, this controller can simply
     55 * obtain one iMCU row at a time from the coefficient or difference controller
     56 * and dole it out as row groups to the postprocessor.
     57 *
     58 * When need_context_rows is TRUE, this controller guarantees that the buffer
     59 * passed to postprocessing contains at least one row group's worth of samples
     60 * above and below the row group(s) being processed.  Note that the context
     61 * rows "above" the first passed row group appear at negative row offsets in
     62 * the passed buffer.  At the top and bottom of the image, the required
     63 * context rows are manufactured by duplicating the first or last real sample
     64 * row; this avoids having special cases in the upsampling inner loops.
     65 *
     66 * The amount of context is fixed at one row group just because that's a
     67 * convenient number for this controller to work with.  The existing
     68 * upsamplers really only need one sample row of context.  An upsampler
     69 * supporting arbitrary output rescaling might wish for more than one row
     70 * group of context when shrinking the image; tough, we don't handle that.
     71 * (This is justified by the assumption that downsizing will be handled mostly
     72 * by adjusting the DCT_scaled_size values, so that the actual scale factor at
     73 * the upsample step needn't be much less than one.)
     74 *
     75 * To provide the desired context, we have to retain the last two row groups
     76 * of one iMCU row while reading in the next iMCU row.  (The last row group
     77 * can't be processed until we have another row group for its below-context,
     78 * and so we have to save the next-to-last group too for its above-context.)
     79 * We could do this most simply by copying data around in our buffer, but
     80 * that'd be very slow.  We can avoid copying any data by creating a rather
     81 * strange pointer structure.  Here's how it works.  We allocate a workspace
     82 * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
     83 * of row groups per iMCU row).  We create two sets of redundant pointers to
     84 * the workspace.  Labeling the physical row groups 0 to M+1, the synthesized
     85 * pointer lists look like this:
     86 *                   M+1                          M-1
     87 * master pointer --> 0         master pointer --> 0
     88 *                    1                            1
     89 *                   ...                          ...
     90 *                   M-3                          M-3
     91 *                   M-2                           M
     92 *                   M-1                          M+1
     93 *                    M                           M-2
     94 *                   M+1                          M-1
     95 *                    0                            0
     96 * We read alternate iMCU rows using each master pointer; thus the last two
     97 * row groups of the previous iMCU row remain un-overwritten in the workspace.
     98 * The pointer lists are set up so that the required context rows appear to
     99 * be adjacent to the proper places when we pass the pointer lists to the
    100 * upsampler.
    101 *
    102 * The above pictures describe the normal state of the pointer lists.
    103 * At top and bottom of the image, we diddle the pointer lists to duplicate
    104 * the first or last sample row as necessary (this is cheaper than copying
    105 * sample rows around).
    106 *
    107 * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1.  In that
    108 * situation each iMCU row provides only one row group so the buffering logic
    109 * must be different (eg, we must read two iMCU rows before we can emit the
    110 * first row group).  For now, we simply do not support providing context
    111 * rows when min_DCT_scaled_size is 1.  That combination seems unlikely to
    112 * be worth providing --- if someone wants a 1/8th-size preview, they probably
    113 * want it quick and dirty, so a context-free upsampler is sufficient.
    114 */
    115 
    116 
    117 /* Forward declarations */
    118 METHODDEF(void) process_data_simple_main(j_decompress_ptr cinfo,
    119                                         _JSAMPARRAY output_buf,
    120                                         JDIMENSION *out_row_ctr,
    121                                         JDIMENSION out_rows_avail);
    122 METHODDEF(void) process_data_context_main(j_decompress_ptr cinfo,
    123                                          _JSAMPARRAY output_buf,
    124                                          JDIMENSION *out_row_ctr,
    125                                          JDIMENSION out_rows_avail);
    126 #ifdef QUANT_2PASS_SUPPORTED
    127 METHODDEF(void) process_data_crank_post(j_decompress_ptr cinfo,
    128                                        _JSAMPARRAY output_buf,
    129                                        JDIMENSION *out_row_ctr,
    130                                        JDIMENSION out_rows_avail);
    131 #endif
    132 
    133 
    134 LOCAL(void)
    135 alloc_funny_pointers(j_decompress_ptr cinfo)
    136 /* Allocate space for the funny pointer lists.
    137 * This is done only once, not once per pass.
    138 */
    139 {
    140  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
    141  int ci, rgroup;
    142  int M = cinfo->_min_DCT_scaled_size;
    143  jpeg_component_info *compptr;
    144  _JSAMPARRAY xbuf;
    145 
    146  /* Get top-level space for component array pointers.
    147   * We alloc both arrays with one call to save a few cycles.
    148   */
    149  main_ptr->xbuffer[0] = (_JSAMPIMAGE)
    150    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    151                                cinfo->num_components * 2 *
    152                                sizeof(_JSAMPARRAY));
    153  main_ptr->xbuffer[1] = main_ptr->xbuffer[0] + cinfo->num_components;
    154 
    155  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    156       ci++, compptr++) {
    157    rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
    158      cinfo->_min_DCT_scaled_size; /* height of a row group of component */
    159    /* Get space for pointer lists --- M+4 row groups in each list.
    160     * We alloc both pointer lists with one call to save a few cycles.
    161     */
    162    xbuf = (_JSAMPARRAY)
    163      (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    164                                  2 * (rgroup * (M + 4)) * sizeof(_JSAMPROW));
    165    xbuf += rgroup;             /* want one row group at negative offsets */
    166    main_ptr->xbuffer[0][ci] = xbuf;
    167    xbuf += rgroup * (M + 4);
    168    main_ptr->xbuffer[1][ci] = xbuf;
    169  }
    170 }
    171 
    172 
    173 LOCAL(void)
    174 make_funny_pointers(j_decompress_ptr cinfo)
    175 /* Create the funny pointer lists discussed in the comments above.
    176 * The actual workspace is already allocated (in main_ptr->buffer),
    177 * and the space for the pointer lists is allocated too.
    178 * This routine just fills in the curiously ordered lists.
    179 * This will be repeated at the beginning of each pass.
    180 */
    181 {
    182  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
    183  int ci, i, rgroup;
    184  int M = cinfo->_min_DCT_scaled_size;
    185  jpeg_component_info *compptr;
    186  _JSAMPARRAY buf, xbuf0, xbuf1;
    187 
    188  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    189       ci++, compptr++) {
    190    rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
    191      cinfo->_min_DCT_scaled_size; /* height of a row group of component */
    192    xbuf0 = main_ptr->xbuffer[0][ci];
    193    xbuf1 = main_ptr->xbuffer[1][ci];
    194    /* First copy the workspace pointers as-is */
    195    buf = main_ptr->buffer[ci];
    196    for (i = 0; i < rgroup * (M + 2); i++) {
    197      xbuf0[i] = xbuf1[i] = buf[i];
    198    }
    199    /* In the second list, put the last four row groups in swapped order */
    200    for (i = 0; i < rgroup * 2; i++) {
    201      xbuf1[rgroup * (M - 2) + i] = buf[rgroup * M + i];
    202      xbuf1[rgroup * M + i] = buf[rgroup * (M - 2) + i];
    203    }
    204    /* The wraparound pointers at top and bottom will be filled later
    205     * (see set_wraparound_pointers, below).  Initially we want the "above"
    206     * pointers to duplicate the first actual data line.  This only needs
    207     * to happen in xbuffer[0].
    208     */
    209    for (i = 0; i < rgroup; i++) {
    210      xbuf0[i - rgroup] = xbuf0[0];
    211    }
    212  }
    213 }
    214 
    215 
    216 LOCAL(void)
    217 set_bottom_pointers(j_decompress_ptr cinfo)
    218 /* Change the pointer lists to duplicate the last sample row at the bottom
    219 * of the image.  whichptr indicates which xbuffer holds the final iMCU row.
    220 * Also sets rowgroups_avail to indicate number of nondummy row groups in row.
    221 */
    222 {
    223  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
    224  int ci, i, rgroup, iMCUheight, rows_left;
    225  jpeg_component_info *compptr;
    226  _JSAMPARRAY xbuf;
    227 
    228  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    229       ci++, compptr++) {
    230    /* Count sample rows in one iMCU row and in one row group */
    231    iMCUheight = compptr->v_samp_factor * compptr->_DCT_scaled_size;
    232    rgroup = iMCUheight / cinfo->_min_DCT_scaled_size;
    233    /* Count nondummy sample rows remaining for this component */
    234    rows_left = (int)(compptr->downsampled_height % (JDIMENSION)iMCUheight);
    235    if (rows_left == 0) rows_left = iMCUheight;
    236    /* Count nondummy row groups.  Should get same answer for each component,
    237     * so we need only do it once.
    238     */
    239    if (ci == 0) {
    240      main_ptr->rowgroups_avail = (JDIMENSION)((rows_left - 1) / rgroup + 1);
    241    }
    242    /* Duplicate the last real sample row rgroup*2 times; this pads out the
    243     * last partial rowgroup and ensures at least one full rowgroup of context.
    244     */
    245    xbuf = main_ptr->xbuffer[main_ptr->whichptr][ci];
    246    for (i = 0; i < rgroup * 2; i++) {
    247      xbuf[rows_left + i] = xbuf[rows_left - 1];
    248    }
    249  }
    250 }
    251 
    252 
    253 /*
    254 * Initialize for a processing pass.
    255 */
    256 
    257 METHODDEF(void)
    258 start_pass_main(j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
    259 {
    260  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
    261 
    262  switch (pass_mode) {
    263  case JBUF_PASS_THRU:
    264    if (cinfo->upsample->need_context_rows) {
    265      main_ptr->pub._process_data = process_data_context_main;
    266      make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
    267      main_ptr->whichptr = 0;   /* Read first iMCU row into xbuffer[0] */
    268      main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
    269      main_ptr->iMCU_row_ctr = 0;
    270    } else {
    271      /* Simple case with no context needed */
    272      main_ptr->pub._process_data = process_data_simple_main;
    273    }
    274    main_ptr->buffer_full = FALSE;      /* Mark buffer empty */
    275    main_ptr->rowgroup_ctr = 0;
    276    break;
    277 #ifdef QUANT_2PASS_SUPPORTED
    278  case JBUF_CRANK_DEST:
    279    /* For last pass of 2-pass quantization, just crank the postprocessor */
    280    main_ptr->pub._process_data = process_data_crank_post;
    281    break;
    282 #endif
    283  default:
    284    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    285    break;
    286  }
    287 }
    288 
    289 
    290 /*
    291 * Process some data.
    292 * This handles the simple case where no context is required.
    293 */
    294 
    295 METHODDEF(void)
    296 process_data_simple_main(j_decompress_ptr cinfo, _JSAMPARRAY output_buf,
    297                         JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
    298 {
    299  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
    300  JDIMENSION rowgroups_avail;
    301 
    302  /* Read input data if we haven't filled the main buffer yet */
    303  if (!main_ptr->buffer_full) {
    304    if (!(*cinfo->coef->_decompress_data) (cinfo, main_ptr->buffer))
    305      return;                   /* suspension forced, can do nothing more */
    306    main_ptr->buffer_full = TRUE;       /* OK, we have an iMCU row to work with */
    307  }
    308 
    309  /* There are always min_DCT_scaled_size row groups in an iMCU row. */
    310  rowgroups_avail = (JDIMENSION)cinfo->_min_DCT_scaled_size;
    311  /* Note: at the bottom of the image, we may pass extra garbage row groups
    312   * to the postprocessor.  The postprocessor has to check for bottom
    313   * of image anyway (at row resolution), so no point in us doing it too.
    314   */
    315 
    316  /* Feed the postprocessor */
    317  (*cinfo->post->_post_process_data) (cinfo, main_ptr->buffer,
    318                                      &main_ptr->rowgroup_ctr, rowgroups_avail,
    319                                      output_buf, out_row_ctr, out_rows_avail);
    320 
    321  /* Has postprocessor consumed all the data yet? If so, mark buffer empty */
    322  if (main_ptr->rowgroup_ctr >= rowgroups_avail) {
    323    main_ptr->buffer_full = FALSE;
    324    main_ptr->rowgroup_ctr = 0;
    325  }
    326 }
    327 
    328 
    329 /*
    330 * Process some data.
    331 * This handles the case where context rows must be provided.
    332 */
    333 
    334 METHODDEF(void)
    335 process_data_context_main(j_decompress_ptr cinfo, _JSAMPARRAY output_buf,
    336                          JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
    337 {
    338  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
    339 
    340  /* Read input data if we haven't filled the main buffer yet */
    341  if (!main_ptr->buffer_full) {
    342    if (!(*cinfo->coef->_decompress_data) (cinfo,
    343                                           main_ptr->xbuffer[main_ptr->whichptr]))
    344      return;                   /* suspension forced, can do nothing more */
    345    main_ptr->buffer_full = TRUE;       /* OK, we have an iMCU row to work with */
    346    main_ptr->iMCU_row_ctr++;   /* count rows received */
    347  }
    348 
    349  /* Postprocessor typically will not swallow all the input data it is handed
    350   * in one call (due to filling the output buffer first).  Must be prepared
    351   * to exit and restart.  This switch lets us keep track of how far we got.
    352   * Note that each case falls through to the next on successful completion.
    353   */
    354  switch (main_ptr->context_state) {
    355  case CTX_POSTPONED_ROW:
    356    /* Call postprocessor using previously set pointers for postponed row */
    357    (*cinfo->post->_post_process_data) (cinfo,
    358                                        main_ptr->xbuffer[main_ptr->whichptr],
    359                                        &main_ptr->rowgroup_ctr,
    360                                        main_ptr->rowgroups_avail, output_buf,
    361                                        out_row_ctr, out_rows_avail);
    362    if (main_ptr->rowgroup_ctr < main_ptr->rowgroups_avail)
    363      return;                   /* Need to suspend */
    364    main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
    365    if (*out_row_ctr >= out_rows_avail)
    366      return;                   /* Postprocessor exactly filled output buf */
    367    FALLTHROUGH                 /*FALLTHROUGH*/
    368  case CTX_PREPARE_FOR_IMCU:
    369    /* Prepare to process first M-1 row groups of this iMCU row */
    370    main_ptr->rowgroup_ctr = 0;
    371    main_ptr->rowgroups_avail = (JDIMENSION)(cinfo->_min_DCT_scaled_size - 1);
    372    /* Check for bottom of image: if so, tweak pointers to "duplicate"
    373     * the last sample row, and adjust rowgroups_avail to ignore padding rows.
    374     */
    375    if (main_ptr->iMCU_row_ctr == cinfo->total_iMCU_rows)
    376      set_bottom_pointers(cinfo);
    377    main_ptr->context_state = CTX_PROCESS_IMCU;
    378    FALLTHROUGH                 /*FALLTHROUGH*/
    379  case CTX_PROCESS_IMCU:
    380    /* Call postprocessor using previously set pointers */
    381    (*cinfo->post->_post_process_data) (cinfo,
    382                                        main_ptr->xbuffer[main_ptr->whichptr],
    383                                        &main_ptr->rowgroup_ctr,
    384                                        main_ptr->rowgroups_avail, output_buf,
    385                                        out_row_ctr, out_rows_avail);
    386    if (main_ptr->rowgroup_ctr < main_ptr->rowgroups_avail)
    387      return;                   /* Need to suspend */
    388    /* After the first iMCU, change wraparound pointers to normal state */
    389    if (main_ptr->iMCU_row_ctr == 1)
    390      set_wraparound_pointers(cinfo);
    391    /* Prepare to load new iMCU row using other xbuffer list */
    392    main_ptr->whichptr ^= 1;    /* 0=>1 or 1=>0 */
    393    main_ptr->buffer_full = FALSE;
    394    /* Still need to process last row group of this iMCU row, */
    395    /* which is saved at index M+1 of the other xbuffer */
    396    main_ptr->rowgroup_ctr = (JDIMENSION)(cinfo->_min_DCT_scaled_size + 1);
    397    main_ptr->rowgroups_avail = (JDIMENSION)(cinfo->_min_DCT_scaled_size + 2);
    398    main_ptr->context_state = CTX_POSTPONED_ROW;
    399  }
    400 }
    401 
    402 
    403 /*
    404 * Process some data.
    405 * Final pass of two-pass quantization: just call the postprocessor.
    406 * Source data will be the postprocessor controller's internal buffer.
    407 */
    408 
    409 #ifdef QUANT_2PASS_SUPPORTED
    410 
    411 METHODDEF(void)
    412 process_data_crank_post(j_decompress_ptr cinfo, _JSAMPARRAY output_buf,
    413                        JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
    414 {
    415  (*cinfo->post->_post_process_data) (cinfo, (_JSAMPIMAGE)NULL,
    416                                      (JDIMENSION *)NULL, (JDIMENSION)0,
    417                                      output_buf, out_row_ctr, out_rows_avail);
    418 }
    419 
    420 #endif /* QUANT_2PASS_SUPPORTED */
    421 
    422 
    423 /*
    424 * Initialize main buffer controller.
    425 */
    426 
    427 GLOBAL(void)
    428 _jinit_d_main_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
    429 {
    430  my_main_ptr main_ptr;
    431  int ci, rgroup, ngroups;
    432  jpeg_component_info *compptr;
    433 
    434  if (cinfo->data_precision != BITS_IN_JSAMPLE)
    435    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
    436 
    437  main_ptr = (my_main_ptr)
    438    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    439                                sizeof(my_main_controller));
    440  cinfo->main = (struct jpeg_d_main_controller *)main_ptr;
    441  main_ptr->pub.start_pass = start_pass_main;
    442 
    443  if (need_full_buffer)         /* shouldn't happen */
    444    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    445 
    446  /* Allocate the workspace.
    447   * ngroups is the number of row groups we need.
    448   */
    449  if (cinfo->upsample->need_context_rows) {
    450    if (cinfo->_min_DCT_scaled_size < 2) /* unsupported, see comments above */
    451      ERREXIT(cinfo, JERR_NOTIMPL);
    452    alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
    453    ngroups = cinfo->_min_DCT_scaled_size + 2;
    454  } else {
    455    ngroups = cinfo->_min_DCT_scaled_size;
    456  }
    457 
    458  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    459       ci++, compptr++) {
    460    rgroup = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /
    461      cinfo->_min_DCT_scaled_size; /* height of a row group of component */
    462    main_ptr->buffer[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
    463                        ((j_common_ptr)cinfo, JPOOL_IMAGE,
    464                         compptr->width_in_blocks * compptr->_DCT_scaled_size,
    465                         (JDIMENSION)(rgroup * ngroups));
    466  }
    467 }
    468 
    469 #endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */