public WicPlanarSplitter(WicPlanarTransform prev, WicPlane plane) : base(prev.Context)
        {
            Frame  = prev.Frame;
            Source = plane == WicPlane.Luma ? prev.SourceY : prev.SourceCbCr;

            Source.GetSize(out Context.Width, out Context.Height);
        }
Exemplo n.º 2
0
        unsafe public void CopyPixels(WicPlane plane, WICRect prc, uint cbStride, uint cbBufferSize, IntPtr pbBuffer)
        {
            if (lineBuffY.Array == null || (plane == WicPlane.Luma && prc.Y + prc.Height > loadedY) || (plane == WicPlane.Chroma && prc.Y + prc.Height > loadedC))
            {
                loadBuffer(plane, prc);
            }

            switch (plane)
            {
            case WicPlane.Luma:
                fixed(byte *pBuffY = lineBuffY.Array)
                for (int y = 0; y < prc.Height; y++)
                {
                    Buffer.MemoryCopy(pBuffY + (prc.Y - startY) * strideY + y * strideY + prc.X, (byte *)pbBuffer + y * cbStride, cbStride, prc.Width);
                }
                nextY = prc.Y + prc.Height - startY;

                break;

            case WicPlane.Chroma:
                fixed(byte *pBuffC = lineBuffC.Array)
                for (int y = 0; y < prc.Height; y++)
                {
                    Buffer.MemoryCopy(pBuffC + (prc.Y - startC) * strideC + y * strideC + prc.X * 2, (byte *)pbBuffer + y * cbStride, cbStride, prc.Width * 2);
                }
                nextC = prc.Y + prc.Height - startC;

                break;
            }
        }
Exemplo n.º 3
0
        public PlanarPixelSource(WicPlanarCache cache, WicPlane plane, WICBitmapPlaneDescription planeDesc)
        {
            Width  = planeDesc.Width;
            Height = planeDesc.Height;
            Format = PixelFormat.Cache[planeDesc.Format];

            cacheSource = cache;
            cachePlane  = plane;
        }
Exemplo n.º 4
0
        public WicPlanarSource(WicPlanarCacheSource cache, WicPlane plane, WICBitmapPlaneDescription planeDesc)
        {
            Width  = planeDesc.Width;
            Height = planeDesc.Height;
            Format = planeDesc.Format;

            cacheSource = cache;
            cachePlane  = plane;
        }
Exemplo n.º 5
0
        unsafe private void loadBuffer(WicPlane plane, WICRect prc)
        {
            if (lineBuffY.Array == null || nextY < buffHeightY / 4 || nextC < buffHeightC / 4)
            {
                if (lineBuffY.Array != null)
                {
                    buffHeightY = Math.Min(buffHeightY * 2, (int)scaledHeight);
                    buffHeightC = Math.Min(buffHeightC * 2, (int)Math.Ceiling(buffHeightY / subsampleRatioY));
                }

                var tbuffY = new ArraySegment <byte>(ArrayPool <byte> .Shared.Rent(buffHeightY * strideY), 0, buffHeightY * strideY);
                var tbuffC = new ArraySegment <byte>(ArrayPool <byte> .Shared.Rent(buffHeightC * strideC), 0, buffHeightC * strideC);

                if (lineBuffY.Array != null)
                {
                    fixed(byte *ptbuffY = tbuffY.Array, ptbuffC = tbuffC.Array, pcbuffY = lineBuffY.Array, pcbuffC = lineBuffC.Array)
                    {
                        Buffer.MemoryCopy(pcbuffY, ptbuffY, tbuffY.Array.Length, lineBuffY.Count);
                        Buffer.MemoryCopy(pcbuffC, ptbuffC, tbuffC.Array.Length, lineBuffC.Count);
                    }

                    ArrayPool <byte> .Shared.Return(lineBuffY.Array);

                    ArrayPool <byte> .Shared.Return(lineBuffC.Array);
                }

                lineBuffY = tbuffY;
                lineBuffC = tbuffC;
            }

            fixed(byte *pBuffY = lineBuffY.Array, pBuffC = lineBuffC.Array)
            {
                int offsY = 0, offsC = 0;

                if (startY == -1)
                {
                    startY = prc.Y;
                    if (startY % subsampleRatioY > 0)
                    {
                        startY = (int)(startY / subsampleRatioY) * (int)subsampleRatioY;
                    }

                    startC = (int)(startY / subsampleRatioY);
                }
                else if (nextY < buffHeightY || nextC < buffHeightC)
                {
                    int minY = (int)Math.Min(nextC * subsampleRatioY, nextY);
                    int minC = (int)(minY / subsampleRatioY);
                    minY = minC * (int)subsampleRatioY;

                    Buffer.MemoryCopy(pBuffY + minY * strideY, pBuffY, lineBuffY.Array.Length, (buffHeightY - minY) * strideY);
                    Buffer.MemoryCopy(pBuffC + minC * strideC, pBuffC, lineBuffC.Array.Length, (buffHeightC - minC) * strideC);

                    offsY = loadedY - startY - minY;
                    offsC = (int)(loadedY / subsampleRatioY) - startC - minC;

                    startY += minY;
                    startC += minC;

                    nextY -= minY;
                    nextC -= minC;
                }
                else
                {
                    startY += buffHeightY;
                    startC += buffHeightC;
                }

                var rect = new WICRect {
                    X      = scaledCrop.X,
                    Y      = Math.Max(0, Math.Max(scaledCrop.Y + startY + offsY, loadedY)),
                    Width  = scaledCrop.Width,
                    Height = Math.Min(buffHeightY - offsY, scaledCrop.Height - (plane == WicPlane.Luma ? prc.Y : (int)Math.Ceiling(prc.Y * subsampleRatioY)))
                };

                var planes = new[] {
                    new WICBitmapPlane {
                        Format = sourceY.Format.FormatGuid, pbBuffer = (IntPtr)(pBuffY + offsY * strideY), cbStride = (uint)strideY, cbBufferSize = (uint)lineBuffY.Count
                    },
                    new WICBitmapPlane {
                        Format = sourceC.Format.FormatGuid, pbBuffer = (IntPtr)(pBuffC + offsC * strideC), cbStride = (uint)strideC, cbBufferSize = (uint)lineBuffC.Count
                    }
                };

                sourceTransform.CopyPixels(rect, scaledWidth, scaledHeight, sourceTransformOptions, WICPlanarOptions.WICPlanarOptionsDefault, planes, (uint)planes.Length);
                loadedY = rect.Y + rect.Height - scaledCrop.Y;
                loadedC = (int)Math.Ceiling(loadedY / subsampleRatioY);
            }
        }
Exemplo n.º 6
0
 public PixelSource GetPlane(WicPlane plane) => plane == WicPlane.Luma ? sourceY : sourceC;
Exemplo n.º 7
0
 public IWICBitmapSource GetPlane(WicPlane plane) => plane == WicPlane.Luma ? sourceY : sourceC;
Exemplo n.º 8
0
        unsafe public void CopyPixels(WicPlane plane, WICRect prc, uint cbStride, uint cbBufferSize, IntPtr pbBuffer)
        {
            if (prc.X < 0 || prc.Y < 0 || prc.X + prc.Width > scaledWidth || prc.Y + prc.Height > scaledHeight)
            {
                throw new ArgumentOutOfRangeException(nameof(prc), "Requested rectangle does not fall within the image bounds");
            }

            bool load = (lineBuffY.Array == null || (plane == WicPlane.Luma && prc.Y + prc.Height > startY + buffHeightY) || (plane == WicPlane.Chroma && prc.Y + prc.Height > startC + buffHeightC));

            if (load && (lineBuffY.Array == null || posY < buffHeightY / 4 || posC < buffHeightC / 4))
            {
                if (lineBuffY.Array != null)
                {
                    buffHeightY = Math.Min(buffHeightY * 2, (int)scaledHeight);
                    buffHeightC = Math.Min(buffHeightC * 2, (int)Math.Ceiling(buffHeightY / subsampleRatioY));
                }

                var tbuffY = new ArraySegment <byte>(ArrayPool <byte> .Shared.Rent(buffHeightY * strideY), 0, buffHeightY * strideY);
                var tbuffC = new ArraySegment <byte>(ArrayPool <byte> .Shared.Rent(buffHeightC * strideC), 0, buffHeightC * strideC);

                if (lineBuffY.Array != null)
                {
                    fixed(byte *ptbuffY = tbuffY.Array, ptbuffC = tbuffC.Array, pcbuffY = lineBuffY.Array, pcbuffC = lineBuffC.Array)
                    {
                        Buffer.MemoryCopy(pcbuffY, ptbuffY, tbuffY.Array.Length, lineBuffY.Count);
                        Buffer.MemoryCopy(pcbuffC, ptbuffC, tbuffC.Array.Length, lineBuffC.Count);

                        var rect = new WICRect {
                            X = scaledCrop.X, Y = scaledCrop.Y + startY + posY, Width = scaledCrop.Width, Height = Math.Min(buffHeightY - posY, scaledCrop.Height - (plane == WicPlane.Luma ? prc.Y : (int)Math.Ceiling(prc.Y * subsampleRatioY)))
                        };

                        loadBuffer(ptbuffY + lineBuffY.Count, ptbuffC + lineBuffC.Count, rect);
                    }

                    load = false;

                    ArrayPool <byte> .Shared.Return(lineBuffY.Array);

                    ArrayPool <byte> .Shared.Return(lineBuffC.Array);
                }

                lineBuffY = tbuffY;
                lineBuffC = tbuffC;
            }

            fixed(byte *pBuffY = lineBuffY.Array, pBuffC = lineBuffC.Array)
            {
                if (load)
                {
                    int offsY = 0, offsC = 0;
                    if (startY == -1)
                    {
                        startY = prc.Y;
                        if (startY % subsampleRatioY > 0)
                        {
                            startY = (int)(startY / subsampleRatioY) * (int)subsampleRatioY;
                        }

                        startC = (int)(startY / subsampleRatioY);
                        posY   = prc.Y - startY;
                        posC   = (int)(posY / subsampleRatioY);
                    }
                    else if (posY < buffHeightY || posC < buffHeightC)
                    {
                        int posMin  = (int)Math.Min(posC * subsampleRatioY, posY);
                        int posMins = (int)(posMin / subsampleRatioY);
                        posMin = posMins * (int)subsampleRatioY;

                        Buffer.MemoryCopy(pBuffY + posMin * strideY, pBuffY, lineBuffY.Array.Length, (buffHeightY - posMin) * strideY);
                        Buffer.MemoryCopy(pBuffC + posMins * strideC, pBuffC, lineBuffC.Array.Length, (buffHeightC - posMins) * strideC);

                        startY += posMin;
                        startC += posMins;

                        posY -= posMin;
                        posC -= posMins;

                        offsY = buffHeightY - posMin;
                        offsC = buffHeightC - posMins;
                    }
                    else
                    {
                        startY += buffHeightY;
                        startC += buffHeightC;
                        posY    = posC = 0;
                    }

                    var rect = new WICRect {
                        X = scaledCrop.X, Y = scaledCrop.Y + startY + offsY, Width = scaledCrop.Width, Height = Math.Min(buffHeightY - offsY, scaledCrop.Height - (plane == WicPlane.Luma ? prc.Y : (int)Math.Ceiling(prc.Y * subsampleRatioY)))
                    };
                    loadBuffer(pBuffY + offsY * strideY, pBuffC + offsC * strideC, rect);
                }

                if (plane == WicPlane.Luma)
                {
                    for (int y = 0; y < prc.Height; y++)
                    {
                        Buffer.MemoryCopy(pBuffY + posY * strideY + y * strideY, (byte *)pbBuffer + y * cbStride, cbBufferSize, cbStride);
                    }
                    posY += prc.Height;
                }
                else
                {
                    for (int y = 0; y < prc.Height; y++)
                    {
                        Buffer.MemoryCopy(pBuffC + posC * strideC + y * strideC, (byte *)pbBuffer + y * cbStride, cbBufferSize, cbStride);
                    }
                    posC += prc.Height;
                }
            }
        }
Exemplo n.º 9
0
 public IWICBitmapSource GetPlane(WicPlane plane)
 {
     return(plane == WicPlane.Luma ? sourceY : sourceC);
 }
Exemplo n.º 10
0
        unsafe public void CopyPixels(WicPlane plane, WICRect prc, uint cbStride, uint cbBufferSize, IntPtr pbBuffer)
        {
            var load = (lineBuffY == null || (plane == WicPlane.Luma && prc.Y + prc.Height > startY + buffHeightY) || (plane == WicPlane.Chroma && prc.Y + prc.Height > startC + buffHeightC));

            if (load && (lineBuffY == null || posY < buffHeightY / 4 || posC < buffHeightC / 4))
            {
                if (lineBuffY != null)
                {
                    buffHeightY *= 2;
                    buffHeightC *= 2;
                }

                var tbuffY = new byte[strideY * buffHeightY];
                var tbuffC = new byte[strideC * buffHeightC];

                if (lineBuffY != null)
                {
                    fixed(byte *ptbuffY = tbuffY, ptbuffC = tbuffC, pcbuffY = lineBuffY, pcbuffC = lineBuffC)
                    {
                        Buffer.MemoryCopy(pcbuffY, ptbuffY, tbuffY.Length, lineBuffY.Length);
                        Buffer.MemoryCopy(pcbuffC, ptbuffC, tbuffC.Length, lineBuffC.Length);

                        var rect = new WICRect {
                            X = scaledCrop.X, Y = scaledCrop.Y + startY + posY, Width = scaledCrop.Width, Height = Math.Min((int)buffHeightY - posY, scaledCrop.Height - prc.Y)
                        };

                        loadBuffer(ptbuffY + (buffHeightY / 2) * strideY, ptbuffC + (buffHeightC / 2) * strideC, rect);
                    }

                    load = false;
                }

                lineBuffY = tbuffY;
                lineBuffC = tbuffC;
            }

            fixed(byte *pBuffY = lineBuffY, pBuffC = lineBuffC)
            {
                if (load)
                {
                    int offsY = 0, offsC = 0;
                    if (startY == -1)
                    {
                        startY = prc.Y;
                        if (startY % subsampleRatioY > 0)
                        {
                            startY = (int)(startY / subsampleRatioY) * (int)subsampleRatioY;
                        }

                        startC = (int)(startY / subsampleRatioY);
                        posY   = prc.Y - startY;
                        posC   = (int)(posY / subsampleRatioY);
                    }
                    else if (posY < buffHeightY || posC < buffHeightC)
                    {
                        int posMin  = (int)Math.Min(posC * subsampleRatioY, posY);
                        int posMins = (int)(posMin / subsampleRatioY);
                        posMin = posMins * (int)subsampleRatioY;

                        Buffer.MemoryCopy(pBuffY + posMin * strideY, pBuffY, lineBuffY.Length, (buffHeightY - posMin) * strideY);
                        Buffer.MemoryCopy(pBuffC + posMins * strideC, pBuffC, lineBuffC.Length, (buffHeightC - posMins) * strideC);

                        startY += posMin;
                        startC += posMins;

                        posY -= posMin;
                        posC -= posMins;

                        offsY = (int)buffHeightY - posMin;
                        offsC = (int)buffHeightC - posMins;
                    }
                    else
                    {
                        startY += (int)buffHeightY;
                        startC += (int)buffHeightC;
                        posY    = posC = 0;
                    }

                    var rect = new WICRect {
                        X = scaledCrop.X, Y = scaledCrop.Y + startY + posY, Width = scaledCrop.Width, Height = Math.Min((int)buffHeightY - posY, scaledCrop.Height - prc.Y)
                    };
                    loadBuffer(pBuffY + offsY * strideY, pBuffC + offsC * strideC, rect);
                }

                if (plane == WicPlane.Luma)
                {
                    Buffer.MemoryCopy(pBuffY + (posY * strideY), (void *)pbBuffer, cbBufferSize, cbBufferSize);
                    posY += prc.Height;
                }
                else
                {
                    Buffer.MemoryCopy(pBuffC + (posC * strideC), (void *)pbBuffer, cbBufferSize, cbBufferSize);
                    posC += prc.Height;
                }
            }
        }