コード例 #1
0
        /// <summary>
        /// fill to left side and right side of the line
        /// </summary>
        /// <param name="destBuffer"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        unsafe void LinearFill(int *destBuffer, int x, int y)
        {
            int leftFillX    = x;
            int bufferOffset = _destImgRW.GetBufferOffsetXY32(x, y);
            int pixelOffset  = (imageWidth * y) + x;

            while (true)
            {
                fillRule.SetPixel(destBuffer + bufferOffset);
                pixelsChecked[pixelOffset] = true;
                leftFillX--;
                pixelOffset--;
                bufferOffset--;
                if (leftFillX <= 0 || (pixelsChecked[pixelOffset]) || !fillRule.CheckPixel(*(destBuffer + bufferOffset)))
                {
                    break;
                }
            }
            leftFillX++;
            //
            int rightFillX = x;

            bufferOffset = _destImgRW.GetBufferOffsetXY32(x, y);
            pixelOffset  = (imageWidth * y) + x;
            while (true)
            {
                fillRule.SetPixel(destBuffer + bufferOffset);
                pixelsChecked[pixelOffset] = true;
                rightFillX++;
                pixelOffset++;
                bufferOffset++;
                if (rightFillX >= imageWidth || pixelsChecked[pixelOffset] || !fillRule.CheckPixel(*(destBuffer + bufferOffset)))
                {
                    break;
                }
            }
            rightFillX--;
            ranges.Enqueue(new Range(leftFillX, rightFillX, y));
        }
コード例 #2
0
        void Attach(IBitmapSrc sourceImage,
                    PixelBlender32 outputPxBlender,
                    int distanceBetweenPixelsInclusive,
                    int arrayElemOffset,
                    int bitsPerPixel)
        {
            _sourceImage = sourceImage;
            SetDimmensionAndFormat(sourceImage.Width,
                                   sourceImage.Height,
                                   sourceImage.Stride,
                                   bitsPerPixel,
                                   distanceBetweenPixelsInclusive);

            int srcOffset32 = sourceImage.GetBufferOffsetXY32(0, 0);

            SetBuffer(sourceImage.GetBufferPtr(), srcOffset32 + arrayElemOffset);
            this.OutputPixelBlender = outputPxBlender;
        }
コード例 #3
0
        public void Fill(IBitmapSrc bufferToFillOn, int x, int y)
        {
            y -= imageHeight;
            unchecked // this way we can overflow the uint on negative and get a big number
            {
                if ((uint)x >= bufferToFillOn.Width || (uint)y >= bufferToFillOn.Height)
                {
                    return;
                }
            }
            _destImgRW = bufferToFillOn;
            TempMemPtr destBufferPtr = bufferToFillOn.GetBufferPtr();

            unsafe
            {
                imageWidth  = bufferToFillOn.Width;
                imageHeight = bufferToFillOn.Height;
                //reset new buffer, clear mem?
                pixelsChecked = new bool[imageWidth * imageHeight];

                int *destBuffer             = (int *)destBufferPtr.Ptr;
                int  startColorBufferOffset = bufferToFillOn.GetBufferOffsetXY32(x, y);

                int start_color = *(destBuffer + startColorBufferOffset);

                fillRule.SetStartColor(Drawing.Color.FromArgb(
                                           (start_color >> 16) & 0xff,
                                           (start_color >> 8) & 0xff,
                                           (start_color) & 0xff));


                LinearFill(destBuffer, x, y);

                while (ranges.Count > 0)
                {
                    Range range           = ranges.Dequeue();
                    int   downY           = range.y - 1;
                    int   upY             = range.y + 1;
                    int   downPixelOffset = (imageWidth * (range.y - 1)) + range.startX;
                    int   upPixelOffset   = (imageWidth * (range.y + 1)) + range.startX;
                    for (int rangeX = range.startX; rangeX <= range.endX; rangeX++)
                    {
                        if (range.y > 0)
                        {
                            if (!pixelsChecked[downPixelOffset])
                            {
                                int bufferOffset = bufferToFillOn.GetBufferOffsetXY32(rangeX, downY);

                                if (fillRule.CheckPixel(*(destBuffer + bufferOffset)))
                                {
                                    LinearFill(destBuffer, rangeX, downY);
                                }
                            }
                        }

                        if (range.y < (imageHeight - 1))
                        {
                            if (!pixelsChecked[upPixelOffset])
                            {
                                int bufferOffset = bufferToFillOn.GetBufferOffsetXY32(rangeX, upY);
                                if (fillRule.CheckPixel(*(destBuffer + bufferOffset)))
                                {
                                    LinearFill(destBuffer, rangeX, upY);
                                }
                            }
                        }
                        upPixelOffset++;
                        downPixelOffset++;
                    }
                }
            }
            destBufferPtr.Release();
        }
コード例 #4
0
        public sealed override void GenerateColors(Drawing.Color[] outputColors, int startIndex, int x, int y, int len)
        {
            ISpanInterpolator spanInterpolator = Interpolator;

            spanInterpolator.Begin(x + dx, y + dy, len);
            int x_hr;
            int y_hr;

            spanInterpolator.GetCoord(out x_hr, out y_hr);
            int x_lr = x_hr >> img_subpix_const.SHIFT;
            int y_lr = y_hr >> img_subpix_const.SHIFT;

            int bufferIndex = _bmpSrc.GetBufferOffsetXY32(x_lr, y_lr);

            unsafe
            {
                using (CpuBlit.Imaging.TempMemPtr srcBufferPtr = _bmpSrc.GetBufferPtr())
                {
                    int *pSource = (int *)srcBufferPtr.Ptr + bufferIndex;

                    do
                    {
                        int src_value = *pSource;
                        //separate each component
                        //TODO: review here, color from source buffer
                        //should be in 'pre-multiplied' format.
                        //so it should be converted to 'straight' color by call something like ..'FromPreMult()'

                        outputColors[startIndex++] = Drawing.Color.FromArgb(
                            (byte)((src_value >> 24) & 0xff), //a
                            (byte)((src_value >> 16) & 0xff), //r
                            (byte)((src_value >> 8) & 0xff),  //g
                            (byte)((src_value) & 0xff));      //b

                        pSource++;                            //move next
                    } while (--len != 0);
                }
            }



            //version 1 , incorrect
            //ISpanInterpolator spanInterpolator = Interpolator;
            //spanInterpolator.Begin(x + dx, y + dy, len);
            //int x_hr;
            //int y_hr;
            //spanInterpolator.GetCoord(out x_hr, out y_hr);
            //int x_lr = x_hr >> img_subpix_const.SHIFT;
            //int y_lr = y_hr >> img_subpix_const.SHIFT;
            //int bufferIndex = srcRW.GetBufferOffsetXY(x_lr, y_lr);
            //byte[] srcBuffer = srcRW.GetBuffer();
            //unsafe
            //{
            //    fixed (byte* pSource = srcBuffer)
            //    {
            //        do
            //        {
            //            outputColors[startIndex++] = *(Drawing.Color*)&(pSource[bufferIndex]);
            //            bufferIndex += 4;
            //        } while (--len != 0);
            //    }
            //}
        }
コード例 #5
0
        public sealed override void GenerateColors(Drawing.Color[] outputColors, int startIndex, int x, int y, int len)
        {
#if DEBUG
            int tmp_len = len;
#endif
            unsafe
            {
                //TODO: review here

                if (_mode0)
                {
                    using (CpuBlit.Imaging.TempMemPtr.FromBmp(_imgsrc, out int *srcBuffer))
                    {
                        int bufferIndex = _imgsrc.GetBufferOffsetXY32(x, y);
                        //unsafe
                        {
#if true
                            do
                            {
                                //TODO: review here, match component?
                                //ORDER IS IMPORTANT!
                                //TODO : use CO (color order instead)
                                int color = srcBuffer[bufferIndex++];

                                //byte b = (byte)srcBuffer[bufferIndex++];
                                //byte g = (byte)srcBuffer[bufferIndex++];
                                //byte r = (byte)srcBuffer[bufferIndex++];
                                //byte a = (byte)srcBuffer[bufferIndex++];

                                //outputColors[startIndex] = Drawing.Color.FromArgb(a, r, g, b);
                                outputColors[startIndex] = Drawing.Color.FromArgb(
                                    (color >> 24) & 0xff, //a
                                    (color >> 16) & 0xff, //r
                                    (color >> 8) & 0xff,  //b
                                    (color) & 0xff        //b
                                    );

                                ++startIndex;
                            } while (--len != 0);
#else
                            fixed(byte *pSource = &fg_ptr[bufferIndex])
                            {
                                int *pSourceInt = (int *)pSource;

                                fixed(RGBA_Bytes *pDest = &span[spanIndex])
                                {
                                    int *pDestInt = (int *)pDest;

                                    do
                                    {
                                        *pDestInt++ = *pSourceInt++;
                                    } while (--len != 0);
                                }
                            }
#endif
                        }
                    }
                }
                else
                {
                    ISpanInterpolator spanInterpolator = base.Interpolator;
                    using (CpuBlit.Imaging.TempMemPtr srcBufferPtr = _imgsrc.GetBufferPtr())
                    {
                        int *srcBuffer = (int *)srcBufferPtr.Ptr;

                        spanInterpolator.Begin(x + base.dx, y + base.dy, len);
                        int accColor0, accColor1, accColor2, accColor3;
                        int back_r = m_bgcolor.red;
                        int back_g = m_bgcolor.green;
                        int back_b = m_bgcolor.blue;
                        int back_a = m_bgcolor.alpha;
                        int maxx   = _imgsrc.Width - 1;
                        int maxy   = _imgsrc.Height - 1;
                        int color  = 0;

                        unchecked
                        {
                            do
                            {
                                int x_hr;
                                int y_hr;
                                spanInterpolator.GetCoord(out x_hr, out y_hr);
                                x_hr -= base.dxInt;
                                y_hr -= base.dyInt;
                                int x_lr = x_hr >> img_subpix_const.SHIFT;
                                int y_lr = y_hr >> img_subpix_const.SHIFT;
                                int weight;
                                if (x_lr >= 0 && y_lr >= 0 &&
                                    x_lr < maxx && y_lr < maxy)
                                {
                                    int bufferIndex = _imgsrc.GetBufferOffsetXY32(x_lr, y_lr);


                                    accColor0             =
                                        accColor1         =
                                            accColor2     =
                                                accColor3 = (int)img_subpix_const.SCALE * (int)img_subpix_const.SCALE / 2;

                                    x_hr &= img_subpix_const.MASK;
                                    y_hr &= img_subpix_const.MASK;

                                    //bufferIndex = _imgsrc.GetBufferOffsetXY32(x_lr, y_lr);

                                    weight = ((img_subpix_const.SCALE - x_hr) *
                                              (img_subpix_const.SCALE - y_hr));
                                    if (weight > BASE_MASK)
                                    {
                                        color = srcBuffer[bufferIndex];

                                        accColor3 += weight * ((color >> 24) & 0xff); //a
                                        accColor0 += weight * ((color >> 16) & 0xff); //r
                                        accColor1 += weight * ((color >> 8) & 0xff);  //g
                                        accColor2 += weight * ((color) & 0xff);       //b
                                    }

                                    weight = (x_hr * ((int)img_subpix_const.SCALE - y_hr));
                                    if (weight > BASE_MASK)
                                    {
                                        bufferIndex++;
                                        color = srcBuffer[bufferIndex];
                                        //
                                        accColor3 += weight * ((color >> 24) & 0xff); //a
                                        accColor0 += weight * ((color >> 16) & 0xff); //r
                                        accColor1 += weight * ((color >> 8) & 0xff);  //g
                                        accColor2 += weight * ((color) & 0xff);       //b
                                    }

                                    weight = (((int)img_subpix_const.SCALE - x_hr) * y_hr);
                                    if (weight > BASE_MASK)
                                    {
                                        ++y_lr;
                                        //
                                        bufferIndex = _imgsrc.GetBufferOffsetXY32(x_lr, y_lr);
                                        color       = srcBuffer[bufferIndex];
                                        //
                                        accColor3 += weight * ((color >> 24) & 0xff); //a
                                        accColor0 += weight * ((color >> 16) & 0xff); //r
                                        accColor1 += weight * ((color >> 8) & 0xff);  //g
                                        accColor2 += weight * ((color) & 0xff);       //b
                                    }
                                    weight = (x_hr * y_hr);
                                    if (weight > BASE_MASK)
                                    {
                                        bufferIndex++;
                                        color = srcBuffer[bufferIndex];
                                        //
                                        accColor3 += weight * ((color >> 24) & 0xff); //a
                                        accColor0 += weight * ((color >> 16) & 0xff); //r
                                        accColor1 += weight * ((color >> 8) & 0xff);  //g
                                        accColor2 += weight * ((color) & 0xff);       //b
                                    }
                                    accColor0 >>= img_subpix_const.SHIFT * 2;
                                    accColor1 >>= img_subpix_const.SHIFT * 2;
                                    accColor2 >>= img_subpix_const.SHIFT * 2;
                                    accColor3 >>= img_subpix_const.SHIFT * 2;
                                }
                                else
                                {
                                    if (x_lr < -1 || y_lr < -1 ||
                                        x_lr > maxx || y_lr > maxy)
                                    {
                                        accColor0 = back_r;
                                        accColor1 = back_g;
                                        accColor2 = back_b;
                                        accColor3 = back_a;
                                    }
                                    else
                                    {
                                        accColor0             =
                                            accColor1         =
                                                accColor2     =
                                                    accColor3 = (int)img_subpix_const.SCALE * (int)img_subpix_const.SCALE / 2;
                                        x_hr  &= (int)img_subpix_const.MASK;
                                        y_hr  &= (int)img_subpix_const.MASK;
                                        weight = (((int)img_subpix_const.SCALE - x_hr) *
                                                  ((int)img_subpix_const.SCALE - y_hr));
                                        if (weight > BASE_MASK)
                                        {
                                            if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy)
                                            {
                                                BlendInFilterPixel(
                                                    ref accColor0, ref accColor1, ref accColor2, ref accColor3,
                                                    srcBuffer,
                                                    _imgsrc.GetBufferOffsetXY32(x_lr, y_lr),
                                                    weight);
                                            }
                                            else
                                            {
                                                accColor0 += back_r * weight;
                                                accColor1 += back_g * weight;
                                                accColor2 += back_b * weight;
                                                accColor3 += back_a * weight;
                                            }
                                        }

                                        x_lr++;
                                        weight = (x_hr * ((int)img_subpix_const.SCALE - y_hr));
                                        if (weight > BASE_MASK)
                                        {
                                            if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy)
                                            {
                                                BlendInFilterPixel(ref accColor0, ref accColor1, ref accColor2, ref accColor3,
                                                                   srcBuffer,
                                                                   _imgsrc.GetBufferOffsetXY32(x_lr, y_lr),
                                                                   weight);
                                            }
                                            else
                                            {
                                                accColor0 += back_r * weight;
                                                accColor1 += back_g * weight;
                                                accColor2 += back_b * weight;
                                                accColor3 += back_a * weight;
                                            }
                                        }

                                        x_lr--;
                                        y_lr++;
                                        weight = (((int)img_subpix_const.SCALE - x_hr) * y_hr);
                                        if (weight > BASE_MASK)
                                        {
                                            if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy)
                                            {
                                                BlendInFilterPixel(ref accColor0, ref accColor1, ref accColor2, ref accColor3,
                                                                   srcBuffer,
                                                                   _imgsrc.GetBufferOffsetXY32(x_lr, y_lr),
                                                                   weight);
                                            }
                                            else
                                            {
                                                accColor0 += back_r * weight;
                                                accColor1 += back_g * weight;
                                                accColor2 += back_b * weight;
                                                accColor3 += back_a * weight;
                                            }
                                        }

                                        x_lr++;
                                        weight = (x_hr * y_hr);
                                        if (weight > BASE_MASK)
                                        {
                                            if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy)
                                            {
                                                BlendInFilterPixel(ref accColor0, ref accColor1, ref accColor2, ref accColor3,
                                                                   srcBuffer,
                                                                   _imgsrc.GetBufferOffsetXY32(x_lr, y_lr),
                                                                   weight);
                                            }
                                            else
                                            {
                                                accColor0 += back_r * weight;
                                                accColor1 += back_g * weight;
                                                accColor2 += back_b * weight;
                                                accColor3 += back_a * weight;
                                            }
                                        }

                                        accColor0 >>= img_subpix_const.SHIFT * 2;
                                        accColor1 >>= img_subpix_const.SHIFT * 2;
                                        accColor2 >>= img_subpix_const.SHIFT * 2;
                                        accColor3 >>= img_subpix_const.SHIFT * 2;
                                    }
                                }

#if DEBUG
                                if (startIndex >= outputColors.Length)
                                {
                                }
#endif
                                outputColors[startIndex] = PixelFarm.Drawing.Color.FromArgb(
                                    (byte)accColor3,
                                    (byte)accColor0,
                                    (byte)accColor1,
                                    (byte)accColor2
                                    );

                                //outputColors[startIndex].red = (byte)accColor0;
                                //outputColors[startIndex].green = (byte)accColor1;
                                //outputColors[startIndex].blue = (byte)accColor2;
                                //outputColors[startIndex].alpha = (byte)accColor3;
                                ++startIndex;
                                spanInterpolator.Next();
                            } while (--len != 0);
                        }
                    }
                }
            }
        }
コード例 #6
0
ファイル: MemBitmap.cs プロジェクト: BiDuc/PixelFarm
        /// <summary>
        /// create thumbnail img with super-sampling technique,(Expensive, High quality thumb)
        /// </summary>
        /// <param name="source"></param>
        /// <param name="dst"></param>
        public static MemBitmap CreateThumbnailWithSuperSamplingTechnique(this MemBitmap source, float scaleRatio)
        {
            // Paint.NET (MIT,from version 3.36.7, see=> https://github.com/rivy/OpenPDN
            //in this version new image MUST smaller than the original one ***
            if (scaleRatio >= 1 || scaleRatio < 0)
            {
                return(null);
            }

            //create new bitmap
            int newBmpW = (int)Math.Round(source.Width * scaleRatio);
            int newBmpH = (int)Math.Round(source.Height * scaleRatio);

            MemBitmap  thumbBitmap = new MemBitmap(newBmpW, newBmpH); //***
            IBitmapSrc source_1    = (IBitmapSrc)source;

            unsafe
            {
                Rectangle dstRoi2 = new Rectangle(0, 0, newBmpW, newBmpH);

                int dstWidth  = dstRoi2.Width;
                int dstHeight = dstRoi2.Height;

                int srcH = source.Height;
                int srcW = source.Width;

                Imaging.TempMemPtr dstMemPtr = MemBitmap.GetBufferPtr(thumbBitmap);
                int dstStrideInt32           = newBmpW;

                for (int dstY = dstRoi2.Top; dstY < dstRoi2.Bottom; ++dstY)
                {
                    //from dst  => find proper source (y)

                    //double srcTop = (double)(dstY * srcH) / (double)dstHeight;
                    double srcTop       = (double)(dstY * srcH) / (double)dstHeight;
                    double srcTopFloor  = Math.Floor(srcTop);
                    double srcTopWeight = 1 - (srcTop - srcTopFloor);
                    int    srcTopInt    = (int)srcTopFloor;

                    //double srcBottom = (double)((dstY + 1) * srcH) / (double)dstHeight;
                    double srcBottom       = (double)((dstY + 1) * srcH) / (double)dstHeight;
                    double srcBottomFloor  = Math.Floor(srcBottom - 0.00001);
                    double srcBottomWeight = srcBottom - srcBottomFloor;
                    int    srcBottomInt    = (int)srcBottomFloor;


                    int *srcBuffer      = (int *)(MemBitmap.GetBufferPtr(source)).Ptr;
                    int  srcStrideInt32 = source.Width;                            //***

                    int *dstAddr = (int *)dstMemPtr.Ptr + (dstStrideInt32 * dstY); //begin at

                    for (int dstX = dstRoi2.Left; dstX < dstRoi2.Right; ++dstX)
                    {
                        //from dst=> find proper source (x)

                        double srcLeft       = (double)(dstX * srcW) / (double)dstWidth;
                        double srcLeftFloor  = Math.Floor(srcLeft);
                        double srcLeftWeight = 1 - (srcLeft - srcLeftFloor);
                        int    srcLeftInt    = (int)srcLeftFloor;

                        double srcRight       = (double)((dstX + 1) * srcW) / (double)dstWidth;
                        double srcRightFloor  = Math.Floor(srcRight - 0.00001);
                        double srcRightWeight = srcRight - srcRightFloor;
                        int    srcRightInt    = (int)srcRightFloor;

                        double blueSum  = 0;
                        double greenSum = 0;
                        double redSum   = 0;
                        double alphaSum = 0;

                        //now we know (left,top) of source that we want
                        //then ask the pixel value from source at that pos

                        //(1) left fractional edge
                        {
                            //PaintFx.ColorBgra* srcLeftPtr = source.GetPointAddressUnchecked(srcLeftInt, srcTopInt + 1);
                            int *srcLeftColorAddr = srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt, srcTopInt + 1);

                            for (int srcY = srcTopInt + 1; srcY < srcBottomInt; ++srcY)
                            {
                                int    srcColor = *srcLeftColorAddr;
                                double a_w      = ((srcColor >> CO.A_SHIFT) & 0xff) * srcLeftWeight;

                                blueSum  += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w;
                                greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w;
                                redSum   += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w;
                                alphaSum += a_w;

                                //move to next row
                                srcLeftColorAddr += srcStrideInt32;
                                //srcLeftPtr = (ColorBgra*)((byte*)srcLeftPtr + source._stride);
                            }
                        }
                        //
                        {
                            //(2) right fractional edge
                            //ColorBgra* srcRightPtr = source.GetPointAddressUnchecked(srcRightInt, srcTopInt + 1);
                            int *srcRightColorAddr = srcBuffer + source_1.GetBufferOffsetXY32(srcRightInt, srcTopInt + 1);

                            for (int srcY = srcTopInt + 1; srcY < srcBottomInt; ++srcY)
                            {
                                int    srcColor = *srcRightColorAddr;
                                double a_w      = ((srcColor >> CO.A_SHIFT) & 0xff) * srcRightWeight;

                                blueSum  += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w;
                                greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w;
                                redSum   += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w;
                                alphaSum += a_w;

                                //srcRightPtr = (ColorBgra*)((byte*)srcRightPtr + source._stride);
                                srcRightColorAddr += srcStrideInt32; //move to next row
                            }
                        }
                        //
                        {
                            //(3) top fractional edge
                            //ColorBgra* srcTopPtr = source.GetPointAddressUnchecked(srcLeftInt + 1, srcTopInt);
                            int *srcTopColorAddr = srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt + 1, srcTopInt);

                            for (int srcX = srcLeftInt + 1; srcX < srcRightInt; ++srcX)
                            {
                                int    srcColor = *srcTopColorAddr;
                                double a_w      = ((srcColor >> CO.A_SHIFT) & 0xff) * srcTopWeight;

                                blueSum  += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w;
                                greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w;
                                redSum   += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w;
                                alphaSum += a_w;

                                //move to next column
                                //++srcTopPtr;
                                ++srcTopColorAddr;
                            }
                        }
                        //
                        {
                            //(4) bottom fractional edge
                            //ColorBgra* srcBottomPtr = source.GetPointAddressUnchecked(srcLeftInt + 1, srcBottomInt);
                            int *srcBottomColorAddr = srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt + 1, srcBottomInt);

                            for (int srcX = srcLeftInt + 1; srcX < srcRightInt; ++srcX)
                            {
                                int    srcColor = *srcBottomColorAddr;
                                double a_w      = ((srcColor >> CO.A_SHIFT) & 0xff) * srcBottomWeight;

                                blueSum  += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w;
                                greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w;
                                redSum   += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w;
                                alphaSum += a_w;

                                //++srcBottomPtr;
                                //move to next column
                                //++srcTopPtr;
                                ++srcBottomColorAddr;
                            }
                        }
                        {
                            //(5) center area
                            for (int srcY = srcTopInt + 1; srcY < srcBottomInt; ++srcY)
                            {
                                //ColorBgra* srcPtr = source.GetPointAddressUnchecked(srcLeftInt + 1, srcY);
                                int *srcColorAddr = srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt + 1, srcY);

                                for (int srcX = srcLeftInt + 1; srcX < srcRightInt; ++srcX)
                                {
                                    int srcColor = *srcColorAddr;

                                    int a = ((srcColor >> CO.A_SHIFT) & 0xff);
                                    blueSum  += ((srcColor >> CO.B_SHIFT) & 0xff) * a;
                                    greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a;
                                    redSum   += ((srcColor >> CO.R_SHIFT) & 0xff) * a;
                                    alphaSum += a;

                                    ++srcColorAddr;
                                }
                            }
                        }


                        //(6) four corner pixels
                        {
                            //6.1
                            //ColorBgra srcTL = source.GetPoint(srcLeftInt, srcTopInt);
                            int srcColor = *(srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt, srcTopInt));

                            double a_w = ((srcColor >> CO.A_SHIFT) & 0xff) * (srcTopWeight * srcLeftWeight);

                            blueSum  += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w;
                            greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w;
                            redSum   += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w;
                            alphaSum += a_w;
                        }

                        {
                            //6.2
                            //ColorBgra srcTR = source.GetPoint(srcRightInt, srcTopInt);
                            //double srcTRA = srcTR.A;
                            //blueSum += srcTR.B * (srcTopWeight * srcRightWeight) * srcTRA;
                            //greenSum += srcTR.G * (srcTopWeight * srcRightWeight) * srcTRA;
                            //redSum += srcTR.R * (srcTopWeight * srcRightWeight) * srcTRA;
                            //alphaSum += srcTR.A * (srcTopWeight * srcRightWeight);

                            int    srcColor = *(srcBuffer + source_1.GetBufferOffsetXY32(srcRightInt, srcTopInt));
                            double a_w      = ((srcColor >> CO.A_SHIFT) & 0xff) * (srcTopWeight * srcRightWeight);

                            blueSum  += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w;
                            greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w;
                            redSum   += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w;
                            alphaSum += a_w;
                        }


                        {
                            //(6.3)
                            int    srcColor = *(srcBuffer + source_1.GetBufferOffsetXY32(srcLeftInt, srcBottomInt));
                            double a_w      = ((srcColor >> CO.A_SHIFT) & 0xff) * (srcBottomWeight * srcLeftWeight);

                            blueSum  += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w;
                            greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w;
                            redSum   += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w;
                            alphaSum += a_w; //without a


                            //ColorBgra srcBL = source.GetPoint(srcLeftInt, srcBottomInt);
                            //double srcBLA = srcBL.A;
                            //blueSum += srcBL.B * (srcBottomWeight * srcLeftWeight) * srcBLA;
                            //greenSum += srcBL.G * (srcBottomWeight * srcLeftWeight) * srcBLA;
                            //redSum += srcBL.R * (srcBottomWeight * srcLeftWeight) * srcBLA;
                            //alphaSum += srcBL.A * (srcBottomWeight * srcLeftWeight);
                        }

                        {
                            //(6.4)

                            //ColorBgra srcBR = source.GetPoint(srcRightInt, srcBottomInt);
                            //double srcBRA = srcBR.A;
                            //blueSum += srcBR.B * (srcBottomWeight * srcRightWeight) * srcBRA;
                            //greenSum += srcBR.G * (srcBottomWeight * srcRightWeight) * srcBRA;
                            //redSum += srcBR.R * (srcBottomWeight * srcRightWeight) * srcBRA;
                            //alphaSum += srcBR.A * (srcBottomWeight * srcRightWeight);

                            int    srcColor = *(srcBuffer + source_1.GetBufferOffsetXY32(srcRightInt, srcBottomInt));
                            double a_w      = ((srcColor >> CO.A_SHIFT) & 0xff) * (srcBottomWeight * srcRightWeight);

                            blueSum  += ((srcColor >> CO.B_SHIFT) & 0xff) * a_w;
                            greenSum += ((srcColor >> CO.G_SHIFT) & 0xff) * a_w;
                            redSum   += ((srcColor >> CO.R_SHIFT) & 0xff) * a_w;
                            alphaSum += a_w;
                        }


                        double area = (srcRight - srcLeft) * (srcBottom - srcTop);

                        double alpha = alphaSum / area;
                        double blue;
                        double green;
                        double red;

                        if (alpha == 0)
                        {
                            blue  = 0;
                            green = 0;
                            red   = 0;
                        }
                        else
                        {
                            blue  = blueSum / alphaSum;
                            green = greenSum / alphaSum;
                            red   = redSum / alphaSum;
                        }

                        // add 0.5 so that rounding goes in the direction we want it to
                        blue  += 0.5;
                        green += 0.5;
                        red   += 0.5;
                        alpha += 0.5;


                        //***
                        //dstPtr->Bgra = (uint)blue + ((uint)green << 8) + ((uint)red << 16) + ((uint)alpha << 24);
                        //++dstPtr;
                        *dstAddr = ((byte)alpha) << CO.A_SHIFT |
                                   ((byte)blue) << CO.B_SHIFT |
                                   ((byte)green) << CO.G_SHIFT |
                                   ((byte)red) << CO.R_SHIFT;

                        //(uint)blue + ((uint)green << 8) + ((uint)red << 16) + ((uint)alpha << 24);
                        ++dstAddr;
                    }
                }
            }
            return(thumbBitmap);
        }
コード例 #7
0
        // Create
        //--------------------------------------------------------------------
        public void Create(IBitmapSrc 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

            _height          = (int)AggMath.uceil(src.Height);
            _width           = (int)AggMath.uceil(src.Width);
            _width_hr        = (int)AggMath.uround(src.Width * LineAA.SUBPIXEL_SCALE);
            _half_height_hr  = (int)AggMath.uround(src.Height * LineAA.SUBPIXEL_SCALE / 2);
            _offset_y_hr     = _dilation_hr + _half_height_hr - LineAA.SUBPIXEL_SCALE / 2;
            _half_height_hr += LineAA.SUBPIXEL_SCALE / 2;
            int bufferWidth    = _width + _dilation * 2;
            int bufferHeight   = _height + _dilation * 2;
            int bytesPerPixel  = src.BitDepth / 8;
            int newSizeInBytes = bufferWidth * bufferHeight * bytesPerPixel;

            if (_DataSizeInBytes < newSizeInBytes)
            {
                _DataSizeInBytes = newSizeInBytes;

                _data.Dispose();

                IntPtr nativeBuff = System.Runtime.InteropServices.Marshal.AllocHGlobal(_DataSizeInBytes);
                _data = new TempMemPtr(nativeBuff, _DataSizeInBytes);
            }

            _buf = new PixelProcessing.SubBitmapBlender(_data, 0, bufferWidth, bufferHeight, bufferWidth * bytesPerPixel, src.BitDepth, bytesPerPixel);

            unsafe
            {
                using (TempMemPtr destMemPtr = _buf.GetBufferPtr())
                    using (TempMemPtr srcMemPtr = src.GetBufferPtr())
                    {
                        int *destBuffer = (int *)destMemPtr.Ptr;
                        int *srcBuffer  = (int *)srcMemPtr.Ptr;
                        // copy the image into the middle of the dest
                        for (int y = 0; y < _height; y++)
                        {
                            for (int x = 0; x < _width; x++)
                            {
                                int sourceOffset = src.GetBufferOffsetXY32(x, y);
                                int destOffset   = _buf.GetBufferOffsetXY32(_dilation, y + _dilation);
                                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 < _height; y++)
                        {
                            int s1Offset = src.GetBufferOffsetXY32(0, y);
                            int d1Offset = _buf.GetBufferOffsetXY32(_dilation + _width, y);
                            int s2Offset = src.GetBufferOffsetXY32(_width - _dilation, y);
                            int d2Offset = _buf.GetBufferOffsetXY32(0, y);

                            for (int x = 0; x < _dilation; x++)
                            {
                                destBuffer[d1Offset++] = srcBuffer[s1Offset++];
                                destBuffer[d2Offset++] = srcBuffer[s2Offset++];
                            }
                        }
                    }
            }
        }
コード例 #8
0
        // Create
        //--------------------------------------------------------------------
        public void Create(IBitmapSrc 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)AggMath.uceil(src.Height);
            m_width           = (int)AggMath.uceil(src.Width);
            m_width_hr        = (int)AggMath.uround(src.Width * LineAA.SUBPIXEL_SCALE);
            m_half_height_hr  = (int)AggMath.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 int[m_DataSizeInBytes / 4];
            }


            m_buf = new PixelProcessing.SubBitmapBlender(m_data, 0, bufferWidth, bufferHeight, bufferWidth * bytesPerPixel, src.BitDepth, bytesPerPixel);

            unsafe
            {
                CpuBlit.Imaging.TempMemPtr destMemPtr = m_buf.GetBufferPtr();
                CpuBlit.Imaging.TempMemPtr srcMemPtr  = src.GetBufferPtr();

                int *destBuffer = (int *)destMemPtr.Ptr;
                int *srcBuffer  = (int *)srcMemPtr.Ptr;
                // 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.GetBufferOffsetXY32(x, y);
                        int destOffset   = m_buf.GetBufferOffsetXY32(m_dilation, y + m_dilation);
                        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.GetBufferOffsetXY32(0, y);
                    int d1Offset = m_buf.GetBufferOffsetXY32(m_dilation + m_width, y);
                    int s2Offset = src.GetBufferOffsetXY32(m_width - m_dilation, y);
                    int d2Offset = m_buf.GetBufferOffsetXY32(0, y);

                    for (int x = 0; x < m_dilation; x++)
                    {
                        destBuffer[d1Offset++] = srcBuffer[s1Offset++];
                        destBuffer[d2Offset++] = srcBuffer[s2Offset++];
                    }
                }

                srcMemPtr.Release();
                destMemPtr.Release();
            }
        }
コード例 #9
0
        void CopyFromNoClipping(IBitmapSrc sourceImage, Q1Rect 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.GetBufferOffsetXY32(clippedSourceImageRect.Left, clippedSourceImageRect.Bottom);

                unsafe
                {
                    using (TempMemPtr memPtr = sourceImage.GetBufferPtr())
                        using (TempMemPtr destPtr = this.GetBufferPtr())
                        {
                            byte *sourceBuffer = (byte *)memPtr.Ptr;
                            byte *destBuffer   = (byte *)destPtr.Ptr;
                            int   destOffset   = GetBufferOffsetXY32(clippedSourceImageRect.Left + destXOffset, clippedSourceImageRect.Bottom + destYOffset);

                            for (int i = 0; i < clippedSourceImageRect.Height; i++)
                            {
                                PixelFarm.Drawing.Internal.MemMx.memmove(destBuffer, destOffset * 4, sourceBuffer, sourceOffset, lengthInBytes);
                                sourceOffset += sourceImage.Stride;
                                destOffset   += Stride;
                            }
                        }
                }
            }
            else
            {
                bool haveConversion = true;
                switch (sourceImage.BitDepth)
                {
                case 24:
                    switch (BitDepth)
                    {
                    case 32:
                    {
                        //TODO: review here, this may not correct
                        int numPixelsToCopy = clippedSourceImageRect.Width;
                        for (int i = clippedSourceImageRect.Bottom; i < clippedSourceImageRect.Top; i++)
                        {
                            int sourceOffset = sourceImage.GetBufferOffsetXY32(clippedSourceImageRect.Left, clippedSourceImageRect.Bottom + i);

                            //byte[] sourceBuffer = sourceImage.GetBuffer();
                            //byte[] destBuffer = GetBuffer();

                            using (TempMemPtr srcMemPtr = sourceImage.GetBufferPtr())
                                using (TempMemPtr destBufferPtr = this.GetBufferPtr())
                                {
                                    int destOffset = GetBufferOffsetXY32(
                                        clippedSourceImageRect.Left + destXOffset,
                                        clippedSourceImageRect.Bottom + i + destYOffset);
                                    unsafe
                                    {
                                        int *destBuffer   = (int *)destBufferPtr.Ptr;
                                        int *sourceBuffer = (int *)srcMemPtr.Ptr;
                                        for (int x = 0; x < numPixelsToCopy; x++)
                                        {
                                            int color = sourceBuffer[sourceOffset++];

                                            destBuffer[destOffset++] =
                                                (255 << 24) |          //a
                                                (color & 0xff0000) |   //b
                                                (color & 0x00ff00) |   //g
                                                (color & 0xff);

                                            //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");
                }
            }
        }