Exemplo n.º 1
0
        // This reads the image and returns a Bitmap
        public Bitmap ReadAsBitmap(Stream stream)
        {
            if (proxyreader != null)
            {
                return(proxyreader.ReadAsBitmap(stream));
            }

            try
            {
                // Create an image in DevIL
                uint imageid = 0;
                ilGenImages(1, new IntPtr(&imageid));
                ilBindImage(imageid);

                // Read image data from stream
                byte[] bytes;
                if (imagebytes == null)
                {
                    bytes = new byte[stream.Length];
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.Read(bytes, 0, bytes.Length);
                    imagebytes = bytes;
                }
                else
                {
                    bytes = imagebytes;

                    fixed(byte *bptr = bytes)
                    {
                        if (!ilLoadL(imagetype, new IntPtr(bptr), (uint)bytes.Length))
                        {
                            throw new BadImageFormatException();
                        }
                    }

                    // [ZZ] check if there was any error code
                    DevilError ilerror = (DevilError)ilGetError();
                    if (ilerror != DevilError.IL_NO_ERROR)
                    {
                        throw new BadImageFormatException("DevIL error: " + ilerror.ToString());
                    }

                    // Get the image properties
                    int width  = ilGetInteger(IL_IMAGE_WIDTH);
                    int height = ilGetInteger(IL_IMAGE_HEIGHT);
                    if ((width < 1) || (height < 1))
                    {
                        throw new BadImageFormatException();
                    }

                    // Convert the image to ARGB if needed
                    ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE);

                    // Copy the image pixels to a Bitmap
                    Bitmap bmp         = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    ilCopyPixels(0, 0, 0, (uint)width, (uint)height, 1, IL_BGRA, IL_UNSIGNED_BYTE, bmpdata.Scan0);
                    bmp.UnlockBits(bmpdata);

                    // Clean up
                    ilDeleteImages(1, new IntPtr(&imageid));

                    //mxd. TGA fix
                    if (imagetype == DevilImageType.IL_TGA)
                    {
                        bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
                    }

                    return(bmp);
            }
            catch (Exception e)
            {
                // [ZZ] try to make a guessed reader
                switch (guesstype)
                {
                case ImageDataFormat.DOOMPICTURE:
                    // Check if data is valid for a doom picture
                    stream.Seek(0, SeekOrigin.Begin);
                    DoomPictureReader picreader = new DoomPictureReader(guesspalette);
                    if (picreader.Validate(stream))
                    {
                        proxyreader = picreader;
                    }
                    break;

                case ImageDataFormat.DOOMFLAT:
                    // Check if data is valid for a doom flat
                    stream.Seek(0, SeekOrigin.Begin);
                    DoomFlatReader flatreader = new DoomFlatReader(guesspalette);
                    if (flatreader.Validate(stream))
                    {
                        proxyreader = flatreader;
                    }
                    break;

                case ImageDataFormat.DOOMCOLORMAP:
                    // Check if data is valid for a doom colormap
                    stream.Seek(0, SeekOrigin.Begin);
                    DoomColormapReader colormapreader = new DoomColormapReader(guesspalette);
                    if (colormapreader.Validate(stream))
                    {
                        proxyreader = colormapreader;
                    }
                    break;
                }

                if (proxyreader != null)
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    return(proxyreader.ReadAsBitmap(stream));
                }

                // Unable to make bitmap
                General.ErrorLogger.Add(ErrorType.Error, "Unable to make file image. " + e.GetType().Name + ": " + e.Message);
                return(null);
            }
        }
        // This reads the image and returns a Bitmap
        public Bitmap ReadAsBitmap(Stream stream)
        {
            if (proxyreader != null)
            {
                return(proxyreader.ReadAsBitmap(stream));
            }

            // Let the .net framework try first
            try
            {
                using (var image = Image.FromStream(new NoCloseStream(stream)))
                {
                    return(new Bitmap(image));
                }
            }
            catch
            {
                stream.Seek(0, SeekOrigin.Begin);
            }

#if !NO_DEVIL
            string error;
            lock (syncobject) // DevIL is not thread safe.
            {
                try
                {
                    // Create an image in DevIL
                    uint imageid = 0;
                    ilGenImages(1, new IntPtr(&imageid));
                    ilBindImage(imageid);

                    // Read image data from stream
                    byte[] bytes;
                    if (imagebytes == null)
                    {
                        bytes = new byte[stream.Length];
                        stream.Seek(0, SeekOrigin.Begin);
                        stream.Read(bytes, 0, bytes.Length);
                        imagebytes = bytes;
                    }
                    else
                    {
                        bytes = imagebytes;
                    }

                    ilEnable(IL_ORIGIN_SET);
                    ilOriginFunc(IL_ORIGIN_UPPER_LEFT);

                    fixed(byte *bptr = bytes)
                    {
                        if (!ilLoadL(imagetype, new IntPtr(bptr), (uint)bytes.Length))
                        {
                            throw new BadImageFormatException();
                        }
                    }

                    // [ZZ] check if there was any error code
                    DevilError ilerror = (DevilError)ilGetError();
                    if (ilerror != DevilError.IL_NO_ERROR)
                    {
                        throw new BadImageFormatException("DevIL error: " + ilerror.ToString());
                    }

                    // Get the image properties
                    int width  = ilGetInteger(IL_IMAGE_WIDTH);
                    int height = ilGetInteger(IL_IMAGE_HEIGHT);
                    if ((width < 1) || (height < 1))
                    {
                        throw new BadImageFormatException();
                    }

                    // Convert the image to ARGB if needed
                    ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE);

                    // Copy the image pixels to a Bitmap
                    Bitmap     bmp     = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    ilCopyPixels(0, 0, 0, (uint)width, (uint)height, 1, IL_BGRA, IL_UNSIGNED_BYTE, bmpdata.Scan0);
                    bmp.UnlockBits(bmpdata);

                    // Clean up
                    ilDeleteImages(1, new IntPtr(&imageid));

                    return(bmp);
                }
                catch (Exception e)
                {
                    // Remove last error from the stack. Workaround for https://github.com/jewalky/GZDoom-Builder-Bugfix/issues/295
                    ilGetError();

                    error = "Unable to make file image. " + e.GetType().Name + ": " + e.Message;
                }
            }
#else
            string error = "No devil image support";
#endif

            // [ZZ] try to make a guessed reader
            switch (guesstype)
            {
            case ImageDataFormat.DOOMPICTURE:
                // Check if data is valid for a doom picture
                stream.Seek(0, SeekOrigin.Begin);
                DoomPictureReader picreader = new DoomPictureReader(guesspalette);
                if (picreader.Validate(stream))
                {
                    proxyreader = picreader;
                }
                break;

            case ImageDataFormat.DOOMFLAT:
                // Check if data is valid for a doom flat
                stream.Seek(0, SeekOrigin.Begin);
                DoomFlatReader flatreader = new DoomFlatReader(guesspalette);
                if (flatreader.Validate(stream))
                {
                    proxyreader = flatreader;
                }
                break;

            case ImageDataFormat.DOOMCOLORMAP:
                // Check if data is valid for a doom colormap
                stream.Seek(0, SeekOrigin.Begin);
                DoomColormapReader colormapreader = new DoomColormapReader(guesspalette);
                if (colormapreader.Validate(stream))
                {
                    proxyreader = colormapreader;
                }
                break;
            }

            if (proxyreader != null)
            {
                stream.Seek(0, SeekOrigin.Begin);
                return(proxyreader.ReadAsBitmap(stream));
            }

            // Unable to make bitmap
            General.ErrorLogger.Add(ErrorType.Error, error);
            return(null);
        }