home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / jpeg / jpegv4a.tar / jcmcu.c < prev    next >
C/C++ Source or Header  |  1992-12-14  |  7KB  |  229 lines

  1. /*
  2.  * jcmcu.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 extraction routines and quantization scaling.
  9.  * These routines are invoked via the extract_MCUs and
  10.  * extract_init/term methods.
  11.  */
  12.  
  13. #include "jinclude.h"
  14.  
  15.  
  16. /*
  17.  * If this file is compiled with -DDCT_ERR_STATS, it will reverse-DCT each
  18.  * block and sum the total errors across the whole picture.  This provides
  19.  * a convenient method of using real picture data to test the roundoff error
  20.  * of a DCT algorithm.  DCT_ERR_STATS should *not* be defined for a production
  21.  * compression program, since compression is much slower with it defined.
  22.  * Also note that jrevdct.o must be linked into the compressor when this
  23.  * switch is defined.
  24.  */
  25.  
  26. #ifdef DCT_ERR_STATS
  27. static int dcterrorsum;        /* these hold the error statistics */
  28. static int dcterrormax;
  29. static int dctcoefcount;    /* This will probably overflow on a 16-bit-int machine */
  30. #endif
  31.  
  32.  
  33. /* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
  34.  
  35. static const int ZAG[DCTSIZE2] = {
  36.   0,  1,  8, 16,  9,  2,  3, 10,
  37.  17, 24, 32, 25, 18, 11,  4,  5,
  38.  12, 19, 26, 33, 40, 48, 41, 34,
  39.  27, 20, 13,  6,  7, 14, 21, 28,
  40.  35, 42, 49, 56, 57, 50, 43, 36,
  41.  29, 22, 15, 23, 30, 37, 44, 51,
  42.  58, 59, 52, 45, 38, 31, 39, 46,
  43.  53, 60, 61, 54, 47, 55, 62, 63
  44. };
  45.  
  46.  
  47. LOCAL void
  48. extract_block (JSAMPARRAY input_data, int start_row, long start_col,
  49.            JBLOCK output_data, QUANT_TBL_PTR quanttbl)
  50. /* Extract one 8x8 block from the specified location in the sample array; */
  51. /* perform forward DCT, quantization scaling, and zigzag reordering on it. */
  52. {
  53.   /* This routine is heavily used, so it's worth coding it tightly. */
  54.   DCTBLOCK block;
  55. #ifdef DCT_ERR_STATS
  56.   DCTBLOCK svblock;        /* saves input data for comparison */
  57. #endif
  58.  
  59.   { register JSAMPROW elemptr;
  60.     register DCTELEM *localblkptr = block;
  61.     register int elemr;
  62.  
  63.     for (elemr = DCTSIZE; elemr > 0; elemr--) {
  64.       elemptr = input_data[start_row++] + start_col;
  65. #if DCTSIZE == 8        /* unroll the inner loop */
  66.       *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
  67.       *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
  68.       *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
  69.       *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
  70.       *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
  71.       *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
  72.       *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
  73.       *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
  74. #else
  75.       { register int elemc;
  76.     for (elemc = DCTSIZE; elemc > 0; elemc--) {
  77.       *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
  78.     }
  79.       }
  80. #endif
  81.     }
  82.   }
  83.  
  84. #ifdef DCT_ERR_STATS
  85.   MEMCOPY(svblock, block, SIZEOF(DCTBLOCK));
  86. #endif
  87.  
  88.   j_fwd_dct(block);
  89.  
  90.   { register JCOEF temp;
  91.     register QUANT_VAL qval;
  92.     register int i;
  93.  
  94.     for (i = 0; i < DCTSIZE2; i++) {
  95.       qval = *quanttbl++;
  96.       temp = (JCOEF) block[ZAG[i]];
  97.       /* Divide the coefficient value by qval, ensuring proper rounding.
  98.        * Since C does not specify the direction of rounding for negative
  99.        * quotients, we have to force the dividend positive for portability.
  100.        *
  101.        * In most files, at least half of the output values will be zero
  102.        * (at default quantization settings, more like three-quarters...)
  103.        * so we should ensure that this case is fast.  On many machines,
  104.        * a comparison is enough cheaper than a divide to make a special test
  105.        * a win.  Since both inputs will be nonnegative, we need only test
  106.        * for a < b to discover whether a/b is 0.
  107.        * If your machine's division is fast enough, define FAST_DIVIDE.
  108.        */
  109. #ifdef FAST_DIVIDE
  110. #define DIVIDE_BY(a,b)    a /= b
  111. #else
  112. #define DIVIDE_BY(a,b)    (a >= b) ? (a /= b) : (a = 0)
  113. #endif
  114.       if (temp < 0) {
  115.     temp = -temp;
  116.     temp += qval>>1;    /* for rounding */
  117.     DIVIDE_BY(temp, qval);
  118.     temp = -temp;
  119.       } else {
  120.     temp += qval>>1;    /* for rounding */
  121.     DIVIDE_BY(temp, qval);
  122.       }
  123.       *output_data++ = temp;
  124.     }
  125.   }
  126.  
  127. #ifdef DCT_ERR_STATS
  128.   j_rev_dct(block);
  129.  
  130.   { register int diff;
  131.     register int i;
  132.  
  133.     for (i = 0; i < DCTSIZE2; i++) {
  134.       diff = block[i] - svblock[i];
  135.       if (diff < 0) diff = -diff;
  136.       dcterrorsum += diff;
  137.       if (dcterrormax < diff) dcterrormax = diff;
  138.     }
  139.     dctcoefcount += DCTSIZE2;
  140.   }
  141. #endif
  142. }
  143.  
  144.  
  145. /*
  146.  * Extract samples in MCU order, process & hand off to output_method.
  147.  * The input is always exactly N MCU rows worth of data.
  148.  */
  149.  
  150. METHODDEF void
  151. extract_MCUs (compress_info_ptr cinfo,
  152.           JSAMPIMAGE image_data,
  153.           int num_mcu_rows,
  154.           MCU_output_method_ptr output_method)
  155. {
  156.   JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
  157.   int mcurow;
  158.   long mcuindex;
  159.   short blkn, ci, xpos, ypos;
  160.   jpeg_component_info * compptr;
  161.   QUANT_TBL_PTR quant_ptr;
  162.  
  163.   for (mcurow = 0; mcurow < num_mcu_rows; mcurow++) {
  164.     for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
  165.       /* Extract data from the image array, DCT it, and quantize it */
  166.       blkn = 0;
  167.       for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
  168.     compptr = cinfo->cur_comp_info[ci];
  169.     quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
  170.     for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
  171.       for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
  172.         extract_block(image_data[ci],
  173.               (mcurow * compptr->MCU_height + ypos)*DCTSIZE,
  174.               (mcuindex * compptr->MCU_width + xpos)*DCTSIZE,
  175.               MCU_data[blkn], quant_ptr);
  176.         blkn++;
  177.       }
  178.     }
  179.       }
  180.       /* Send the MCU whereever the pipeline controller wants it to go */
  181.       (*output_method) (cinfo, MCU_data);
  182.     }
  183.   }
  184. }
  185.  
  186.  
  187. /*
  188.  * Initialize for processing a scan.
  189.  */
  190.  
  191. METHODDEF void
  192. extract_init (compress_info_ptr cinfo)
  193. {
  194.   /* no work for now */
  195. #ifdef DCT_ERR_STATS
  196.   dcterrorsum = dcterrormax = dctcoefcount = 0;
  197. #endif
  198. }
  199.  
  200.  
  201. /*
  202.  * Clean up after a scan.
  203.  */
  204.  
  205. METHODDEF void
  206. extract_term (compress_info_ptr cinfo)
  207. {
  208.   /* no work for now */
  209. #ifdef DCT_ERR_STATS
  210.   TRACEMS3(cinfo->emethods, 0, "DCT roundoff errors = %d/%d,  max = %d",
  211.        dcterrorsum, dctcoefcount, dcterrormax);
  212. #endif
  213. }
  214.  
  215.  
  216.  
  217. /*
  218.  * The method selection routine for MCU extraction.
  219.  */
  220.  
  221. GLOBAL void
  222. jselcmcu (compress_info_ptr cinfo)
  223. {
  224.   /* just one implementation for now */
  225.   cinfo->methods->extract_init = extract_init;
  226.   cinfo->methods->extract_MCUs = extract_MCUs;
  227.   cinfo->methods->extract_term = extract_term;
  228. }
  229.