home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / jpeg / jpegv4a.tar / jdmcu.c < prev    next >
C/C++ Source or Header  |  1993-02-17  |  6KB  |  216 lines

  1. /*
  2.  * jdmcu.c
  3.  *
  4.  * Copyright (C) 1991, 1992, 1993, 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 and IDCT control routines.
  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.  * Fetch one MCU row from entropy_decode, build coefficient array.
  18.  * This version is used for noninterleaved (single-component) scans.
  19.  */
  20.  
  21. METHODDEF void
  22. disassemble_noninterleaved_MCU (decompress_info_ptr cinfo,
  23.                 JBLOCKIMAGE image_data)
  24. {
  25.   JBLOCKROW MCU_data[1];
  26.   long mcuindex;
  27.  
  28.   /* this is pretty easy since there is one component and one block per MCU */
  29.  
  30.   /* Pre-zero the target area to speed up entropy decoder */
  31.   /* (we assume wholesale zeroing is faster than retail) */
  32.   jzero_far((void FAR *) image_data[0][0],
  33.         (size_t) (cinfo->MCUs_per_row * SIZEOF(JBLOCK)));
  34.  
  35.   for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
  36.     /* Point to the proper spot in the image array for this MCU */
  37.     MCU_data[0] = image_data[0][0] + mcuindex;
  38.     /* Fetch the coefficient data */
  39.     (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
  40.   }
  41. }
  42.  
  43.  
  44. /*
  45.  * Fetch one MCU row from entropy_decode, build coefficient array.
  46.  * This version is used for interleaved (multi-component) scans.
  47.  */
  48.  
  49. METHODDEF void
  50. disassemble_interleaved_MCU (decompress_info_ptr cinfo,
  51.                  JBLOCKIMAGE image_data)
  52. {
  53.   JBLOCKROW MCU_data[MAX_BLOCKS_IN_MCU];
  54.   long mcuindex;
  55.   short blkn, ci, xpos, ypos;
  56.   jpeg_component_info * compptr;
  57.   JBLOCKROW image_ptr;
  58.  
  59.   /* Pre-zero the target area to speed up entropy decoder */
  60.   /* (we assume wholesale zeroing is faster than retail) */
  61.   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
  62.     compptr = cinfo->cur_comp_info[ci];
  63.     for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
  64.       jzero_far((void FAR *) image_data[ci][ypos],
  65.         (size_t) (cinfo->MCUs_per_row * compptr->MCU_width * SIZEOF(JBLOCK)));
  66.     }
  67.   }
  68.  
  69.   for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
  70.     /* Point to the proper spots in the image array for this MCU */
  71.     blkn = 0;
  72.     for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
  73.       compptr = cinfo->cur_comp_info[ci];
  74.       for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
  75.     image_ptr = image_data[ci][ypos] + (mcuindex * compptr->MCU_width);
  76.     for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
  77.       MCU_data[blkn] = image_ptr;
  78.       image_ptr++;
  79.       blkn++;
  80.     }
  81.       }
  82.     }
  83.     /* Fetch the coefficient data */
  84.     (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
  85.   }
  86. }
  87.  
  88.  
  89. /*
  90.  * Perform inverse DCT on each block in an MCU row's worth of data;
  91.  * output the results into a sample array starting at row start_row.
  92.  * NB: start_row can only be nonzero when dealing with a single-component
  93.  * scan; otherwise we'd have to pass different offsets for different
  94.  * components, since the heights of interleaved MCU rows can vary.
  95.  * But the pipeline controller logic is such that this is not necessary.
  96.  */
  97.  
  98. METHODDEF void
  99. reverse_DCT (decompress_info_ptr cinfo,
  100.          JBLOCKIMAGE coeff_data, JSAMPIMAGE output_data, int start_row)
  101. {
  102.   DCTBLOCK block;
  103.   JBLOCKROW browptr;
  104.   JSAMPARRAY srowptr;
  105.   jpeg_component_info * compptr;
  106.   long blocksperrow, bi;
  107.   short numrows, ri;
  108.   short ci;
  109.  
  110.   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
  111.     compptr = cinfo->cur_comp_info[ci];
  112.     /* don't bother to IDCT an uninteresting component */
  113.     if (! compptr->component_needed)
  114.       continue;
  115.     /* calculate size of an MCU row in this component */
  116.     blocksperrow = compptr->downsampled_width / DCTSIZE;
  117.     numrows = compptr->MCU_height;
  118.     /* iterate through all blocks in MCU row */
  119.     for (ri = 0; ri < numrows; ri++) {
  120.       browptr = coeff_data[ci][ri];
  121.       srowptr = output_data[ci] + (ri * DCTSIZE + start_row);
  122.       for (bi = 0; bi < blocksperrow; bi++) {
  123.     /* copy the data into a local DCTBLOCK.  This allows for change of
  124.      * representation (if DCTELEM != JCOEF).  On 80x86 machines it also
  125.      * brings the data back from FAR storage to NEAR storage.
  126.      */
  127.     { register JCOEFPTR elemptr = browptr[bi];
  128.       register DCTELEM *localblkptr = block;
  129.       register int elem = DCTSIZE2;
  130.  
  131.       while (--elem >= 0)
  132.         *localblkptr++ = (DCTELEM) *elemptr++;
  133.     }
  134.  
  135.     j_rev_dct(block);    /* perform inverse DCT */
  136.  
  137.     /* Output the data into the sample array.
  138.      * Note change from signed to unsigned representation:
  139.      * DCT calculation works with values +-CENTERJSAMPLE,
  140.      * but sample arrays always hold 0..MAXJSAMPLE.
  141.      * We have to do range-limiting because of quantization errors in the
  142.      * DCT/IDCT phase.  We use the sample_range_limit[] table to do this
  143.      * quickly; the CENTERJSAMPLE offset is folded into table indexing.
  144.      */
  145.     { register JSAMPROW elemptr;
  146.       register DCTELEM *localblkptr = block;
  147.       register JSAMPLE *range_limit = cinfo->sample_range_limit +
  148.                         CENTERJSAMPLE;
  149. #if DCTSIZE != 8
  150.       register int elemc;
  151. #endif
  152.       register int elemr;
  153.  
  154.       for (elemr = 0; elemr < DCTSIZE; elemr++) {
  155.         elemptr = srowptr[elemr] + (bi * DCTSIZE);
  156. #if DCTSIZE == 8        /* unroll the inner loop */
  157.         *elemptr++ = range_limit[*localblkptr++];
  158.         *elemptr++ = range_limit[*localblkptr++];
  159.         *elemptr++ = range_limit[*localblkptr++];
  160.         *elemptr++ = range_limit[*localblkptr++];
  161.         *elemptr++ = range_limit[*localblkptr++];
  162.         *elemptr++ = range_limit[*localblkptr++];
  163.         *elemptr++ = range_limit[*localblkptr++];
  164.         *elemptr++ = range_limit[*localblkptr++];
  165. #else
  166.         for (elemc = DCTSIZE; elemc > 0; elemc--) {
  167.           *elemptr++ = range_limit[*localblkptr++];
  168.         }
  169. #endif
  170.       }
  171.     }
  172.       }
  173.     }
  174.   }
  175. }
  176.  
  177.  
  178. /*
  179.  * Initialize for processing a scan.
  180.  */
  181.  
  182. METHODDEF void
  183. disassemble_init (decompress_info_ptr cinfo)
  184. {
  185.   /* no work for now */
  186. }
  187.  
  188.  
  189. /*
  190.  * Clean up after a scan.
  191.  */
  192.  
  193. METHODDEF void
  194. disassemble_term (decompress_info_ptr cinfo)
  195. {
  196.   /* no work for now */
  197. }
  198.  
  199.  
  200.  
  201. /*
  202.  * The method selection routine for MCU disassembly.
  203.  */
  204.  
  205. GLOBAL void
  206. jseldmcu (decompress_info_ptr cinfo)
  207. {
  208.   if (cinfo->comps_in_scan == 1)
  209.     cinfo->methods->disassemble_MCU = disassemble_noninterleaved_MCU;
  210.   else
  211.     cinfo->methods->disassemble_MCU = disassemble_interleaved_MCU;
  212.   cinfo->methods->reverse_DCT = reverse_DCT;
  213.   cinfo->methods->disassemble_init = disassemble_init;
  214.   cinfo->methods->disassemble_term = disassemble_term;
  215. }
  216.