示例#1
0
        /// <summary> Fill this image from another source at reduced resolution.  Pixel
        /// averaging will be used.
        ///
        /// </summary>
        /// <param name="src">image map to reduce
        /// </param>
        /// <param name="subsample">rate to subsample
        /// </param>
        /// <param name="pdr">target bounds
        /// </param>
        public virtual void Downsample(Map src, int subsample, Rectangle pdr)
        {
            Rectangle rect = new Rectangle(0, 0, ((src.ImageWidth + subsample) - 1) / subsample,
                                           ((src.ImageHeight + subsample) - 1) / subsample);

            if (pdr != null)
            {
                if ((pdr.Right < rect.Right) || (pdr.Bottom < rect.Bottom) || (pdr.Left > rect.Left) || (pdr.Top > rect.Top))
                {
                    throw new ArgumentException("Specified rectangle overflows destination PixelMap");
                }
                rect = pdr;
            }

            Init(rect.Height, rect.Width, null);

            int sy   = rect.Bottom * subsample;
            int sxz  = rect.Right * subsample;
            int sidx = src.RowOffset(sy);
            int didx = 0;

            PixelReference sptr = src.CreateGPixelReference(0);
            PixelReference dptr = CreateGPixelReference(0);

            for (int y = 0; y < ImageHeight; y++)
            {
                int sx = sxz;

                for (int x = ImageWidth; x-- > 0; dptr.IncOffset())
                {
                    int r    = 0;
                    int g    = 0;
                    int b    = 0;
                    int s    = 0;
                    int kidx = sidx;
                    int lsy  = sy + subsample;

                    if (lsy > src.ImageHeight)
                    {
                        lsy = src.ImageHeight;
                    }

                    int lsx = sx + subsample;

                    if (lsx > src.ImageWidth)
                    {
                        lsx = src.ImageWidth;
                    }

                    for (int rsy = sy; rsy < lsy; rsy++)
                    {
                        sptr.SetOffset(kidx + sx);
                        if (!IsRampNeeded)
                        {
                            for (int rsx = lsx - sx; rsx-- > 0; sptr.IncOffset())
                            {
                                r += sptr.Red;
                                g += sptr.Green;
                                b += sptr.Blue;
                                s++;
                            }
                        }
                        else
                        {
                            for (int rsx = lsx - sx; rsx-- > 0; sptr.IncOffset())
                            {
                                Pixel pix = src.PixelRamp(sptr);
                                r += pix.Red;
                                g += pix.Green;
                                b += pix.Blue;
                                s++;
                            }
                        }

                        kidx += src.GetRowSize();
                    }

                    if (s >= _invmap.Length)
                    {
                        dptr.SetBGR(b / s, g / s, r / s);
                    }
                    else
                    {
                        dptr.SetBGR(((b * _invmap[s]) + 32768) >> 16, ((g * _invmap[s]) + 32768) >> 16,
                                    ((r * _invmap[s]) + 32768) >> 16);
                    }

                    sx += subsample;
                }

                sy   += subsample;
                sidx += src.RowOffset(subsample);
                dptr.SetOffset(didx += GetRowSize());
            }
        }
示例#2
0
        /// <summary> Fill this image from another source at reduced resolution of 4 vertical
        /// pixels to 3.  An extrapulating pixel averaging algorithm is used.
        ///
        /// </summary>
        /// <param name="src">image map to reduce
        /// </param>
        /// <param name="pdr">target bounds
        ///
        /// </param>
        /// <throws>  IllegalArgumentException if the target rectangle is out of bounds </throws>
        public virtual void Downsample43(Map src, Rectangle pdr)
        {
            int srcwidth  = src.ImageWidth;
            int srcheight = src.ImageHeight;
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            int destwidth = (int)Math.Ceiling(srcwidth * 0.75D);
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            int       destheight = (int)Math.Ceiling(srcheight * 0.75D);
            Rectangle rect       = new Rectangle(0, 0, destwidth, destheight);

            if (pdr != null)
            {
                if ((pdr.Right < rect.Right) || (pdr.Bottom < rect.Bottom) || (pdr.Left > rect.Left) || (pdr.Top > rect.Top))
                {
                    throw new ArgumentException("rectangle out of bounds" + "pdr=(" + pdr.Right + "," + pdr.Bottom + "," +
                                                pdr.Left + "," + pdr.Top + "),rect=(" + rect.Right + "," + rect.Bottom +
                                                "," + rect.Left + "," + rect.Top + ")");
                }

                rect       = pdr;
                destwidth  = rect.Width;
                destheight = rect.Height;
            }

            Init(destheight, destwidth, null);

            int sy = rect.Bottom / 3;
            int dy = rect.Bottom - (3 * sy);

            //    if(dy < 0)
            //    {
            //      sy--;
            //      dy += 3;
            //    }

            int sxz = rect.Right / 3;
            int dxz = rect.Right - (3 * sxz);

            if (dxz < 0)
            {
                sxz--;
                dxz += 3;
            }

            sxz *= 4;
            sy  *= 4;

            PixelReference spix0 = src.CreateGPixelReference(0);
            PixelReference spix1 = src.CreateGPixelReference(0);
            PixelReference spix2 = src.CreateGPixelReference(0);
            PixelReference spix3 = src.CreateGPixelReference(0);
            PixelReference dpix0 = CreateGPixelReference(0);
            PixelReference dpix1 = CreateGPixelReference(0);
            PixelReference dpix2 = CreateGPixelReference(0);

            while (dy < destheight)
            {
                spix0.SetOffset(sy++, sxz);

                if (sy >= srcheight)
                {
                    sy--;
                }

                spix1.SetOffset(sy++, sxz);

                if (sy >= srcheight)
                {
                    sy--;
                }

                spix2.SetOffset(sy++, sxz);

                if (sy >= srcheight)
                {
                    sy--;
                }

                spix3.SetOffset(sy++, sxz);

                dpix0.SetOffset((dy < 0) ? 0 : dy, dxz);

                if (++dy >= destheight)
                {
                    dy--;
                }

                dpix1.SetOffset((dy < 0) ? 0 : dy, dxz);

                if (++dy >= destheight)
                {
                    dy--;
                }

                dpix2.SetOffset(dy++, dxz);
                int dx = dxz;
                int sx = sxz;

                Pixel pix0 = src.PixelRamp(spix0);
                Pixel pix1 = src.PixelRamp(spix1);
                Pixel pix2 = src.PixelRamp(spix2);
                Pixel pix3 = src.PixelRamp(spix3);
                while (dx < destwidth)
                {
                    int s00b = pix0.Blue;
                    int s00g = pix0.Green;
                    int s00r = pix0.Red;
                    int s01b = pix1.Blue;
                    int s01g = pix1.Green;
                    int s01r = pix1.Red;
                    int s02b = pix2.Blue;
                    int s02g = pix2.Green;
                    int s02r = pix2.Red;
                    int s03b = pix3.Blue;
                    int s03g = pix3.Green;
                    int s03r = pix3.Red;

                    if (++sx < srcwidth)
                    {
                        spix0.IncOffset();
                        spix1.IncOffset();
                        spix2.IncOffset();
                        spix3.IncOffset();
                        pix0 = src.PixelRamp(spix0);
                        pix1 = src.PixelRamp(spix1);
                        pix2 = src.PixelRamp(spix2);
                        pix3 = src.PixelRamp(spix3);
                    }

                    int s10b = pix0.Blue;
                    int s10g = pix0.Green;
                    int s10r = pix0.Red;
                    int s11b = pix1.Blue;
                    int s11g = pix1.Green;
                    int s11r = pix1.Red;
                    int s12b = pix2.Blue;
                    int s12g = pix2.Green;
                    int s12r = pix2.Red;
                    int s13b = pix3.Blue;
                    int s13g = pix3.Green;
                    int s13r = pix3.Red;

                    if (++sx < srcwidth)
                    {
                        spix0.IncOffset();
                        spix1.IncOffset();
                        spix2.IncOffset();
                        spix3.IncOffset();
                        pix0 = src.PixelRamp(spix0);
                        pix1 = src.PixelRamp(spix1);
                        pix2 = src.PixelRamp(spix2);
                        pix3 = src.PixelRamp(spix3);
                    }

                    int s20b = pix0.Blue;
                    int s20g = pix0.Green;
                    int s20r = pix0.Red;
                    int s21b = pix1.Blue;
                    int s21g = pix1.Green;
                    int s21r = pix1.Red;
                    int s22b = pix2.Blue;
                    int s22g = pix2.Green;
                    int s22r = pix2.Red;
                    int s23b = pix3.Blue;
                    int s23g = pix3.Green;
                    int s23r = pix3.Red;

                    if (++sx < srcwidth)
                    {
                        spix0.IncOffset();
                        spix1.IncOffset();
                        spix2.IncOffset();
                        spix3.IncOffset();
                        pix0 = src.PixelRamp(spix0);
                        pix1 = src.PixelRamp(spix1);
                        pix2 = src.PixelRamp(spix2);
                        pix3 = src.PixelRamp(spix3);
                    }

                    int s30b = pix0.Blue;
                    int s30g = pix0.Green;
                    int s30r = pix0.Red;
                    int s31b = pix1.Blue;
                    int s31g = pix1.Green;
                    int s31r = pix1.Red;
                    int s32b = pix2.Blue;
                    int s32g = pix2.Green;
                    int s32r = pix2.Red;
                    int s33b = pix3.Blue;
                    int s33g = pix3.Green;
                    int s33r = pix3.Red;

                    if (++sx < srcwidth)
                    {
                        spix0.IncOffset();
                        spix1.IncOffset();
                        spix2.IncOffset();
                        spix3.IncOffset();
                        pix0 = src.PixelRamp(spix0);
                        pix1 = src.PixelRamp(spix1);
                        pix2 = src.PixelRamp(spix2);
                        pix3 = src.PixelRamp(spix3);
                    }

                    dpix0.Blue  = (sbyte)(((11 * s00b) + (2 * (s01b + s10b)) + s11b + 8) >> 4);
                    dpix0.Green = (sbyte)(((11 * s00g) + (2 * (s01g + s10g)) + s11g + 8) >> 4);
                    dpix0.Red   = (sbyte)(((11 * s00r) + (2 * (s01r + s10r)) + s11r + 8) >> 4);
                    dpix1.Blue  = (sbyte)(((7 * (s01b + s02b)) + s11b + s12b + 8) >> 4);
                    dpix1.Green = (sbyte)(((7 * (s01g + s02g)) + s11g + s12g + 8) >> 4);
                    dpix1.Red   = (sbyte)(((7 * (s01r + s02r)) + s11r + s12r + 8) >> 4);
                    dpix2.Blue  = (sbyte)(((11 * s03b) + (2 * (s02b + s13b)) + s12b + 8) >> 4);
                    dpix2.Green = (sbyte)(((11 * s03g) + (2 * (s02g + s13g)) + s12g + 8) >> 4);
                    dpix2.Red   = (sbyte)(((11 * s03r) + (2 * (s02r + s13r)) + s12r + 8) >> 4);

                    if (++dx < destwidth)
                    {
                        dpix0.IncOffset();
                        dpix1.IncOffset();
                        dpix2.IncOffset();
                    }

                    dpix0.Blue  = (sbyte)(((7 * (s10b + s20b)) + s11b + s21b + 8) >> 4);
                    dpix0.Green = (sbyte)(((7 * (s10g + s20g)) + s11g + s21g + 8) >> 4);
                    dpix0.Red   = (sbyte)(((7 * (s10r + s20r)) + s11r + s21r + 8) >> 4);
                    dpix1.Blue  = (sbyte)((s12b + s22b + s11b + s21b + 2) >> 2);
                    dpix1.Green = (sbyte)((s12g + s22g + s11g + s21g + 2) >> 2);
                    dpix1.Red   = (sbyte)((s12r + s22r + s11r + s21r + 2) >> 2);
                    dpix2.Blue  = (sbyte)(((7 * (s13b + s23b)) + s12b + s22b + 8) >> 4);
                    dpix2.Green = (sbyte)(((7 * (s13g + s23g)) + s12g + s22g + 8) >> 4);
                    dpix2.Red   = (sbyte)(((7 * (s13r + s23r)) + s12r + s22r + 8) >> 4);

                    if (++dx < destwidth)
                    {
                        dpix0.IncOffset();
                        dpix1.IncOffset();
                        dpix2.IncOffset();
                    }

                    dpix0.Blue  = (sbyte)(((11 * s30b) + (2 * (s31b + s20b)) + s21b + 8) >> 4);
                    dpix0.Green = (sbyte)(((11 * s30g) + (2 * (s31g + s20g)) + s21g + 8) >> 4);
                    dpix0.Red   = (sbyte)(((11 * s30r) + (2 * (s31r + s20r)) + s21r + 8) >> 4);
                    dpix1.Blue  = (sbyte)(((7 * (s31b + s32b)) + s21b + s22b + 8) >> 4);
                    dpix1.Green = (sbyte)(((7 * (s31g + s32g)) + s21g + s22g + 8) >> 4);
                    dpix1.Red   = (sbyte)(((7 * (s31r + s32r)) + s21r + s22r + 8) >> 4);
                    dpix2.Blue  = (sbyte)(((11 * s33b) + (2 * (s32b + s23b)) + s22b + 8) >> 4);
                    dpix2.Green = (sbyte)(((11 * s33g) + (2 * (s32g + s23g)) + s22g + 8) >> 4);
                    dpix2.Red   = (sbyte)(((11 * s33r) + (2 * (s32r + s23r)) + s22r + 8) >> 4);

                    if (++dx < destwidth)
                    {
                        dpix0.IncOffset();
                        dpix1.IncOffset();
                        dpix2.IncOffset();
                    }
                }
            }
        }
示例#3
0
        /// <summary> Insert the specified bitmap with the specified color.
        ///
        /// </summary>
        /// <param name="bm">bitmap to insert
        /// </param>
        /// <param name="xpos">horizontal position
        /// </param>
        /// <param name="ypos">vertical position
        /// </param>
        /// <param name="color">color to insert bitmap with
        /// </param>
        public virtual void Blit(Bitmap bm, int xpos, int ypos, Pixel color)
        {
            // Check
            if (color == null)
            {
                return;
            }

            // Compute number of rows and columns
            int xrows = ypos + bm.ImageHeight;

            if (xrows > ImageHeight)
            {
                xrows = ImageHeight;
            }

            if (ypos > 0)
            {
                xrows -= ypos;
            }

            int xcolumns = xpos + bm.ImageWidth;

            if (xcolumns > ImageWidth)
            {
                xcolumns = ImageWidth;
            }

            if (xpos > 0)
            {
                xcolumns -= xpos;
            }

            if ((xrows <= 0) || (xcolumns <= 0))
            {
                return;
            }

            // Precompute multiplier map
            int maxgray = bm.Grays - 1;

            int[] multiplier = new int[maxgray];

            for (int i = 0; i < maxgray; i++)
            {
                multiplier[i] = 0x10000 - ((i << 16) / maxgray);
            }

            // Cache target color
            int gr = color.Red;
            int gg = color.Green;
            int gb = color.Blue;

            // Compute starting point
            int src = bm.RowOffset((ypos < 0) ? (-ypos) : 0) - ((xpos < 0) ? xpos : 0);
            int dst = ((ypos > 0) ? RowOffset(ypos) : 0) + ((xpos > 0) ? xpos : 0);

            PixelReference dstPixel = CreateGPixelReference(dst);

            // Loop over rows
            for (int y = 0; y < xrows; y++)
            {
                // Loop over columns
                dstPixel.SetOffset(dst);

                for (int x = 0; x < xcolumns; dstPixel.IncOffset())
                {
                    int srcpix = bm.GetByteAt(src + (x++));

                    // Perform pixel operation
                    if (srcpix != 0)
                    {
                        if (srcpix >= maxgray)
                        {
                            dstPixel.SetBGR(gb, gg, gr);
                        }
                        else
                        {
                            int level0 = multiplier[srcpix];
                            int level1 = 0x10000 - level0;
                            dstPixel.SetBGR(_clip[((dstPixel.Blue * level0) + (gb * level1)) >> 16],
                                            _clip[((dstPixel.Green * level0) + (gg * level1)) >> 16],
                                            _clip[((dstPixel.Red * level0) + (gr * level1)) >> 16]);
                        }
                    }
                }

                // Next line
                dst += GetRowSize();
                src += bm.GetRowSize();
            }
        }
示例#4
0
 internal static Graphics.Pixel InvertColor(Graphics.Pixel color)
 {
     return(new Graphics.Pixel((sbyte)(color.Blue ^ unchecked ((sbyte)0xff)), (sbyte)(color.Green ^ unchecked ((sbyte)0xff)), (sbyte)(color.Red ^ unchecked ((sbyte)0xff))));
 }
示例#5
0
        public static unsafe Bitmap BuildImage(this DjvuImage image, int subsample = 1)
        {
            Verify.SubsampleRange(subsample);

            lock (image.LoadingLock)
            {
                Bitmap background = image.GetBackgroundImage(subsample, true);

                // TODO ETW logging goes here

                using (Bitmap foreground = image.GetForegroundImage(subsample, true))
                {
                    using (Bitmap mask = image.GetMaskImage(subsample, true))
                    {
                        image.HasLoaded = true;

                        BitmapData backgroundData =
                            background.LockBits(new Rectangle(0, 0, background.Width, background.Height),
                                                ImageLockMode.ReadWrite, background.PixelFormat);
                        int backgroundPixelSize = GetPixelSize(backgroundData.PixelFormat);

                        BitmapData foregroundData =
                            foreground.LockBits(new Rectangle(0, 0, foreground.Width, foreground.Height),
                                                ImageLockMode.ReadOnly, foreground.PixelFormat);
                        int foregroundPixelSize = GetPixelSize(foregroundData.PixelFormat);

                        BitmapData maskData = mask.LockBits(new Rectangle(0, 0, mask.Width, mask.Height),
                                                            ImageLockMode.ReadOnly, mask.PixelFormat);

                        //int maskPixelSize = GetPixelSize(maskData);

                        int bgndHeight = background.Height;
                        int bgndWidth  = background.Width;

                        int fgndHeight = foreground.Height;
                        int fgndWidth  = foreground.Width;

                        int maskHeight = mask.Height;
                        int maskWidth  = mask.Width;

                        int maskbgnH = maskHeight / bgndHeight;
                        int maskfgnH = maskHeight / fgndHeight;

                        int maskbgnW = maskWidth / bgndWidth;
                        int maskfgnW = maskWidth / fgndWidth;

                        //Parallel.For(
                        //    0,
                        //    height,
                        //    y =>
                        //    {

                        for (int y = 0, yf = 0, yb = 0; y < maskHeight && yb < bgndHeight && yf < fgndHeight; ++y, yf = yb = y)
                        {
                            byte *maskRow = (byte *)maskData.Scan0 + (y * maskData.Stride);
                            DjvuNet.Graphics.Pixel *backgroundRow = (DjvuNet.Graphics.Pixel *)(backgroundData.Scan0 + (yb * backgroundData.Stride));
                            DjvuNet.Graphics.Pixel *foregroundRow = (DjvuNet.Graphics.Pixel *)(foregroundData.Scan0 + (yf * foregroundData.Stride));

                            for (int x = 0, xf = 0, xb = 0; x < bgndWidth && xb < maskWidth && xf < fgndWidth; x++)
                            {
                                // Check if the mask byte is set
                                if (maskRow[x] > 0)
                                {
                                    DjvuNet.Graphics.Pixel xF = foregroundRow[xf];

                                    if (image.IsInverted)
                                    {
                                        backgroundRow[xb] = InvertColor(xF);
                                    }
                                    else
                                    {
                                        backgroundRow[xb] = xF;
                                    }
                                }
                                else if (image.IsInverted)
                                {
                                    backgroundRow[xb] = InvertColor(backgroundRow[xb]);
                                }

                                if (x >= 0)
                                {
                                    if (x % maskbgnW == 0)
                                    {
                                        xb++;
                                    }

                                    if (x % maskfgnW == 0)
                                    {
                                        xf++;
                                    }
                                }
                            }

                            if (y >= 0)
                            {
                                if (y % maskbgnH == 0)
                                {
                                    yb++;
                                }

                                if (y % maskfgnH == 0)
                                {
                                    yf++;
                                }
                            }
                        }
                        //});

                        mask.UnlockBits(maskData);
                        foreground.UnlockBits(foregroundData);
                        background.UnlockBits(backgroundData);

                        return(background);
                    }
                }
            }
        }
示例#6
0
 /// <summary> Overwrites #p# with the color located at position #index# in the
 /// palette.
 ///
 /// </summary>
 /// <param name="index">DOCUMENT ME!
 /// </param>
 /// <param name="p">DOCUMENT ME!
 /// </param>
 public void index_to_color(int index, DjvuNet.Graphics.Pixel p)
 {
     p.CopyFrom(PaletteColors[index]);
 }
示例#7
0
        public void Scale(Rectangle srcRect, IPixelMap srcMap, Rectangle targetRect, IPixelMap targetMap)
        {
            // Parameter validation
            if ((srcRect.Width != srcMap.Width) || (srcRect.Height != srcMap.Height))
            {
                throw new DjvuArgumentException("Invalid rectangle", nameof(srcRect));
            }

            // Compute rectangles
            Rectangle required_red = new Rectangle();
            Rectangle sourceRect   = CreateRectangles(targetRect, required_red);

            if ((srcRect.XMin > sourceRect.XMin) || (srcRect.YMin > sourceRect.YMin) ||
                (srcRect.XMax < sourceRect.XMax) || (srcRect.YMax < sourceRect.YMax))
            {
                throw new DjvuArgumentException("Invalid rectangle", nameof(srcRect));
            }

            // Adjust output pixmap
            if ((targetRect.Width != (int)targetMap.Width) || (targetRect.Height != (int)targetMap.Height))
            {
                targetMap.Init(targetRect.Height, targetRect.Width, null);
            }

            // Prepare temp stuff
            int bufw = required_red.Width;

            Pixel[] lbuffer = new Pixel[bufw + 2];

            try
            {
                if ((_XShift > 0) || (_YShift > 0))
                {
                    _PixelMap1 = new PixelMap().Init(1, bufw, null);
                    _PixelMap2 = new PixelMap().Init(2, bufw, null);
                    _L1        = _L2 = -1;
                }

                IPixelReference upper = srcMap.CreateGPixelReference(0, 0);
                IPixelReference lower = srcMap.CreateGPixelReference(0, 0);
                IPixelReference dest  = targetMap.CreateGPixelReference(0, 0);

                // Loop on output lines
                for (int y = targetRect.YMin; y < targetRect.YMax; y++)
                {
                    // Perform vertical interpolation
                    {
                        int fy  = _VCoord[y];
                        int fy1 = fy >> FRACBITS;
                        int fy2 = fy1 + 1;

                        // Obtain upper and lower line in reduced image
                        if ((_XShift > 0) || (_YShift > 0))
                        {
                            lower = GetLine(fy1, required_red, srcRect, srcMap);
                            upper = GetLine(fy2, required_red, srcRect, srcMap);
                        }
                        else
                        {
                            int dx = required_red.XMin - srcRect.XMin;

                            if (required_red.YMin > fy1)
                            {
                                fy1 = required_red.YMin;
                            }

                            if (required_red.YMax <= fy2)
                            {
                                fy2 = required_red.YMax - 1;
                            }

                            lower.SetOffset(fy1 - srcRect.YMin, dx);
                            // srcMap.CreateGPixelReference(fy1 - srcRect.YMin, dx);
                            upper.SetOffset(fy2 - srcRect.YMin, dx);
                            // srcMap.CreateGPixelReference(fy2 - srcRect.YMin, dx);
                        }

                        // Compute line
                        int     idest  = 1;
                        short[] deltas = interp[fy & FRACMASK];

                        unsafe
                        {
                            for (int edest = idest + bufw; idest < edest; upper.IncOffset(), lower.IncOffset())
                            {
                                Pixel destPix = lbuffer[idest++];

                                int    color    = 0;
                                sbyte *colorPtr = (sbyte *)&color;
                                // Skip alpha and set pointer to Blue
                                colorPtr++;
                                *colorPtr  = lower.Blue;
                                *colorPtr += (sbyte)deltas[(256 + upper.Blue) - *colorPtr];

                                // Set pointer to Green
                                colorPtr++;
                                *colorPtr  = lower.Green;
                                *colorPtr += (sbyte)deltas[(256 + upper.Green) - *colorPtr];

                                // Set pointer to Red
                                colorPtr++;
                                *colorPtr  = lower.Red;
                                *colorPtr += (sbyte)deltas[(256 + upper.Red) - *colorPtr];

                                //Pixel d = (Pixel) lower.ToPixel();
                                //destPix.SetBGR(d);
                                destPix.SetBGR(*colorPtr);
                            }
                        }
                    }

                    // Perform horizontal interpolation
                    {
                        // Prepare for side effects
                        lbuffer[0] = lbuffer[1];

                        // lbuffer[bufw] = lbuffer[bufw];
                        int line = 1 - required_red.XMin;
                        dest.SetOffset(y - targetRect.YMin, 0);
                        //= targetMap.CreateGPixelReference(y - targetRect.YMin, 0);

                        // Loop horizontally
                        unsafe
                        {
                            for (int x = targetRect.XMin; x < targetRect.XMax; x++)
                            {
                                int     n      = _HCoord[x];
                                int     lowerl = line + (n >> FRACBITS);
                                Pixel   lower0 = lbuffer[lowerl];
                                Pixel   lower1 = lbuffer[lowerl + 1];
                                short[] deltas = interp[n & FRACMASK];

                                int    color    = 0;
                                sbyte *colorPtr = (sbyte *)&color;
                                // Skip alpha and set pointer to Blue
                                colorPtr++;
                                *colorPtr  = lower0.Blue;
                                *colorPtr += (sbyte)deltas[(256 + lower1.Blue) - *colorPtr];

                                // Set pointer to Green
                                colorPtr++;
                                *colorPtr  = lower0.Green;
                                *colorPtr += (sbyte)deltas[(256 + lower1.Green) - *colorPtr];

                                // Set pointer to Red
                                colorPtr++;
                                *colorPtr  = lower0.Red;
                                *colorPtr += (sbyte)deltas[(256 + lower1.Red) - *colorPtr];

                                dest.SetBGR(*colorPtr);
                                dest.IncOffset();
                            }
                        }
                    }
                }
            }
            finally
            {
                _PixelMap1 = null;
                _PixelMap2 = null;
            }
        }