home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / jpeg3.arj / JDMCU.C < prev    next >
C/C++ Source or Header  |  1992-01-17  |  6KB  |  220 lines

  1. /*
  2.  * jdmcu.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains MCU disassembly routines and quantization descaling.
  9.  * These routines are invoked via the disassemble_MCU, reverse_DCT, and
  10.  * disassemble_init/term methods.
  11.  */
  12.  
  13. #include "jinclude.h"
  14.  
  15.  
  16. /*
  17.  * Quantization descaling and zigzag reordering
  18.  */
  19.  
  20.  
  21. /* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
  22.  
  23. static const short ZAG[DCTSIZE2] = {
  24.   0,  1,  8, 16,  9,  2,  3, 10,
  25.  17, 24, 32, 25, 18, 11,  4,  5,
  26.  12, 19, 26, 33, 40, 48, 41, 34,
  27.  27, 20, 13,  6,  7, 14, 21, 28,
  28.  35, 42, 49, 56, 57, 50, 43, 36,
  29.  29, 22, 15, 23, 30, 37, 44, 51,
  30.  58, 59, 52, 45, 38, 31, 39, 46,
  31.  53, 60, 61, 54, 47, 55, 62, 63
  32. };
  33.  
  34.  
  35. LOCAL void
  36. qdescale_zig (JBLOCK input, JBLOCKROW outputptr, QUANT_TBL_PTR quanttbl)
  37. {
  38.   const short * zagptr = ZAG;
  39.   short i;
  40.  
  41.   for (i = DCTSIZE2-1; i >= 0; i--) {
  42.     (*outputptr)[*zagptr++] = (*input++) * (*quanttbl++);
  43.   }
  44. }
  45.  
  46.  
  47.  
  48. /*
  49.  * Fetch one MCU row from entropy_decode, build coefficient array.
  50.  * This version is used for noninterleaved (single-component) scans.
  51.  */
  52.  
  53. METHODDEF void
  54. disassemble_noninterleaved_MCU (decompress_info_ptr cinfo,
  55.                 JBLOCKIMAGE image_data)
  56. {
  57.   JBLOCK MCU_data[1];
  58.   long mcuindex;
  59.   jpeg_component_info * compptr;
  60.   QUANT_TBL_PTR quant_ptr;
  61.  
  62.   /* this is pretty easy since there is one component and one block per MCU */
  63.   compptr = cinfo->cur_comp_info[0];
  64.   quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
  65.   for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
  66.     /* Fetch the coefficient data */
  67.     (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
  68.     /* Descale, reorder, and distribute it into the image array */
  69.     qdescale_zig(MCU_data[0], image_data[0][0] + mcuindex, quant_ptr);
  70.   }
  71. }
  72.  
  73.  
  74. /*
  75.  * Fetch one MCU row from entropy_decode, build coefficient array.
  76.  * This version is used for interleaved (multi-component) scans.
  77.  */
  78.  
  79. METHODDEF void
  80. disassemble_interleaved_MCU (decompress_info_ptr cinfo,
  81.                  JBLOCKIMAGE image_data)
  82. {
  83.   JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
  84.   long mcuindex;
  85.   short blkn, ci, xpos, ypos;
  86.   jpeg_component_info * compptr;
  87.   QUANT_TBL_PTR quant_ptr;
  88.   JBLOCKROW image_ptr;
  89.  
  90.   for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
  91.     /* Fetch the coefficient data */
  92.     (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
  93.     /* Descale, reorder, and distribute it into the image array */
  94.     blkn = 0;
  95.     for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
  96.       compptr = cinfo->cur_comp_info[ci];
  97.       quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
  98.       for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
  99.     image_ptr = image_data[ci][ypos] + (mcuindex * compptr->MCU_width);
  100.     for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
  101.       qdescale_zig(MCU_data[blkn], image_ptr, quant_ptr);
  102.       image_ptr++;
  103.       blkn++;
  104.     }
  105.       }
  106.     }
  107.   }
  108. }
  109.  
  110.  
  111. /*
  112.  * Perform inverse DCT on each block in an MCU row's worth of data;
  113.  * output the results into a sample array starting at row start_row.
  114.  * NB: start_row can only be nonzero when dealing with a single-component
  115.  * scan; otherwise we'd have to pass different offsets for different
  116.  * components, since the heights of interleaved MCU rows can vary.
  117.  * But the pipeline controller logic is such that this is not necessary.
  118.  */
  119.  
  120. METHODDEF void
  121. reverse_DCT (decompress_info_ptr cinfo,
  122.          JBLOCKIMAGE coeff_data, JSAMPIMAGE output_data, int start_row)
  123. {
  124.   DCTBLOCK block;
  125.   JBLOCKROW browptr;
  126.   JSAMPARRAY srowptr;
  127.   long blocksperrow, bi;
  128.   short numrows, ri;
  129.   short ci;
  130.  
  131.   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
  132.     /* calculate size of an MCU row in this component */
  133.     blocksperrow = cinfo->cur_comp_info[ci]->subsampled_width / DCTSIZE;
  134.     numrows = cinfo->cur_comp_info[ci]->MCU_height;
  135.     /* iterate through all blocks in MCU row */
  136.     for (ri = 0; ri < numrows; ri++) {
  137.       browptr = coeff_data[ci][ri];
  138.       srowptr = output_data[ci] + (ri * DCTSIZE + start_row);
  139.       for (bi = 0; bi < blocksperrow; bi++) {
  140.     /* copy the data into a local DCTBLOCK.  This allows for change of
  141.      * representation (if DCTELEM != JCOEF).  On 80x86 machines it also
  142.      * brings the data back from FAR storage to NEAR storage.
  143.      */
  144.     { register JCOEFPTR elemptr = browptr[bi];
  145.       register DCTELEM *localblkptr = block;
  146.       register short elem = DCTSIZE2;
  147.  
  148.       while (--elem >= 0)
  149.         *localblkptr++ = (DCTELEM) *elemptr++;
  150.     }
  151.  
  152.     j_rev_dct(block);    /* perform inverse DCT */
  153.  
  154.     /* output the data into the sample array.
  155.      * Note change from signed to unsigned representation:
  156.      * DCT calculation works with values +-CENTERJSAMPLE,
  157.      * but sample arrays always hold 0..MAXJSAMPLE.
  158.      * Have to do explicit range-limiting because of quantization errors
  159.      * and so forth in the DCT/IDCT phase.
  160.      */
  161.     { register JSAMPROW elemptr;
  162.       register DCTELEM *localblkptr = block;
  163.       register short elemr, elemc;
  164.       register DCTELEM temp;
  165.  
  166.       for (elemr = 0; elemr < DCTSIZE; elemr++) {
  167.         elemptr = srowptr[elemr] + (bi * DCTSIZE);
  168.         for (elemc = 0; elemc < DCTSIZE; elemc++) {
  169.           temp = (*localblkptr++) + CENTERJSAMPLE;
  170.           if (temp < 0) temp = 0;
  171.           else if (temp > MAXJSAMPLE) temp = MAXJSAMPLE;
  172.           *elemptr++ = (JSAMPLE) temp;
  173.         }
  174.       }
  175.     }
  176.       }
  177.     }
  178.   }
  179. }
  180.  
  181.  
  182. /*
  183.  * Initialize for processing a scan.
  184.  */
  185.  
  186. METHODDEF void
  187. disassemble_init (decompress_info_ptr cinfo)
  188. {
  189.   /* no work for now */
  190. }
  191.  
  192.  
  193. /*
  194.  * Clean up after a scan.
  195.  */
  196.  
  197. METHODDEF void
  198. disassemble_term (decompress_info_ptr cinfo)
  199. {
  200.   /* no work for now */
  201. }
  202.  
  203.  
  204.  
  205. /*
  206.  * The method selection routine for MCU disassembly.
  207.  */
  208.  
  209. GLOBAL void
  210. jseldmcu (decompress_info_ptr cinfo)
  211. {
  212.   if (cinfo->comps_in_scan == 1)
  213.     cinfo->methods->disassemble_MCU = disassemble_noninterleaved_MCU;
  214.   else
  215.     cinfo->methods->disassemble_MCU = disassemble_interleaved_MCU;
  216.   cinfo->methods->reverse_DCT = reverse_DCT;
  217.   cinfo->methods->disassemble_init = disassemble_init;
  218.   cinfo->methods->disassemble_term = disassemble_term;
  219. }
  220.