private static void ConvertYUV420ToRGB(byte[] dstPtr, int dstPitch, YUVToRGBLookup lookup, short[] colorTab, byte[] ySrc, byte[] uSrc, byte[] vSrc, int yWidth, int yHeight, int yPitch, int uvPitch, int size)
{
var putPixel = size == sizeof(uint) ? ScummHelper.WriteUInt32 : new Action <byte[], int, uint>((dst, offset, value) => ScummHelper.WriteUInt16(dst, offset, (ushort)value));
int halfHeight = yHeight >> 1;
int halfWidth = yWidth >> 1;
// Keep the tables in pointers here to avoid a dereference on each pixel
var Cr_r_tab = 0;
var Cr_g_tab = 256;
var Cb_g_tab = Cr_g_tab + 256;
var Cb_b_tab = Cb_g_tab + 256;
var y = 0;
var u = 0;
var v = 0;
var d = 0;
for (int h = 0; h < halfHeight; h++)
{
for (int w = 0; w < halfWidth; w++)
{
short cr_r = colorTab[Cr_r_tab + vSrc[v]];
short crb_g = (short)(colorTab[Cr_g_tab + vSrc[v]] + colorTab[Cb_g_tab + uSrc[u]]);
short cb_b = colorTab[Cb_b_tab + uSrc[u]];
++u;
++v;
var value = new Func <int, uint>(s =>
{
var rgbToPix = lookup.GetRGBToPix();
var val = (rgbToPix[s + cr_r] | rgbToPix[s + crb_g] | rgbToPix[s + cb_b]);
return(val);
});
putPixel(dstPtr, d, value(ySrc[y]));
putPixel(dstPtr, d + dstPitch, value(ySrc[y + yPitch]));
y++;
d += size;
putPixel(dstPtr, d, value(ySrc[y]));
putPixel(dstPtr, d + dstPitch, value(ySrc[y + yPitch]));
y++;
d += size;
}
d += dstPitch;
y += (yPitch << 1) - yWidth;
u += uvPitch - halfWidth;
v += uvPitch - halfWidth;
}
}