Beispiel #1
1
        private static RGBQUAD ConvertYCrCbToRGB(byte y, byte cr, byte cb)
        {
            RGBQUAD rgbq = new RGBQUAD();

            int c = y - 16;
            int d = cb - 128;
            int e = cr - 128;

            rgbq.R = Clip((298 * c + 409 * e + 128) >> 8);
            rgbq.G = Clip((298 * c - 100 * d - 208 * e + 128) >> 8);
            rgbq.B = Clip((298 * c + 516 * d + 128) >> 8);

            return(rgbq);
        }
Beispiel #2
0
        public void CreateDIBitmapTest2()
        {
            BITMAPINFO bmi = new()
            {
                bmiHeader = new(4, 4, 8)
                {
                    biXPelsPerMeter = 1,
                    biYPelsPerMeter = 1,
                    biClrUsed       = 1,
                },
                bmiColors = new RGBQUAD[1]
            };
            BITMAPINFO bmiBroken = new()
            {
                bmiHeader = new(-2, -4, 42)
                {
                    biPlanes        = 55,
                    biXPelsPerMeter = 1,
                    biYPelsPerMeter = 1,
                    biClrUsed       = 1,
                },
                bmiColors = new RGBQUAD[1]
            };

            byte[] ajBits = new byte[10];

            using var hdc = CreateCompatibleDC();
            Assert.That(hdc, ResultIs.ValidHandle);

            var hbmp = CreateDIBitmap(hdc, bmi.bmiHeader, CBM.CBM_INIT, ajBits, bmi, DIBColorMode.DIB_PAL_COLORS);

            Assert.That(hbmp, ResultIs.ValidHandle);

            hbmp = CreateDIBitmap(hdc, bmi.bmiHeader, CBM.CBM_INIT, default, bmi, DIBColorMode.DIB_PAL_COLORS);
Beispiel #3
0
        public unsafe override void Read(Stream stream, int resourceSize)
        {
            // BitmapInfoHeader
            mHeader.Read(stream);

            // Palette
            mColors = new RGBQUAD[ColorsInPalette];
            byte[] colorBuffer = new byte[mColors.Length * sizeof(RGBQUAD)];
            stream.Read(colorBuffer, 0, colorBuffer.Length);
            GCHandle handle = GCHandle.Alloc(mColors, GCHandleType.Pinned);

            Marshal.Copy(colorBuffer, 0, handle.AddrOfPinnedObject(), colorBuffer.Length);
            handle.Free();

            // XOR Image
            int stride = (int)((mHeader.biWidth * mHeader.biBitCount + 31) & ~31) >> 3;

            mXOR = new byte[stride * (mHeader.biHeight / 2)];
            stream.Read(mXOR, 0, mXOR.Length);

            // AND Image
            stride = (int)((mHeader.biWidth * 1 + 31) & ~31) >> 3;
            mAND   = new byte[stride * (mHeader.biHeight / 2)];
            stream.Read(mAND, 0, mAND.Length);
        }
Beispiel #4
0
        private static int InitPalette(RGBQUAD[] targetPalette, int bpp, ColorPalette originalPalette, Color[] desiredPalette, out int transparentIndex)
        {
            int maxColors = 1 << bpp;

            // using desired palette
            Color[] sourcePalette = desiredPalette;

            // or, using original palette if it has fewer or the same amount of colors as requested
            if (sourcePalette == null && originalPalette != null && originalPalette.Entries.Length > 0 && originalPalette.Entries.Length <= maxColors)
            {
                sourcePalette = originalPalette.Entries;
            }

            // or, using default system palette
            if (sourcePalette == null)
            {
                using (Bitmap bmpReference = new Bitmap(1, 1, GetPixelFormat(bpp))) {
                    sourcePalette = bmpReference.Palette.Entries;
                }
            }

            // it is ignored if source has too few colors (rest of the entries will be black)
            transparentIndex = -1;
            bool hasBlack   = false;
            int  colorCount = Math.Min(maxColors, sourcePalette.Length);

            for (int i = 0; i < colorCount; i++)
            {
                targetPalette[i] = new RGBQUAD(sourcePalette[i]);
                if (transparentIndex == -1 && sourcePalette[i].A == 0)
                {
                    transparentIndex = i;
                }
                if (!hasBlack && (sourcePalette[i].ToArgb() & 0xFFFFFF) == 0)
                {
                    hasBlack = true;
                }
            }

            // if transparent index is 0, relocating it and setting transparent index to 1
            if (transparentIndex == 0)
            {
                targetPalette[0] = targetPalette[1];
                transparentIndex = 1;
            }
            // otherwise, setting the color of transparent index the same as the previous color, so it will not be used during the conversion
            else if (transparentIndex != -1)
            {
                targetPalette[transparentIndex] = targetPalette[transparentIndex - 1];
            }

            // if black color is not found in palette, counting 1 extra colors because it can be used in conversion
            if (colorCount < maxColors && !hasBlack)
            {
                colorCount++;
            }

            return(colorCount);
        }
Beispiel #5
0
    public static unsafe RGBQUAD[] TransformColorsTo_sRGB(SafeProfileHandle source, RGBQUAD[] color, mscmsIntent dwIntent)
    {
        var colorSize = Environment.Is64BitProcess ? 16 : 8;
        var size      = colorSize * color.Length;

        // https://docs.microsoft.com/en-us/windows/win32/api/icm/nf-icm-translatecolors
        // https://docs.microsoft.com/en-us/windows/win32/api/icm/ns-icm-color

        IntPtr paInputColors  = Marshal.AllocHGlobal(size);
        IntPtr paOutputColors = Marshal.AllocHGlobal(size);

        const double cmax  = 255d;
        const double nmax  = 0xFFFF;
        const ushort nmask = 0xFFFF;

        try
        {
            var inputPtr = (byte *)paInputColors;
            foreach (var c in color)
            {
                var nclr = (long)(c.rgbRed / cmax * nmax) | ((long)(c.rgbGreen / cmax * nmax) << 16) | ((long)(c.rgbBlue / cmax * nmax) << 32);
                *((long *)inputPtr) = nclr;
                inputPtr           += colorSize;
            }

            using (var dest = OpenProfile_sRGB())
                using (var transform = CreateTransform(source, dest, dwIntent))
                {
                    var success = TranslateColors(transform, paInputColors, (uint)color.Length, COLOR_TYPE.COLOR_3_CHANNEL, paOutputColors, COLOR_TYPE.COLOR_3_CHANNEL);
                    if (!success)
                    {
                        throw new Win32Exception();
                    }

                    var outputPtr = (byte *)paOutputColors;
                    var output    = new RGBQUAD[color.Length];
                    for (int i = 0; i < color.Length; i++)
                    {
                        long nclr = *((long *)outputPtr);
                        output[i] = new RGBQUAD
                        {
                            rgbRed   = (byte)((nclr & nmask) / nmax * cmax),
                            rgbGreen = (byte)(((nclr >> 16) & nmask) / nmax * cmax),
                            rgbBlue  = (byte)(((nclr >> 32) & nmask) / nmax * cmax),
                        };
                        outputPtr += colorSize;
                    }

                    return(output);
                }
        }
        finally
        {
            Marshal.FreeHGlobal(paInputColors);
            Marshal.FreeHGlobal(paOutputColors);
        }
    }
 public static RGBQUAD[] GetL8Palette()
 {
     RGBQUAD[] quad = new RGBQUAD[256];
     for (int i = 0; i < 256; i++)
     {
         quad[i] = Color.FromArgb(i, 255, 255, 255);
     }
     return(quad);
 }
Beispiel #7
0
    public void PopulateWithData(byte[] data, int StartAddress)

    {
        bmiHeader = new BITMAPINFOHEADER();

        bmiHeader.PopulateWithData(data, StartAddress + 0);

        bmiColors = new RGBQUAD();

        bmiColors.PopulateWithData(data, StartAddress + 40);
    }
Beispiel #8
0
        public void ApplyFilters(List <Schema.SkinFile.Attachment.Filter> filters)
        {
            if (dib.IsNull)
            {
                return;
            }

            foreach (Schema.SkinFile.Attachment.Filter filter in filters)
            {
                switch (filter.name)
                {
                case "invert":
                {
                    ///
                    /// TODO: Variable invertion using amount property
                    ///
                    FreeImage.AdjustColors(dib, 0, 0, 0, true);
                    break;
                }

                case "colorOverlay":
                {
                    try
                    {
                        ///
                        /// TODO: Variable overlay using amount property
                        ///
                        RGBQUAD overlayColor = new RGBQUAD(), oldColor;
                        overlayColor.uintValue = Convert.ToUInt32(filter.color, 16);
                        //Console.WriteLine((double)filter.amount / 100);
                        for (uint y = 0; y < FreeImage.GetHeight(dib); y++)
                        {
                            for (uint x = 0; x < FreeImage.GetWidth(dib); x++)
                            {
                                FreeImage.GetPixelColor(dib, x, y, out oldColor);
                                overlayColor.rgbReserved = oldColor.rgbReserved;
                                FreeImage.SetPixelColor(dib, x, y, ref overlayColor);
                            }
                        }
                    }
                    catch { }
                    break;
                }
                }
            }
        }
Beispiel #9
0
        // Таблица цветов из WallControll-a
        private static RGBQUAD[] GetColourMask(PixelFormat format)
        {
            RGBQUAD[] array = new RGBQUAD[3];
            if (format == PixelFormat.Format16bppRgb555)
            {
                array[0].rgbBlue  = 0;
                array[0].rgbGreen = 124;
                array[0].rgbRed   = 0;
                array[1].rgbBlue  = 224;
                array[1].rgbGreen = 3;
                array[1].rgbRed   = 0;
                array[2].rgbBlue  = 31;
                array[2].rgbGreen = 0;
                array[2].rgbRed   = 0;
            }
            else if (format == PixelFormat.Format16bppRgb565)
            {
                array[0].rgbBlue  = 0;
                array[0].rgbGreen = 248;
                array[0].rgbRed   = 0;
                array[1].rgbBlue  = 224;
                array[1].rgbGreen = 7;
                array[1].rgbRed   = 0;
                array[2].rgbBlue  = 31;
                array[2].rgbGreen = 0;
                array[2].rgbRed   = 0;
            }
            else if (format == PixelFormat.Format32bppRgb)
            {
                array[0].rgbBlue  = 0;
                array[0].rgbGreen = 0;
                array[0].rgbRed   = byte.MaxValue;
                array[1].rgbBlue  = 0;
                array[1].rgbGreen = byte.MaxValue;
                array[1].rgbRed   = 0;
                array[2].rgbBlue  = byte.MaxValue;
                array[2].rgbGreen = 0;
                array[2].rgbRed   = 0;
            }
            else
            {
                throw new Exception("Invalid Pixel Format");
            }

            return(array);
        }
        public void RGBQUAD()
        {
            RGBQUAD rgbq = new RGBQUAD();

            Assert.AreEqual(0, rgbq.rgbBlue);
            Assert.AreEqual(0, rgbq.rgbGreen);
            Assert.AreEqual(0, rgbq.rgbRed);
            Assert.AreEqual(0, rgbq.rgbReserved);

            rgbq = new RGBQUAD(Color.Chartreuse);
            Assert.That(EqualColors(Color.Chartreuse, rgbq.Color));

            rgbq = new RGBQUAD(Color.FromArgb(133, 83, 95, 173));
            Assert.AreEqual(173, rgbq.rgbBlue);
            Assert.AreEqual(95, rgbq.rgbGreen);
            Assert.AreEqual(83, rgbq.rgbRed);
            Assert.AreEqual(133, rgbq.rgbReserved);

            rgbq.Color = Color.Crimson;
            Assert.That(EqualColors(Color.Crimson, rgbq.Color));

            rgbq.Color = Color.MidnightBlue;
            Assert.That(EqualColors(Color.MidnightBlue, rgbq.Color));

            rgbq.Color = Color.White;
            Assert.AreEqual(255, rgbq.rgbBlue);
            Assert.AreEqual(255, rgbq.rgbGreen);
            Assert.AreEqual(255, rgbq.rgbRed);
            Assert.AreEqual(255, rgbq.rgbReserved);

            rgbq.Color = Color.Black;
            Assert.AreEqual(0, rgbq.rgbBlue);
            Assert.AreEqual(0, rgbq.rgbGreen);
            Assert.AreEqual(0, rgbq.rgbRed);
            Assert.AreEqual(255, rgbq.rgbReserved);

            rgbq = Color.DarkGoldenrod;
            Color color = rgbq;

            Assert.That(EqualColors(Color.DarkGoldenrod, color));
        }
Beispiel #11
0
        public unsafe override void Read(Stream stream, int resourceSize)
        {
            // BitmapInfoHeader
            mHeader.Read(stream);

            // Palette
            mColors             = new RGBQUAD[ColorsInPalette];
            byte[] colorBuffer  = new byte[mColors.Length * sizeof(RGBQUAD)];
            stream.Read(colorBuffer, 0, colorBuffer.Length);
            GCHandle handle = GCHandle.Alloc(mColors, GCHandleType.Pinned);
            Marshal.Copy(colorBuffer, 0, handle.AddrOfPinnedObject(), colorBuffer.Length);
            handle.Free();

            // XOR Image
            int stride = (int) ((mHeader.biWidth * mHeader.biBitCount + 31) & ~31) >> 3;
            mXOR = new byte[stride * (mHeader.biHeight / 2)];
            stream.Read(mXOR, 0, mXOR.Length);

            // AND Image
            stride = (int) ((mHeader.biWidth * 1 + 31) & ~31) >> 3;
            mAND = new byte[stride * (mHeader.biHeight / 2)];
            stream.Read(mAND, 0, mAND.Length);
        }
Beispiel #12
0
        /// <summary>
        /// Builds an FIBitmap from the stream and job.Settings
        /// </summary>
        /// <param name="original"></param>
        /// <param name="supportsTransparency"></param>
        /// <param name="mayUnloadOriginal"></param>
        /// <param name="job"></param>
        /// <returns></returns>
        protected FIBITMAP buildFiBitmap(ref FIBITMAP original, ImageJob job, bool supportsTransparency, bool mayUnloadOriginal)
        {
            ResizeSettings settings = job.Settings;

            if (original.IsNull)
            {
                return(FIBITMAP.Zero);
            }
            FIBITMAP final = FIBITMAP.Zero;

            //Find the image size
            Size orig = new Size((int)FreeImage.GetWidth(original), (int)FreeImage.GetHeight(original));

            //Calculate the new size of the image and the canvas.
            ImageState state = new ImageState(settings, orig, true);

            state.Job = job;
            c.CurrentImageBuilder.Process(state);
            RectangleF imageDest = PolygonMath.GetBoundingBox(state.layout["image"]);

            if (imageDest.Width != orig.Width || imageDest.Height != orig.Height)
            {
                //Rescale
                bool temp;
                final = FreeImage.Rescale(original, (int)imageDest.Width, (int)imageDest.Height, FreeImageScalingPlugin.ParseResizeAlgorithm(settings["fi.scale"], FREE_IMAGE_FILTER.FILTER_BOX, out temp));
                if (mayUnloadOriginal)
                {
                    FreeImage.UnloadEx(ref original);
                }
                if (final.IsNull)
                {
                    return(FIBITMAP.Zero);
                }
            }
            else
            {
                final = original;
            }

            RGBQUAD bgcolor = default(RGBQUAD);

            bgcolor.Color = settings.BackgroundColor;
            if (settings.BackgroundColor == Color.Transparent && !supportsTransparency)
            {
                bgcolor.Color = Color.White;
            }

            //If we need to leave padding, do so.
            BoxPadding outsideImage = new BoxPadding(imageDest.Left, imageDest.Top, state.destSize.Width - imageDest.Right, state.destSize.Height - imageDest.Bottom);

            if (outsideImage.All != 0)
            {
                var old = final;
                //Extend canvas
                final = FreeImage.EnlargeCanvas <RGBQUAD>(old,
                                                          (int)outsideImage.Left, (int)outsideImage.Top, (int)outsideImage.Right, (int)outsideImage.Bottom,
                                                          bgcolor.Color != Color.Transparent ? new Nullable <RGBQUAD>(bgcolor) : null,
                                                          FREE_IMAGE_COLOR_OPTIONS.FICO_RGBA);
                if (old == original)
                {
                    if (mayUnloadOriginal)
                    {
                        FreeImage.UnloadEx(ref original);
                        old = original;
                    }
                }
                else
                {
                    FreeImage.UnloadEx(ref old); //'old' has the original value of 'final', which we allocated.
                }
                if (final.IsNull)
                {
                    return(FIBITMAP.Zero);
                }
            }

            if (!final.IsNull)
            {
                job.ResultInfo["final.width"]  = (int)FreeImage.GetWidth(final);
                job.ResultInfo["final.height"] = (int)FreeImage.GetHeight(final);
            }

            return(final);
        }
Beispiel #13
0
        public void Write(System.Drawing.Image i, System.IO.Stream s)
        {
            if (!(i is Bitmap))
            {
                throw new ArgumentException("FreeImageEncoder only works with bitmaps");
            }
            FIBITMAP bit = FreeImage.CreateFromBitmap(i as Bitmap);

            if (bit.IsNull)
            {
                throw new ImageProcessingException("FreeImageEncoder failed to convert System.Drawing.Bitmap to FIBITMAP");
            }
            if (Format == FREE_IMAGE_FORMAT.FIF_GIF || (Format == FREE_IMAGE_FORMAT.FIF_PNG && colors != -1))
            {
                FreeImage.SetTransparent(bit, true);
                FIBITMAP old = bit;
                //TODO - ColorQuantizeEx returns null no matter what we do.. Is it because the image is 32-bit?
                bit = FreeImage.ColorQuantizeEx(bit, FREE_IMAGE_QUANTIZE.FIQ_NNQUANT, 256, 1, RGBQUAD.ToRGBQUAD(new Color[] { Color.Transparent }));
                if (bit.IsNull)
                {
                    bit = old;
                }
                else if (bit != old)
                {
                    FreeImage.UnloadEx(ref old);
                }
            }
            FreeImage.SaveToStream(ref bit, s, Format, EncodingOptions, true);
        }
Beispiel #14
0
    public static void ReadHeader(byte *source, int sourceLength, out BITMAP_READ_DETAILS info, uint bcrFlags)
    {
        var ptr = source;

        if ((sourceLength) < 12) // min header size
        {
            throw new InvalidOperationException(ERR_HEOF);
        }

        bool hasFileHeader = StructUtil.ReadU16(ptr) == BFH_BM;
        var  size_fh       = Marshal.SizeOf <BITMAPFILEHEADER>();

        int offset = 0;
        var fh     = default(BITMAPFILEHEADER);

        if (hasFileHeader)
        {
            var fhsize = Marshal.SizeOf <BITMAPFILEHEADER>();
            if (offset + fhsize > sourceLength)
            {
                throw new InvalidOperationException(ERR_HEOF);
            }

            fh      = StructUtil.Deserialize <BITMAPFILEHEADER>(ptr);
            ptr    += fhsize;
            offset += fhsize;
        }

        // we'll just unpack all the various header types we support into a standard BMPV5 header
        // this makes subsequent code easier to maintain as it only needs to refer to one place

        if ((sourceLength - offset) < 12) // min header size
        {
            throw new InvalidOperationException(ERR_HEOF);
        }

        var  header_size = StructUtil.ReadU32(ptr);
        var  bi          = default(BITMAPV5HEADER);
        bool is_os21x_   = false;

        if (header_size == 12)
        {
            var bich = StructUtil.Deserialize <BITMAPCOREHEADER>(ptr);
            bi.bV5Size     = bich.bcSize;
            bi.bV5Width    = bich.bcWidth;
            bi.bV5Height   = bich.bcHeight;
            bi.bV5Planes   = bich.bcPlanes;
            bi.bV5BitCount = bich.bcBitCount;

            bi.bV5CSType = ColorSpaceType.LCS_sRGB;
            is_os21x_    = true;
        }
        else if (/*header_size == 14 || */ header_size == 16 || header_size == 42 || header_size == 46 || header_size == 64)
        {
            var biih = StructUtil.Deserialize <BITMAPINFOHEADER>(ptr);
            bi.bV5Size     = biih.bV5Size;
            bi.bV5Width    = biih.bV5Width;
            bi.bV5Height   = biih.bV5Height;
            bi.bV5Planes   = biih.bV5Planes;
            bi.bV5BitCount = biih.bV5BitCount;

            if (header_size > 16)
            {
                bi.bV5Compression   = biih.bV5Compression;
                bi.bV5SizeImage     = biih.bV5SizeImage;
                bi.bV5XPelsPerMeter = biih.bV5XPelsPerMeter;
                bi.bV5YPelsPerMeter = biih.bV5YPelsPerMeter;
                bi.bV5ClrUsed       = biih.bV5ClrUsed;
                bi.bV5ClrImportant  = biih.bV5ClrImportant;
            }

            // https://www.fileformat.info/mirror/egff/ch09_05.htm (G31D)
            if (bi.bV5Compression == (BitmapCompressionMode)3 && bi.bV5BitCount == 1)
            {
                bi.bV5Compression = BitmapCompressionMode.OS2_HUFFMAN1D;
            }

            else if (bi.bV5Compression == (BitmapCompressionMode)4 && bi.bV5BitCount == 24)
            {
                bi.bV5Compression = BitmapCompressionMode.OS2_RLE24;
            }

            bi.bV5CSType = ColorSpaceType.LCS_sRGB;
        }
        else if (header_size == 40)
        {
            var biih = StructUtil.Deserialize <BITMAPINFOHEADER>(ptr);
            bi.bV5Size          = biih.bV5Size;
            bi.bV5Width         = biih.bV5Width;
            bi.bV5Height        = biih.bV5Height;
            bi.bV5Planes        = biih.bV5Planes;
            bi.bV5BitCount      = biih.bV5BitCount;
            bi.bV5Compression   = biih.bV5Compression;
            bi.bV5SizeImage     = biih.bV5SizeImage;
            bi.bV5XPelsPerMeter = biih.bV5XPelsPerMeter;
            bi.bV5YPelsPerMeter = biih.bV5YPelsPerMeter;
            bi.bV5ClrUsed       = biih.bV5ClrUsed;
            bi.bV5ClrImportant  = biih.bV5ClrImportant;

            bi.bV5CSType = ColorSpaceType.LCS_sRGB;
        }
        else if (header_size == 52 || header_size == 56)
        {
            var biih = StructUtil.Deserialize <BITMAPV3INFOHEADER>(ptr);
            bi.bV5Size          = biih.bV5Size;
            bi.bV5Width         = biih.bV5Width;
            bi.bV5Height        = biih.bV5Height;
            bi.bV5Planes        = biih.bV5Planes;
            bi.bV5BitCount      = biih.bV5BitCount;
            bi.bV5Compression   = biih.bV5Compression;
            bi.bV5SizeImage     = biih.bV5SizeImage;
            bi.bV5XPelsPerMeter = biih.bV5XPelsPerMeter;
            bi.bV5YPelsPerMeter = biih.bV5YPelsPerMeter;
            bi.bV5ClrUsed       = biih.bV5ClrUsed;
            bi.bV5ClrImportant  = biih.bV5ClrImportant;
            bi.bV5RedMask       = biih.bV5RedMask;
            bi.bV5GreenMask     = biih.bV5GreenMask;
            bi.bV5BlueMask      = biih.bV5BlueMask;

            if (header_size == 56) // 56b header adds alpha mask
            {
                bi.bV5AlphaMask = biih.bV5AlphaMask;
            }

            bi.bV5CSType = ColorSpaceType.LCS_sRGB;
        }
        else if (header_size == 108)
        {
            var biih = StructUtil.Deserialize <BITMAPV4HEADER>(ptr);
            bi.bV5Size          = biih.bV5Size;
            bi.bV5Width         = biih.bV5Width;
            bi.bV5Height        = biih.bV5Height;
            bi.bV5Planes        = biih.bV5Planes;
            bi.bV5BitCount      = biih.bV5BitCount;
            bi.bV5Compression   = biih.bV5Compression;
            bi.bV5SizeImage     = biih.bV5SizeImage;
            bi.bV5XPelsPerMeter = biih.bV5XPelsPerMeter;
            bi.bV5YPelsPerMeter = biih.bV5YPelsPerMeter;
            bi.bV5ClrUsed       = biih.bV5ClrUsed;
            bi.bV5ClrImportant  = biih.bV5ClrImportant;
            bi.bV5RedMask       = biih.bV5RedMask;
            bi.bV5GreenMask     = biih.bV5GreenMask;
            bi.bV5BlueMask      = biih.bV5BlueMask;
            bi.bV5AlphaMask     = biih.bV5AlphaMask;
            bi.bV5CSType        = biih.bV5CSType;
            bi.bV5Endpoints_1x  = biih.bV5Endpoints_1x;
            bi.bV5Endpoints_1y  = biih.bV5Endpoints_1y;
            bi.bV5Endpoints_1z  = biih.bV5Endpoints_1z;
            bi.bV5Endpoints_2x  = biih.bV5Endpoints_2x;
            bi.bV5Endpoints_2y  = biih.bV5Endpoints_2y;
            bi.bV5Endpoints_2z  = biih.bV5Endpoints_2z;
            bi.bV5Endpoints_3x  = biih.bV5Endpoints_3x;
            bi.bV5Endpoints_3y  = biih.bV5Endpoints_3y;
            bi.bV5Endpoints_3z  = biih.bV5Endpoints_3z;
            bi.bV5GammaRed      = biih.bV5GammaRed;
            bi.bV5GammaGreen    = biih.bV5GammaGreen;
            bi.bV5GammaBlue     = biih.bV5GammaBlue;
        }
        else if (header_size == 124)
        {
            bi = StructUtil.Deserialize <BITMAPV5HEADER>(ptr);
        }
        else
        {
            throw new NotSupportedException($"Bitmap header size '{header_size}' not known / supported.");
        }

        ptr    += header_size;
        offset += (int)header_size;

        ushort nbits = bi.bV5BitCount;

        //if (bi.bV5Planes != 1)
        //    throw new NotSupportedException($"Bitmap bV5Planes of '{bi.bV5Planes}' is not supported.");

        // we don't support linked profiles, custom windows profiles, etc - so default to sRGB instead of throwing...

        if (bi.bV5CSType != ColorSpaceType.LCS_CALIBRATED_RGB && bi.bV5CSType != ColorSpaceType.PROFILE_EMBEDDED)
        {
            bi.bV5CSType = ColorSpaceType.LCS_sRGB;
        }

        uint maskR = 0;
        uint maskG = 0;
        uint maskB = 0;
        uint maskA = 0;

        bool hasAlphaChannel       = false;
        bool skipVerifyBppAndMasks = false;

        switch (bi.bV5Compression)
        {
        case BitmapCompressionMode.BI_BITFIELDS:

            var rgb = StructUtil.Deserialize <MASKTRIPLE>(ptr);
            maskR   = rgb.rgbRed;
            maskG   = rgb.rgbGreen;
            maskB   = rgb.rgbBlue;
            offset += Marshal.SizeOf <MASKTRIPLE>();

            break;

        case BitmapCompressionMode.BI_ALPHABITFIELDS:

            var rgba = StructUtil.Deserialize <MASKQUAD>(ptr);
            maskR   = rgba.rgbRed;
            maskG   = rgba.rgbGreen;
            maskB   = rgba.rgbBlue;
            maskA   = rgba.rgbAlpha;
            offset += Marshal.SizeOf <MASKQUAD>();

            hasAlphaChannel = true;
            break;

        case BitmapCompressionMode.BI_RGB:
            switch (nbits)
            {
            case 32:
                // windows wrongly uses the 4th byte of BI_RGB 32bit dibs as alpha
                // but we need to do it too if we have any hope of reading alpha data
                maskB = 0xff;
                maskG = 0xff00;
                maskR = 0xff0000;
                maskA = 0xff000000;         // fake transparency?
                break;

            case 24:
                maskB = 0xff;
                maskG = 0xff00;
                maskR = 0xff0000;
                break;

            case 16:
                maskB = 0x001f;
                maskG = 0x03e0;
                maskR = 0x7c00;
                // we can check for transparency in 16b RGB but it is slower and is very uncommon
                // maskA = 0x8000; // fake transparency?
                break;
            }
            break;

        case BitmapCompressionMode.BI_JPEG:
        case BitmapCompressionMode.BI_PNG:
        case BitmapCompressionMode.BI_RLE4:
        case BitmapCompressionMode.BI_RLE8:
        case BitmapCompressionMode.OS2_RLE24:
            if (bi.bV5Height < 0)
            {
                throw new NotSupportedException("Top-down bitmaps are not supported with RLE/JPEG/PNG compression.");
            }
            skipVerifyBppAndMasks = true;
            break;

        case BitmapCompressionMode.OS2_HUFFMAN1D:
            if (bi.bV5Height < 0)
            {
                throw new NotSupportedException("Top-down bitmaps are not supported with Huffman1D compression.");
            }
            if (bi.bV5BitCount != 1)
            {
                throw new NotSupportedException("Huffman1D compression is only supported with 1bpp bitmaps");
            }
            skipVerifyBppAndMasks = true;
            break;

        default:
            throw new NotSupportedException($"Bitmap with bV5Compression of '{bi.bV5Compression.ToString()}' is not supported.");
        }

        // lets use the v3/v4/v5 masks if present instead of RGB
        // according to some readers (FIREFOX!) these masks are only valid if the compression mode is
        // BI_BITFIELDS, meaning they might write garbage here when the compression is RGB
        if (bi.bV5Size >= 52 && bi.bV5Compression == BitmapCompressionMode.BI_BITFIELDS)
        {
            if (bi.bV5RedMask != 0)
            {
                maskR = bi.bV5RedMask;
            }
            if (bi.bV5BlueMask != 0)
            {
                maskB = bi.bV5BlueMask;
            }
            if (bi.bV5GreenMask != 0)
            {
                maskG = bi.bV5GreenMask;
            }
        }

        // if an alpha mask has been provided in the header, lets use it.
        if (bi.bV5Size >= 56 && bi.bV5AlphaMask != 0)
        {
            maskA           = bi.bV5AlphaMask;
            hasAlphaChannel = true;
        }

        // try to infer alpha if 32bpp & no alpha mask was set (ie, BI_BITFIELDS)
        // this will only be used if the PRESERVE_FAKE_ALPHA flag is set
        if (maskA == 0 && nbits == 32)
        {
            maskA = (maskB | maskG | maskR) ^ 0xFFFFFFFF;
        }

        bool smBit = nbits == 1 || nbits == 2 || nbits == 4 || nbits == 8;
        bool lgBit = nbits == 16 || nbits == 24 || nbits == 32;

        if (!skipVerifyBppAndMasks)
        {
            if (!lgBit && !smBit)
            {
                throw new NotSupportedException($"Bitmap with bits per pixel of '{nbits}' are not valid.");
            }

            if (lgBit && maskR == 0 && maskB == 0 && maskG == 0)
            {
                throw new NotSupportedException($"Bitmap (bbp {nbits}) color masks could not be determined, this usually indicates a malformed bitmap file.");
            }
        }

        // The number of entries in the palette is either 2n (where n is the number of bits per pixel) or a smaller number specified in the header
        // always allocate at least 256 entries so we can ignore bad data which seeks past the end of palette data.
        var pallength = nbits < 16 ? (1 << nbits) : 0;

        if (bi.bV5ClrUsed > 0)
        {
            pallength = (int)bi.bV5ClrUsed;
        }

        if (pallength > 256) // technically the max is 256..? some bitmaps have invalidly/absurdly large palettes
        {
            if (hasFileHeader)
            {
                // if we have a file header, we can correct our pixel data offset below, so the only
                // important thing is that we don't read too many colors.
                pallength = 256;
            }
            else
            {
                throw new NotSupportedException("Bitmap has an oversized/invalid color palette.");
            }
        }

        RGBQUAD[] palette = new RGBQUAD[pallength];
        var       clrSize = is_os21x_ ? Marshal.SizeOf <RGBTRIPLE>() : Marshal.SizeOf <RGBQUAD>();

        for (int i = 0; i < palette.Length; i++)
        {
            if (is_os21x_)
            {
                var small = StructUtil.Deserialize <RGBTRIPLE>(ptr);
                palette[i] = new RGBQUAD {
                    rgbBlue = small.rgbBlue, rgbGreen = small.rgbGreen, rgbRed = small.rgbRed
                };
            }
            else
            {
                palette[i] = StructUtil.Deserialize <RGBQUAD>(ptr);
            }
            ptr += clrSize;
        }

        offset += pallength * clrSize;

        // For RGB DIBs, the image orientation is indicated by the biHeight member of the BITMAPINFOHEADER structure.
        // If biHeight is positive, the image is bottom-up. If biHeight is negative, the image is top-down.
        // DirectDraw uses top-down DIBs. In GDI, all DIBs are bottom-up.
        // Also, any DIB type that uses a FOURCC in the biCompression member, should express its biHeight as a positive number
        // no matter what its orientation is, since the FOURCC itself identifies a compression scheme whose image orientation
        // should be understood by any compatible filter. Common YUV formats such as UYVY, YV12, and YUY2 are top-down oriented.
        // It is invalid to store an image with these compression types in bottom-up orientation.
        // The sign of biHeight for such formats must always be set positive

        var  width   = bi.bV5Width;
        var  height  = bi.bV5Height;
        bool topDown = false;

        if (height < 0)
        {
            height  = -height;
            topDown = true;
        }

        if (width < 0)
        {
            throw new NotSupportedException("Bitmap with negative width is not allowed");
        }

        uint source_stride = StructUtil.CalcStride(nbits, width);
        uint dataOffset    = hasFileHeader ? fh.bfOffBits : (uint)offset;
        uint dataSize      = bi.bV5SizeImage > 0 ? bi.bV5SizeImage : (source_stride * (uint)height);

        if (dataOffset + dataSize > sourceLength)
        {
            throw new InvalidOperationException(ERR_HEOF);
        }

        var  profileSize   = bi.bV5ProfileSize;
        uint profileOffset = (hasFileHeader ? (uint)size_fh : 0) + bi.bV5ProfileData;

        if (profileOffset + profileSize > sourceLength)
        {
            throw new InvalidOperationException(ERR_HEOF);
        }

        var masks = new BITMASKS
        {
            maskRed   = maskR,
            maskGreen = maskG,
            maskBlue  = maskB,
            maskAlpha = maskA,
        };

        var fmt = BitmapCorePixelFormat.Formats.SingleOrDefault(f => f.IsMatch(nbits, masks));

        // currently we only support RLE -> Bgra32
        if (bi.bV5Compression == BitmapCompressionMode.BI_RLE4 || bi.bV5Compression == BitmapCompressionMode.BI_RLE8 || bi.bV5Compression == BitmapCompressionMode.OS2_RLE24)
        {
            fmt = null;
        }

        double pixelPerMeterToDpi(int pels)
        {
            if (pels == 0)
            {
                return(96);
            }
            return(pels * 0.0254d);
        }

        mscms.SafeProfileHandle clrsource = null;
        mscms.mscmsIntent       clrintent = mscms.mscmsIntent.INTENT_PERCEPTUAL;

        bool ignoreColorProfile = (bcrFlags & BC_READ_IGNORE_COLOR_PROFILE) > 0;

        if (!ignoreColorProfile)
        {
            try
            {
                if (bi.bV5CSType == ColorSpaceType.LCS_CALIBRATED_RGB)
                {
                    clrsource = mscms.CreateProfileFromLogicalColorSpace(bi);
                }
                else if (bi.bV5CSType == ColorSpaceType.PROFILE_EMBEDDED)
                {
                    clrsource = mscms.OpenProfile((source + profileOffset), profileSize);
                }

                switch (bi.bV5Intent)
                {
                case Bv5Intent.LCS_GM_BUSINESS:
                    clrintent = mscms.mscmsIntent.INTENT_RELATIVE_COLORIMETRIC;
                    break;

                case Bv5Intent.LCS_GM_GRAPHICS:
                    clrintent = mscms.mscmsIntent.INTENT_SATURATION;
                    break;

                case Bv5Intent.LCS_GM_ABS_COLORIMETRIC:
                    clrintent = mscms.mscmsIntent.INTENT_ABSOLUTE_COLORIMETRIC;
                    break;
                }

                if (clrsource != null && fmt != null && fmt.MscmsFormat.HasValue && fmt.IsIndexed)
                {
                    // transform color table if indexed image
                    palette = mscms.TransformColorsTo_sRGB(clrsource, palette, clrintent);
                }
            }
            catch
            {
                // ignore color profile errors
            }
        }

        info = new BITMAP_READ_DETAILS
        {
            dibHeader   = bi,
            bbp         = nbits,
            compression = bi.bV5Compression,
            dpiX        = pixelPerMeterToDpi(bi.bV5XPelsPerMeter),
            dpiY        = pixelPerMeterToDpi(bi.bV5YPelsPerMeter),

            cMasks     = masks,
            cIndexed   = smBit,
            cTrueAlpha = hasAlphaChannel,

            imgColorTable = palette,
            imgHeight     = height,
            imgTopDown    = topDown,
            imgWidth      = width,
            imgDataOffset = dataOffset,
            imgDataSize   = dataSize,
            imgStride     = source_stride,
            imgSourceFmt  = fmt,

            colorProfile       = clrsource,
            colorProfileIntent = clrintent,
        };
    }
Beispiel #15
0
        /**
        Get a deep copy of the image palette.
        @param bitmap Pointer to a loaded image.
        @return Array or RGBQUAD values representing the image palette.
        */
        public static unsafe RGBQUAD[] GetPaletteCopy(FIBITMAP dib)
        {
            RGBQUAD [] paletteCopy = new RGBQUAD[256];

            // Only interested in indexed images.
            if (GetBPP(dib) <= 8) {
                UIntPtr palette = GetRawPalette(dib);
             				byte * ptr = (byte *)(void*)palette;
             				for (int q = 0; q < 256; q++) {
                    paletteCopy[q] = new RGBQUAD();
                    paletteCopy[q].rgbBlue = (byte)*ptr;
                    ptr += 1;
                    paletteCopy[q].rgbGreen = (byte)*ptr;
                    ptr += 1;
                    paletteCopy[q].rgbRed = (byte)*ptr;
                    ptr += 1;
                    paletteCopy[q].rgbReserved = (byte)*ptr;
                    ptr += 1;
                }
            }

            return paletteCopy;
        }
Beispiel #16
0
        //-------------------------------------------------------------------
        // TransformImage_NV12
        //
        // NV12 to RGB-32
        //-------------------------------------------------------------------
        unsafe private static void TransformImage_NV12(IntPtr pDest, int lDestStride, IntPtr pSrc, int lSrcStride, int dwWidthInPixels, int dwHeightInPixels)
        {
            Byte *lpBitsY  = (byte *)pSrc;
            Byte *lpBitsCb = lpBitsY + (dwHeightInPixels * lSrcStride);
            Byte *lpBitsCr = lpBitsCb + 1;

            Byte *lpLineY1;
            Byte *lpLineY2;
            Byte *lpLineCr;
            Byte *lpLineCb;

            Byte *lpDibLine1 = (Byte *)pDest;

            for (UInt32 y = 0; y < dwHeightInPixels; y += 2)
            {
                lpLineY1 = lpBitsY;
                lpLineY2 = lpBitsY + lSrcStride;
                lpLineCr = lpBitsCr;
                lpLineCb = lpBitsCb;

                Byte *lpDibLine2 = lpDibLine1 + lDestStride;

                for (UInt32 x = 0; x < dwWidthInPixels; x += 2)
                {
                    byte y0 = lpLineY1[0];
                    byte y1 = lpLineY1[1];
                    byte y2 = lpLineY2[0];
                    byte y3 = lpLineY2[1];
                    byte cb = lpLineCb[0];
                    byte cr = lpLineCr[0];

                    RGBQUAD r = ConvertYCrCbToRGB(y0, cr, cb);
                    lpDibLine1[0] = r.B;
                    lpDibLine1[1] = r.G;
                    lpDibLine1[2] = r.R;
                    lpDibLine1[3] = 0; // Alpha

                    r             = ConvertYCrCbToRGB(y1, cr, cb);
                    lpDibLine1[4] = r.B;
                    lpDibLine1[5] = r.G;
                    lpDibLine1[6] = r.R;
                    lpDibLine1[7] = 0; // Alpha

                    r             = ConvertYCrCbToRGB(y2, cr, cb);
                    lpDibLine2[0] = r.B;
                    lpDibLine2[1] = r.G;
                    lpDibLine2[2] = r.R;
                    lpDibLine2[3] = 0; // Alpha

                    r             = ConvertYCrCbToRGB(y3, cr, cb);
                    lpDibLine2[4] = r.B;
                    lpDibLine2[5] = r.G;
                    lpDibLine2[6] = r.R;
                    lpDibLine2[7] = 0; // Alpha

                    lpLineY1 += 2;
                    lpLineY2 += 2;
                    lpLineCr += 2;
                    lpLineCb += 2;

                    lpDibLine1 += 8;
                    lpDibLine2 += 8;
                }

                pDest    += (2 * lDestStride);
                lpBitsY  += (2 * lSrcStride);
                lpBitsCr += lSrcStride;
                lpBitsCb += lSrcStride;
            }
        }
Beispiel #17
0
 public static bool CompareRGBQUADToColor(RGBQUAD rgbQuad, Color color)
 {
     return(rgbQuad.rgbRed == color.R && rgbQuad.rgbGreen == color.G && rgbQuad.rgbBlue == color.B);
 }
Beispiel #18
0
        private static Image ConvertPixelFormat(Image image, PixelFormat newPixelFormat, Color[] palette)
        {
            int bpp = Image.GetPixelFormatSize(newPixelFormat);

            if (newPixelFormat == PixelFormat.Format16bppArgb1555 || newPixelFormat == PixelFormat.Format16bppGrayScale)
            {
                throw new NotSupportedException("This pixel format is not supported by GDI+");
            }

            Bitmap result;

            // non-indexed target image (transparency preserved automatically)
            if (bpp > 8)
            {
                result = new Bitmap(image.Width, image.Height, newPixelFormat);
                using (Graphics g = Graphics.FromImage(result)) {
                    g.DrawImage(image, 0, 0, image.Width, image.Height);
                }

                return(result);
            }

            int    transparentIndex;
            Bitmap bmp;

            // indexed colors: using GDI+ natively
            RGBQUAD[]  targetPalette = new RGBQUAD[256];
            int        colorCount    = InitPalette(targetPalette, bpp, (image is Bitmap) ? image.Palette : null, palette, out transparentIndex);
            BITMAPINFO bmi           = new BITMAPINFO();

            bmi.icHeader.biSize          = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER));
            bmi.icHeader.biWidth         = image.Width;
            bmi.icHeader.biHeight        = image.Height;
            bmi.icHeader.biPlanes        = 1;
            bmi.icHeader.biBitCount      = (ushort)bpp;
            bmi.icHeader.biCompression   = BI_RGB;
            bmi.icHeader.biSizeImage     = (uint)(((image.Width + 7) & 0xFFFFFFF8) * image.Height / (8 / bpp));
            bmi.icHeader.biXPelsPerMeter = 0;
            bmi.icHeader.biYPelsPerMeter = 0;
            bmi.icHeader.biClrUsed       = (uint)colorCount;
            bmi.icHeader.biClrImportant  = (uint)colorCount;
            bmi.icColors = targetPalette;

            bmp = (image as Bitmap) ?? new Bitmap(image);

            // Creating the indexed bitmap
            IntPtr bits;
            IntPtr hbmResult = CreateDIBSection(IntPtr.Zero, ref bmi, DIB_RGB_COLORS, out bits, IntPtr.Zero, 0);

            // Obtaining screen DC
            IntPtr dcScreen = GetDC(IntPtr.Zero);

            // DC for the original hbitmap
            IntPtr hbmSource = bmp.GetHbitmap();
            IntPtr dcSource  = CreateCompatibleDC(dcScreen);

            SelectObject(dcSource, hbmSource);

            // DC for the indexed hbitmap
            IntPtr dcTarget = CreateCompatibleDC(dcScreen);

            SelectObject(dcTarget, hbmResult);

            // Copy content
            BitBlt(dcTarget, 0, 0, image.Width, image.Height, dcSource, 0, 0, 0x00CC0020 /*TernaryRasterOperations.SRCCOPY*/);

            // obtaining result
            result = Image.FromHbitmap(hbmResult);
            result.SetResolution(image.HorizontalResolution, image.VerticalResolution);

            // cleanup
            DeleteDC(dcSource);
            DeleteDC(dcTarget);
            ReleaseDC(IntPtr.Zero, dcScreen);
            DeleteObject(hbmSource);
            DeleteObject(hbmResult);

            ColorPalette resultPalette = result.Palette;
            bool         resetPalette  = false;

            // restoring transparency
            if (transparentIndex >= 0)
            {
                // updating palette if transparent color is not actually transparent
                if (resultPalette.Entries[transparentIndex].A != 0)
                {
                    resultPalette.Entries[transparentIndex] = Color.Transparent;
                    resetPalette = true;
                }

                ToIndexedTransparentByArgb(result, bmp, transparentIndex);
            }

            if (resetPalette)
            {
                result.Palette = resultPalette;
            }

            if (!ReferenceEquals(bmp, image))
            {
                bmp.Dispose();
            }
            return(result);
        }
        private static FIBITMAP NewFiBitMap(PixImage <byte> pi)
        {
            FreeImageCheck(pi.Volume.Info);
            var  sx    = pi.Size.X;
            var  sy    = pi.Size.Y;
            var  bpp   = pi.ChannelCount == 1 && pi.Format == Col.Format.BW ? 1 : pi.ChannelCount * 8;
            var  dib   = FreeImage.Allocate(sx, sy, bpp);
            var  delta = (int)FreeImage.GetPitch(dib);
            var  data  = pi.Volume.Data;
            long i     = pi.Volume.FirstIndex;
            long j     = pi.Volume.JY;
            var  bits  = FreeImage.GetBits(dib) + sy * delta;

            switch (bpp)
            {
            case 1:
            {
                var palette = FreeImage.GetPaletteEx(dib);
                if (palette != null)         // should alway be != null
                {
                    palette[0] = new RGBQUAD {
                        rgbRed = 0, rgbGreen = 0, rgbBlue = 0
                    };
                    palette[1] = new RGBQUAD {
                        rgbRed = 255, rgbGreen = 255, rgbBlue = 255
                    };
                }
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    byte bit = 0x80;
                    int  bi  = 0;
                    unsafe
                    {
                        byte *pixel = (byte *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            if ((data[i++] & 0x80) != 0)
                            {
                                pixel[bi] |= bit;
                            }
                            bit >>= 1; if (bit == 0)
                            {
                                bit = 0x80; bi++;
                            }
                        }
                    }
                    i += j;
                }
            }
            break;

            case 8:
            {
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        byte *pixel = (byte *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            pixel[x] = data[i++];
                        }
                    }
                    i += j;
                }
            }
            break;

            case 24:
            {
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        Byte *pixel = (Byte *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            pixel[FreeImage.FI_RGBA_BLUE]  = data[i++];
                            pixel[FreeImage.FI_RGBA_GREEN] = data[i++];
                            pixel[FreeImage.FI_RGBA_RED]   = data[i++];
                            pixel += 3;
                        }
                    }
                    i += j;
                }
            }
            break;

            case 32:
            {
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        Byte *pixel = (Byte *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            pixel[FreeImage.FI_RGBA_BLUE]  = data[i++];
                            pixel[FreeImage.FI_RGBA_GREEN] = data[i++];
                            pixel[FreeImage.FI_RGBA_RED]   = data[i++];
                            pixel[FreeImage.FI_RGBA_ALPHA] = data[i++];
                            pixel += 4;
                        }
                    }
                    i += j;
                }
            }
            break;
            }
            return(dib);
        }
Beispiel #20
0
        public void Transform(Schema.SkinFile.Attachment.Transform trnsfrm)
        {
            if (dib.IsNull)
            {
                return;
            }

            if (FreeImage.GetWidth(dib) <= 1 || FreeImage.GetHeight(dib) <= 1)
            {
                return;
            }
            FREE_IMAGE_FILTER filter = FREE_IMAGE_FILTER.FILTER_BSPLINE;

            if (trnsfrm.scaleFilter != null)
            {
                switch (trnsfrm.scaleFilter.ToUpper())
                {
                case "BOX":
                    filter = FREE_IMAGE_FILTER.FILTER_BOX;
                    break;

                case "BICUBIC":
                    filter = FREE_IMAGE_FILTER.FILTER_BICUBIC;
                    break;

                case "BILINEAR":
                    filter = FREE_IMAGE_FILTER.FILTER_BILINEAR;
                    break;

                case "BSPLINE":
                    filter = FREE_IMAGE_FILTER.FILTER_BSPLINE;
                    break;

                case "CATMULLROM":
                    filter = FREE_IMAGE_FILTER.FILTER_CATMULLROM;
                    break;

                case "LANCZOS3":
                    filter = FREE_IMAGE_FILTER.FILTER_LANCZOS3;
                    break;
                }
            }
            RectangleF   originalDimensions, rotationDimensions;
            GraphicsUnit pageUnit = GraphicsUnit.Pixel;

            dib = FreeImage.Rescale(dib, (int)(FreeImage.GetWidth(dib) * trnsfrm.scaleX), (int)(FreeImage.GetHeight(dib) * trnsfrm.scaleY), filter);
            originalDimensions = FreeImage.GetBitmap(dib).GetBounds(ref pageUnit);

            RGBQUAD bgColor = new RGBQUAD();

            bgColor.rgbRed      = 0x00;
            bgColor.rgbGreen    = 0x00;
            bgColor.rgbBlue     = 0x00;
            bgColor.rgbReserved = 0x00;
            // TODO: вычесть из положения разницу между оригинальными размерами и размерами после поворота (по крайней мере сверху)
            //int size = (int)(trnsfrm.x > 0 ? trnsfrm.x : 0) + (int)(trnsfrm.y > 0 ? trnsfrm.y : 0);
            //trnsfrm.angle = -45;

            /*
             * double cos = Math.Cos(-trnsfrm.angle * Math.PI / 180), sin = Math.Sin(-trnsfrm.angle * Math.PI / 180);
             * Point[] points = new Point[4] {
             *  new Point((int)(originalDimensions.Width / 2), (int)(originalDimensions.Height / 2)),  // top left //(int)(originalDimensions.Width / 2 * cos - originalDimensions.Height / 2 * sin), (int)(originalDimensions.Width / 2 * sin + originalDimensions.Height / 2 * cos)),
             *  new Point((int)(originalDimensions.Width / 2), (int)(-originalDimensions.Height / 2)), // top right
             *  new Point((int)(-originalDimensions.Width / 2), (int)(originalDimensions.Height / 2)), // bottom left
             *  new Point((int)(-originalDimensions.Width / 2), (int)(-originalDimensions.Height / 2)) // bottom right
             * };
             * for (int i = 0; i < points.Length; i++)
             * {
             *  points[i].X = (int)(points[i].X * cos - points[i].Y * sin);
             *  points[i].Y = (int)(points[i].X * sin + points[i].Y * cos);
             * }
             * int maxRight = points[0].X, maxBottom = points[0].Y;
             * for (int i = 0; i < points.Length; i++)
             * {
             *  if (points[i].X > maxRight) maxRight = points[i].X;
             *  if (points[i].Y > maxBottom) maxBottom = points[i].Y;
             * }
             *
             * Console.WriteLine(points[0]);
             * Console.WriteLine(points[1]);
             * Console.WriteLine(points[2]);
             * Console.WriteLine(points[3]);
             *
             * Console.WriteLine(maxRight);
             * Console.WriteLine(maxBottom);
             * int rightOffset = (int)(maxRight - originalDimensions.Width / 2), bottomOffset = (int)(maxBottom - originalDimensions.Height / 2);
             * Console.WriteLine(rightOffset);
             * Console.WriteLine(bottomOffset);
             */
            /*
             * Console.WriteLine(originalDimensions);
             * Console.WriteLine(originalDimensions.Width / 2 * Math.Cos(trnsfrm.angle * Math.PI / 180) - originalDimensions.Height / 2 * Math.Sin(trnsfrm.angle * Math.PI / 180));
             * Console.WriteLine(originalDimensions.Width / 2 * Math.Sin(trnsfrm.angle * Math.PI / 180) + originalDimensions.Height / 2 * Math.Cos(trnsfrm.angle * Math.PI / 180));
             */
            dib = FreeImage.Rotate <RGBQUAD>(dib, -trnsfrm.angle, bgColor);
            rotationDimensions = FreeImage.GetBitmap(dib).GetBounds(ref pageUnit);
            dib = FreeImage.EnlargeCanvas <RGBQUAD>(dib,
                                                    0,
                                                    0,
                                                    (int)(trnsfrm.x > 0 ? trnsfrm.x : 0), // + rightOffset,//(int)(originalDimensions.Width / 2 * Math.Cos(trnsfrm.angle * Math.PI / 180) - originalDimensions.Height / 2 * Math.Sin(trnsfrm.angle * Math.PI / 180) - originalDimensions.Width / 2) + 2,
                                                    (int)(trnsfrm.y > 0 ? trnsfrm.y : 0), // + bottomOffset,//(int)(originalDimensions.Width / 2 * Math.Sin(trnsfrm.angle * Math.PI / 180) + originalDimensions.Height / 2 * Math.Cos(trnsfrm.angle * Math.PI / 180)),
                                                    bgColor,
                                                    FREE_IMAGE_COLOR_OPTIONS.FICO_RGBA
                                                    );
            //dib = FreeImage.RotateEx(dib, 0, trnsfrm.x, trnsfrm.y, 0, 0, true);
            //dib = FreeImage.Rotate<RGBQUAD>(dib, trnsfrm.angle, bgColor);

            //dib = FreeImage.RotateEx(dib, 0, trnsfrm.x, trnsfrm.y, originalDimensions.Width / 2, originalDimensions.Height / 2, true);
            dib = FreeImage.RotateEx(dib, 0, trnsfrm.x, trnsfrm.y, 0, 0, true);
            dib = FreeImage.EnlargeCanvas <RGBQUAD>(dib,
                                                    (int)(rotationDimensions.Width - originalDimensions.Width) / -2,
                                                    (int)(rotationDimensions.Height - originalDimensions.Height) / -2,
                                                    0,
                                                    0,
                                                    bgColor,
                                                    FREE_IMAGE_COLOR_OPTIONS.FICO_RGBA
                                                    );
            //dib = FreeImage.RotateEx(dib, 0, trnsfrm.x - (rotationDimensions.Width - originalDimensions.Width) / 2, trnsfrm.y - (rotationDimensions.Height - originalDimensions.Height) / 2, 0, 0, true);
            //dib = FreeImage.RotateEx(dib, 0, trnsfrm.x, trnsfrm.y, 0, 0, true);
        }
Beispiel #21
0
        public static BitmapData LoadBmpIconFrame(Stream stream, int offset, int length)
        {
            stream.Position = offset;
            using (var reader = new BinaryReader(stream, Encoding.Default, true))
            {
                var info = new BITMAPINFOHEADER
                {
                    biSize          = reader.ReadInt32(),
                    biWidth         = reader.ReadInt32(),
                    biHeight        = reader.ReadInt32(),
                    biPlanes        = reader.ReadInt16(),
                    biBitCount      = reader.ReadInt16(),
                    biCompression   = (BitmapCompression)reader.ReadInt32(),
                    biSizeImage     = reader.ReadInt32(),
                    biXPelsPerMeter = reader.ReadInt32(),
                    biYPelsPerMeter = reader.ReadInt32(),
                    biClrUsed       = reader.ReadInt32(),
                    biClrImportant  = reader.ReadInt32(),
                };

                int height = Math.Abs(info.biHeight) / 2;

                BitmapData bitmapData = null;
                if (info.biCompression == BitmapCompression.BI_BITFIELDS)
                {
                    bitmapData = LoadBmpData_BITFIELDS(reader, info, height);
                }
                else
                {
                    int     colorTableSize = (info.biBitCount <= 8 && info.biClrUsed == 0) ? (int)Math.Pow(2, info.biBitCount) : info.biClrUsed;
                    Color[] colorTable     = null;
                    if (colorTableSize > 0)
                    {
                        colorTable = new Color[colorTableSize];
                        for (int i = 0; i < colorTableSize; i++)
                        {
                            var rgb = new RGBQUAD
                            {
                                rgbBlue     = reader.ReadByte(),
                                rgbGreen    = reader.ReadByte(),
                                rgbRed      = reader.ReadByte(),
                                rgbReserved = reader.ReadByte()
                            };
                            colorTable[i] = Color.FromArgb(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
                        }
                    }

                    if (info.biCompression == BitmapCompression.BI_RLE4)
                    {
                        bitmapData = LoadBmpData_RLE4(reader, info, height, colorTable);
                    }
                    else if (info.biCompression == BitmapCompression.BI_RLE8)
                    {
                        bitmapData = LoadBmpData_RLE8(reader, info, height, colorTable);
                    }
                    else if (colorTable != null)
                    {
                        bitmapData = LoadBitmapData(stream, info, height, colorTable);
                    }
                    else
                    {
                        bitmapData = LoadBitmapData(stream, info, height);
                    }
                }

                // load AND mask
                var andMask = new List <bool[]>();
                int stride  = (info.biWidth + 31) / 32 * 4;
                for (int y = 0; y < height; y++)
                {
                    byte[] line = new byte[stride];
                    stream.Read(line, 0, line.Length);
                    var lineMask = new List <bool>();
                    foreach (var lb in line)
                    {
                        lineMask.Add((lb & 0b_1000_0000) == 0);
                        lineMask.Add((lb & 0b_0100_0000) == 0);
                        lineMask.Add((lb & 0b_0010_0000) == 0);
                        lineMask.Add((lb & 0b_0001_0000) == 0);
                        lineMask.Add((lb & 0b_0000_1000) == 0);
                        lineMask.Add((lb & 0b_0000_0100) == 0);
                        lineMask.Add((lb & 0b_0000_0010) == 0);
                        lineMask.Add((lb & 0b_0000_0001) == 0);
                    }
                    andMask.Add(lineMask.ToArray());
                }
                andMask.Reverse();
                if (info.biBitCount < 32)
                {
                    bitmapData.AndMaskToAlpha(andMask);
                }

                return(bitmapData);
            }
        }
Beispiel #22
0
        public unsafe void Properties()
        {
            string filename = iManager.GetBitmapPath(ImageType.Even, ImageColorType.Type_32);

            Assert.IsNotNull(filename);
            Assert.IsTrue(File.Exists(filename));

            FreeImageBitmap fib = new FreeImageBitmap(filename);

            Assert.IsFalse(fib.HasPalette);

            try
            {
                Palette palette = fib.Palette;
                Assert.Fail();
            }
            catch
            {
            }

            Assert.IsFalse(fib.HasBackgroundColor);
            fib.BackgroundColor = Color.LightSeaGreen;
            Assert.IsTrue(fib.HasBackgroundColor);
            Assert.That(
                Color.LightSeaGreen.B == fib.BackgroundColor.Value.B &&
                Color.LightSeaGreen.G == fib.BackgroundColor.Value.G &&
                Color.LightSeaGreen.R == fib.BackgroundColor.Value.R);
            fib.BackgroundColor = null;
            Assert.IsFalse(fib.HasBackgroundColor);
            fib.Dispose();

            fib = new FreeImageBitmap(100, 100, PixelFormat.Format1bppIndexed);
            ImageFlags flags = (ImageFlags)fib.Flags;

            Assert.That((flags & ImageFlags.ColorSpaceRgb) == ImageFlags.ColorSpaceRgb);
            Assert.That((flags & ImageFlags.HasAlpha) != ImageFlags.HasAlpha);
            Assert.That((flags & ImageFlags.HasRealDpi) != ImageFlags.HasRealDpi);
            Assert.That((flags & ImageFlags.HasTranslucent) != ImageFlags.HasTranslucent);
            fib.Dispose();

            dib = FreeImage.Allocate(100, 100, 32, 0xFF0000, 0xFF00, 0xFF);
            FIICCPROFILE *prof = (FIICCPROFILE *)FreeImage.CreateICCProfile(dib, new byte[] { 0, 1, 2, 3 }, 4);

            fib = new FreeImageBitmap(dib);
            Scanline <RGBQUAD> sc   = (Scanline <RGBQUAD>)fib.GetScanline(0);
            RGBQUAD            rgbq = sc[0];

            rgbq.rgbReserved = 127;
            sc[0]            = rgbq;
            flags            = (ImageFlags)fib.Flags;
            Assert.That((flags & ImageFlags.HasAlpha) == ImageFlags.HasAlpha);
            Assert.That((flags & ImageFlags.HasRealDpi) != ImageFlags.HasRealDpi);
            Assert.That((flags & ImageFlags.HasTranslucent) == ImageFlags.HasTranslucent);
            fib.Dispose();
            fib = null;
            GC.Collect(2, GCCollectionMode.Forced);
            GC.WaitForPendingFinalizers();

            fib = new FreeImageBitmap(iManager.GetBitmapPath(ImageType.Metadata, ImageColorType.Type_01_Dither));
            int[] propList = fib.PropertyIdList;
            Assert.IsNotNull(propList);
            Assert.Greater(propList.Length, 0);
            PropertyItem[] propItemList = fib.PropertyItems;
            Assert.IsNotNull(propItemList);
            Assert.Greater(propItemList.Length, 0);
            Assert.IsNotNull(fib.RawFormat);
            fib.Dispose();

            fib = new FreeImageBitmap(iManager.GetBitmapPath(ImageType.Multipaged, ImageColorType.Type_01_Dither));
            Assert.Greater(fib.FrameCount, 1);
            fib.Dispose();
        }
        public void MetadataTag()
        {
            FITAG       tag;
            MetadataTag metaTag;

            Random rand = new Random();

            dib = iManager.GetBitmap(ImageType.Metadata, ImageColorType.Type_01_Dither);
            Assert.IsFalse(dib.IsNull);

            Assert.That(FreeImage.GetMetadataCount(FREE_IMAGE_MDMODEL.FIMD_EXIF_MAIN, dib) > 0);

            FIMETADATA mData = FreeImage.FindFirstMetadata(FREE_IMAGE_MDMODEL.FIMD_EXIF_MAIN, dib, out tag);

            Assert.IsFalse(tag.IsNull);
            Assert.IsFalse(mData.IsNull);

            //
            // Constructors
            //

            metaTag = new MetadataTag(tag, dib);
            Assert.That(metaTag.Model == FREE_IMAGE_MDMODEL.FIMD_EXIF_MAIN);

            metaTag = new MetadataTag(tag, FREE_IMAGE_MDMODEL.FIMD_EXIF_MAIN);
            Assert.That(metaTag.Model == FREE_IMAGE_MDMODEL.FIMD_EXIF_MAIN);

            //
            // Properties
            //

            metaTag.ID = ushort.MinValue;
            Assert.That(metaTag.ID == ushort.MinValue);

            metaTag.ID = ushort.MaxValue;
            Assert.That(metaTag.ID == ushort.MaxValue);

            metaTag.ID = ushort.MaxValue / 2;
            Assert.That(metaTag.ID == ushort.MaxValue / 2);

            metaTag.Description = "";
            Assert.That(metaTag.Description == "");

            metaTag.Description = "A";
            Assert.That(metaTag.Description == "A");

            metaTag.Description = "ABCDEFG";
            Assert.That(metaTag.Description == "ABCDEFG");

            metaTag.Key = "";
            Assert.That(metaTag.Key == "");

            metaTag.Key = "A";
            Assert.That(metaTag.Key == "A");

            metaTag.Key = "ABCDEFG";
            Assert.That(metaTag.Key == "ABCDEFG");

            //
            // SetValue
            //

            try
            {
                metaTag.SetValue(null, FREE_IMAGE_MDTYPE.FIDT_ASCII);
                Assert.Fail();
            }
            catch
            {
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_ASCII
            //

            string testString = "";

            Assert.IsTrue(metaTag.SetValue(testString, FREE_IMAGE_MDTYPE.FIDT_ASCII));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((string)metaTag.Value).Length == 0);

            testString = "X";

            Assert.IsTrue(metaTag.SetValue(testString, FREE_IMAGE_MDTYPE.FIDT_ASCII));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((string)metaTag.Value).Length == testString.Length);
            Assert.That(((string)metaTag.Value) == testString);

            testString = "TEST-STRING";

            Assert.IsTrue(metaTag.SetValue(testString, FREE_IMAGE_MDTYPE.FIDT_ASCII));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((string)metaTag.Value).Length == testString.Length);
            Assert.That(((string)metaTag.Value) == testString);

            //
            // FREE_IMAGE_MDTYPE.FIDT_BYTE
            //

            byte testByte;

            byte[] testByteArray;

            Assert.IsTrue(metaTag.SetValue(byte.MinValue, FREE_IMAGE_MDTYPE.FIDT_BYTE));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((byte[])metaTag.Value).Length == 1);
            Assert.That(((byte[])metaTag.Value)[0] == byte.MinValue);

            Assert.IsTrue(metaTag.SetValue(byte.MaxValue, FREE_IMAGE_MDTYPE.FIDT_BYTE));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((byte[])metaTag.Value).Length == 1);
            Assert.That(((byte[])metaTag.Value)[0] == byte.MaxValue);

            for (int i = 0; i < 10; i++)
            {
                testByte      = (byte)rand.Next(byte.MinValue, byte.MaxValue);
                testByteArray = new byte[rand.Next(0, 31)];

                for (int j = 0; j < testByteArray.Length; j++)
                {
                    testByteArray[j] = (byte)rand.Next();
                }

                Assert.IsTrue(metaTag.SetValue(testByte, FREE_IMAGE_MDTYPE.FIDT_BYTE));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((byte[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 1);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_BYTE);
                Assert.That(((byte[])metaTag.Value)[0] == testByte);

                Assert.IsTrue(metaTag.SetValue(testByteArray, FREE_IMAGE_MDTYPE.FIDT_BYTE));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((byte[])metaTag.Value).Length == testByteArray.Length);
                Assert.That(metaTag.Count == testByteArray.Length);
                Assert.That(metaTag.Length == testByteArray.Length * 1);

                byte[] value = (byte[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testByteArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_DOUBLE
            //

            double testDouble;

            double[] testDoubleArray;

            Assert.IsTrue(metaTag.SetValue(double.MinValue, FREE_IMAGE_MDTYPE.FIDT_DOUBLE));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((double[])metaTag.Value).Length == 1);
            Assert.That(((double[])metaTag.Value)[0] == double.MinValue);

            Assert.IsTrue(metaTag.SetValue(double.MaxValue, FREE_IMAGE_MDTYPE.FIDT_DOUBLE));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((double[])metaTag.Value).Length == 1);
            Assert.That(((double[])metaTag.Value)[0] == double.MaxValue);

            for (int i = 0; i < 10; i++)
            {
                testDouble      = (double)rand.NextDouble();
                testDoubleArray = new double[rand.Next(0, 31)];

                for (int j = 0; j < testDoubleArray.Length; j++)
                {
                    testDoubleArray[j] = rand.NextDouble();
                }

                Assert.IsTrue(metaTag.SetValue(testDouble, FREE_IMAGE_MDTYPE.FIDT_DOUBLE));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((double[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 8);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_DOUBLE);
                Assert.That(((double[])metaTag.Value)[0] == testDouble);

                Assert.IsTrue(metaTag.SetValue(testDoubleArray, FREE_IMAGE_MDTYPE.FIDT_DOUBLE));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((double[])metaTag.Value).Length == testDoubleArray.Length);
                Assert.That(metaTag.Count == testDoubleArray.Length);
                Assert.That(metaTag.Length == testDoubleArray.Length * 8);

                double[] value = (double[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testDoubleArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_FLOAT
            //

            float testfloat;

            float[] testFloatArray;

            Assert.IsTrue(metaTag.SetValue(float.MinValue, FREE_IMAGE_MDTYPE.FIDT_FLOAT));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((float[])metaTag.Value).Length == 1);
            Assert.That(((float[])metaTag.Value)[0] == float.MinValue);

            Assert.IsTrue(metaTag.SetValue(float.MaxValue, FREE_IMAGE_MDTYPE.FIDT_FLOAT));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((float[])metaTag.Value).Length == 1);
            Assert.That(((float[])metaTag.Value)[0] == float.MaxValue);

            for (int i = 0; i < 10; i++)
            {
                testfloat      = (float)rand.NextDouble();
                testFloatArray = new float[rand.Next(0, 31)];

                for (int j = 0; j < testFloatArray.Length; j++)
                {
                    testFloatArray[j] = (float)rand.NextDouble();
                }

                Assert.IsTrue(metaTag.SetValue(testfloat, FREE_IMAGE_MDTYPE.FIDT_FLOAT));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((float[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 4);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_FLOAT);
                Assert.That(((float[])metaTag.Value)[0] == testfloat);

                Assert.IsTrue(metaTag.SetValue(testFloatArray, FREE_IMAGE_MDTYPE.FIDT_FLOAT));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((float[])metaTag.Value).Length == testFloatArray.Length);
                Assert.That(metaTag.Count == testFloatArray.Length);
                Assert.That(metaTag.Length == testFloatArray.Length * 4);

                float[] value = (float[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testFloatArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_IFD
            //

            uint testUint;

            uint[] testUintArray;

            Assert.IsTrue(metaTag.SetValue(uint.MinValue, FREE_IMAGE_MDTYPE.FIDT_IFD));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((uint[])metaTag.Value).Length == 1);
            Assert.That(((uint[])metaTag.Value)[0] == uint.MinValue);

            Assert.IsTrue(metaTag.SetValue(uint.MaxValue, FREE_IMAGE_MDTYPE.FIDT_IFD));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((uint[])metaTag.Value).Length == 1);
            Assert.That(((uint[])metaTag.Value)[0] == uint.MaxValue);

            for (int i = 0; i < 10; i++)
            {
                testUint      = (uint)rand.NextDouble();
                testUintArray = new uint[rand.Next(0, 31)];

                for (int j = 0; j < testUintArray.Length; j++)
                {
                    testUintArray[j] = (uint)rand.Next();
                }

                Assert.IsTrue(metaTag.SetValue(testUint, FREE_IMAGE_MDTYPE.FIDT_IFD));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((uint[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 4);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_IFD);
                Assert.That(((uint[])metaTag.Value)[0] == testUint);

                Assert.IsTrue(metaTag.SetValue(testUintArray, FREE_IMAGE_MDTYPE.FIDT_IFD));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((uint[])metaTag.Value).Length == testUintArray.Length);
                Assert.That(metaTag.Count == testUintArray.Length);
                Assert.That(metaTag.Length == testUintArray.Length * 4);

                uint[] value = (uint[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testUintArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_LONG
            //

            Assert.IsTrue(metaTag.SetValue(uint.MinValue, FREE_IMAGE_MDTYPE.FIDT_LONG));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((uint[])metaTag.Value).Length == 1);
            Assert.That(((uint[])metaTag.Value)[0] == uint.MinValue);

            Assert.IsTrue(metaTag.SetValue(uint.MaxValue, FREE_IMAGE_MDTYPE.FIDT_LONG));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((uint[])metaTag.Value).Length == 1);
            Assert.That(((uint[])metaTag.Value)[0] == uint.MaxValue);

            for (int i = 0; i < 10; i++)
            {
                testUint      = (uint)rand.NextDouble();
                testUintArray = new uint[rand.Next(0, 31)];

                for (int j = 0; j < testUintArray.Length; j++)
                {
                    testUintArray[j] = (uint)rand.Next();
                }

                Assert.IsTrue(metaTag.SetValue(testUint, FREE_IMAGE_MDTYPE.FIDT_LONG));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((uint[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 4);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_LONG);
                Assert.That(((uint[])metaTag.Value)[0] == testUint);

                Assert.IsTrue(metaTag.SetValue(testUintArray, FREE_IMAGE_MDTYPE.FIDT_LONG));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((uint[])metaTag.Value).Length == testUintArray.Length);
                Assert.That(metaTag.Count == testUintArray.Length);
                Assert.That(metaTag.Length == testUintArray.Length * 4);

                uint[] value = (uint[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testUintArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_NOTYPE
            //

            try
            {
                metaTag.SetValue(new object(), FREE_IMAGE_MDTYPE.FIDT_NOTYPE);
                Assert.Fail();
            }
            catch (NotSupportedException)
            {
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_PALETTE
            //

            RGBQUAD testRGBQUAD;

            RGBQUAD[] testRGBQUADArray;

            for (int i = 0; i < 10; i++)
            {
                testRGBQUAD      = new RGBQUAD(Color.FromArgb(rand.Next()));
                testRGBQUADArray = new RGBQUAD[rand.Next(0, 31)];

                for (int j = 0; j < testRGBQUADArray.Length; j++)
                {
                    testRGBQUADArray[j] = new RGBQUAD(Color.FromArgb(rand.Next()));
                }

                Assert.IsTrue(metaTag.SetValue(testRGBQUAD, FREE_IMAGE_MDTYPE.FIDT_PALETTE));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((RGBQUAD[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 4);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_PALETTE);
                Assert.That(((RGBQUAD[])metaTag.Value)[0] == testRGBQUAD);

                Assert.IsTrue(metaTag.SetValue(testRGBQUADArray, FREE_IMAGE_MDTYPE.FIDT_PALETTE));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((RGBQUAD[])metaTag.Value).Length == testRGBQUADArray.Length);
                Assert.That(metaTag.Count == testRGBQUADArray.Length);
                Assert.That(metaTag.Length == testRGBQUADArray.Length * 4);

                RGBQUAD[] value = (RGBQUAD[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testRGBQUADArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_RATIONAL
            //

            FIURational testFIURational;

            FIURational[] testFIURationalArray;

            for (int i = 0; i < 10; i++)
            {
                testFIURational      = new FIURational((uint)rand.Next(), (uint)rand.Next());
                testFIURationalArray = new FIURational[rand.Next(0, 31)];

                for (int j = 0; j < testFIURationalArray.Length; j++)
                {
                    testFIURationalArray[j] = new FIURational((uint)rand.Next(), (uint)rand.Next());
                }

                Assert.IsTrue(metaTag.SetValue(testFIURational, FREE_IMAGE_MDTYPE.FIDT_RATIONAL));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((FIURational[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 8);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_RATIONAL);
                Assert.That(((FIURational[])metaTag.Value)[0] == testFIURational);

                Assert.IsTrue(metaTag.SetValue(testFIURationalArray, FREE_IMAGE_MDTYPE.FIDT_RATIONAL));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((FIURational[])metaTag.Value).Length == testFIURationalArray.Length);
                Assert.That(metaTag.Count == testFIURationalArray.Length);
                Assert.That(metaTag.Length == testFIURationalArray.Length * 8);

                FIURational[] value = (FIURational[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testFIURationalArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_SBYTE
            //

            sbyte testSByte;

            sbyte[] testSByteArray;

            Assert.IsTrue(metaTag.SetValue(sbyte.MinValue, FREE_IMAGE_MDTYPE.FIDT_SBYTE));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((sbyte[])metaTag.Value).Length == 1);
            Assert.That(((sbyte[])metaTag.Value)[0] == sbyte.MinValue);

            Assert.IsTrue(metaTag.SetValue(sbyte.MaxValue, FREE_IMAGE_MDTYPE.FIDT_SBYTE));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((sbyte[])metaTag.Value).Length == 1);
            Assert.That(((sbyte[])metaTag.Value)[0] == sbyte.MaxValue);

            for (int i = 0; i < 10; i++)
            {
                testSByte      = (sbyte)rand.Next(sbyte.MinValue, sbyte.MaxValue);
                testSByteArray = new sbyte[rand.Next(0, 31)];

                for (int j = 0; j < testSByteArray.Length; j++)
                {
                    testSByteArray[j] = (sbyte)rand.Next();
                }

                Assert.IsTrue(metaTag.SetValue(testSByte, FREE_IMAGE_MDTYPE.FIDT_SBYTE));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((sbyte[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 1);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_SBYTE);
                Assert.That(((sbyte[])metaTag.Value)[0] == testSByte);

                Assert.IsTrue(metaTag.SetValue(testSByteArray, FREE_IMAGE_MDTYPE.FIDT_SBYTE));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((sbyte[])metaTag.Value).Length == testSByteArray.Length);
                Assert.That(metaTag.Count == testSByteArray.Length);
                Assert.That(metaTag.Length == testSByteArray.Length * 1);

                sbyte[] value = (sbyte[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testSByteArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_SHORT
            //

            ushort testUShort;

            ushort[] testUShortArray;

            Assert.IsTrue(metaTag.SetValue(ushort.MinValue, FREE_IMAGE_MDTYPE.FIDT_SHORT));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((ushort[])metaTag.Value).Length == 1);
            Assert.That(((ushort[])metaTag.Value)[0] == ushort.MinValue);

            Assert.IsTrue(metaTag.SetValue(ushort.MaxValue, FREE_IMAGE_MDTYPE.FIDT_SHORT));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((ushort[])metaTag.Value).Length == 1);
            Assert.That(((ushort[])metaTag.Value)[0] == ushort.MaxValue);

            for (int i = 0; i < 10; i++)
            {
                testUShort      = (ushort)rand.Next(ushort.MinValue, sbyte.MaxValue);
                testUShortArray = new ushort[rand.Next(0, 31)];

                for (int j = 0; j < testUShortArray.Length; j++)
                {
                    testUShortArray[j] = (ushort)rand.Next();
                }

                Assert.IsTrue(metaTag.SetValue(testUShort, FREE_IMAGE_MDTYPE.FIDT_SHORT));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((ushort[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 2);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_SHORT);
                Assert.That(((ushort[])metaTag.Value)[0] == testUShort);

                Assert.IsTrue(metaTag.SetValue(testUShortArray, FREE_IMAGE_MDTYPE.FIDT_SHORT));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((ushort[])metaTag.Value).Length == testUShortArray.Length);
                Assert.That(metaTag.Count == testUShortArray.Length);
                Assert.That(metaTag.Length == testUShortArray.Length * 2);

                ushort[] value = (ushort[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testUShortArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_SLONG
            //

            int testInt;

            int[] testIntArray;

            Assert.IsTrue(metaTag.SetValue(int.MinValue, FREE_IMAGE_MDTYPE.FIDT_SLONG));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((int[])metaTag.Value).Length == 1);
            Assert.That(((int[])metaTag.Value)[0] == int.MinValue);

            Assert.IsTrue(metaTag.SetValue(int.MaxValue, FREE_IMAGE_MDTYPE.FIDT_SLONG));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((int[])metaTag.Value).Length == 1);
            Assert.That(((int[])metaTag.Value)[0] == int.MaxValue);

            for (int i = 0; i < 10; i++)
            {
                testInt      = (int)rand.NextDouble();
                testIntArray = new int[rand.Next(0, 31)];

                for (int j = 0; j < testIntArray.Length; j++)
                {
                    testIntArray[j] = rand.Next();
                }

                Assert.IsTrue(metaTag.SetValue(testInt, FREE_IMAGE_MDTYPE.FIDT_SLONG));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((int[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 4);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_SLONG);
                Assert.That(((int[])metaTag.Value)[0] == testInt);

                Assert.IsTrue(metaTag.SetValue(testIntArray, FREE_IMAGE_MDTYPE.FIDT_SLONG));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((int[])metaTag.Value).Length == testIntArray.Length);
                Assert.That(metaTag.Count == testIntArray.Length);
                Assert.That(metaTag.Length == testIntArray.Length * 4);

                int[] value = (int[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testIntArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_SRATIONAL
            //

            FIRational testFIRational;

            FIRational[] testFIRationalArray;

            for (int i = 0; i < 10; i++)
            {
                testFIRational      = new FIRational(rand.Next(), rand.Next());
                testFIRationalArray = new FIRational[rand.Next(0, 31)];

                for (int j = 0; j < testFIRationalArray.Length; j++)
                {
                    testFIRationalArray[j] = new FIRational(rand.Next(), rand.Next());
                }

                Assert.IsTrue(metaTag.SetValue(testFIRational, FREE_IMAGE_MDTYPE.FIDT_SRATIONAL));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((FIRational[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 8);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_SRATIONAL);
                Assert.That(((FIRational[])metaTag.Value)[0] == testFIRational);

                Assert.IsTrue(metaTag.SetValue(testFIRationalArray, FREE_IMAGE_MDTYPE.FIDT_SRATIONAL));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((FIRational[])metaTag.Value).Length == testFIRationalArray.Length);
                Assert.That(metaTag.Count == testFIRationalArray.Length);
                Assert.That(metaTag.Length == testFIRationalArray.Length * 8);

                FIRational[] value = (FIRational[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testFIRationalArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_SSHORT
            //

            short testShort;

            short[] testShortArray;

            Assert.IsTrue(metaTag.SetValue(short.MinValue, FREE_IMAGE_MDTYPE.FIDT_SSHORT));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((short[])metaTag.Value).Length == 1);
            Assert.That(((short[])metaTag.Value)[0] == short.MinValue);

            Assert.IsTrue(metaTag.SetValue(short.MaxValue, FREE_IMAGE_MDTYPE.FIDT_SSHORT));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((short[])metaTag.Value).Length == 1);
            Assert.That(((short[])metaTag.Value)[0] == short.MaxValue);

            for (int i = 0; i < 10; i++)
            {
                testShort      = (short)rand.Next(short.MinValue, short.MaxValue);
                testShortArray = new short[rand.Next(0, 31)];

                for (int j = 0; j < testShortArray.Length; j++)
                {
                    testShortArray[j] = (short)rand.Next();
                }

                Assert.IsTrue(metaTag.SetValue(testShort, FREE_IMAGE_MDTYPE.FIDT_SSHORT));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((short[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 2);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_SSHORT);
                Assert.That(((short[])metaTag.Value)[0] == testShort);

                Assert.IsTrue(metaTag.SetValue(testShortArray, FREE_IMAGE_MDTYPE.FIDT_SSHORT));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((short[])metaTag.Value).Length == testShortArray.Length);
                Assert.That(metaTag.Count == testShortArray.Length);
                Assert.That(metaTag.Length == testShortArray.Length * 2);

                short[] value = (short[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testShortArray[j] == value[j]);
                }
            }

            //
            // FREE_IMAGE_MDTYPE.FIDT_UNDEFINED
            //

            Assert.IsTrue(metaTag.SetValue(byte.MinValue, FREE_IMAGE_MDTYPE.FIDT_UNDEFINED));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((byte[])metaTag.Value).Length == 1);
            Assert.That(((byte[])metaTag.Value)[0] == byte.MinValue);

            Assert.IsTrue(metaTag.SetValue(byte.MaxValue, FREE_IMAGE_MDTYPE.FIDT_UNDEFINED));
            Assert.IsNotNull(metaTag.Value);
            Assert.That(((byte[])metaTag.Value).Length == 1);
            Assert.That(((byte[])metaTag.Value)[0] == byte.MaxValue);

            for (int i = 0; i < 10; i++)
            {
                testByte      = (byte)rand.Next(byte.MinValue, byte.MaxValue);
                testByteArray = new byte[rand.Next(0, 31)];

                for (int j = 0; j < testByteArray.Length; j++)
                {
                    testByteArray[j] = (byte)rand.Next();
                }

                Assert.IsTrue(metaTag.SetValue(testByte, FREE_IMAGE_MDTYPE.FIDT_UNDEFINED));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((byte[])metaTag.Value).Length == 1);
                Assert.That(metaTag.Count == 1);
                Assert.That(metaTag.Length == 1);
                Assert.That(metaTag.Type == FREE_IMAGE_MDTYPE.FIDT_UNDEFINED);
                Assert.That(((byte[])metaTag.Value)[0] == testByte);

                Assert.IsTrue(metaTag.SetValue(testByteArray, FREE_IMAGE_MDTYPE.FIDT_UNDEFINED));
                Assert.IsNotNull(metaTag.Value);
                Assert.That(((byte[])metaTag.Value).Length == testByteArray.Length);
                Assert.That(metaTag.Count == testByteArray.Length);
                Assert.That(metaTag.Length == testByteArray.Length * 1);

                byte[] value = (byte[])metaTag.Value;

                for (int j = 0; j < value.Length; j++)
                {
                    Assert.That(testByteArray[j] == value[j]);
                }
            }

            FreeImage.UnloadEx(ref dib);
        }
 private void writeColor(
    BinaryWriter bw,
    Color color
    )
 {
    RGBQUAD r = new RGBQUAD(color);
    r.Write(bw);
 }
Beispiel #25
0
        // Convert a global memory block to a bitmap
        private Bitmap ConvertMemoryBlockToBitmap(IntPtr hMem)
        {
            Bitmap BMP = null;

            BITMAPINFOHEADER BIH = new BITMAPINFOHEADER();
            IntPtr           bihPtr;
            IntPtr           dataPtr;
            IntPtr           palPtr;
            uint             HdrSize;
            PixelFormat      PixFormat  = PixelFormat.Format1bppIndexed;
            uint             PalEntries = 0;
            RGBQUAD          rgb        = new RGBQUAD();

            bihPtr = GlobalLock(hMem);

            if (!bihPtr.Equals(IntPtr.Zero))
            {
                BIH     = ((BITMAPINFOHEADER)(Marshal.PtrToStructure(bihPtr, typeof(BITMAPINFOHEADER))));
                HdrSize = BIH.biSize;
                palPtr  = (IntPtr)(bihPtr.ToInt32() + HdrSize);

                // Most of these formats are untested
                switch (BIH.biBitCount)
                {
                case 1:
                    HdrSize   += (uint)(2 * Marshal.SizeOf(rgb));
                    PixFormat  = PixelFormat.Format1bppIndexed;
                    PalEntries = 2;
                    break;

                case 4:
                    HdrSize   += (uint)(16 * Marshal.SizeOf(rgb));
                    PixFormat  = PixelFormat.Format4bppIndexed;
                    PalEntries = BIH.biClrUsed;
                    break;

                case 8:
                    HdrSize   += (uint)(256 * Marshal.SizeOf(rgb));
                    PixFormat  = PixelFormat.Format8bppIndexed;
                    PalEntries = BIH.biClrUsed;
                    break;

                case 16:
                    // Account for the 3 DWORD colour mask
                    if (BIH.biCompression == BI_BITFIELDS)
                    {
                        HdrSize += 12;
                    }
                    PixFormat  = PixelFormat.Format16bppRgb555;
                    PalEntries = 0;
                    break;

                case 24:
                    PixFormat  = PixelFormat.Format24bppRgb;
                    PalEntries = 0;
                    break;

                case 32:
                    // Account for the 3 DWORD colour mask
                    if (BIH.biCompression == BI_BITFIELDS)
                    {
                        HdrSize += 12;
                    }
                    PixFormat  = PixelFormat.Format32bppRgb;
                    PalEntries = 0;
                    break;

                default:
                    break;
                }

                dataPtr = (IntPtr)(bihPtr.ToInt32() + HdrSize);
                BMP     = new Bitmap(BIH.biWidth, Math.Abs(BIH.biHeight), PixFormat);
                if (PalEntries > 0)
                {
                    palPtr = (IntPtr)(bihPtr.ToInt32() + BIH.biSize);
                    ColorPalette Pal = BMP.Palette;
                    for (int PalEntry = 0; PalEntry < PalEntries; PalEntry++)
                    {
                        rgb = ((RGBQUAD)(Marshal.PtrToStructure(palPtr, typeof(RGBQUAD))));
                        Pal.Entries[PalEntry] = Color.FromArgb(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue);
                        palPtr = (IntPtr)(palPtr.ToInt32() + Marshal.SizeOf(rgb));
                    }
                    BMP.Palette = Pal;
                }
                BitmapData BMPData = BMP.LockBits(new Rectangle(new Point(), BMP.Size), ImageLockMode.ReadWrite, PixFormat);
                CopyMemory((uint)BMPData.Scan0.ToInt32(), dataPtr, (uint)(BMPData.Stride * BMP.Height));
                BMP.UnlockBits(BMPData);
                // Flip the bitmap (GDI+ bitmap scan lines are top down, GDI are bottom up)
                BMP.RotateFlip(RotateFlipType.RotateNoneFlipY);

                // Reset the resolutions
                BMP.SetResolution((float)((int)(BIH.biXPelsPerMeter * 2.54 / 100 + 0.5)), (float)((int)(BIH.biYPelsPerMeter * 2.54 / 100 + 0.5)));
                GlobalUnlock(hMem);
            }

            return(BMP);
        }
 private int XorImageIndex(
    BITMAPINFOHEADER bmInfoHeader)
 {
    // Returns the position of the DIB bitmap bits within a
    // DIB bitmap array:
    RGBQUAD rgbq = new RGBQUAD();
    return Marshal.SizeOf(bmInfoHeader) + 
       dibNumColors(bmInfoHeader) * Marshal.SizeOf(rgbq);
 }                                            
Beispiel #27
0
        public static Bitmap GetThumbnail(string strFile, bool boolRetainBackColor, bool boolSaveToFile, string strSaveName)
        {
            Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed);
            byte   bytCnt;

            byte[]       bytBMPBuff;
            int          lngImgLoc;
            FileStream   fs = null;
            BinaryReader br = null;
            int          lngCurLoc;
            int          lngY;
            int          lngX;
            int          lngColor;
            int          lngCnt;
            short        intCnt;
            IMGREC       udtRec;

            RGBQUAD[]        udtColors;
            RGBQUAD          udtColor;
            BITMAPINFOHEADER udtHeader;
            short            intRed;
            short            intGreen;
            short            intBlue;

            try
            {
                if (File.Exists(strFile))
                {
                    fs = File.OpenRead(strFile);
                    using (br = new BinaryReader(fs))
                    {
                        fs.Seek(13, SeekOrigin.Begin);
                        lngImgLoc = br.ReadInt32();
                        fs.Seek(lngImgLoc + 17, SeekOrigin.Begin);
                        lngCurLoc = lngImgLoc + 17;
                        fs.Seek(lngCurLoc + 3, SeekOrigin.Begin);
                        bytCnt = br.ReadByte();
                        if (bytCnt > 1)
                        {
                            for (intCnt = 0; intCnt < bytCnt; intCnt++)
                            {
                                udtRec.bytType  = br.ReadByte();
                                udtRec.lngStart = br.ReadInt32();
                                udtRec.lngLen   = br.ReadInt32();
                                if (udtRec.bytType == 2)
                                {
                                    fs.Seek(udtRec.lngStart, SeekOrigin.Begin);
                                    udtHeader.biSize          = br.ReadInt32();
                                    udtHeader.biWidth         = br.ReadInt32();
                                    udtHeader.biHeight        = br.ReadInt32();
                                    udtHeader.biPlanes        = br.ReadInt16();
                                    udtHeader.biBitCount      = br.ReadInt16();
                                    udtHeader.biCompression   = br.ReadInt32();
                                    udtHeader.biSizeImage     = br.ReadInt32();
                                    udtHeader.biXPelsPerMeter = br.ReadInt32();
                                    udtHeader.biYPelsPerMeter = br.ReadInt32();
                                    udtHeader.biClrUsed       = br.ReadInt32();
                                    udtHeader.biClrImportant  = br.ReadInt32();
                                    bytBMPBuff = new byte[udtRec.lngLen + 1];
                                    if (udtHeader.biBitCount == 8)
                                    {
                                        udtColors = new RGBQUAD[256];
                                        for (int count = 0; count < 256; count++)
                                        {
                                            udtColors[count].rgbBlue     = br.ReadByte();
                                            udtColors[count].rgbGreen    = br.ReadByte();
                                            udtColors[count].rgbRed      = br.ReadByte();
                                            udtColors[count].rgbReserved = br.ReadByte();
                                        }
                                        fs.Seek(udtRec.lngStart - 1, SeekOrigin.Begin);
                                        for (int count = 0; count <= udtRec.lngLen; count++)
                                        {
                                            bytBMPBuff[count] = br.ReadByte();
                                        }
                                        bmp    = new Bitmap(udtHeader.biWidth, udtHeader.biHeight);
                                        lngCnt = 0;
                                        for (lngY = 1; lngY <= udtHeader.biHeight; lngY++)
                                        {
                                            for (lngX = udtHeader.biWidth; lngX >= 1; lngX--)
                                            {
                                                lngColor = bytBMPBuff[bytBMPBuff.GetUpperBound(0) - lngCnt];
                                                udtColor = udtColors[lngColor];
                                                intRed   = Convert.ToInt16(udtColor.rgbRed);
                                                intGreen = Convert.ToInt16(udtColor.rgbGreen);
                                                intBlue  = Convert.ToInt16(udtColor.rgbBlue);
                                                lngColor = ColorTranslator.ToOle(Color.FromArgb(intRed, intGreen, intBlue));
                                                if (boolRetainBackColor == false)
                                                {
                                                    if (lngColor == ColorTranslator.ToOle(Color.Black))
                                                    {
                                                        lngColor = ColorTranslator.ToOle(Color.White);
                                                    }
                                                    else
                                                    {
                                                        if (lngColor == ColorTranslator.ToOle(Color.White))
                                                        {
                                                            lngColor = ColorTranslator.ToOle(Color.Black);
                                                        }
                                                    }
                                                }
                                                bmp.SetPixel(lngX - 1, lngY - 1, ColorTranslator.FromOle(lngColor));
                                                lngCnt++;
                                            }
                                        }
                                    }
                                    goto Exit_Here;
                                }
                                else
                                {
                                    if (udtRec.bytType == 3)
                                    {
                                        goto Exit_Here;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
Exit_Here:
            //if (br != null)
            //{
            //    br.Close();
            //    fs.Close();
            //    fs.Dispose();
            //}
            if (boolSaveToFile == true)
            {
                if (strSaveName == "")
                {
                    string fName;
                    fName = String.Concat(Path.GetTempPath(), Path.GetFileNameWithoutExtension(Path.GetRandomFileName()), ".bmp");
                    bmp.Save(fName);
                }
                else
                {
                    bmp.Save(strSaveName);
                }
            }
            return(bmp);
        }
Beispiel #28
0
        /// <summary>
        /// Compile input images into WAD texture file.
        /// </summary>
        /// <param name="outputFilename">Output wad file path.</param>
        /// <param name="images">Input image files.</param>
        /// <param name="names">Names of textures.</param>
        /// <param name="reserverLastPalColor">Reserve last color in palette if name starts with {.</param>
        public static void CreateWad(string outputFilename, string[] images, string[] names, Color alphaReplacementColor, bool reserverLastPalColor = false)
        {
            using (FileStream fs = new FileStream(outputFilename, FileMode.Create))
                using (BinaryWriter bw = new BinaryWriter(fs))
                {
                    //Convert bitmaps to 8bpp format
                    List <FreeImageBitmap> imgs = new List <FreeImageBitmap>();
                    for (int i = 0; i < images.Length; i++)
                    {
                        //Quantize images
                        FreeImageBitmap originalImage = new FreeImageBitmap(images[i]);

                        //If texture will be transparent, reserve last color if enabled
                        bool reserveLastClr     = (names[i].StartsWith("{") && reserverLastPalColor);
                        bool isTransparentImage = originalImage.IsTransparent;
                        bool is8Bpp             = originalImage.BitsPerPixel == 8;
                        int  r = reserveLastClr ? 1 : 0;

                        if (isTransparentImage)
                        {
                            originalImage.SwapColors(new RGBQUAD(Color.Transparent), new RGBQUAD(alphaReplacementColor), false);
                        }

                        originalImage.Quantize(FREE_IMAGE_QUANTIZE.FIQ_NNQUANT, MaxPaletteColors - r);
                        originalImage.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_08_BPP);

                        if (reserveLastClr)
                        {
                            if (isTransparentImage)
                            {
                                bool foundReplacementColor = false;
                                for (int pindex = 0; pindex < originalImage.Palette.Length; pindex++)
                                {
                                    RGBQUAD rgb = originalImage.Palette.GetValue(pindex);
                                    if (rgb.rgbRed == alphaReplacementColor.R && rgb.rgbGreen == alphaReplacementColor.G && rgb.rgbBlue == alphaReplacementColor.B)
                                    {
                                        var lastColor = originalImage.Palette.GetValue(MaxPaletteColors - 1);
                                        originalImage.Palette[pindex] = lastColor;
                                        originalImage.Palette[MaxPaletteColors - 1] = new RGBQUAD(alphaReplacementColor);
                                        originalImage.SwapPaletteIndices((byte)pindex, MaxPaletteColors - 1);
                                        foundReplacementColor = true;
                                        break;
                                    }
                                }

                                // If didn't found replacement, set directly last alpha color
                                if (!foundReplacementColor)
                                {
                                    originalImage.Palette[MaxPaletteColors - 1] = new RGBQUAD(alphaReplacementColor);
                                }
                            }
                            else
                            {
                                originalImage.Palette[MaxPaletteColors - 1] = new RGBQUAD(alphaReplacementColor);
                            }
                        }

                        imgs.Add(originalImage);
                    }
                    uint[] offsets = new uint[images.Length];
                    uint[] sizes   = new uint[images.Length];

                    //WAD header
                    bw.Write(WadHeaderId);
                    bw.Write(images.Length);
                    bw.Write(0); //This will be changed later

                    //Write textures
                    for (int i = 0; i < images.Length; i++)
                    {
                        uint posTextureStart = (uint)bw.BaseStream.Position;
                        offsets[i] = posTextureStart;
                        //Texture name
                        byte[] name = CreateTextureName(names[i]);
                        bw.Write(name, 0, name.Length);

                        //Texture dimensions
                        bw.Write(imgs[i].Width);
                        bw.Write(imgs[i].Height);

                        //Offsets
                        uint posImage = (uint)(bw.BaseStream.Position - posTextureStart);
                        bw.Write(posImage + 16); //image
                        int pixelSize = ((imgs[i].Width) * (imgs[i].Height));
                        int m1        = ((imgs[i].Width / 2) * (imgs[i].Height / 2));
                        int m2        = ((imgs[i].Width / 4) * (imgs[i].Height / 4));
                        int m3        = ((imgs[i].Width / 8) * (imgs[i].Height / 8));
                        bw.Write((uint)(posImage + pixelSize + 16));           //mipmap1
                        bw.Write((uint)(posImage + pixelSize + m1 + 16));      //mipmap2
                        bw.Write((uint)(posImage + pixelSize + m1 + m2 + 16)); //mipmap3

                        //Write pixel data
                        imgs[i].RotateFlip(RotateFlipType.RotateNoneFlipX);
                        byte[] arr = new byte[imgs[i].Width * imgs[i].Height];
                        System.Runtime.InteropServices.Marshal.Copy(imgs[i].GetScanlinePointer(0), arr, 0, arr.Length);
                        Array.Reverse(arr);
                        bw.Write(arr);
                        //

                        //Mip map data
                        int factor = 2;
                        for (int a = 0; a < 3; a++)
                        {
                            int widthMM  = (imgs[i].Width / factor);
                            int heightMM = (imgs[i].Height / factor);

                            using (FreeImageBitmap clBmp = new FreeImageBitmap(imgs[i]))
                            {
                                //TODO: Transparent png
                                clBmp.Rescale(widthMM, heightMM, FREE_IMAGE_FILTER.FILTER_LANCZOS3);
                                clBmp.Quantize(FREE_IMAGE_QUANTIZE.FIQ_NNQUANT, MaxPaletteColors, imgs[i].Palette);

                                byte[] arrMM = new byte[widthMM * heightMM];
                                System.Runtime.InteropServices.Marshal.Copy(clBmp.GetScanlinePointer(0), arrMM, 0, arrMM.Length);
                                Array.Reverse(arrMM);
                                bw.Write(arrMM);
                            }
                            factor *= 2;
                        }

                        //Unknown 2 bytes
                        bw.Write(new byte[] { 0x00, 0x01 });

                        //Write color palette
                        for (int p = 0; p < imgs[i].Palette.Length; p++)
                        {
                            bw.Write(imgs[i].Palette[p].rgbRed);
                            bw.Write(imgs[i].Palette[p].rgbGreen);
                            bw.Write(imgs[i].Palette[p].rgbBlue);
                        }

                        //Padding
                        bw.Write(new byte[] { 0x00, 0x00 });
                        sizes[i] = (uint)bw.BaseStream.Position - posTextureStart;
                    }

                    long posLumps = bw.BaseStream.Position;
                    bw.Seek(8, SeekOrigin.Begin);
                    bw.Write((uint)posLumps);
                    bw.Seek((int)posLumps, SeekOrigin.Begin);
                    //Write Lumps infos
                    for (int i = 0; i < images.Length; i++)
                    {
                        bw.Write(offsets[i]);
                        bw.Write(sizes[i]);
                        bw.Write(sizes[i]);
                        bw.Write((byte)0x43);
                        bw.Write((byte)0);
                        bw.Write(new byte[] { 0x00, 0x00 });
                        byte[] name = CreateTextureName(names[i]);
                        bw.Write(name, 0, name.Length);
                    }

                    //Free resources
                    for (int i = 0; i < imgs.Count; i++)
                    {
                        imgs[i].Dispose();
                    }
                }
        }
      private void setMaskBitsFromBitmap(
         Bitmap bm
         )
      {
         IntPtr hdcc = CreateDC("DISPLAY", IntPtr.Zero, IntPtr.Zero,
          IntPtr.Zero);
         IntPtr hdc = CreateCompatibleDC(hdcc);
         DeleteDC(hdcc);
         IntPtr hBmp = bm.GetHbitmap();

         BITMAPINFOHEADER bmInfoHdr = new BITMAPINFOHEADER(
            this.size, this.colorDepth);

         // Now prepare the for GetDIBits call:
         RGBQUAD rgbQuad = new RGBQUAD();
         int monoBmHdrSize = bmInfoHdr.biSize + Marshal.SizeOf(rgbQuad)* 2;

         IntPtr bitsInfo = Marshal.AllocCoTaskMem(
            monoBmHdrSize);
         Marshal.WriteInt32(bitsInfo, Marshal.SizeOf(bmInfoHdr));
         Marshal.WriteInt32(bitsInfo, 4, this.size.Width);
         Marshal.WriteInt32(bitsInfo, 8, this.size.Height);
         Marshal.WriteInt16(bitsInfo, 12, 1);
         Marshal.WriteInt16(bitsInfo, 14, 1);
         Marshal.WriteInt32(bitsInfo, 16, BI_RGB);
         Marshal.WriteInt32(bitsInfo, 20, 0);
         Marshal.WriteInt32(bitsInfo, 24, 0);
         Marshal.WriteInt32(bitsInfo, 28, 0);
         Marshal.WriteInt32(bitsInfo, 32, 0);
         Marshal.WriteInt32(bitsInfo, 36, 0);
         // Write the black and white colour indices:
         Marshal.WriteInt32(bitsInfo, 40, 0);
         Marshal.WriteByte(bitsInfo, 44, 255);
         Marshal.WriteByte(bitsInfo, 45, 255);
         Marshal.WriteByte(bitsInfo, 46, 255);
         Marshal.WriteByte(bitsInfo, 47, 0);

         int maskImageBytes = MaskImageSize(bmInfoHdr);
         IntPtr bits = Marshal.AllocCoTaskMem(maskImageBytes);

         int success = GetDIBits(hdc, hBmp, 0, this.size.Height, bits,
          bitsInfo, DIB_RGB_COLORS);

         Marshal.Copy(bits, data, MaskImageIndex(bmInfoHdr), maskImageBytes);

         // Free memory:
         Marshal.FreeCoTaskMem(bits);
         Marshal.FreeCoTaskMem(bitsInfo);

         DeleteObject(hBmp);
         DeleteDC(hdc);

         createIcon();

      }
        public void Open(System.IO.Stream Source)
        {
            File iconFile = new File();

            iconFile.Read(Source);
            foreach (Frame iconFrame in iconFile.Frames)
            {
                System.Windows.Media.Imaging.BitmapFrame frame = null;
                if (iconFrame.type == FrameType.BITMAP)
                {
                    if (iconFrame.iconImage.icHeader.biBitCount == 32)
                    {
                        byte[] pixels = iconFrame.iconImage.icXOR;
                        pixels = Utilities.FlipYBuffer(pixels, iconFrame.Width, iconFrame.Height, iconFrame.iconImage.XorStride);
                        BitmapSource bp = BitmapSource.Create(iconFrame.Width, iconFrame.Height, 96, 96, PixelFormats.Bgra32, null, pixels, iconFrame.iconImage.XorStride);
                        frame = BitmapFrame.Create(bp);
                    }
                    else if (iconFrame.iconImage.icHeader.biBitCount == 24)
                    {
                        byte[] pixels = iconFrame.iconImage.icXOR;
                        pixels = Utilities.FlipYBuffer(pixels, iconFrame.Width, iconFrame.Height, iconFrame.iconImage.XorStride);
                        BitmapSource bp = BitmapSource.Create(iconFrame.Width, iconFrame.Height, 96, 96, PixelFormats.Bgr24, null, pixels, iconFrame.iconImage.XorStride);
                        frame = BitmapFrame.Create(bp);
                    }
                    else if (iconFrame.iconImage.icHeader.biBitCount == 8)
                    {
                        byte[] pixels = iconFrame.iconImage.icXOR;
                        pixels = Utilities.FlipYBuffer(pixels, iconFrame.Width, iconFrame.Height, iconFrame.iconImage.XorStride);
                        BitmapSource bp = BitmapSource.Create(iconFrame.Width, iconFrame.Height, 96, 96, PixelFormats.Indexed8, GetPalette(iconFrame.iconImage.icColors, true), pixels, iconFrame.iconImage.XorStride);
                        frame = BitmapFrame.Create(bp);
                    }
                    else if (iconFrame.iconImage.icHeader.biBitCount == 4)
                    {
                        byte[] pixels = iconFrame.iconImage.icXOR;
                        pixels = Utilities.FlipYBuffer(pixels, iconFrame.Width, iconFrame.Height, iconFrame.iconImage.XorStride);
                        BitmapSource bp = BitmapSource.Create(iconFrame.Width, iconFrame.Height, 96, 96, PixelFormats.Indexed4, GetPalette(iconFrame.iconImage.icColors, true), pixels, iconFrame.iconImage.XorStride);
                        frame = BitmapFrame.Create(bp);
                    }
                    else
                    {
                        try
                        {
                            byte[] pixels = iconFrame.iconImage.icXOR;
                            pixels = Utilities.FlipYBuffer(pixels, iconFrame.Width, iconFrame.Height, iconFrame.iconImage.XorStride);
                            BitmapSource bp = BitmapSource.Create(iconFrame.Width, iconFrame.Height, 96, 96, PixelFormats.Indexed1, GetPalette(iconFrame.iconImage.icColors, true), pixels, iconFrame.iconImage.XorStride);
                            frame = BitmapFrame.Create(bp);
                        }
                        catch { continue; }
                    }

                    if (iconFrame.iconImage.icAND?.Length > 0)
                    {
                        RGBQUAD[] palette = new RGBQUAD[2] {
                            RGBQUAD.FromRGBA(0, 0, 0, 0), RGBQUAD.FromRGBA(255, 255, 255, 255)
                        };
                        byte[] pixels = iconFrame.iconImage.icAND;
                        pixels = Utilities.FlipYBuffer(pixels, iconFrame.Width, iconFrame.Height, iconFrame.iconImage.AndStride);
                        BitmapSource AND = BitmapSource.Create(iconFrame.Width, iconFrame.Height,
                                                               96, 96, PixelFormats.Indexed1, GetPalette(palette, true), pixels, iconFrame.iconImage.AndStride);

                        EditableBitmapImage editableXOR = new EditableBitmapImage(frame);
                        EditableBitmapImage editableAND = new EditableBitmapImage(AND);
                        for (int x = 0; x < editableXOR.PixelWidth; x++)
                        {
                            for (int y = 0; y < editableXOR.PixelHeight; y++)
                            {
                                Color px = editableAND.GetPixel(x, y);
                                if (px == Colors.White)
                                {
                                    Color c = editableXOR.GetPixel(x, y);
                                    c.A = 0;
                                    editableXOR.SetPixel(x, y, c);
                                }
                            }
                        }
                        if (frame.Format.BitsPerPixel == 32)
                        {
                            // Do nothing
                        }
                        else if (frame.Format.BitsPerPixel == 24)
                        {
                            frame = BitmapFrame.Create(editableXOR);
                        }
                        else if (frame.Format.BitsPerPixel == 8)
                        {
                            BitmapSource s = Helpers.Get8BitImage(editableXOR);
                            frame = BitmapFrame.Create(s);
                        }
                        else if (frame.Format.BitsPerPixel == 4)
                        {
                            BitmapSource s = Helpers.Get4BitImage(editableXOR);
                            frame = BitmapFrame.Create(s);
                        }
                    }
                }
                else
                {
                    try
                    {
                        PngBitmapDecoder decoder = new PngBitmapDecoder(new System.IO.MemoryStream(iconFrame.pngBuffer), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
                        frame = decoder.Frames[0];
                    }
                    catch
                    {
                        frame = BitmapFrame.Create(CreateEmptyBitmap(iconFrame.Width));
                    }
                }
                _Frames.Add(frame);
            }
        }
      private Bitmap getIconBitmap(
         bool mask,
         bool returnHandle,
         ref IntPtr hBmp
         )
      {
         // Bitmap to return
         Bitmap bm = null;

         // Get bitmap info:         
         BITMAPINFOHEADER bmInfoHdr = new BITMAPINFOHEADER(data);

         if (mask)
         {
            // extract monochrome mask
            IntPtr hdc = CreateCompatibleDC(IntPtr.Zero);
            hBmp = CreateCompatibleBitmap(hdc, bmInfoHdr.biWidth,
             bmInfoHdr.biHeight / 2);
            IntPtr hBmpOld = SelectObject(hdc, hBmp);

            // Prepare BitmapInfoHeader for mono bitmap:
            RGBQUAD rgbQuad = new RGBQUAD();
            int monoBmHdrSize = bmInfoHdr.biSize + Marshal.SizeOf(rgbQuad)* 2;

            IntPtr bitsInfo = Marshal.AllocCoTaskMem(
               monoBmHdrSize);
            Marshal.WriteInt32(bitsInfo, Marshal.SizeOf(bmInfoHdr));
            Marshal.WriteInt32(bitsInfo, 4, bmInfoHdr.biWidth);
            Marshal.WriteInt32(bitsInfo, 8, bmInfoHdr.biHeight / 2);
            Marshal.WriteInt16(bitsInfo, 12, 1);
            Marshal.WriteInt16(bitsInfo, 14, 1);
            Marshal.WriteInt32(bitsInfo, 16, BI_RGB);
            Marshal.WriteInt32(bitsInfo, 20, 0);
            Marshal.WriteInt32(bitsInfo, 24, 0);
            Marshal.WriteInt32(bitsInfo, 28, 0);
            Marshal.WriteInt32(bitsInfo, 32, 0);
            Marshal.WriteInt32(bitsInfo, 36, 0);
            // Write the black and white colour indices:
            Marshal.WriteInt32(bitsInfo, 40, 0);
            Marshal.WriteByte(bitsInfo, 44, 255);
            Marshal.WriteByte(bitsInfo, 45, 255);
            Marshal.WriteByte(bitsInfo, 46, 255);
            Marshal.WriteByte(bitsInfo, 47, 0);

            // Prepare Mask bits:
            int maskImageBytes = MaskImageSize(bmInfoHdr);
            IntPtr bits = Marshal.AllocCoTaskMem(maskImageBytes);
            Marshal.Copy(data, MaskImageIndex(bmInfoHdr), bits, maskImageBytes);

            int success = SetDIBitsToDevice(
               hdc, 
               0, 0, bmInfoHdr.biWidth, bmInfoHdr.biHeight / 2, 
               0, 0, 0, bmInfoHdr.biHeight / 2, 
               bits, 
               bitsInfo, 
               DIB_RGB_COLORS);

            Marshal.FreeCoTaskMem(bits);
            Marshal.FreeCoTaskMem(bitsInfo);

            SelectObject(hdc, hBmpOld);
            DeleteObject(hdc);

         }
         else
         {
            // extract colour (XOR) part of image:
            
            // Create bitmap:
            IntPtr hdcDesktop = CreateDC("DISPLAY", IntPtr.Zero, IntPtr.Zero,
             IntPtr.Zero);
            IntPtr hdc = CreateCompatibleDC(hdcDesktop);
            hBmp = CreateCompatibleBitmap(hdcDesktop, bmInfoHdr.biWidth,
             bmInfoHdr.biHeight / 2);
            DeleteDC(hdcDesktop);
            IntPtr hBmpOld = SelectObject(hdc, hBmp);
            
            // Find the index of the XOR bytes:
            int xorIndex = XorImageIndex(bmInfoHdr);
            int xorImageSize = XorImageSize(bmInfoHdr);

            // Get Bitmap info header to a pointer:                        
            IntPtr bitsInfo = Marshal.AllocCoTaskMem(xorIndex);
            Marshal.Copy(data, 0, bitsInfo, xorIndex);
            // fix the height:
            Marshal.WriteInt32(bitsInfo, 8, bmInfoHdr.biHeight / 2);

            // Get the XOR bits:            
            IntPtr bits = Marshal.AllocCoTaskMem(xorImageSize);
            Marshal.Copy(data, xorIndex, bits, xorImageSize);

            int success = SetDIBitsToDevice(
               hdc, 
               0, 0, bmInfoHdr.biWidth, bmInfoHdr.biHeight/2, 
               0, 0, 0, bmInfoHdr.biHeight/2, 
               bits, 
               bitsInfo, 
               DIB_RGB_COLORS);

            Marshal.FreeCoTaskMem(bits);
            Marshal.FreeCoTaskMem(bitsInfo);

            SelectObject(hdc, hBmpOld);
            DeleteObject(hdc);
         }

         if (!returnHandle)
         {
            // the bitmap will own the handle and clear
            // it up when it is disposed.  Otherwise
            // need to call DeleteObject on hBmp
            // returned.
            bm = Bitmap.FromHbitmap(hBmp);
         }
         return bm;
      }
Beispiel #32
0
 private unsafe void SetPalette(ColorPalette colorPalette, BITMAPINFO info)
 {
     ushort bitCount = info.bmiHeader.biBitCount;
       RGBQUAD rgb = new RGBQUAD();
       int* pRgb = info.bmiColors;
       if (bitCount==1 || bitCount==4 || bitCount==8) {
     for (int i = 0; i < colorPalette.Entries.Length; i++) {
       int value = *(pRgb+i);
       rgb.value = value;
       int r = rgb.rgbRed;
       int g = rgb.rgbGreen;
       int b = rgb.rgbBlue;
       colorPalette.Entries[i] = Color.FromArgb(r, g, b);
     }
       }
 }
Beispiel #33
0
 public unsafe static extern void CopyMemory(RGBQUAD* dest, byte* src, int cb);
Beispiel #34
0
        private static RGBQUAD ConvertYCrCbToRGB(byte y, byte cr, byte cb)
        {
            RGBQUAD rgbq = new RGBQUAD();

            int c = y - 16;
            int d = cb - 128;
            int e = cr - 128;

            rgbq.R = Clip((298 * c + 409 * e + 128) >> 8);
            rgbq.G = Clip((298 * c - 100 * d - 208 * e + 128) >> 8);
            rgbq.B = Clip((298 * c + 516 * d + 128) >> 8);

            return rgbq;
        }
Beispiel #35
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                PrintHelp();
                return;
            }

            try
            {
                string inputFile  = args[0];
                string outputFile = args[1];

                Console.WriteLine(String.Format("Loading file: {0}", inputFile));
                FIBITMAP image = FreeImage.LoadEx(inputFile);

                // Make sure the image is one of the supported types
                FREE_IMAGE_TYPE imgType = FreeImage.GetImageType(image);
                switch (imgType)
                {
                case FREE_IMAGE_TYPE.FIT_INT16:
                    Console.WriteLine("Detected 16-bit short");
                    break;

                case FREE_IMAGE_TYPE.FIT_INT32:
                    Console.WriteLine("Detected 32-bit int");
                    break;

                case FREE_IMAGE_TYPE.FIT_UINT16:
                    Console.WriteLine("Detected 16-bit ushort");
                    break;

                case FREE_IMAGE_TYPE.FIT_UINT32:
                    Console.WriteLine("Detected 32-bit uint");
                    break;

                default:
                    Console.WriteLine(String.Format("Unsupported file type: {0}", imgType.ToString()));
                    return;
                }

                uint width   = FreeImage.GetWidth(image);
                uint height  = FreeImage.GetHeight(image);
                uint fileBPP = FreeImage.GetBPP(image);

                // Allocate new RGB Image
                FIBITMAP newMap  = FreeImage.Allocate((int)width, (int)height, 8 /*BitsPerPixel*/ * 3);
                RGBQUAD  outQuad = new RGBQUAD();

                // Multiplier for the byte offset into the scaline
                int iterations       = 0;
                int lateralMultipler = fileBPP == 16 ? 2 : 4;
                for (uint x = 0; x < width; ++x, ++iterations)
                {
                    float progress = ((float)(iterations)) / ((float)(width * height));
                    Console.Write(String.Format("\rProgress {0:000.0}%     ", progress * 100.0f));
                    for (uint y = 0; y < height; ++y, ++iterations)
                    {
                        IntPtr line = FreeImage.GetScanLine(image, (int)y);
                        if (fileBPP >= 16)
                        {
                            line = new IntPtr(line.ToInt64() + lateralMultipler * x);
                            if (imgType == FREE_IMAGE_TYPE.FIT_UINT16)
                            {
                                ushort value = (ushort)System.Runtime.InteropServices.Marshal.ReadInt16(line);
                                outQuad.rgbRed   = (byte)(value / 256);
                                outQuad.rgbGreen = (byte)(value % 256);
                            }
                            else if (imgType == FREE_IMAGE_TYPE.FIT_UINT32)
                            {
                                uint value = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(line);
                                outQuad.rgbRed   = (byte)(value / 256);
                                outQuad.rgbGreen = (byte)(value % 256);
                            }
                            else if (imgType == FREE_IMAGE_TYPE.FIT_INT16)
                            {
                                short value = (short)System.Runtime.InteropServices.Marshal.ReadInt16(line);
                                outQuad.rgbRed   = (byte)(value / 256);
                                outQuad.rgbGreen = (byte)(value % 256);
                            }
                            else if (imgType == FREE_IMAGE_TYPE.FIT_INT32)
                            {
                                int value = (int)System.Runtime.InteropServices.Marshal.ReadInt32(line);
                                outQuad.rgbRed   = (byte)(value / 256);
                                outQuad.rgbGreen = (byte)(value % 256);
                            }
                            FreeImage.SetPixelColor(newMap, x, y, ref outQuad);
                        }
                        else
                        {
                        }
                    }
                }
                Console.WriteLine(" "); //empty space
                Console.WriteLine(String.Format("Writing file: {0}", outputFile));
                if (FreeImage.SaveEx(newMap, outputFile))
                {
                    Console.WriteLine("Finished");
                }
                else
                {
                    Console.WriteLine("ERROR: Failed to write file");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: ");
                Console.Write(ex.Message);
            }
        }
Beispiel #36
0
        public void Example03()
        {
            dib = FreeImage.LoadEx("Sample.tif");

            // Check whether loading succeeded
            if (dib.IsNull)
            {
                Console.WriteLine("Sample.tif could not be loaded. Aborting.");
                return;
            }

            // Check whether the bitmap has 4 bpp color depth to ensure
            // using FI4B is correct.
            if (FreeImage.GetBPP(dib) != 4)
            {
                Console.WriteLine("Sample.tif is no 4 bpp bitmap. Aborting.");
                FreeImage.UnloadEx(ref dib);
                return;
            }

            // Get the bitmaps palette
            Palette palette = FreeImage.GetPaletteEx(dib);

            int size = (int)palette.Length;

            // Check whether the palette has a color (is valid)
            if (size == 0)
            {
                Console.WriteLine("Sample.tif has no valid palette. Aborting.");
                FreeImage.UnloadEx(ref dib);
                return;
            }

            // Swapping the palette
            for (int i = 0; i < size / 2; i++)
            {
                RGBQUAD temp = palette[i];
                palette[i]            = palette[size - 1 - i];
                palette[size - 1 - i] = temp;
            }

            // Iterate over each scanline
            for (int i = 0; i < FreeImage.GetHeight(dib); i++)
            {
                // Get scanline
                Scanline <FI4BIT> scanline = new Scanline <FI4BIT>(dib, i);

                // Iterate over all pixels swapping the palette index
                // so that the color will stay the same
                for (int j = 0; j < scanline.Length; j++)
                {
                    scanline[j] = (byte)(size - 1 - scanline[j]);
                }
            }

            // Save the bitmap to disk
            if (!FreeImage.SaveEx(ref dib, "SampleOut03.tif", FREE_IMAGE_SAVE_FLAGS.TIFF_LZW, true))
            {
                Console.WriteLine("Error while saving 'SampleOut03.tif'");
                FreeImage.UnloadEx(ref dib);
            }
        }
Beispiel #37
0
 private static extern bool FreeImage_GetPixelColor(FIBITMAP dib, int x, int y, RGBQUAD value);
Beispiel #38
0
 private Bitmap getIconBitmap(bool mask, bool returnHandle, ref IntPtr hBmp)
 {
     Bitmap bitmap = null;
     BITMAPINFOHEADER structure = new BITMAPINFOHEADER(this.data);
     if (mask)
     {
         IntPtr hdc = CreateCompatibleDC(IntPtr.Zero);
         hBmp = CreateCompatibleBitmap(hdc, structure.biWidth, structure.biHeight / 2);
         IntPtr hObject = SelectObject(hdc, hBmp);
         RGBQUAD rgbquad = new RGBQUAD();
         int cb = structure.biSize + (Marshal.SizeOf(rgbquad) * 2);
         IntPtr ptr = Marshal.AllocCoTaskMem(cb);
         Marshal.WriteInt32(ptr, Marshal.SizeOf(structure));
         Marshal.WriteInt32(ptr, 4, structure.biWidth);
         Marshal.WriteInt32(ptr, 8, structure.biHeight / 2);
         Marshal.WriteInt16(ptr, 12, (short)1);
         Marshal.WriteInt16(ptr, 14, (short)1);
         Marshal.WriteInt32(ptr, 0x10, 0);
         Marshal.WriteInt32(ptr, 20, 0);
         Marshal.WriteInt32(ptr, 0x18, 0);
         Marshal.WriteInt32(ptr, 0x1c, 0);
         Marshal.WriteInt32(ptr, 0x20, 0);
         Marshal.WriteInt32(ptr, 0x24, 0);
         Marshal.WriteInt32(ptr, 40, 0);
         Marshal.WriteByte(ptr, 0x2c, 0xff);
         Marshal.WriteByte(ptr, 0x2d, 0xff);
         Marshal.WriteByte(ptr, 0x2e, 0xff);
         Marshal.WriteByte(ptr, 0x2f, 0);
         int num2 = this.MaskImageSize(structure);
         IntPtr destination = Marshal.AllocCoTaskMem(num2);
         Marshal.Copy(this.data, this.MaskImageIndex(structure), destination, num2);
         SetDIBitsToDevice(hdc, 0, 0, structure.biWidth, structure.biHeight / 2, 0, 0, 0, structure.biHeight / 2, destination, ptr, 0);
         Marshal.FreeCoTaskMem(destination);
         Marshal.FreeCoTaskMem(ptr);
         SelectObject(hdc, hObject);
         DeleteObject(hdc);
     }
     else
     {
         IntPtr ptr5 = CreateDC("DISPLAY", IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
         IntPtr ptr6 = CreateCompatibleDC(ptr5);
         hBmp = CreateCompatibleBitmap(ptr5, structure.biWidth, structure.biHeight / 2);
         DeleteDC(ptr5);
         IntPtr ptr7 = SelectObject(ptr6, hBmp);
         int num3 = this.XorImageIndex(structure);
         int num4 = this.XorImageSize(structure);
         IntPtr ptr8 = Marshal.AllocCoTaskMem(num3);
         Marshal.Copy(this.data, 0, ptr8, num3);
         Marshal.WriteInt32(ptr8, 8, structure.biHeight / 2);
         IntPtr ptr9 = Marshal.AllocCoTaskMem(num4);
         Marshal.Copy(this.data, num3, ptr9, num4);
         SetDIBitsToDevice(ptr6, 0, 0, structure.biWidth, structure.biHeight / 2, 0, 0, 0, structure.biHeight / 2, ptr9, ptr8, 0);
         Marshal.FreeCoTaskMem(ptr9);
         Marshal.FreeCoTaskMem(ptr8);
         SelectObject(ptr6, ptr7);
         DeleteObject(ptr6);
     }
     if (!returnHandle)
     {
         bitmap = Image.FromHbitmap(hBmp);
     }
     return bitmap;
 }
Beispiel #39
0
        private FIBITMAP formatImage(FIBITMAP dib, int icoSize, int dstBpp)
        {
            const int hideOpacity = 128;

            //FIBITMAP dibTmp = FreeImage.Rescale(dib, icoSize, icoSize, FREE_IMAGE_FILTER.FILTER_BICUBIC);
            FIBITMAP dibTmp = FreeImage.Rescale(dib, icoSize, icoSize, FREE_IMAGE_FILTER.FILTER_LANCZOS3);

            if (dstBpp >= 32)
            {
                return(dibTmp);
            }

            int  paletteSize    = (int)Math.Pow(2, dstBpp);
            byte lastPaletteIdx = (byte)(paletteSize - 1);

            // quantize ico
            // reserve last one palette, to set transparent
            //FIBITMAP dibTmp2 = FreeImage.ConvertColorDepth(dibTmp, FREE_IMAGE_COLOR_DEPTH.FICD_04_BPP);
            FIBITMAP dibOut = FreeImage.ColorQuantizeEx(dibTmp, FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, paletteSize - 1, null, dstBpp);

            // set transparent color index to last one palette
            RGBQUAD rgb = new RGBQUAD();
            byte    val = 0;

            for (int m = icoSize - 1; m >= 0; --m)
            {
                string str = "";
                for (int n = icoSize - 1; n >= 0; --n)
                {
                    FreeImage.GetPixelIndex(dibOut, (uint)n, (uint)m, out val);
                    FreeImage.GetPixelColor(dibTmp, (uint)n, (uint)m, out rgb);
                    //uint val = rgb.uintValue & 0x00FFFFFF;
                    if (rgb.rgbReserved <= hideOpacity)
                    {
                        FreeImage.SetPixelIndex(dibOut, (uint)n, (uint)m, ref lastPaletteIdx);
                    }
                    str += val + ",";
                }
            }

            FreeImage.Unload(dibTmp);

            //uint bpp = FreeImage.GetBPP(dibOut);

            // set transarency table
            try {
                RGBQUAD[] palette      = new Palette(dibOut).AsArray;
                byte[]    transparency = new byte[palette.Length];
                for (int m = 0; m < palette.Length; ++m)
                {
                    transparency[m] = 0xFF;
                    if (m == lastPaletteIdx)
                    {
                        transparency[m] = 0;
                    }
                }
                FreeImage.SetTransparencyTable(dibOut, transparency);
            } catch (Exception) { }

            return(dibOut);
        }
Beispiel #40
0
 private void setMaskBitsFromBitmap(Bitmap bm)
 {
     IntPtr hdc = CreateDC("DISPLAY", IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
     IntPtr ptr2 = CreateCompatibleDC(hdc);
     DeleteDC(hdc);
     IntPtr hbitmap = bm.GetHbitmap();
     BITMAPINFOHEADER structure = new BITMAPINFOHEADER(this.size, this.colorDepth);
     RGBQUAD rgbquad = new RGBQUAD();
     int cb = structure.biSize + (Marshal.SizeOf(rgbquad) * 2);
     IntPtr ptr = Marshal.AllocCoTaskMem(cb);
     Marshal.WriteInt32(ptr, Marshal.SizeOf(structure));
     Marshal.WriteInt32(ptr, 4, this.size.Width);
     Marshal.WriteInt32(ptr, 8, this.size.Height);
     Marshal.WriteInt16(ptr, 12, (short)1);
     Marshal.WriteInt16(ptr, 14, (short)1);
     Marshal.WriteInt32(ptr, 0x10, 0);
     Marshal.WriteInt32(ptr, 20, 0);
     Marshal.WriteInt32(ptr, 0x18, 0);
     Marshal.WriteInt32(ptr, 0x1c, 0);
     Marshal.WriteInt32(ptr, 0x20, 0);
     Marshal.WriteInt32(ptr, 0x24, 0);
     Marshal.WriteInt32(ptr, 40, 0);
     Marshal.WriteByte(ptr, 0x2c, 0xff);
     Marshal.WriteByte(ptr, 0x2d, 0xff);
     Marshal.WriteByte(ptr, 0x2e, 0xff);
     Marshal.WriteByte(ptr, 0x2f, 0);
     int num2 = this.MaskImageSize(structure);
     IntPtr bits = Marshal.AllocCoTaskMem(num2);
     GetDIBits(ptr2, hbitmap, 0, this.size.Height, bits, ptr, 0);
     Marshal.Copy(bits, this.data, this.MaskImageIndex(structure), num2);
     Marshal.FreeCoTaskMem(bits);
     Marshal.FreeCoTaskMem(ptr);
     DeleteObject(hbitmap);
     DeleteDC(ptr2);
     this.createIcon();
 }
Beispiel #41
0
        private void SetColorChannels(int redmask, int greenmask, int bluemask)
        {
            if (Bitmap)
            {
                // Create a temporary clone.
                using (FreeImageBitmap bitmap = (FreeImageBitmap)this.bitmap.Clone())
                {
                    if (bitmap != null)
                    {
                        // Check whether the bitmap has a palette
                        if (bitmap.HasPalette)
                        {
                            // Use the Palette class to handle the bitmap's
                            // palette. A palette always consist of RGBQUADs.
                            Palette palette = bitmap.Palette;
                            // Apply the new values for all three color components.
                            for (int i = 0; i < palette.Length; i++)
                            {
                                RGBQUAD rgbq = palette[i];

                                rgbq.rgbRed   = (byte)(rgbq.rgbRed & redmask);
                                rgbq.rgbGreen = (byte)(rgbq.rgbGreen & greenmask);
                                rgbq.rgbBlue  = (byte)(rgbq.rgbBlue & bluemask);

                                palette[i] = rgbq;
                            }
                        }
                        // In case the bitmap has no palette it must have a color depth
                        // of 16, 24 or 32. Each color depth needs a different wrapping
                        // structure for the bitmaps data. These structures can be accessed
                        // by using the foreach clause.
                        else if (bitmap.ColorDepth == 16)
                        {
                            // Iterate over each scanline
                            // For 16bpp use either Scanline<FI16RGB555> or Scanline<FI16RGB565>
                            if (bitmap.IsRGB555)
                            {
                                foreach (Scanline <FI16RGB555> scanline in bitmap)
                                {
                                    for (int x = 0; x < scanline.Length; x++)
                                    {
                                        FI16RGB555 pixel = scanline[x];
                                        pixel.Red   = (byte)(pixel.Red & redmask);
                                        pixel.Green = (byte)(pixel.Green & greenmask);
                                        pixel.Blue  = (byte)(pixel.Blue & bluemask);
                                        scanline[x] = pixel;
                                    }
                                }
                            }
                            else if (bitmap.IsRGB565)
                            {
                                foreach (Scanline <FI16RGB565> scanline in bitmap)
                                {
                                    for (int x = 0; x < scanline.Length; x++)
                                    {
                                        FI16RGB565 pixel = scanline[x];
                                        pixel.Red   = (byte)(pixel.Red & redmask);
                                        pixel.Green = (byte)(pixel.Green & greenmask);
                                        pixel.Blue  = (byte)(pixel.Blue & bluemask);
                                        scanline[x] = pixel;
                                    }
                                }
                            }
                        }
                        else if (bitmap.ColorDepth == 24)
                        {
                            // Iterate over each scanline
                            // For 24bpp Scanline<RGBTRIPLE> must be used
                            foreach (Scanline <RGBTRIPLE> scanline in bitmap)
                            {
                                for (int x = 0; x < scanline.Length; x++)
                                {
                                    RGBTRIPLE pixel = scanline[x];
                                    pixel.rgbtRed   = (byte)(pixel.rgbtRed & redmask);
                                    pixel.rgbtGreen = (byte)(pixel.rgbtGreen & greenmask);
                                    pixel.rgbtBlue  = (byte)(pixel.rgbtBlue & bluemask);
                                    scanline[x]     = pixel;
                                }
                            }
                        }
                        else if (bitmap.ColorDepth == 32)
                        {
                            // Iterate over each scanline
                            // For 32bpp Scanline<RGBQUAD> must be used
                            foreach (Scanline <RGBQUAD> scanline in bitmap)
                            {
                                for (int x = 0; x < scanline.Length; x++)
                                {
                                    RGBQUAD pixel = scanline[x];
                                    pixel.rgbRed   = (byte)(pixel.rgbRed & redmask);
                                    pixel.rgbGreen = (byte)(pixel.rgbGreen & greenmask);
                                    pixel.rgbBlue  = (byte)(pixel.rgbBlue & bluemask);
                                    scanline[x]    = pixel;
                                }
                            }
                        }
                        // Dispose only the picturebox's bitmap
                        if (pictureBox.Image != null)
                        {
                            pictureBox.Image.Dispose();
                        }
                        pictureBox.Image = (Bitmap)bitmap;
                    }
                }
            }
        }
Beispiel #42
0
 private int XorImageIndex(BITMAPINFOHEADER bmInfoHeader)
 {
     RGBQUAD structure = new RGBQUAD();
     return (Marshal.SizeOf(bmInfoHeader) + (this.dibNumColors(bmInfoHeader) * Marshal.SizeOf(structure)));
 }