//-------------------------------------------------------------------- public byte pixel(int x, int y) { int bufferIndex = m_rbuf.GetBufferOffsetXY(x, y); byte[] buffer = m_rbuf.GetBuffer(); return(buffer[bufferIndex]); }
byte[] GetPixels(out int bufferByteOffset) { int x = m_x; int y = m_y; unchecked { if ((uint)x >= (uint)m_src_width) { if (x < 0) { x = 0; } else { x = (int)m_src_width - 1; } } if ((uint)y >= (uint)m_src_height) { if (y < 0) { y = 0; } else { y = (int)m_src_height - 1; } } } bufferByteOffset = imgRW.GetBufferOffsetXY(x, y); return(imgRW.GetBuffer()); }
//-------------------------------------------------------------------- public byte pixel(int x, int y) { unchecked { if ((uint)x < (uint)m_rbuf.Width && (uint)y < (uint)m_rbuf.Height) { int bufferIndex = m_rbuf.GetBufferOffsetXY(x, y); byte[] buffer = m_rbuf.GetBuffer(); return(buffer[bufferIndex]); } } return(0); }
public void RenderScanline( IImageReaderWriter dest, ScanlineRasterizer sclineRas, Scanline scline, Color color) { #if DEBUG int dbugMinScanlineCount = 0; #endif //1. ensure single line buffer width _grayScaleLine.EnsureLineStride(dest.Width + 4); //2. setup vars byte[] dest_buffer = dest.GetBuffer(); int dest_w = dest.Width; int dest_h = dest.Height; int dest_stride = dest.Stride; int src_w = dest_w; int src_stride = dest_stride; //*** set color before call Blend() this._color = color; byte color_alpha = color.alpha; //--------------------------- //3. loop, render single scanline with subpixel rendering byte[] lineBuff = _grayScaleLine.GetInternalBuffer(); while (sclineRas.SweepScanline(scline)) { //3.1. clear _grayScaleLine.Clear(); //3.2. write grayscale span to temp buffer //3.3 convert to subpixel value and write to dest buffer //render solid single scanline int num_spans = scline.SpanCount; byte[] covers = scline.GetCovers(); //render each span in the scanline for (int i = 1; i <= num_spans; ++i) { ScanlineSpan span = scline.GetSpan(i); if (span.len > 0) { //positive len _grayScaleLine.SubPixBlendSolidHSpan(span.x, span.len, color_alpha, covers, span.cover_index); } else { //fill the line, same coverage area int x = span.x; int x2 = (x - span.len - 1); _grayScaleLine.SubPixBlendHL(x, x2, color_alpha, covers[span.cover_index]); } } BlendScanline(dest_buffer, dest_stride, scline.Y, src_w, src_stride, lineBuff); #if DEBUG dbugMinScanlineCount++; #endif } }
void Attach(IImageReaderWriter imgRW) { this.imgRW = imgRW; m_buffer = imgRW.GetBuffer(); m_src_width = imgRW.Width; m_src_height = imgRW.Height; m_distanceBetweenPixelsInclusive = imgRW.BytesBetweenPixelsInclusive; }
int bufferOffset; // the beggining of the image in this buffer public ChildImage(IImageReaderWriter image, int bufferOffsetToFirstPixel, int width, int height) { SetRecieveBlender(image.GetRecieveBlender()); AttachBuffer(image.GetBuffer(), bufferOffsetToFirstPixel, width, height, image.Stride, image.BitDepth, image.BytesBetweenPixelsInclusive); }
void Attach(IImageReaderWriter sourceImage, IPixelBlender recieveBlender, int distanceBetweenPixelsInclusive, int bufferOffset, int bitsPerPixel) { SetDimmensionAndFormat(sourceImage.Width, sourceImage.Height, sourceImage.Stride, bitsPerPixel, distanceBetweenPixelsInclusive); int offset = sourceImage.GetBufferOffsetXY(0, 0); byte[] buffer = sourceImage.GetBuffer(); SetBuffer(buffer, offset + bufferOffset); SetRecieveBlender(recieveBlender); }
bool Attach(IImageReaderWriter sourceImage, int x1, int y1, int x2, int y2) { m_ByteBuffer = null; if (x1 > x2 || y1 > y2) { throw new Exception("You need to have your x1 and y1 be the lower left corner of your sub image."); } RectInt boundsRect = new RectInt(x1, y1, x2, y2); if (boundsRect.Clip(new RectInt(0, 0, (int)sourceImage.Width - 1, (int)sourceImage.Height - 1))) { SetDimmensionAndFormat(boundsRect.Width, boundsRect.Height, sourceImage.Stride, sourceImage.BitDepth, sourceImage.BytesBetweenPixelsInclusive); int bufferOffset = sourceImage.GetBufferOffsetXY(boundsRect.Left, boundsRect.Bottom); byte[] buffer = sourceImage.GetBuffer(); SetBuffer(buffer, bufferOffset); return(true); } return(false); }
void CopyFromNoClipping(IImageReaderWriter sourceImage, RectInt clippedSourceImageRect, int destXOffset, int destYOffset) { if (BytesBetweenPixelsInclusive != BitDepth / 8 || sourceImage.BytesBetweenPixelsInclusive != sourceImage.BitDepth / 8) { throw new Exception("WIP we only support packed pixel formats at this time."); } if (BitDepth == sourceImage.BitDepth) { int lengthInBytes = clippedSourceImageRect.Width * BytesBetweenPixelsInclusive; int sourceOffset = sourceImage.GetBufferOffsetXY(clippedSourceImageRect.Left, clippedSourceImageRect.Bottom); byte[] sourceBuffer = sourceImage.GetBuffer(); byte[] destBuffer = GetBuffer(); int destOffset = GetBufferOffsetXY(clippedSourceImageRect.Left + destXOffset, clippedSourceImageRect.Bottom + destYOffset); for (int i = 0; i < clippedSourceImageRect.Height; i++) { AggMemMx.memmove(destBuffer, destOffset, sourceBuffer, sourceOffset, lengthInBytes); sourceOffset += sourceImage.Stride; destOffset += Stride; } } else { bool haveConversion = true; switch (sourceImage.BitDepth) { case 24: switch (BitDepth) { case 32: { int numPixelsToCopy = clippedSourceImageRect.Width; for (int i = clippedSourceImageRect.Bottom; i < clippedSourceImageRect.Top; i++) { int sourceOffset = sourceImage.GetBufferOffsetXY(clippedSourceImageRect.Left, clippedSourceImageRect.Bottom + i); byte[] sourceBuffer = sourceImage.GetBuffer(); byte[] destBuffer = GetBuffer(); int destOffset = GetBufferOffsetXY(clippedSourceImageRect.Left + destXOffset, clippedSourceImageRect.Bottom + i + destYOffset); for (int x = 0; x < numPixelsToCopy; x++) { destBuffer[destOffset++] = sourceBuffer[sourceOffset++]; destBuffer[destOffset++] = sourceBuffer[sourceOffset++]; destBuffer[destOffset++] = sourceBuffer[sourceOffset++]; destBuffer[destOffset++] = 255; } } } break; default: haveConversion = false; break; } break; default: haveConversion = false; break; } if (!haveConversion) { throw new NotImplementedException("You need to write the " + sourceImage.BitDepth.ToString() + " to " + BitDepth.ToString() + " conversion"); } } }
void SubPixRender(IImageReaderWriter dest, Scanline scanline, Color color) { byte[] covers = scanline.GetCovers(); int num_spans = scanline.SpanCount; int y = scanline.Y; byte[] buffer = dest.GetBuffer(); IPixelBlender blender = dest.GetRecieveBlender(); int last_x = int.MinValue; int bufferOffset = 0; //------------------------------------------ Color bgColor = Color.White; float cb_R = bgColor.R / 255f; float cb_G = bgColor.G / 255f; float cb_B = bgColor.B / 255f; float cf_R = color.R / 255f; float cf_G = color.G / 255f; float cf_B = color.B / 255f; //------------------------------------------ int prevCover = -1; for (int i = 1; i <= num_spans; ++i) { //render span by span ScanlineSpan span = scanline.GetSpan(i); if (span.x != last_x + 1) { bufferOffset = dest.GetBufferOffsetXY(span.x, y); } last_x = span.x; int num_pix = span.len; if (num_pix < 0) { //special encode*** num_pix = -num_pix; //make it positive value last_x += (num_pix - 1); //long span with coverage int coverageValue = covers[span.cover_index]; //------------------------------------------- if (coverageValue >= 255) { //100% cover int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; Color todrawColor = Color.FromArgb(a, Color.FromArgb(color.R, color.G, color.B)); while (num_pix > 0) { blender.BlendPixel(buffer, bufferOffset, todrawColor); bufferOffset += 4; //1 pixel 4 bytes --num_pix; } } else { int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; Color newc = Color.FromArgb(color.R, color.G, color.B); Color todrawColor = Color.FromArgb(a, newc); while (num_pix > 0) { blender.BlendPixel(buffer, bufferOffset, todrawColor); bufferOffset += 4; //1 pixel 4 bytes --num_pix; } } prevCover = coverageValue; } else { int coverIndex = span.cover_index; last_x += (num_pix - 1); while (num_pix > 0) { int coverageValue = covers[coverIndex++]; if (coverageValue >= 255) { //100% cover Color newc = Color.FromArgb(color.R, color.G, color.B); int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, newc)); prevCover = coverageValue; } else { //check direction : bool isUpHill = coverageValue >= prevCover; //if (isUpHill != ((coverageValue % 2) > 0)) //{ //} //---------------------------- byte c_r = 0, c_g = 0, c_b = 0; //---------------------------- //assume lcd screen is RGB float subpix_percent = ((float)(coverageValue) / 256f); if (coverageValue < cover_1_3) { //assume LCD color arrangement is BGR if (isUpHill) { c_r = bgColor.R; c_g = bgColor.G; c_b = (byte)(mix(cb_B, cf_B, subpix_percent) * 255); } else { c_r = (byte)(mix(cb_R, cf_R, subpix_percent) * 255); c_g = bgColor.G; c_b = bgColor.B; } int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b))); } else if (coverageValue < cover_2_3) { if (isUpHill) { c_r = bgColor.R; c_g = (byte)(mix(cb_G, cf_G, subpix_percent) * 255); c_b = (byte)(mix(cb_B, cf_B, 1) * 255); } else { c_r = (byte)(mix(cb_R, cf_R, 1) * 255); c_g = (byte)(mix(cb_G, cf_G, subpix_percent) * 255); c_b = bgColor.B; } int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b))); } else { //cover > 2/3 but not full if (isUpHill) { c_r = (byte)(mix(cb_R, cf_R, subpix_percent) * 255); c_g = (byte)(mix(cb_G, cf_G, 1) * 255); c_b = (byte)(mix(cb_B, cf_B, 1) * 255); } else { c_r = (byte)(mix(cb_R, cf_R, 1) * 255); c_g = (byte)(mix(cb_G, cf_G, 1) * 255); c_b = (byte)(mix(cb_B, cf_B, subpix_percent) * 255); } int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, Color.FromArgb(a, Color.FromArgb(c_r, c_g, c_b))); } } bufferOffset += 4; //1 pixel 4 bits --num_pix; prevCover = coverageValue; } } } }
public byte[] GetBuffer() { return(linkedImage.GetBuffer()); }
void SubPixRender(IImageReaderWriter dest, Scanline scanline, ColorRGBA color) { byte[] covers = scanline.GetCovers(); int num_spans = scanline.SpanCount; int y = scanline.Y; byte[] buffer = dest.GetBuffer(); IPixelBlender blender = dest.GetRecieveBlender(); int last_x = int.MinValue; int prev_cover = 0; int bufferOffset = 0; ColorRGBA prevColor = ColorRGBA.White; for (int i = 1; i <= num_spans; ++i) { //render span by span ScanlineSpan span = scanline.GetSpan(i); if (span.x != last_x + 1) { bufferOffset = dest.GetBufferOffsetXY(span.x, y); //when skip then reset prev_cover = 0; prevColor = ColorRGBA.White; } last_x = span.x; int num_pix = span.len; if (num_pix < 0) { //special encode*** num_pix = -num_pix; //make it positive value last_x += (num_pix - 1); //long span with coverage int coverageValue = covers[span.cover_index]; //------------------------------------------- if (coverageValue >= 255) { //100% cover int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; ColorRGBA newc = prevColor = new ColorRGBA(color.red, color.green, color.blue); ColorRGBA todrawColor = new ColorRGBA(newc, a); prev_cover = 255;//full while (num_pix > 0) { blender.BlendPixel(buffer, bufferOffset, todrawColor); bufferOffset += 4; //1 pixel 4 bytes --num_pix; } } else { prev_cover = coverageValue; int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; ColorRGBA newc = prevColor = new ColorRGBA(color.red, color.green, color.blue); ColorRGBA todrawColor = new ColorRGBA(newc, a); while (num_pix > 0) { blender.BlendPixel(buffer, bufferOffset, todrawColor); bufferOffset += 4; //1 pixel 4 bytes --num_pix; } } } else { int coverIndex = span.cover_index; last_x += (num_pix - 1); while (num_pix > 0) { int coverageValue = covers[coverIndex++]; if (coverageValue >= 255) { //100% cover ColorRGBA newc = new ColorRGBA(color.red, color.green, color.blue); prevColor = newc; int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a)); prev_cover = 255;//full } else { //check direction : bool isLeftToRight = coverageValue >= prev_cover; prev_cover = coverageValue; byte c_r, c_g, c_b; float subpix_percent = ((float)(coverageValue) / 256f); if (coverageValue < cover_1_3) { if (isLeftToRight) { c_r = 255; c_g = 255; c_b = (byte)(255 - (255f * (subpix_percent))); } else { c_r = (byte)(255 - (255f * (subpix_percent))); c_g = 255; c_b = 255; } ColorRGBA newc = prevColor = new ColorRGBA(c_r, c_g, c_b); int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a)); } else if (coverageValue < cover_2_3) { if (isLeftToRight) { c_r = prevColor.blue; c_g = (byte)(255 - (255f * (subpix_percent))); c_b = color.blue; } else { c_r = color.blue; c_g = (byte)(255 - (255f * (subpix_percent))); c_b = 255; } ColorRGBA newc = prevColor = new ColorRGBA(c_r, c_g, c_b); int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a)); } else { //cover > 2/3 but not full if (isLeftToRight) { c_r = (byte)(255 - (255f * (subpix_percent))); c_g = color.green; c_b = color.blue; } else { c_r = prevColor.green; c_g = prevColor.blue; c_b = (byte)(255 - (255f * (subpix_percent))); } ColorRGBA newc = prevColor = new ColorRGBA(c_r, c_g, c_b); int a = ((coverageValue + 1) * color.Alpha0To255) >> 8; blender.BlendPixel(buffer, bufferOffset, new ColorRGBA(newc, a)); } } bufferOffset += 4; //1 pixel 4 bits --num_pix; } } } }
bool Attach(IImageReaderWriter sourceImage, int x1, int y1, int x2, int y2) { m_ByteBuffer = null; if (x1 > x2 || y1 > y2) { throw new Exception("You need to have your x1 and y1 be the lower left corner of your sub image."); } RectInt boundsRect = new RectInt(x1, y1, x2, y2); if (boundsRect.Clip(new RectInt(0, 0, (int)sourceImage.Width - 1, (int)sourceImage.Height - 1))) { SetDimmensionAndFormat(boundsRect.Width, boundsRect.Height, sourceImage.Stride, sourceImage.BitDepth, sourceImage.BytesBetweenPixelsInclusive); int bufferOffset = sourceImage.GetBufferOffsetXY(boundsRect.Left, boundsRect.Bottom); byte[] buffer = sourceImage.GetBuffer(); SetBuffer(buffer, bufferOffset); return true; } return false; }
public byte[] GetBuffer() { //TODO: review here, this may not correct return(linkedImage.GetBuffer()); }
// Create //-------------------------------------------------------------------- public void Create(IImageReaderWriter src) { // we are going to create a dialated image for filtering // we add m_dilation pixels to every side of the image and then copy the image in the x // dirrection into each end so that we can sample into this image to get filtering on x repeating // if the original image look like this // // 123456 // // the new image would look like this // // 0000000000 // 0000000000 // 5612345612 // 0000000000 // 0000000000 m_height = (int)AggBasics.uceil(src.Height); m_width = (int)AggBasics.uceil(src.Width); m_width_hr = (int)AggBasics.uround(src.Width * LineAA.SUBPIXEL_SCALE); m_half_height_hr = (int)AggBasics.uround(src.Height * LineAA.SUBPIXEL_SCALE / 2); m_offset_y_hr = m_dilation_hr + m_half_height_hr - LineAA.SUBPIXEL_SCALE / 2; m_half_height_hr += LineAA.SUBPIXEL_SCALE / 2; int bufferWidth = m_width + m_dilation * 2; int bufferHeight = m_height + m_dilation * 2; int bytesPerPixel = src.BitDepth / 8; int newSizeInBytes = bufferWidth * bufferHeight * bytesPerPixel; if (m_DataSizeInBytes < newSizeInBytes) { m_DataSizeInBytes = newSizeInBytes; m_data = new byte[m_DataSizeInBytes]; } m_buf = new ChildImage(m_data, 0, bufferWidth, bufferHeight, bufferWidth * bytesPerPixel, src.BitDepth, bytesPerPixel); byte[] destBuffer = m_buf.GetBuffer(); byte[] srcBuffer = src.GetBuffer(); // copy the image into the middle of the dest for (int y = 0; y < m_height; y++) { for (int x = 0; x < m_width; x++) { int sourceOffset = src.GetBufferOffsetXY(x, y); int destOffset = m_buf.GetBufferOffsetXY(m_dilation, y + m_dilation); for (int channel = 0; channel < bytesPerPixel; channel++) { destBuffer[destOffset++] = srcBuffer[sourceOffset++]; } } } // copy the first two pixels form the end into the begining and from the begining into the end for (int y = 0; y < m_height; y++) { int s1Offset = src.GetBufferOffsetXY(0, y); int d1Offset = m_buf.GetBufferOffsetXY(m_dilation + m_width, y); int s2Offset = src.GetBufferOffsetXY(m_width - m_dilation, y); int d2Offset = m_buf.GetBufferOffsetXY(0, y); for (int x = 0; x < m_dilation; x++) { for (int channel = 0; channel < bytesPerPixel; channel++) { destBuffer[d1Offset++] = srcBuffer[s1Offset++]; destBuffer[d2Offset++] = srcBuffer[s2Offset++]; } } } }