Exemplo n.º 1
0
forward_DCT( j_compress_ptr cinfo, jpeg_component_info *compptr,
             JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
             JDIMENSION start_row, JDIMENSION start_col,
             JDIMENSION num_blocks )
/* This version is used for integer DCT implementations. */
{
    /* This routine is heavily used, so it's worth coding it tightly. */
    my_fdct_ptr fdct = ( my_fdct_ptr ) cinfo->fdct;
    forward_DCT_method_ptr do_dct = fdct->do_dct[compptr->component_index];
    DCTELEM *divisors = ( DCTELEM * ) compptr->dct_table;
    DCTELEM workspace[DCTSIZE2];	/* work area for FDCT subroutine */
    JDIMENSION bi;

    sample_data += start_row;	/* fold in the vertical offset once */

    for( bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size )
    {
        /* Perform the DCT */
        ( *do_dct )( workspace, sample_data, start_col );

        /* Quantize/descale the coefficients, and store into coef_blocks[] */
        {
            register DCTELEM temp, qval;
            register int i;
            register JCOEFPTR output_ptr = coef_blocks[bi];

            for( i = 0; i < DCTSIZE2; i++ )
            {
                qval = divisors[i];
                temp = workspace[i];
                /* Divide the coefficient value by qval, ensuring proper rounding.
                 * Since C does not specify the direction of rounding for negative
                 * quotients, we have to force the dividend positive for portability.
                 *
                 * In most files, at least half of the output values will be zero
                 * (at default quantization settings, more like three-quarters...)
                 * so we should ensure that this case is fast.  On many machines,
                 * a comparison is enough cheaper than a divide to make a special test
                 * a win.  Since both inputs will be nonnegative, we need only test
                 * for a < b to discover whether a/b is 0.
                 * If your machine's division is fast enough, define FAST_DIVIDE.
                 */
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a,b)	a /= b
#else
#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0
#endif
                if( temp < 0 )
                {
                    temp = -temp;
                    temp += qval >> 1;	/* for rounding */
                    DIVIDE_BY( temp, qval );
                    temp = -temp;
                }
                else
                {
                    temp += qval >> 1;	/* for rounding */
                    DIVIDE_BY( temp, qval );
                }
                output_ptr[i] = ( JCOEF ) temp;
            }
        }
Exemplo n.º 2
0
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
	     JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
	     JDIMENSION start_row, JDIMENSION start_col,
	     JDIMENSION num_blocks)
/* This version is used for integer DCT implementations. */
{
  /* This routine is heavily used, so it's worth coding it tightly. */
  j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec;
  fdct_ptr fdct = (fdct_ptr) lossyc->fdct_private;
  forward_DCT_method_ptr do_dct = fdct->do_dct;
  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
  DCTELEM workspace[DCTSIZE2];	/* work area for FDCT subroutine */
  JDIMENSION bi;

  sample_data += start_row;	/* fold in the vertical offset once */

  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
    /* Load data into workspace, applying unsigned->signed conversion */
    { register DCTELEM *workspaceptr;
      register JSAMPROW elemptr;
      register int elemr;

      workspaceptr = workspace;
      for (elemr = 0; elemr < DCTSIZE; elemr++) {
	elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8		/* unroll the inner loop */
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
#else
	{ register int elemc;
	  for (elemc = DCTSIZE; elemc > 0; elemc--) {
	    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
	  }
	}
#endif
      }
    }

    /* Perform the DCT */
    (*do_dct) (workspace);

    /* Quantize/descale the coefficients, and store into coef_blocks[] */
    { register DCTELEM temp, qval;
      register int i;
      register JCOEFPTR output_ptr = coef_blocks[bi];

      for (i = 0; i < DCTSIZE2; i++) {
	qval = divisors[i];
	temp = workspace[i];
	/* Divide the coefficient value by qval, ensuring proper rounding.
	 * Since C does not specify the direction of rounding for negative
	 * quotients, we have to force the dividend positive for portability.
	 *
	 * In most files, at least half of the output values will be zero
	 * (at default quantization settings, more like three-quarters...)
	 * so we should ensure that this case is fast.  On many machines,
	 * a comDicomon is enough cheaper than a divide to make a special test
	 * a win.  Since both inputs will be nonnegative, we need only test
	 * for a < b to discover whether a/b is 0.
	 * If your machine's division is fast enough, define FAST_DIVIDE.
	 */
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a,b)	a /= b
#else
#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0
#endif
	if (temp < 0) {
	  temp = -temp;
	  temp += qval>>1;	/* for rounding */
	  DIVIDE_BY(temp, qval);
	  temp = -temp;
	} else {
	  temp += qval>>1;	/* for rounding */
	  DIVIDE_BY(temp, qval);
	}
	output_ptr[i] = (JCOEF) temp;
      }
    }
Exemplo n.º 3
0
LOCAL void
extract_block (JSAMPARRAY input_data, int start_row, long start_col,
	       JBLOCK output_data, QUANT_TBL_PTR quanttbl)
/* Extract one 8x8 block from the specified location in the sample array; */
/* perform forward DCT, quantization scaling, and zigzag reordering on it. */
{
  /* This routine is heavily used, so it's worth coding it tightly. */
  DCTBLOCK block;
#ifdef DCT_ERR_STATS
  DCTBLOCK svblock;		/* saves input data for comparison */
#endif

  { register JSAMPROW elemptr;
    register DCTELEM *localblkptr = block;
    register int elemr;

    for (elemr = DCTSIZE; elemr > 0; elemr--) {
      elemptr = input_data[start_row++] + start_col;
#if DCTSIZE == 8		/* unroll the inner loop */
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
      *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
#else
      { register int elemc;
	for (elemc = DCTSIZE; elemc > 0; elemc--) {
	  *localblkptr++ = (DCTELEM) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
	}
      }
#endif
    }
  }

#ifdef DCT_ERR_STATS
  MEMCOPY(svblock, block, SIZEOF(DCTBLOCK));
#endif

  j_fwd_dct(block);

  { register JCOEF temp;
    register QUANT_VAL qval;
    register int i;

    for (i = 0; i < DCTSIZE2; i++) {
      qval = *quanttbl++;
      temp = (JCOEF) block[ZAG[i]];
      /* Divide the coefficient value by qval, ensuring proper rounding.
       * Since C does not specify the direction of rounding for negative
       * quotients, we have to force the dividend positive for portability.
       *
       * In most files, at least half of the output values will be zero
       * (at default quantization settings, more like three-quarters...)
       * so we should ensure that this case is fast.  On many machines,
       * a comparison is enough cheaper than a divide to make a special test
       * a win.  Since both inputs will be nonnegative, we need only test
       * for a < b to discover whether a/b is 0.
       * If your machine's division is fast enough, define FAST_DIVIDE.
       */
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a,b)	a /= b
#else
#define DIVIDE_BY(a,b)	(a >= b) ? (a /= b) : (a = 0)
#endif
      if (temp < 0) {
	temp = -temp;
	temp += qval>>1;	/* for rounding */
	DIVIDE_BY(temp, qval);
	temp = -temp;
      } else {
	temp += qval>>1;	/* for rounding */
	DIVIDE_BY(temp, qval);
      }
      *output_data++ = temp;
    }