protected int ShiftDirectContext(Bitmap bm, int context, int next, int up2, int up1, int up0, int column) { return (((context << 1) & 0x37a) | (bm.GetByteAt(up1 + column + 2) << 2) | (bm.GetByteAt(up2 + column + 1) << 7) | next); }
protected int GetDirectContext(Bitmap bm, int up2, int up1, int up0, int column) { return ((bm.GetByteAt((up2 + column) - 1) << 9) | (bm.GetByteAt(up2 + column) << 8) | (bm.GetByteAt(up2 + column + 1) << 7) | (bm.GetByteAt((up1 + column) - 2) << 6) | (bm.GetByteAt((up1 + column) - 1) << 5) | (bm.GetByteAt(up1 + column) << 4) | (bm.GetByteAt(up1 + column + 1) << 3) | (bm.GetByteAt(up1 + column + 2) << 2) | (bm.GetByteAt((up0 + column) - 2) << 1) | (bm.GetByteAt((up0 + column) - 1))); }
protected int ShiftCrossContext(Bitmap bm, Bitmap cbm, int context, int n, int up1, int up0, int xup1, int xup0, int xdn1, int column) { return (((context << 1) & 0x636) | (bm.GetByteAt(up1 + column + 1) << 8) | (cbm.GetByteAt(xup1 + column) << 6) | (cbm.GetByteAt(xup0 + column + 1) << 3) | (cbm.GetByteAt(xdn1 + column + 1)) | (n << 7)); }
/// <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(); } } }
protected int GetCrossContext(Bitmap bm, Bitmap cbm, int up1, int up0, int xup1, int xup0, int xdn1, int column) { return ((bm.GetByteAt((up1 + column) - 1) << 10) | (bm.GetByteAt(up1 + column) << 9) | (bm.GetByteAt(up1 + column + 1) << 8) | (bm.GetByteAt((up0 + column) - 1) << 7) | (cbm.GetByteAt(xup1 + column) << 6) | (cbm.GetByteAt((xup0 + column) - 1) << 5) | (cbm.GetByteAt(xup0 + column) << 4) | (cbm.GetByteAt(xup0 + column + 1) << 3) | (cbm.GetByteAt((xdn1 + column) - 1) << 2) | (cbm.GetByteAt(xdn1 + column) << 1) | (cbm.GetByteAt(xdn1 + column + 1))); }
/// <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> 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 unsafe 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(gTableLocation[fgx.Blue], gTableLocation[fgx.Green], gTableLocation[fgx.Red]); } else { int level = multiplier[srcpix]; dst.SetBGR(((dst.Blue * (0x10000 - level)) + (level * gTableLocation[fgx.Blue])) >> 16, ((dst.Green * (0x10000 - level)) + (level * gTableLocation[fgx.Green])) >> 16, ((dst.Red * (0x10000 - level)) + (level * gTableLocation[fgx.Red])) >> 16); } } } // Next column if (++fgx1 >= ratioFg) { fgx1 -= ratioFg; fgx.IncOffset(); } } // Next line if (++fgy1 >= ratioFg) { fgy1 -= ratioFg; fg += foregroundMap.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(); } }