예제 #1
0
        /// <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;
                }
            }
        }
예제 #2
0
        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]);
                            }
        }
예제 #3
0
        /// <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];
예제 #4
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]);
                            }
        }
예제 #5
0
        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]);
                }
            }
        }
예제 #6
0
        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]);
                            }
        }