/// <summary> /// Converts the 8x8 region of the image whose top-left corner is x,y to its YCbCr values. /// </summary> /// <typeparam name="TColor">The pixel format.</typeparam> /// <param name="pixels">The pixel accessor.</param> /// <param name="x">The x-position within the image.</param> /// <param name="y">The y-position within the image.</param> /// <param name="yBlock">The luminance block.</param> /// <param name="cbBlock">The red chroma block.</param> /// <param name="crBlock">The blue chroma block.</param> /// <param name="rgbBytes">Temporal <see cref="PixelArea{TColor}"/> provided by the caller</param> private static void ToYCbCr <TColor>( PixelAccessor <TColor> pixels, int x, int y, Block8x8F *yBlock, Block8x8F *cbBlock, Block8x8F *crBlock, PixelArea <TColor> rgbBytes) where TColor : struct, IPackedPixel, IEquatable <TColor> { float *yBlockRaw = (float *)yBlock; float *cbBlockRaw = (float *)cbBlock; float *crBlockRaw = (float *)crBlock; rgbBytes.Reset(); pixels.CopyRGBBytesStretchedTo(rgbBytes, y, x); byte *data = (byte *)rgbBytes.DataPointer; for (int j = 0; j < 8; j++) { int j8 = j * 8; for (int i = 0; i < 8; i++) { // Convert returned bytes into the YCbCr color space. Assume RGBA int r = data[0]; int g = data[1]; int b = data[2]; // Speed up the algorithm by removing floating point calculation // Scale by 65536, add .5F and truncate value. We use bit shifting to divide the result int y0 = 19595 * r; // (0.299F * 65536) + .5F int y1 = 38470 * g; // (0.587F * 65536) + .5F int y2 = 7471 * b; // (0.114F * 65536) + .5F int cb0 = -11057 * r; // (-0.168736F * 65536) + .5F int cb1 = 21710 * g; // (0.331264F * 65536) + .5F int cb2 = 32768 * b; // (0.5F * 65536) + .5F int cr0 = 32768 * r; // (0.5F * 65536) + .5F int cr1 = 27439 * g; // (0.418688F * 65536) + .5F int cr2 = 5329 * b; // (0.081312F * 65536) + .5F float yy = (y0 + y1 + y2) >> 16; float cb = 128 + ((cb0 - cb1 + cb2) >> 16); float cr = 128 + ((cr0 - cr1 - cr2) >> 16); int index = j8 + i; yBlockRaw[index] = yy; cbBlockRaw[index] = cb; crBlockRaw[index] = cr; data += 3; } } }
public void CopyStretchedRGBTo_FromOrigo <TPixel>(TestImageProvider <TPixel> provider) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> src = provider.GetImage()) using (Image <TPixel> dest = new Image <TPixel>(8, 8)) using (PixelArea <TPixel> area = new PixelArea <TPixel>(8, 8, ComponentOrder.Xyz)) using (PixelAccessor <TPixel> s = src.Lock()) using (PixelAccessor <TPixel> d = dest.Lock()) { s.CopyRGBBytesStretchedTo(area, 0, 0); d.CopyFrom(area, 0, 0); Assert.Equal(s[0, 0], d[0, 0]); Assert.Equal(s[7, 0], d[7, 0]); Assert.Equal(s[0, 7], d[0, 7]); Assert.Equal(s[7, 7], d[7, 7]); } }
/// <summary> /// Converts the 8x8 region of the image whose top-left corner is x,y to its YCbCr values. /// </summary> /// <typeparam name="TColor">The pixel format.</typeparam> /// <param name="pixels">The pixel accessor.</param> /// <param name="x">The x-position within the image.</param> /// <param name="y">The y-position within the image.</param> /// <param name="yBlock">The luminance block.</param> /// <param name="cbBlock">The red chroma block.</param> /// <param name="crBlock">The blue chroma block.</param> /// <param name="rgbBytes">Temporal <see cref="PixelArea{TColor}"/> provided by the caller</param> private static void ToYCbCr <TColor>( PixelAccessor <TColor> pixels, int x, int y, Block8x8F *yBlock, Block8x8F *cbBlock, Block8x8F *crBlock, PixelArea <TColor> rgbBytes) where TColor : struct, IPixel <TColor> { float *yBlockRaw = (float *)yBlock; float *cbBlockRaw = (float *)cbBlock; float *crBlockRaw = (float *)crBlock; rgbBytes.Reset(); pixels.CopyRGBBytesStretchedTo(rgbBytes, y, x); ref byte data0 = ref rgbBytes.Bytes[0];
public void CopyStretchedRGBTo_FromOrigo <TColor>(TestImageProvider <TColor> provider) where TColor : struct, IPackedPixel, IEquatable <TColor> { using (Image <TColor> src = provider.GetImage()) using (Image <TColor> dest = provider.Factory.CreateImage(8, 8)) using (PixelArea <TColor> area = new PixelArea <TColor>(8, 8, ComponentOrder.Xyz)) using (PixelAccessor <TColor> s = src.Lock()) using (PixelAccessor <TColor> d = dest.Lock()) { s.CopyRGBBytesStretchedTo(area, 0, 0); d.CopyFrom(area, 0, 0); Assert.Equal(s[0, 0], d[0, 0]); Assert.Equal(s[7, 0], d[7, 0]); Assert.Equal(s[0, 7], d[0, 7]); Assert.Equal(s[7, 7], d[7, 7]); } }
public void CopyStretchedRGBTo_WithOffset <TColor>(TestImageProvider <TColor> provider) where TColor : struct, IPackedPixel, IEquatable <TColor> { Image <TColor> src = provider.GetImage(); PixelArea <TColor> area = new PixelArea <TColor>(8, 8, ComponentOrder.Xyz); Image <TColor> dest = provider.Factory.CreateImage(8, 8); using (PixelAccessor <TColor> s = src.Lock()) { using (var d = dest.Lock()) { s.CopyRGBBytesStretchedTo(area, 7, 6); d.CopyFrom(area, 0, 0); Assert.Equal(s[6, 7], d[0, 0]); Assert.Equal(s[6, 8], d[0, 1]); Assert.Equal(s[7, 8], d[1, 1]); Assert.Equal(s[6, 9], d[0, 2]); Assert.Equal(s[6, 9], d[0, 3]); Assert.Equal(s[6, 9], d[0, 7]); Assert.Equal(s[7, 9], d[1, 2]); Assert.Equal(s[7, 9], d[1, 3]); Assert.Equal(s[7, 9], d[1, 7]); Assert.Equal(s[9, 9], d[3, 2]); Assert.Equal(s[9, 9], d[3, 3]); Assert.Equal(s[9, 9], d[3, 7]); Assert.Equal(s[9, 7], d[3, 0]); Assert.Equal(s[9, 7], d[4, 0]); Assert.Equal(s[9, 7], d[7, 0]); Assert.Equal(s[9, 9], d[3, 2]); Assert.Equal(s[9, 9], d[4, 2]); Assert.Equal(s[9, 9], d[7, 2]); Assert.Equal(s[9, 9], d[4, 3]); Assert.Equal(s[9, 9], d[7, 7]); } } }
public void CopyStretchedRGBTo_WithOffset <TPixel>(TestImageProvider <TPixel> provider) where TPixel : struct, IPixel <TPixel> { using (Image <TPixel> src = provider.GetImage()) using (PixelArea <TPixel> area = new PixelArea <TPixel>(8, 8, ComponentOrder.Xyz)) using (Image <TPixel> dest = new Image <TPixel>(8, 8)) using (PixelAccessor <TPixel> s = src.Lock()) using (PixelAccessor <TPixel> d = dest.Lock()) { s.CopyRGBBytesStretchedTo(area, 7, 6); d.CopyFrom(area, 0, 0); Assert.Equal(s[6, 7], d[0, 0]); Assert.Equal(s[6, 8], d[0, 1]); Assert.Equal(s[7, 8], d[1, 1]); Assert.Equal(s[6, 9], d[0, 2]); Assert.Equal(s[6, 9], d[0, 3]); Assert.Equal(s[6, 9], d[0, 7]); Assert.Equal(s[7, 9], d[1, 2]); Assert.Equal(s[7, 9], d[1, 3]); Assert.Equal(s[7, 9], d[1, 7]); Assert.Equal(s[9, 9], d[3, 2]); Assert.Equal(s[9, 9], d[3, 3]); Assert.Equal(s[9, 9], d[3, 7]); Assert.Equal(s[9, 7], d[3, 0]); Assert.Equal(s[9, 7], d[4, 0]); Assert.Equal(s[9, 7], d[7, 0]); Assert.Equal(s[9, 9], d[3, 2]); Assert.Equal(s[9, 9], d[4, 2]); Assert.Equal(s[9, 9], d[7, 2]); Assert.Equal(s[9, 9], d[4, 3]); Assert.Equal(s[9, 9], d[7, 7]); } }