//========================================================================== // // 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 #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 */ int *YRMultPtr; int *YGMultPtr; int *YBMultPtr; int *URMultPtr; int *UGMultPtr; int *UBVRMultPtr; int *VGMultPtr; 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));; } }