/*
 * jbsmooth.c
 *
 * Copyright (C) 1991, Thomas G. Lane.
 * This file is part of the Independent JPEG Group's software.
 * For conditions of distribution and use, see the accompanying README file.
 *
 * This file contains cross-block smoothing routines.
 * These routines are invoked via the smooth_coefficients method.
 */

#include "jinclude.h"

#ifdef BLOCK_SMOOTHING_SUPPORTED


/*
 * Cross-block coefficient smoothing.
 */

METHODDEF void
smooth_coefficients (decompress_info_ptr cinfo,
		     jpeg_component_info *compptr,
		     JBLOCKROW above,
		     JBLOCKROW currow,
		     JBLOCKROW below,
		     JBLOCKROW output)
{
  QUANT_TBL_PTR Qptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
  long blocks_in_row = compptr->subsampled_width / DCTSIZE;
  long col;

  /* First, copy the block row as-is.
   * This takes care of the first & last blocks in the row, the top/bottom
   * special cases, and the higher-order coefficients in each block.
   */
  jcopy_block_row(currow, output, blocks_in_row);

  /* Now apply the smoothing calculation, but not to any blocks on the
   * edges of the image.
   */

  if (above != NULL && below != NULL) {
    for (col = 1; col < blocks_in_row-1; col++) {

      /* See section 13.10 of JPEG-8-R8, or K.8 of JPEG-9-R6.
       *
       * As I understand it, this produces approximations
       * for the low frequency AC components, based on the
       * DC values of the block and its eight neighboring blocks.
       * (Thus it can't be used for blocks on the image edges.)
       */

      /* The layout of these variables corresponds to
       * the text in 13.10
       */
      
      JCOEF DC1, DC2, DC3;
      JCOEF DC4, DC5, DC6;
      JCOEF DC7, DC8, DC9;
      
      long       AC01, AC02;
      long AC10, AC11;
      long AC20;
      
      DC1 = above [col-1][0];
      DC2 = above [col  ][0];
      DC3 = above [col+1][0];
      DC4 = currow[col-1][0];
      DC5 = currow[col  ][0];
      DC6 = currow[col+1][0];
      DC7 = below [col-1][0];
      DC8 = below [col  ][0];
      DC9 = below [col+1][0];
      
#define DIVIDE_256(x)	x = ( (x) < 0 ? -((128-(x))/256) : ((x)+128)/256 )
      
      AC01 = (36 * (DC4 - DC6));
      DIVIDE_256(AC01);
      AC10 = (36 * (DC2 - DC8));
      DIVIDE_256(AC10);
      AC20 = (9 * (DC2 + DC8 - 2*DC5));
      DIVIDE_256(AC20);
      AC11 = (5 * ((DC1 - DC3) - (DC7 - DC9)));
      DIVIDE_256(AC11);
      AC02 = (9 * (DC4 + DC6 - 2*DC5));
      DIVIDE_256(AC02);
      
      /* I think that this checks to see if the quantisation
       * on the transmitting side would have produced this
       * answer. If so, then we use our (hopefully better)
       * estimate.
       */

#define ABS(x)	((x) < 0 ? -(x) : (x))

#define COND_ASSIGN(_ac,_n,_z)   if ((ABS(output[col][_n] - (_ac))<<1) <= Qptr[_z]) output[col][_n] = (_ac)

      COND_ASSIGN(AC01,  1, 1);
      COND_ASSIGN(AC02,  2, 5);
      COND_ASSIGN(AC10,  8, 2);
      COND_ASSIGN(AC11,  9, 4);
      COND_ASSIGN(AC20, 16, 3);
    }
  }
}


/*
 * The method selection routine for cross-block smoothing.
 */

GLOBAL void
jselbsmooth (decompress_info_ptr cinfo)
{
  /* just one implementation for now */
  cinfo->methods->smooth_coefficients = smooth_coefficients;
}

#endif /* BLOCK_SMOOTHING_SUPPORTED */
