public void pixel_high_res(ImageBuffer sourceImage, RGBA_Bytes[] destBuffer, int destBufferOffset, int x, int y) { int r, g, b, a; r = g = b = a = LineAABasics.line_subpixel_scale * LineAABasics.line_subpixel_scale / 2; int weight; int x_lr = x >> LineAABasics.line_subpixel_shift; int y_lr = y >> LineAABasics.line_subpixel_shift; x &= LineAABasics.line_subpixel_mask; y &= LineAABasics.line_subpixel_mask; int sourceOffset; byte[] ptr = sourceImage.GetPixelPointerXY(x_lr, y_lr, out sourceOffset); weight = (LineAABasics.line_subpixel_scale - x) * (LineAABasics.line_subpixel_scale - y); r += weight * ptr[sourceOffset + ImageBuffer.OrderR]; g += weight * ptr[sourceOffset + ImageBuffer.OrderG]; b += weight * ptr[sourceOffset + ImageBuffer.OrderB]; a += weight * ptr[sourceOffset + ImageBuffer.OrderA]; sourceOffset += sourceImage.GetBytesBetweenPixelsInclusive(); weight = x * (LineAABasics.line_subpixel_scale - y); r += weight * ptr[sourceOffset + ImageBuffer.OrderR]; g += weight * ptr[sourceOffset + ImageBuffer.OrderG]; b += weight * ptr[sourceOffset + ImageBuffer.OrderB]; a += weight * ptr[sourceOffset + ImageBuffer.OrderA]; ptr = sourceImage.GetPixelPointerXY(x_lr, y_lr + 1, out sourceOffset); weight = (LineAABasics.line_subpixel_scale - x) * y; r += weight * ptr[sourceOffset + ImageBuffer.OrderR]; g += weight * ptr[sourceOffset + ImageBuffer.OrderG]; b += weight * ptr[sourceOffset + ImageBuffer.OrderB]; a += weight * ptr[sourceOffset + ImageBuffer.OrderA]; sourceOffset += sourceImage.GetBytesBetweenPixelsInclusive(); weight = x * y; r += weight * ptr[sourceOffset + ImageBuffer.OrderR]; g += weight * ptr[sourceOffset + ImageBuffer.OrderG]; b += weight * ptr[sourceOffset + ImageBuffer.OrderB]; a += weight * ptr[sourceOffset + ImageBuffer.OrderA]; destBuffer[destBufferOffset].red = (byte)(r >> LineAABasics.line_subpixel_shift * 2); destBuffer[destBufferOffset].green = (byte)(g >> LineAABasics.line_subpixel_shift * 2); destBuffer[destBufferOffset].blue = (byte)(b >> LineAABasics.line_subpixel_shift * 2); destBuffer[destBufferOffset].alpha = (byte)(a >> LineAABasics.line_subpixel_shift * 2); }
public override void generate(RGBA_Bytes[] span, int spanIndex, int x, int y, int len) { ImageBuffer SourceRenderingBuffer = (ImageBuffer)GetImageBufferAccessor().SourceImage; int bytesBetweenPixelsInclusive = SourceRenderingBuffer.GetBytesBetweenPixelsInclusive(); if (SourceRenderingBuffer.BitDepth != 8) { throw new NotSupportedException("The source is expected to be 32 bit."); } ISpanInterpolator spanInterpolator = interpolator(); spanInterpolator.begin(x + filter_dx_dbl(), y + filter_dy_dbl(), len); int x_hr; int y_hr; spanInterpolator.coordinates(out x_hr, out y_hr); int x_lr = x_hr >> (int)image_subpixel_scale_e.image_subpixel_shift; int y_lr = y_hr >> (int)image_subpixel_scale_e.image_subpixel_shift; int bufferIndex; bufferIndex = SourceRenderingBuffer.GetBufferOffsetXY(x_lr, y_lr); byte[] fg_ptr = SourceRenderingBuffer.GetBuffer(); #if USE_UNSAFE_CODE unsafe { fixed(byte *pSource = fg_ptr) { do { span[spanIndex].red = pSource[bufferIndex]; span[spanIndex].green = pSource[bufferIndex]; span[spanIndex].blue = pSource[bufferIndex]; span[spanIndex].alpha = 255; spanIndex++; bufferIndex += bytesBetweenPixelsInclusive; } while (--len != 0); } } #else do { throw new Exception("this code is for 32 bit"); RGBA_Bytes color; color.blue = fg_ptr[bufferIndex++]; color.green = fg_ptr[bufferIndex++]; color.red = fg_ptr[bufferIndex++]; color.alpha = fg_ptr[bufferIndex++]; span[spanIndex++] = color; } while (--len != 0); #endif }
void LinearFill(int x, int y) { int bytesPerPixel = destImage.GetBytesBetweenPixelsInclusive(); int imageWidth = destImage.Width; int leftFillX = x; int bufferOffset = destImage.GetBufferOffsetXY(x, y); int pixelOffset = (imageWidth * y) + x; while (true) { fillRule.SetPixel(destBuffer, bufferOffset); pixelsChecked[pixelOffset] = true; leftFillX--; pixelOffset--; bufferOffset -= bytesPerPixel; if (leftFillX <= 0 || (pixelsChecked[pixelOffset]) || !fillRule.CheckPixel(destBuffer, bufferOffset)) { break; } } leftFillX++; int rightFillX = x; bufferOffset = destImage.GetBufferOffsetXY(x, y); pixelOffset = (imageWidth * y) + x; while (true) { fillRule.SetPixel(destBuffer, bufferOffset); pixelsChecked[pixelOffset] = true; rightFillX++; pixelOffset++; bufferOffset += bytesPerPixel; if (rightFillX >= imageWidth || pixelsChecked[pixelOffset] || !fillRule.CheckPixel(destBuffer, bufferOffset)) { break; } } rightFillX--; ranges.Enqueue(new Range(leftFillX, rightFillX, y)); }
void CalculateSumResponseAtAllPixels(ImageBuffer imageBuffer, int totalResponseThreshold) { validResponsesBotomToTopList.Clear(); if (imageBuffer.GetBytesBetweenPixelsInclusive() != 1) { throw new NotImplementedException("We only process gray scale images that are packed"); } int width = imageBuffer.Width; int height = imageBuffer.Height; byte[] buffer = imageBuffer.GetBuffer(); for (int y = trimPixels; y < height - trimPixels; y++) { int byteOffset = imageBuffer.GetBufferOffsetXY(trimPixels, y); ValidResponseData[] totalResponseRow = allResponsesGrid.GetRow(y); for (int x = trimPixels; x < width - trimPixels; x++) { int sumResponse = 0; for (int angleToCheckIndex = 0; angleToCheckIndex < 4; angleToCheckIndex++) { int sum = (buffer[byteOffset + byteOffsetToPixel[angleToCheckIndex]] + buffer[byteOffset + byteOffsetToPixel[angleToCheckIndex + 8]]) - (buffer[byteOffset + byteOffsetToPixel[angleToCheckIndex + 4]] + buffer[byteOffset + byteOffsetToPixel[angleToCheckIndex + 12]]); int absSum = Math.Abs(sum); sumResponse += absSum; } int neighborMeanTotal = 0; int diffResponse = 0; for (int diffCheck = 0; diffCheck < 8; diffCheck++) { int testValue = buffer[byteOffset + byteOffsetToPixel[diffCheck]]; int oppositeValue = buffer[byteOffset + byteOffsetToPixel[diffCheck + 8]]; diffResponse += Math.Abs(testValue - oppositeValue); neighborMeanTotal += testValue + oppositeValue; } int neighborMean = (neighborMeanTotal + 8) / 16; int centerMeanTotal = buffer[byteOffset - 1] + buffer[byteOffset + 1] + buffer[byteOffset - width] + buffer[byteOffset - width]; int centerMean = (centerMeanTotal + 2) / 4; int absMeanResponse = Math.Abs(neighborMean - centerMean); ValidResponseData newResponse = new ValidResponseData(); int totalResponse = sumResponse - diffResponse - absMeanResponse; if (totalResponse >= totalResponseThreshold) { newResponse.totalResponse = totalResponse; newResponse.position = new Vector2(x, y); newResponse.originalIndex = validResponsesBotomToTopList.Count; // we are scanning pixels bottom to top so they go in the list bottom to top validResponsesBotomToTopList.Add(newResponse); } totalResponseRow[x] = newResponse; byteOffset++; } } }