blob: 8d701427b291a164e37d3f20132228453b0af197 [file]
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#include <assert.h>
#include "colorconversions.h"
#include "lutbl.h"
#include "ccstr.h"
/*
* **-CC_RGB24toYV12_C
*
* See cclib.h for a more detailed desciption of the function
*
*/
void CC_RGB24toYV12_C( unsigned char *RGBBuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch,int DstPitch )
{
unsigned char *YPtr1, *YPtr2; /* Local pointers to buffers */
unsigned char *UPtr, *VPtr;
RGB24Pixel *RGBPtr1, *RGBPtr2;
int WidthCtr, HeightCtr;
int RSum, GSum, BSum;
int YScaled, UScaled, VScaled; /* scaled Y, U, V values */
const int *YRMultPtr;
const int *YGMultPtr;
const int *YBMultPtr;
const int *URMultPtr;
const int *UGMultPtr;
const int *UBVRMultPtr;
const int *VGMultPtr;
const int *VBMultPtr;
assert( !(ImageHeight & 0x1) ); /* Height must be even otherwise we will behave incorrectly */
assert( !(ImageWidth & 0x1) ); /* Width must be even otherwise we will behave incorrectly */
YRMultPtr = YRMult;
YGMultPtr = YGMult;
YBMultPtr = YBMult;
URMultPtr = URMult;
UGMultPtr = UGMult;
UBVRMultPtr = UBVRMult;
VGMultPtr = VGMult;
VBMultPtr = VBMult;
/* setup pointers to first image line that we are processing */
RGBPtr1 = (RGB24Pixel *)RGBBuffer;
YPtr1 = YBuffer;
UPtr = UBuffer;
VPtr = VBuffer;
/* setup pointers to second image line that we are processing */
RGBPtr2 = ((RGB24Pixel *)(RGBBuffer + SrcPitch));
YPtr2 = YBuffer + DstPitch;
for( HeightCtr = ImageHeight; HeightCtr != 0; HeightCtr-=2 )
{
for( WidthCtr = 0; WidthCtr < ImageWidth; WidthCtr += 2 )
{
/* process pixel (0,0) in our 2x2 block */
YScaled = YRMultPtr[RGBPtr1[WidthCtr].Red];
RSum = RGBPtr1[WidthCtr].Red;
YScaled += YGMultPtr[RGBPtr1[WidthCtr].Green];
GSum = RGBPtr1[WidthCtr].Green;
YScaled += YBMultPtr[RGBPtr1[WidthCtr].Blue];
BSum = RGBPtr1[WidthCtr].Blue;
YPtr1[WidthCtr] = (unsigned char)(YScaled >> ShiftFactor); /* Y value valid write to output array */
/* process pixel (1,0) in our 2x2 block */
YScaled = YRMultPtr[RGBPtr2[WidthCtr].Red];
RSum += RGBPtr2[WidthCtr].Red;
YScaled += YGMultPtr[RGBPtr2[WidthCtr].Green];
GSum += RGBPtr2[WidthCtr].Green;
YScaled += YBMultPtr[RGBPtr2[WidthCtr].Blue];
BSum += RGBPtr2[WidthCtr].Blue;
YPtr2[WidthCtr] = (unsigned char)(YScaled >> ShiftFactor); /* Y value valid write to output array */
/* process pixel (0,1) in our 2x2 block */
YScaled = YRMultPtr[RGBPtr1[WidthCtr+1].Red];
RSum += RGBPtr1[WidthCtr+1].Red;
YScaled += YGMultPtr[RGBPtr1[WidthCtr+1].Green];
GSum += RGBPtr1[WidthCtr+1].Green;
YScaled += YBMultPtr[RGBPtr1[WidthCtr+1].Blue];
BSum += RGBPtr1[WidthCtr+1].Blue;
YPtr1[WidthCtr+1] = (unsigned char)(YScaled >> ShiftFactor); /* Y value valid write to output array */
/* process pixel (1,1) in our 2x2 block */
YScaled = YRMultPtr[RGBPtr2[WidthCtr+1].Red];
RSum += RGBPtr2[WidthCtr+1].Red;
YScaled += YGMultPtr[RGBPtr2[WidthCtr+1].Green];
GSum += RGBPtr2[WidthCtr+1].Green;
YScaled += YBMultPtr[RGBPtr2[WidthCtr+1].Blue];
BSum += RGBPtr2[WidthCtr+1].Blue;
YPtr2[WidthCtr+1] = (unsigned char)(YScaled >> ShiftFactor); /* Y value valid write to output array */
// convert our sums to averages
RSum += 2;
GSum += 2;
BSum += 2;
RSum = RSum >> 2;
GSum = GSum >> 2;
BSum = BSum >> 2;
// process u for the 4 pixels
UScaled = URMultPtr[RSum];
UScaled += UGMultPtr[GSum];
UScaled += UBVRMultPtr[BSum];
UScaled = UScaled >> ShiftFactor;
UPtr[(WidthCtr>>1)] = (unsigned char)UScaled;
// process v for the 4 pixels
VScaled = UBVRMultPtr[RSum];
VScaled += VGMultPtr[GSum];
VScaled += VBMultPtr[BSum];
VScaled = VScaled >> ShiftFactor;
VPtr[(WidthCtr>>1)] = (unsigned char)VScaled;
}
/* Increment our pointers */
UPtr += (DstPitch>>1);
VPtr += (DstPitch>>1);
YPtr1 += 2*DstPitch;
YPtr2 += 2*DstPitch;
RGBPtr1 = ((RGB24Pixel *)((unsigned char *) RGBPtr1 + SrcPitch*2));;
RGBPtr2 = ((RGB24Pixel *)((unsigned char *) RGBPtr2 + SrcPitch*2));;
}
}