/* DirectShow capture services (QCAP.DLL)
 *
 * Copyright 2005 Maarten Lankhorst
 *
 * This file contains the part of the vfw capture interface that
 * does the actual Video4Linux(1/2) stuff required for capturing
 * and setting/getting media format..
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>

#include "windef.h"
#include "wingdi.h"
#include "objbase.h"
#include "strmif.h"
#include "qcap_main.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(qcap);

static int yuv_xy[256]; /* Gray value */
static int yuv_gu[256]; /* Green U */
static int yuv_bu[256]; /* Blue  U */
static int yuv_rv[256]; /* Red   V */
static int yuv_gv[256]; /* Green V */
static int initialised = 0;

static inline int ValidRange(int in) {
   if (in > 255) in = 255;
   if (in < 0) in = 0;
   return in;
}

typedef struct RGB {
#if 0 /* For some reason I have to revert R and B, not sure why */
  unsigned char r, g, b;
#else
  unsigned char b, g, r;
#endif
} RGB;

static inline void YUV2RGB(const unsigned char y_, const unsigned char cb, const unsigned char cr, RGB* retval) {
   retval->r = ValidRange(yuv_xy[y_] + yuv_rv[cr]);
   retval->g = ValidRange(yuv_xy[y_] + yuv_gu[cb] + yuv_gv[cr]);
   retval->b = ValidRange(yuv_xy[y_] + yuv_bu[cb]);
}

void YUV_Init(void) {
   float y, u, v;
   int y_, cb, cr;

   if (initialised++) return;

   for (y_ = 0; y_ <= 255; y_++)
   {
      y = ((float) 255 / 219) * (y_ - 16);
      yuv_xy[y_] = y;
   }

   for (cb = 0; cb <= 255; cb++)
   {
      u = ((float) 255 / 224) * (cb - 128);
      yuv_gu[cb] = -0.344 * u;
      yuv_bu[cb] =  1.772 * u;
   }

   for (cr = 0; cr <= 255; cr++)
   {
      v = ((float) 255 / 224) * (cr - 128);
      yuv_rv[cr] =  1.402 * v;
      yuv_gv[cr] = -0.714 * v;
   }
   TRACE("Filled hash table\n");
}

static void Parse_YUYV(unsigned char *destbuffer, const unsigned char *input, int width, int height)
{
   const unsigned char *pY, *pCb, *pCr;
   int togo = width * height / 2;
   pY = input;
   pCb = input+1;
   pCr = input+3;
   while (--togo) {
      YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
      pY += 2; destbuffer += 3;
      YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
      pY += 2; pCb += 4; pCr += 4; destbuffer += 3;
   }
}

static void Parse_UYVY(unsigned char *destbuffer, const unsigned char *input, int width, int height)
{
   const unsigned char *pY, *pCb, *pCr;
   int togo = width * height / 2;
   pY = input+1;
   pCb = input;
   pCr = input+2;
   while (--togo) {
      YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
      pY += 2; destbuffer += 3;
      YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
      pY += 2; pCb += 4; pCr += 4; destbuffer += 3;
   }
}

static void Parse_UYYVYY(unsigned char *destbuffer, const unsigned char *input, int width, int height)
{
   const unsigned char *pY, *pCb, *pCr;
   int togo = width * height / 4;
   pY = input+1;
   pCb = input;
   pCr = input+4;
   while (--togo) {
      YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
      destbuffer += 3; pY++;
      YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
      pY += 2; destbuffer += 3;
      YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
      destbuffer += 3; pY++;
      YUV2RGB(*pY, *pCb, *pCr, (RGB *)destbuffer);
      pY += 2; pCb += 6; pCr += 6; destbuffer += 3;
   }
}

static void Parse_PYUV(unsigned char *destbuffer, const unsigned char *input, int width, int height, int wstep, int hstep)
{
   /* We have 3 pointers, One to Y, one to Cb and 1 to Cr */

/* C19 *89* declaration block (Grr julliard for not allowing C99) */
   int ysize, uvsize;
   const unsigned char *pY, *pCb, *pCr;
   int swstep = 0, shstep = 0;
   int ypos = 0, xpos = 0;
   int indexUV = 0, cUv;
/* End of Grr */

   ysize = width * height;
   uvsize = (width / wstep) * (height / hstep);
   pY = input;
   pCb = pY + ysize;
   pCr = pCb + uvsize;
   /* Bottom down DIB */
   do {
      swstep = 0;
      cUv = indexUV;
      for (xpos = 0; xpos < width; xpos++) {
         YUV2RGB(*(pY++), pCb[cUv], pCr[cUv], (RGB *)destbuffer);
         destbuffer += 3;
         if (++swstep == wstep) {
            cUv++;
            swstep = 0;
         }
      }
      if (++shstep == hstep) {
         shstep = 0;
         indexUV = cUv;
      }
   } while (++ypos < height);
}

void YUV_To_RGB24(enum YUV_Format format, unsigned char *target, const unsigned char *source, int width, int height) {
   int wstep, hstep;
   if (format < ENDPLANAR) {
      switch (format) {
         case YUVP_421: wstep = 2; hstep = 1; break;
         case YUVP_422: wstep = 2; hstep = 2; break;
         case YUVP_441: wstep = 4; hstep = 1; break;
         case YUVP_444: wstep = 4; hstep = 4; break;
         default: ERR("Unhandled format \"%d\"\n", format); return;
      }
      Parse_PYUV(target, source, width, height, wstep, hstep);
   } else {
      switch (format) {
         case YUYV: Parse_YUYV(target, source, width, height); return;
         case UYVY: Parse_UYVY(target, source, width, height); return;
         case UYYVYY: Parse_UYYVYY(target, source, width, height); return;
         default: ERR("Unhandled format \"%d\"\n", format); return;
      }
   }
}
