/// <summary> Initialize this PixelMap from another image map. /// /// </summary> /// <param name="ref">image map to initialize from /// /// </param> /// <returns> the initialized PixelMap /// </returns> public virtual PixelMap Init(Map ref_Renamed) { Init(ref_Renamed.ImageHeight, ref_Renamed.ImageWidth, ((null))); PixelReference pixel = CreateGPixelReference(0); if ((ImageHeight > 0) && (ImageWidth > 0)) { PixelReference refPixel = (ref_Renamed).CreateGPixelReference(0); for (int y = 0; y < ImageHeight; y++) { pixel.SetOffset(y, 0); refPixel.SetOffset(y, 0); if (!IsRampNeeded) { for (int x = ImageWidth; x-- > 0; pixel.IncOffset(), refPixel.IncOffset()) { pixel.CopyFrom(refPixel); } } else { for (int x = ImageWidth; x-- > 0; pixel.IncOffset(), refPixel.IncOffset()) { pixel.CopyFrom(ref_Renamed.PixelRamp(refPixel)); } } } } return(this); }
/// <summary> Fills an array of pixels from the specified values. /// /// </summary> /// <param name="x">the x-coordinate of the upper-left corner of the region of /// pixels /// </param> /// <param name="y">the y-coordinate of the upper-left corner of the region of /// pixels /// </param> /// <param name="w">the width of the region of pixels /// </param> /// <param name="h">the height of the region of pixels /// </param> /// <param name="pixels">the array of pixels /// </param> /// <param name="off">the offset into the pixel array /// </param> /// <param name="scansize">the distance from one row of pixels to the next in the /// array /// </param> public void FillRgbPixels(int x, int y, int w, int h, int[] pixels, int off, int scansize) { int yrev = _parent.ImageHeight - y; if (!_parent.IsRampNeeded) { for (int y0 = yrev; y0-- > (yrev - h); off += scansize) { for (int i = off, j = (_parent.RowOffset(y0) + x) * _ncolors, k = w; k > 0; k--, j += _ncolors) { pixels[i++] = unchecked ((int)0xff000000) | (0xff0000 & (_parent.Data[j + _redOffset] << 16)) | (0xff00 & (_parent.Data[j + _greenOffset] << 8)) | (0xff & _parent.Data[j + _blueOffset]); } } } else { PixelReference ref_Renamed = _parent.CreateGPixelReference(0); for (int y0 = yrev; y0-- > (yrev - h); off += scansize) { ref_Renamed.SetOffset(y0, x); for (int i = off, k = w; k > 0; k--, ref_Renamed.IncOffset()) { pixels[i++] = _parent.PixelRamp(ref_Renamed).GetHashCode(); } } } }
/// <summary> Copy the pixel values. /// /// </summary> /// <param name="ref">pixel to copy /// </param> public void SetPixels(PixelReference ref_Renamed, int length) { if (ref_Renamed._ncolors != _ncolors || ref_Renamed._blueOffset != _blueOffset || ref_Renamed._greenOffset != _greenOffset || ref_Renamed._redOffset != _redOffset) { while (length-- > 0) { CopyFrom(ref_Renamed); ref_Renamed.IncOffset(); IncOffset(); } } else { Array.Copy(ref_Renamed._parent.Data, ref_Renamed._offset, _parent.Data, _offset, length * _ncolors); ref_Renamed.IncOffset(length); IncOffset(length); } }
/// <summary> Insert the reference map at the specified location. /// /// </summary> /// <param name="ref">map to insert /// </param> /// <param name="dx">horizontal position to insert at /// </param> /// <param name="dy">vertical position to insert at /// </param> public override void Fill(Map ref_Renamed, int dx, int dy) { int x0 = (dx > 0) ? dx : 0; int y0 = (dy > 0) ? dy : 0; int x1 = (dx < 0) ? (-dx) : 0; int y1 = (dy < 0) ? (-dy) : 0; int w0 = ImageWidth - x0; int w1 = ref_Renamed.ImageWidth - x1; int w = (w0 < w1) ? w0 : w1; int h0 = ImageHeight - y0; int h1 = ref_Renamed.ImageHeight - y1; int h = (h0 < h1) ? h0 : h1; if ((w > 0) && (h > 0)) { PixelReference pixel = CreateGPixelReference(0); PixelReference refPixel = ref_Renamed.CreateGPixelReference(0); do { pixel.SetOffset(y0++, x0); refPixel.SetOffset(y1++, x1); if (!IsRampNeeded) { pixel.SetPixels(refPixel, w); } else { int i = w; do { pixel.CopyFrom(ref_Renamed.PixelRamp(refPixel)); pixel.IncOffset(); refPixel.IncOffset(); } while (--i > 0); } } while (--h > 0); } }
/// <summary> Initialize this PixelMap from a segment of another image map. /// /// </summary> /// <param name="ref">image map to initialize from /// </param> /// <param name="rect">bounding rectangle to initialize from /// /// </param> /// <returns> the initialized PixelMap /// </returns> public virtual PixelMap Init(Map ref_Renamed, Rectangle rect) { Init(rect.Height, rect.Width, ((null))); Rectangle rect2 = new Rectangle(0, 0, ref_Renamed.ImageWidth, ref_Renamed.ImageHeight); rect2.Intersect(rect2, rect); rect2.Translate(-rect.Right, -rect.Bottom); if (!rect2.Empty) { PixelReference pixel = CreateGPixelReference(0); PixelReference refPixel = ref_Renamed.CreateGPixelReference(0); for (int y = rect2.Bottom; y < rect2.Top; y++) { pixel.SetOffset(y, rect2.Right); refPixel.SetOffset(y + rect.Bottom, rect.Right + rect2.Right); if (!IsRampNeeded) { for (int x = rect2.Left - rect2.Right; x-- > 0; pixel.IncOffset(), refPixel.IncOffset()) { pixel.CopyFrom(refPixel); } } else { for (int x = rect2.Left - rect2.Right; x-- > 0; pixel.IncOffset(), refPixel.IncOffset()) { pixel.CopyFrom(ref_Renamed.PixelRamp(refPixel)); } } } } return(this); }
private PixelReference GetLine(int fy, Rectangle required_red, Rectangle provided_input, PixelMap input) { if (fy < required_red.YMin) { fy = required_red.YMin; } else if (fy >= required_red.YMax) { fy = required_red.YMax - 1; } // Cached line if (fy == l2) { return(p2.CreateGPixelReference(0)); } if (fy == l1) { return(p1.CreateGPixelReference(0)); } // Shift PixelMap p = p1; p1 = p2; l1 = l2; p2 = p; l2 = fy; // Compute location of line Rectangle line = new Rectangle(); line.XMin = required_red.XMin << xshift; line.XMax = required_red.XMax << xshift; line.YMin = fy << yshift; line.YMax = (fy + 1) << yshift; line.Intersect(line, provided_input); line.Translate(-provided_input.XMin, -provided_input.YMin); // Prepare variables int botline = input.RowOffset(line.YMin); int rowsize = input.GetRowSize(); int sw = 1 << xshift; int div = xshift + yshift; int rnd = 1 << (div - 1); int rnd2 = rnd + rnd; PixelReference inp1 = input.CreateGPixelReference(0); PixelReference ip = p.CreateGPixelReference(0); // Compute averages for (int x = line.XMin; x < line.XMax; x += sw, ip.IncOffset()) { int r = 0; int g = 0; int b = 0; int s = 0; int inp0 = botline + x; int sy2 = line.Height; int sy1 = (1 << yshift); if (sy1 > sy2) { sy1 = sy2; } for (int sy = 0; sy < sy1; sy++, inp0 += rowsize) { int sx1 = x + sw; inp1.SetOffset(inp0); if (sx1 > line.XMax) { sx1 = line.XMax; } for (int sx = sx1 - x; sx-- > 0; s++, inp1.IncOffset()) { r += inp1.Red; g += inp1.Green; b += inp1.Blue; } } if (s == rnd2) { ip.SetBGR((b + rnd) >> div, (g + r) >> div, (r + rnd) >> div); } else { ip.SetBGR((b + (s / 2)) / 2, (g + (s / 2)) / s, (r + (s / 2)) / s); } } // Return return(p2.CreateGPixelReference(0)); }
public void Scale(Rectangle provided_input, PixelMap sourceMap, Rectangle targetRect, PixelMap output) { // Compute rectangles Rectangle required_red = new Rectangle(); Rectangle sourceRect = CreateRectangles(targetRect, required_red); // Parameter validation if ( (provided_input.Width != sourceMap.ImageWidth) || (provided_input.Height != sourceMap.ImageHeight)) { throw new Exception("invalid rectangle"); } if ( (provided_input.XMin > sourceRect.XMin) || (provided_input.YMin > sourceRect.YMin) || (provided_input.XMax < sourceRect.XMax) || (provided_input.YMax < sourceRect.YMax)) { throw new Exception("invalid rectangle"); } // Adjust output pixmap if ( (targetRect.Width != (int)output.ImageWidth) || (targetRect.Height != (int)output.ImageHeight)) { output.Init( targetRect.Height, targetRect.Width, null); } // Prepare temp stuff int bufw = required_red.Width; Pixel[] lbuffer = new Pixel[bufw + 2]; for (int i = 0; i < lbuffer.Length;) { lbuffer[i++] = new Pixel(); } try { if ((xshift > 0) || (yshift > 0)) { p1 = new PixelMap().Init(1, bufw, null); p2 = new PixelMap().Init(2, bufw, null); l1 = l2 = -1; } // 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; PixelReference upper; PixelReference lower; // Obtain upper and lower line in reduced image if ((xshift > 0) || (yshift > 0)) { lower = GetLine(fy1, required_red, provided_input, sourceMap); upper = GetLine(fy2, required_red, provided_input, sourceMap); } else { int dx = required_red.XMin - provided_input.XMin; if (required_red.YMin > fy1) { fy1 = required_red.YMin; } if (required_red.YMax <= fy2) { fy2 = required_red.YMax - 1; } lower = sourceMap.CreateGPixelReference(fy1 - provided_input.YMin, dx); upper = sourceMap.CreateGPixelReference(fy2 - provided_input.YMin, dx); } // Compute line int idest = 1; short[] deltas = interp[fy & FRACMASK]; for ( int edest = idest + bufw; idest < edest; upper.IncOffset(), lower.IncOffset()) { Pixel dest = lbuffer[idest++]; int lower_r = lower.Red; int delta_r = deltas[(256 + upper.Red) - lower_r]; int lower_g = lower.Green; int delta_g = deltas[(256 + upper.Green) - lower_g]; int lower_b = lower.Blue; int delta_b = deltas[(256 + upper.Blue) - lower_b]; dest.SetBGR(lower_b + delta_b, lower_g + delta_g, lower_r + delta_r); } } // Perform horizontal interpolation { // Prepare for side effects lbuffer[0] = lbuffer[1]; // lbuffer[bufw] = lbuffer[bufw]; int line = 1 - required_red.XMin; PixelReference dest = output.CreateGPixelReference(y - targetRect.YMin, 0); // Loop horizontally for (int x = targetRect.XMin; x < targetRect.XMax; x++) { int n = hcoord[x]; int lower = line + (n >> FRACBITS); Pixel lower0 = lbuffer[lower]; Pixel lower1 = lbuffer[lower + 1]; short[] deltas = interp[n & FRACMASK]; int lower_r = lower0.Red; int delta_r = deltas[(256 + lower1.Red) - lower_r]; int lower_g = lower0.Green; int delta_g = deltas[(256 + lower1.Green) - lower_g]; int lower_b = lower0.Blue; int delta_b = deltas[(256 + lower1.Blue) - lower_b]; dest.SetBGR(lower_b + delta_b, lower_g + delta_g, lower_r + delta_r); dest.IncOffset(); } } } } finally { p1 = null; p2 = null; } }
/// <summary> Draw the foreground layer onto this background image. /// /// </summary> /// <param name="mask">the mask layer /// </param> /// <param name="foregroundMap">the foreground colors /// </param> /// <param name="supersample">rate to upsample the foreground colors /// </param> /// <param name="subsample">rate to subsample the foreground colors /// </param> /// <param name="bounds">the target rectangle /// </param> /// <param name="gamma">color correction factor /// /// </param> /// <throws> IllegalArgumentException if the specified bounds are not contained in the page </throws> public virtual void Stencil(Bitmap mask, PixelMap foregroundMap, int supersample, int subsample, Rectangle bounds, double gamma) { // Check arguments Rectangle rect = new Rectangle(0, 0, (foregroundMap.ImageWidth * supersample + subsample - 1) / subsample, (foregroundMap.ImageHeight * supersample + subsample - 1) / subsample); if (bounds != null) { if ((bounds.Right < rect.Right) || (bounds.Bottom < rect.Bottom) || (bounds.Left > rect.Left) || (bounds.Top > rect.Top)) { throw new ArgumentException("rectangle out of bounds" + "bounds=(" + bounds.Right + "," + bounds.Bottom + "," + bounds.Left + "," + bounds.Top + "),rect=(" + rect.Right + "," + rect.Bottom + "," + rect.Left + "," + rect.Top + ")"); } rect = bounds; } // Compute number of rows int xrows = ImageHeight; if (mask.ImageHeight < xrows) { xrows = mask.ImageHeight; } if (rect.Height < xrows) { xrows = rect.Height; } // Compute number of columns int xcolumns = ImageWidth; if (mask.ImageWidth < xcolumns) { xcolumns = mask.ImageWidth; } if (rect.Width < xcolumns) { xcolumns = rect.Width; } // Precompute multiplier map int maxgray = mask.Grays - 1; int[] multiplier = new int[maxgray]; for (int i = 1; i < maxgray; i++) { multiplier[i] = (0x10000 * i) / maxgray; } // Prepare color correction table int[] gtable = GetColorCorrection(gamma); double ratioFg = supersample / (double)subsample; // Compute starting point in blown up foreground PixelMap int fgy = (rect.Bottom * subsample) / supersample; double fgy1 = rect.Bottom - ratioFg * fgy; if (fgy1 < 0) { fgy--; fgy1 += ratioFg; } int fgxz = (rect.Right * subsample) / supersample; double fgx1z = rect.Right - ratioFg * fgxz; if (fgx1z < 0) { fgxz--; fgx1z += ratioFg; } int fg = foregroundMap.RowOffset(fgy); PixelReference fgx = foregroundMap.CreateGPixelReference(0); PixelReference dst = CreateGPixelReference(0); // Loop over rows for (int y = 0; y < xrows; y++) { // Loop over columns fgx.SetOffset(fg + fgxz); double fgx1 = fgx1z; dst.SetOffset(y, 0); int src = mask.RowOffset(y); for (int x = 0; x < xcolumns; x++, dst.IncOffset()) { int srcpix = mask.GetByteAt(src + x); // Perform pixel operation if (srcpix > 0) { //fixed (int* gTableLocation = gtable) { if (srcpix >= maxgray) { dst.SetBGR(gtable[fgx.Blue], gtable[fgx.Green], gtable[fgx.Red]); } else { int level = multiplier[srcpix]; dst.SetBGR(((dst.Blue * (0x10000 - level)) + (level * gtable[fgx.Blue])) >> 16, ((dst.Green * (0x10000 - level)) + (level * gtable[fgx.Green])) >> 16, ((dst.Red * (0x10000 - level)) + (level * gtable[fgx.Red])) >> 16); } } } // Next column if (++fgx1 >= ratioFg) { fgx1 -= ratioFg; fgx.IncOffset(); } } // Next line if (++fgy1 >= ratioFg) { fgy1 -= ratioFg; fg += foregroundMap.GetRowSize(); } } }
/// <summary> /// Convert the pixel to 24 bit color. /// </summary> public override Pixel PixelRamp(PixelReference ref_Renamed) { return(Ramp[ref_Renamed.Blue]); }
/// <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()); } }
/// <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(); } }
/// <summary> Attenuate the specified bitmap. /// /// </summary> /// <param name="bm">Bitmap to attenuate /// </param> /// <param name="xpos">horizontal position /// </param> /// <param name="ypos">vertical position /// </param> public virtual void Attenuate(Bitmap bm, int xpos, int ypos) { // Check // 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 = GetMultiplier(maxgray); // Compute starting point int src = bm.RowOffset((ypos < 0) ? (-ypos) : 0) - ((xpos < 0) ? xpos : 0); int dst = RowOffset((ypos > 0) ? ypos : 0) + ((xpos > 0) ? xpos : 0); PixelReference dstPixel = CreateGPixelReference(0); // 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.SetGray(0); } else { int level = multiplier[srcpix]; dstPixel.SetBGR((dstPixel.Blue * level) >> 16, (dstPixel.Green * level) >> 16, (dstPixel.Red * level) >> 16); } } } // Next line dst += GetRowSize(); src += bm.GetRowSize(); } }
/// <summary> /// Convert the pixel to 24 bit color. /// </summary> public override Pixel PixelRamp(PixelReference ref_Renamed) { return Ramp[ref_Renamed.Blue]; }
/// <summary> Convert the pixel to 24 bit color. /// /// </summary> /// <returns> /// the converted pixel /// </returns> public virtual Pixel PixelRamp(PixelReference pixel) { return pixel; }
/// <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(); } } } }
/// <summary> Convert the pixel to 24 bit color. /// /// </summary> /// <returns> /// the converted pixel /// </returns> public virtual Pixel PixelRamp(PixelReference pixel) { return(pixel); }