//------------------------------------------------------------------- // TransformImage_YUY2 // // YUY2 to RGB-32 //------------------------------------------------------------------- unsafe private static void TransformImage_YUY2( IntPtr pDest, int lDestStride, IntPtr pSrc, int lSrcStride, int dwWidthInPixels, int dwHeightInPixels) { YUYV * pSrcPel = (YUYV *)pSrc; RGBQUAD *pDestPel = (RGBQUAD *)pDest; lSrcStride /= 4; // convert lSrcStride to YUYV lDestStride /= 4; // convert lDestStride to RGBQUAD for (int y = 0; y < dwHeightInPixels; y++) { for (int x = 0; x < dwWidthInPixels / 2; x++) { pDestPel[x * 2] = ConvertYCrCbToRGB(pSrcPel[x].Y, pSrcPel[x].V, pSrcPel[x].U); pDestPel[(x * 2) + 1] = ConvertYCrCbToRGB(pSrcPel[x].Y2, pSrcPel[x].V, pSrcPel[x].U); } pSrcPel += lSrcStride; pDestPel += lDestStride; } }
/// <summary> /// Convert a 32-bit ARGB image to YUY2 /// </summary> /// <param name="dwWidthInPixels">Width to copy in pixels</param> /// <param name="dwHeightInPixels">Height to copy in pixels</param> /// <param name="dwDestStride">Stride of target in bytes</param> /// <param name="ipSrc">Pointer to source data</param> /// <param name="ipDest">Pointer to destination data</param> unsafe static public int ARGB32_To_YUY2( int dwWidthInPixels, int dwHeightInPixels, int dwDestStride, IntPtr ipSrc, IntPtr ipDest ) { Debug.Assert(dwDestStride >= (dwWidthInPixels * 2)); RGB * pSrcPixel = (RGB *)ipSrc; YUYV *pDestPixel = (YUYV *)ipDest; int dwUseWidth = dwWidthInPixels / 2; for (int y = 0; y < dwHeightInPixels; y++) { for (int x = 0; x < dwUseWidth; x++) { pDestPixel[x].Y = (byte)(((66 * pSrcPixel->R + 129 * pSrcPixel->G + 25 * pSrcPixel->B + 128) >> 8) + 16); pDestPixel[x].U = (byte)(((-38 * pSrcPixel->R - 74 * pSrcPixel->G + 112 * pSrcPixel->B + 128) >> 8) + 128); pSrcPixel++; pDestPixel[x].Y2 = (byte)(((66 * pSrcPixel->R + 129 * pSrcPixel->G + 25 * pSrcPixel->B + 128) >> 8) + 16); pDestPixel[x].V = (byte)(((112 * pSrcPixel->R - 94 * pSrcPixel->G - 18 * pSrcPixel->B + 128) >> 8) + 128); pSrcPixel++; } pDestPixel = &pDestPixel[dwDestStride / sizeof(YUYV)]; } return((int)((byte *)pDestPixel - (byte *)ipDest)); }
#pragma warning restore 649 unsafe static void YUY2_TO_RGB32( IntPtr ipSrc, IntPtr ipDest, int dwWidthInPixels, int dwHeightInPixels, int dwSrcStride ) { // Assumes no padding on dest buffer YUYV *pSrcRow = (YUYV *)ipSrc; uint *pDestPixel = (uint *)ipDest; int dwUseWidth = dwWidthInPixels / 2; int dwUseStride = dwSrcStride / sizeof(YUYV); int y = dwHeightInPixels; do { YUYV *pSrcPixel = pSrcRow; int x = dwUseWidth; do { int c = pSrcPixel->Y; c -= 16; c *= 298; c += 128; int d = pSrcPixel->U; d -= 128; int e = pSrcPixel->V; e -= 128; // Expanding it out like this gains a bit of perf uint i = 0; int j = (c + 516 * d) >> 8; // blue if (j > 0) { if (j < 255) { i = (uint)j; } else { i = 255; } } j = (c - 100 * d - 208 * e) >> 8; // green if (j > 0) { if (j < 255) { i |= ((uint)j) << 8; } else { i |= 255 << 8; } } j = (c + 409 * e) >> 8; // red if (j > 0) { if (j < 255) { i |= ((uint)j) << 16; } else { i |= 255 << 16; } } *pDestPixel = i; c = pSrcPixel->Y2; c -= 16; c *= 298; c += 128; pDestPixel++; i = 0; j = (c + 516 * d) >> 8; // blue if (j > 0) { if (j < 255) { i = (uint)j; } else { i = 255; } } j = (c - 100 * d - 208 * e) >> 8; // green if (j > 0) { if (j < 255) { i |= ((uint)j) << 8; } else { i |= 255 << 8; } } j = (c + 409 * e) >> 8; // red if (j > 0) { if (j < 255) { i |= ((uint)j) << 16; } else { i |= 255 << 16; } } *pDestPixel = i; pDestPixel++; pSrcPixel++; x--; } while (x > 0); // Account for padding on input buffers pSrcRow += dwUseStride; y--; } while (y > 0); }