예제 #1
0
 /// <summary>
 /// blend multiple pixels
 /// </summary>
 /// <param name="dstBuffer"></param>
 /// <param name="arrayElemOffset"></param>
 /// <param name="sourceColors"></param>
 /// <param name="sourceColorsOffset"></param>
 /// <param name="covers"></param>
 /// <param name="coversIndex"></param>
 /// <param name="firstCoverForAll"></param>
 /// <param name="count"></param>
 internal abstract void BlendPixels(
     Imaging.TempMemPtr dstBuffer, int arrayElemOffset,
     Color[] sourceColors, int sourceColorsOffset,
     byte[] covers, int coversIndex, bool firstCoverForAll, int count);
예제 #2
0
 /// <summary>
 /// copy multiple pixels
 /// </summary>
 /// <param name="dstBuffer"></param>
 /// <param name="arrayOffset"></param>
 /// <param name="srcColor"></param>
 /// <param name="count"></param>
 internal abstract void CopyPixels(Imaging.TempMemPtr dstBuffer, int arrayOffset, Color srcColor, int count);
예제 #3
0
 //
 /// <summary>
 /// blend multiple pixels
 /// </summary>
 /// <param name="dstBuffer"></param>
 /// <param name="arrayOffset"></param>
 /// <param name="srcColor"></param>
 internal abstract void BlendPixels(Imaging.TempMemPtr dstBuffer, int arrayOffset, Color srcColor);
예제 #4
0
        /// <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);
        }
예제 #5
0
        //public static void InvertColor(this MemBitmap memBmp)
        //{
        //    //temp fix
        //    unsafe
        //    {
        //        Imaging.TempMemPtr tmp = MemBitmap.GetBufferPtr(memBmp);
        //        int* buffer = (int*)tmp.Ptr;
        //        int len32 = tmp.LengthInBytes / 4;
        //        unsafe
        //        {
        //            {
        //                int* head_i32 = (int*)buffer;
        //                for (int n = len32 - 1; n >= 0; --n)
        //                {
        //                    int value = *head_i32;
        //                    int r = (value >> CO.R_SHIFT) & 0xff;
        //                    int g = (value >> CO.G_SHIFT) & 0xff;
        //                    int b = (value >> CO.B_SHIFT) & 0xff;
        //                    int a = (value >> CO.A_SHIFT) & 0xff;

        //                    *head_i32 = ((255 - r) << CO.R_SHIFT) | ((255 - g) << CO.G_SHIFT) | ((255 - b) << CO.B_SHIFT) | ((255 - a) << CO.A_SHIFT);
        //                    head_i32++;
        //                }
        //            }
        //        }
        //    }
        //}
        internal static void Clear(Imaging.TempMemPtr tmp, Color color)
        {
            unsafe
            {
                int *buffer = (int *)tmp.Ptr;
                int  len32  = tmp.LengthInBytes / 4;

                //------------------------------
                //fast clear buffer
                //skip clipping ****
                //TODO: reimplement clipping***
                //------------------------------
                if (color == Color.White)
                {
                    //fast cleat with white color
                    int n = len32;
                    unsafe
                    {
                        //fixed (void* head = &buffer[0])
                        {
                            uint *head_i32 = (uint *)buffer;
                            for (int i = n - 1; i >= 0; --i)
                            {
                                *head_i32 = 0xffffffff; //white (ARGB)
                                head_i32++;
                            }
                        }
                    }
                }
                else if (color == Color.Black)
                {
                    //fast clear with black color
                    int n = len32;
                    unsafe
                    {
                        //fixed (void* head = &buffer[0])
                        {
                            uint *head_i32 = (uint *)buffer;
                            for (int i = n - 1; i >= 0; --i)
                            {
                                *head_i32 = 0xff000000; //black (ARGB)
                                head_i32++;
                            }
                        }
                    }
                }
                else if (color == Color.Empty)
                {
                    int n = len32;
                    unsafe
                    {
                        //fixed (void* head = &buffer[0])
                        {
                            uint *head_i32 = (uint *)buffer;
                            for (int i = n - 1; i >= 0; --i)
                            {
                                *head_i32 = 0x00000000; //empty
                                head_i32++;
                            }
                        }
                    }
                }
                else
                {
                    //other color
                    //#if WIN
                    //                            uint colorARGB = (uint)((color.alpha << 24) | ((color.red << 16) | (color.green << 8) | color.blue));
                    //#else
                    //                            uint colorARGB = (uint)((color.alpha << 24) | ((color.blue << 16) | (color.green << 8) | color.red));
                    //#endif

                    //ARGB
                    uint colorARGB = (uint)((color.alpha << CO.A_SHIFT) | ((color.red << CO.R_SHIFT) | (color.green << CO.G_SHIFT) | color.blue << CO.B_SHIFT));
                    int  n         = len32;
                    unsafe
                    {
                        //fixed (void* head = &buffer[0])
                        {
                            uint *head_i32 = (uint *)buffer;
                            for (int i = n - 1; i >= 0; --i)
                            {
                                *head_i32 = colorARGB;
                                head_i32++;
                            }
                        }
                    }
                }
            }
        }
        public void SetPixelHighRes(BitmapBlenderBase sourceImage,
                                    Color[] destBuffer,
                                    int destBufferOffset,
                                    int x,
                                    int y)
        {
            int r, g, b, a;

            r = g = b = a = LineAA.SUBPIXEL_SCALE * LineAA.SUBPIXEL_SCALE / 2;
            int weight;
            int x_lr = x >> LineAA.SUBPIXEL_SHIFT;
            int y_lr = y >> LineAA.SUBPIXEL_SHIFT;

            x &= LineAA.SUBPIXEL_MARK;
            y &= LineAA.SUBPIXEL_MARK;
            int sourceOffset;

            //
            unsafe
            {
                Imaging.TempMemPtr ptr1 = sourceImage.GetBufferPtr();
                int *ptr = (int *)ptr1.Ptr;
                sourceOffset = sourceImage.GetBufferOffsetXY32(x_lr, y_lr);
                weight       = (LineAA.SUBPIXEL_SCALE - x) *
                               (LineAA.SUBPIXEL_SCALE - y);
                //
                int ptr_v = ptr[sourceOffset];
                r += weight * ((ptr_v >> (CO.R_SHIFT) & 0xff)); // ptr[sourceOffset + CO.R];
                g += weight * ((ptr_v >> (CO.G_SHIFT) & 0xff)); //ptr[sourceOffset + CO.G];
                b += weight * ((ptr_v >> (CO.B_SHIFT) & 0xff)); //ptr[sourceOffset + CO.B];
                a += weight * ((ptr_v >> (CO.A_SHIFT) & 0xff)); //ptr[sourceOffset + CO.A];
                                                                //
                sourceOffset += 1;                              // sourceImage.BytesBetweenPixelsInclusive;
                weight        = x * (LineAA.SUBPIXEL_SCALE - y);
                //r += weight * ptr[sourceOffset + CO.R];
                //g += weight * ptr[sourceOffset + CO.G];
                //b += weight * ptr[sourceOffset + CO.B];
                //a += weight * ptr[sourceOffset + CO.A];
                ptr_v = ptr[sourceOffset];
                r    += weight * ((ptr_v >> (CO.R_SHIFT) & 0xff)); // ptr[sourceOffset + CO.R];
                g    += weight * ((ptr_v >> (CO.G_SHIFT) & 0xff)); //ptr[sourceOffset + CO.G];
                b    += weight * ((ptr_v >> (CO.B_SHIFT) & 0xff)); //ptr[sourceOffset + CO.B];
                a    += weight * ((ptr_v >> (CO.A_SHIFT) & 0xff)); //ptr[sourceOffset + CO.A];

                //
                sourceOffset = sourceImage.GetBufferOffsetXY32(x_lr, y_lr + 1);
                weight       = (LineAA.SUBPIXEL_SCALE - x) * y;
                //r += weight * ptr[sourceOffset + CO.R];
                //g += weight * ptr[sourceOffset + CO.G];
                //b += weight * ptr[sourceOffset + CO.B];
                //a += weight * ptr[sourceOffset + CO.A];
                ptr_v = ptr[sourceOffset];
                r    += weight * ((ptr_v >> (CO.R_SHIFT) & 0xff)); // ptr[sourceOffset + CO.R];
                g    += weight * ((ptr_v >> (CO.G_SHIFT) & 0xff)); //ptr[sourceOffset + CO.G];
                b    += weight * ((ptr_v >> (CO.B_SHIFT) & 0xff)); //ptr[sourceOffset + CO.B];
                a    += weight * ((ptr_v >> (CO.A_SHIFT) & 0xff)); //ptr[sourceOffset + CO.A];
                                                                   //
                sourceOffset += 1;                                 // sourceImage.BytesBetweenPixelsInclusive;
                weight        = x * y;
                //r += weight * ptr[sourceOffset + CO.R];
                //g += weight * ptr[sourceOffset + CO.G];
                //b += weight * ptr[sourceOffset + CO.B];
                //a += weight * ptr[sourceOffset + CO.A];

                ptr_v = ptr[sourceOffset];
                r    += weight * ((ptr_v >> (CO.R_SHIFT) & 0xff)); // ptr[sourceOffset + CO.R];
                g    += weight * ((ptr_v >> (CO.G_SHIFT) & 0xff)); //ptr[sourceOffset + CO.G];
                b    += weight * ((ptr_v >> (CO.B_SHIFT) & 0xff)); //ptr[sourceOffset + CO.B];
                a    += weight * ((ptr_v >> (CO.A_SHIFT) & 0xff)); //ptr[sourceOffset + CO.A];


                //destBuffer[destBufferOffset].red = (byte)(r >> LineAA.SUBPIXEL_SHIFT * 2);
                //destBuffer[destBufferOffset].green = (byte)(g >> LineAA.SUBPIXEL_SHIFT * 2);
                //destBuffer[destBufferOffset].blue = (byte)(b >> LineAA.SUBPIXEL_SHIFT * 2);
                //destBuffer[destBufferOffset].alpha = (byte)(a >> LineAA.SUBPIXEL_SHIFT * 2);
            }

            destBuffer[destBufferOffset] = Color.FromArgb(
                (byte)(a >> LineAA.SUBPIXEL_SHIFT * 2),
                (byte)(r >> LineAA.SUBPIXEL_SHIFT * 2),
                (byte)(g >> LineAA.SUBPIXEL_SHIFT * 2),
                (byte)(b >> LineAA.SUBPIXEL_SHIFT * 2)
                );
        }
예제 #7
0
 protected void SetBuffer(Imaging.TempMemPtr tmpMem)
 {
     _raw_buffer32        = tmpMem.Ptr;
     _rawBufferLenInBytes = tmpMem.LengthInBytes;
 }