/*
 * jocolor.c
 */

#include "jinclude.h"
#include "JOColor.h"


#define SCALEBITS       16      /* speedier right-shift on some machines */
#define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
#define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))


static INT32 * rgb_y_tab;                       /* Table for RGB to Y conversion */
#define R_Y_OFF         0                       /* offset to R => Y section */
#define G_Y_OFF         (1*256)                 /* offset to G => Y section */
#define B_Y_OFF         (2*256)                 /* etc. */
#define TABLE_SIZE      (3*256)

/*
 * Initialize for colorspace conversion.
 */

void rgb_y_init (compress_info_ptr cinfo)
{
  INT32 i;

  /* Allocate and fill in the conversion tables. */
  rgb_y_tab = (INT32 *) (*cinfo->emethods->alloc_small)
                                (TABLE_SIZE * SIZEOF(INT32));

  for (i = 0; i <= MAXJSAMPLE; i++) {
    rgb_y_tab[i+R_Y_OFF] = FIX(0.29900) * i;
    rgb_y_tab[i+G_Y_OFF] = FIX(0.58700) * i;
    rgb_y_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
  }
}

void rgb_y (compress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
{
  register int r, g, b;
  register INT32 * ctab = rgb_y_tab;
  register JSAMPROW inptr0, inptr1, inptr2;
  register JSAMPROW outptr;
  register long col;
  long width = cinfo->image_width;
  int row;

  for (row = 0; row < num_rows; row++) {
    /* Convert colorspace */
    inptr0 = pixel_data[0][row];
    inptr1 = pixel_data[1][row];
    inptr2 = pixel_data[2][row];
    outptr = pixel_data[0][row];
    for (col = 0; col < width; col++) {
      r = GETJSAMPLE(inptr0[col]);
      g = GETJSAMPLE(inptr1[col]);
      b = GETJSAMPLE(inptr2[col]);
      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
       * must be too; we do not need an explicit range-limiting operation.
       * Hence the value being shifted is never negative, and we don't
       * need the general RIGHT_SHIFT macro.
       */
      /* Y */
      outptr[col] = (JSAMPLE)
                ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
                 >> SCALEBITS);
    }
  }
}
