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);
        }
Beispiel #2
0
        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
        }
Beispiel #3
0
        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++;
                }
            }
        }