Ejemplo n.º 1
0
        public void Render(IntPtr pRender)
        {
            unsafe
            {
                ColorTable table = BurnGfxData.Instance.GetMapColorTable(mapId);

                PixelColor *ptr      = (PixelColor *)pRender;
                int         pos      = 0;
                int         nextstep = 0;

                for (int i = 0; i < Width * Height; i++)
                {
                    byte fileData = data[i];

                    int x = pos % Width;
                    int y = (pos - x) / Width;

                    ptr[(x + y * Width)] = table.GetColor(fileData);

                    pos      += 4;
                    nextstep += 4;

                    if (nextstep >= Width * Height)
                    {
                        pos -= Width * Height;
                        pos++;
                        nextstep = 0;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        // This draws the picture to the given pixel color data
        // Throws exception on failure
        public void DrawToPixelData(Stream stream, PixelColor *target, int targetwidth, int targetheight, int x, int y)
        {
            int width, height, ox, oy;

            // Read pixel data
            PixelColor[] pixeldata = ReadAsPixelData(stream, out width, out height, out ox, out oy);
            if (pixeldata != null)
            {
                // Go for all source pixels
                // We don't care about the original image offset, so reuse ox/oy
                for (ox = 0; ox < width; ox++)
                {
                    for (oy = 0; oy < height; oy++)
                    {
                        // Copy this pixel?
                        if (pixeldata[oy * width + ox].a > 0.5f)
                        {
                            // Calculate target pixel and copy when within bounds
                            int tx = x + ox;
                            int ty = y + oy;
                            if ((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
                            {
                                target[ty * targetwidth + tx] = pixeldata[oy * width + ox];
                            }
                        }
                    }
                }
            }
            else
            {
                throw new InvalidDataException("Failed to read pixeldata");                 //mxd. Let's throw exception on failure
            }
        }
Ejemplo n.º 3
0
 // Constructor
 public Plotter(PixelColor *pixels, int width, int height)
 {
     // Initialize
     this.pixels = pixels;
     this.width  = width;
     this.height = height;
 }
        unsafe void MakeAlphaTestImage(LocalLoadResult loadResult)
        {
            if (loadResult.bitmap == null)
            {
                return;
            }

            int width  = loadResult.bitmap.Width;
            int height = loadResult.bitmap.Height;

            loadResult.alphatestWidth  = width;
            loadResult.alphatestHeight = height;

            BitmapData  bmpdata = loadResult.bitmap.LockBits(new Rectangle(0, 0, loadResult.bitmap.Size.Width, loadResult.bitmap.Size.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            PixelColor *pixels  = (PixelColor *)(bmpdata.Scan0.ToPointer());

            for (int y = 0; y < height; y++)
            {
                PixelColor *line = pixels + y * width;
                for (int x = 0; x < width; x++)
                {
                    if (line[x].a == 0)
                    {
                        if (loadResult.alphatest == null)
                        {
                            loadResult.alphatest = new BitArray(width * height, true);
                        }
                        loadResult.alphatest.Set(x + y * width, false);
                    }
                }
            }

            loadResult.bitmap.UnlockBits(bmpdata);
        }
Ejemplo n.º 5
0
        private unsafe static Bitmap CreateVoxelTexture(PixelColor[] palette)
        {
            Bitmap     bmp     = new Bitmap(16, 16);
            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, 16, 16), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            if (bmpdata != null)
            {
                PixelColor *pixels    = (PixelColor *)(bmpdata.Scan0.ToPointer());
                const int   numpixels = 256;
                int         i         = 255;

                for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--, i--)
                {
                    cp->r = palette[i].r;
                    cp->g = palette[i].g;
                    cp->b = palette[i].b;
                    cp->a = palette[i].a;
                }
                bmp.UnlockBits(bmpdata);
            }

            //scale bitmap, so colors stay (almost) the same when bilinear filtering is enabled
            Bitmap scaled = new Bitmap(64, 64);

            using (Graphics gs = Graphics.FromImage(scaled))
            {
                gs.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                gs.DrawImage(bmp, new Rectangle(0, 0, 64, 64), new Rectangle(0, 0, 16, 16), GraphicsUnit.Pixel);
            }
            bmp.Dispose();

            return(scaled);
        }
Ejemplo n.º 6
0
        // This draws the picture to the given pixel color data
        // Throws exception on failure
        public void DrawToPixelData(Stream stream, PixelColor *target, int targetwidth, int targetheight, int x, int y)
        {
            PixelColorBlock pixeldata;
            int             width, height, ox, oy, tx, ty;

            // Read pixel data
            pixeldata = ReadAsPixelData(stream, out width, out height, out ox, out oy);
            if (pixeldata != null)
            {
                // Go for all source pixels
                // We don't care about the original image offset, so reuse ox/oy
                for (ox = 0; ox < width; ox++)
                {
                    for (oy = 0; oy < height; oy++)
                    {
                        // Copy this pixel?
                        if (pixeldata.Pointer[oy * width + ox].a > 0.5f)
                        {
                            // Calculate target pixel and copy when within bounds
                            tx = x + ox;
                            ty = y + oy;
                            if ((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
                            {
                                target[ty * targetwidth + tx] = pixeldata.Pointer[oy * width + ox];
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 7
0
        // This draws the picture to the given pixel color data
        // Throws exception on failure
        public void DrawToPixelData(Stream stream, PixelColor *target, int targetwidth, int targetheight, int x, int y)
        {
            // Get bitmap
            Bitmap bmp    = ReadAsBitmap(stream);
            int    width  = bmp.Size.Width;
            int    height = bmp.Size.Height;

            // Lock bitmap pixels
            BitmapData  bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            PixelColor *pixels  = (PixelColor *)bmpdata.Scan0.ToPointer();

            // Go for all pixels in the original image
            for (int ox = 0; ox < width; ox++)
            {
                for (int oy = 0; oy < height; oy++)
                {
                    // Copy this pixel?
                    if (pixels[oy * width + ox].a > 0.5f)
                    {
                        // Calculate target pixel and copy when within bounds
                        int tx = x + ox;
                        int ty = y + oy;
                        if ((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
                        {
                            target[ty * targetwidth + tx] = pixels[oy * width + ox];
                        }
                    }
                }
            }

            // Done
            bmp.UnlockBits(bmpdata);
            bmp.Dispose();
        }
Ejemplo n.º 8
0
        // This draws a pixel alpha blended
        public void DrawPixelAlpha(int x, int y, ref PixelColor c)
        {
            // Draw only when within range
            if ((x >= 0) && (x < visiblewidth) && (y >= 0) && (y < visibleheight))
            {
                // Get the target pixel
                PixelColor *p = pixels + (y * width + x);

                // Not drawn on target yet?
                if (*(int *)p == 0)
                {
                    // Simply apply color to pixel
                    *p = c;
                }
                else
                {
                    // Blend with pixel
                    float a = c.a * 0.003921568627450980392156862745098f;
                    if (p->a + c.a > 255)
                    {
                        p->a = 255;
                    }
                    else
                    {
                        p->a += c.a;
                    }
                    p->r = (byte)(p->r * (1f - a) + c.r * a);
                    p->g = (byte)(p->g * (1f - a) + c.g * a);
                    p->b = (byte)(p->b * (1f - a) + c.b * a);
                }
            }
        }
Ejemplo n.º 9
0
 // This applies color-correction over a block of pixel data
 internal unsafe void ApplyColorCorrection(PixelColor *pixels, int numpixels)
 {
     for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
     {
         cp->r = correctiontable[cp->r];
         cp->g = correctiontable[cp->g];
         cp->b = correctiontable[cp->b];
     }
 }
Ejemplo n.º 10
0
        // Constructor
        public Plotter(PixelColor *pixels, int width, int height, int visiblewidth, int visibleheight)
        {
            // Initialize
            this.pixels        = pixels;
            this.width         = width;
            this.height        = height;
            this.visiblewidth  = width;
            this.visibleheight = height;

            // We have no destructor
            GC.SuppressFinalize(this);
        }
Ejemplo n.º 11
0
        // This loads the image
        protected override void LocalLoadImage()
        {
            // Leave when already loaded
            if (this.IsImageLoaded)
            {
                return;
            }
            if ((width == 0) || (height == 0))
            {
                return;
            }

            lock (this)
            {
                // Create bitmap
                try
                {
                    if (bitmap != null)
                    {
                        bitmap.Dispose();
                    }
                    bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    BitmapData  bitmapdata = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    PixelColor *pixels     = (PixelColor *)bitmapdata.Scan0.ToPointer();
                    for (int i = 0; i < (width * height); i++)
                    {
                        *pixels = color;
                        pixels++;
                    }
                    bitmap.UnlockBits(bitmapdata);
                }
                catch (Exception e)
                {
                    // Unable to make bitmap
                    General.ErrorLogger.Add(ErrorType.Error, "Unable to create color image '" + this.Name + "'. " + e.GetType().Name + ": " + e.Message);
                    loadfailed = true;
                }

                // Dispose bitmap if load failed
                if (loadfailed && (bitmap != null))
                {
                    bitmap.Dispose();
                    bitmap = null;
                }

                // Pass on to base
                base.LocalLoadImage();
            }
        }
        // This creates a Bitmap from the given data
        // Returns null on failure
        public Bitmap ReadAsBitmap(Stream stream, out int offsetx, out int offsety)
        {
            offsetx = int.MinValue;
            offsety = int.MinValue;

            int    width, height;
            Bitmap bmp;

            // Read pixel data
            PixelColor[] pixeldata = ReadAsPixelData(stream, out width, out height);
            if (pixeldata != null)
            {
                try
                {
                    // Create bitmap and lock pixels
                    bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    BitmapData  bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    PixelColor *targetdata = (PixelColor *)bitmapdata.Scan0.ToPointer();

                    //mxd. Copy the pixels
                    int size = pixeldata.Length - 1;
                    for (PixelColor *cp = targetdata + size; cp >= targetdata; cp--)
                    {
                        *cp = pixeldata[size--];
                    }

                    // Done
                    bmp.UnlockBits(bitmapdata);
                }
                catch (Exception e)
                {
                    // Unable to make bitmap
                    General.ErrorLogger.Add(ErrorType.Error, "Unable to make Doom flat data. " + e.GetType().Name + ": " + e.Message);
                    return(null);
                }
            }
            else
            {
                // Failed loading picture
                bmp = null;
            }

            // Return result
            return(bmp);
        }
Ejemplo n.º 13
0
        // Constructor
        public PixelColorBlock(int width, int height)
        {
            // Check input
            if ((width <= 0) || (height <= 0))
            {
                throw new ArgumentException("Cannot allocate a memory block of zero size!");
            }

            // Initialize
            this.width      = width;
            this.height     = height;
            this.memorysize = width * height * sizeof(PixelColor);
            this.memory     = (PixelColor *)Marshal.AllocCoTaskMem(memorysize);
            if (this.memory == (PixelColor *)0)
            {
                throw new OutOfMemoryException();
            }
            GC.AddMemoryPressure(memorysize);
        }
Ejemplo n.º 14
0
        private static unsafe void ParallelForEach(PixelColor *startPtr, int width, int height)
        {
            Parallel.ForEach(Partitioner.Create(0, height), (h) =>
            {
                var ptr = startPtr + h.Item1 * width;

                for (int y = h.Item1; y < h.Item2; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        var c        = *ptr;
                        var gray     = ((c.Red * 38 + c.Green * 75 + c.Blue * 15) >> 7);
                        (*ptr).Green = (*ptr).Red = (*ptr).Blue = (byte)gray;

                        ptr++;
                    }
                }
            });
        }
Ejemplo n.º 15
0
        // This creates a Bitmap from the given data
        // Returns null on failure
        public Bitmap ReadAsBitmap(Stream stream)
        {
            int    width, height;
            Bitmap bmp;

            // Read pixel data
            PixelColorBlock pixeldata = ReadAsPixelData(stream, out width, out height);

            if (pixeldata != null)
            {
                try
                {
                    // Create bitmap and lock pixels
                    bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    BitmapData  bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    PixelColor *targetdata = (PixelColor *)bitmapdata.Scan0.ToPointer();

                    // Copy the pixels
                    General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor)));

                    // Done
                    bmp.UnlockBits(bitmapdata);
                }
                catch (Exception e)
                {
                    // Unable to make bitmap
                    General.ErrorLogger.Add(ErrorType.Error, "Unable to make Doom flat data. " + e.GetType().Name + ": " + e.Message);
                    return(null);
                }
            }
            else
            {
                // Failed loading picture
                bmp = null;
            }

            // Return result
            return(bmp);
        }
Ejemplo n.º 16
0
        // This loads the image
        protected override void LocalLoadImage()
        {
            IImageReader reader;
            MemoryStream mem;

            byte[]   membytes;
            Graphics g = null;

            // Checks
            if (this.IsImageLoaded)
            {
                return;
            }
            if ((width == 0) || (height == 0))
            {
                return;
            }

            lock (this)
            {
                // Create texture bitmap
                try
                {
                    if (bitmap != null)
                    {
                        bitmap.Dispose();
                    }
                    bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    BitmapData  bitmapdata = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    PixelColor *pixels     = (PixelColor *)bitmapdata.Scan0.ToPointer();
                    General.ZeroMemory(new IntPtr(pixels), width * height * sizeof(PixelColor));
                    bitmap.UnlockBits(bitmapdata);
                    g = Graphics.FromImage(bitmap);
                }
                catch (Exception e)
                {
                    // Unable to make bitmap
                    General.ErrorLogger.Add(ErrorType.Error, "Unable to load texture image '" + this.Name + "'. " + e.GetType().Name + ": " + e.Message);
                    loadfailed = true;
                }

                if (!loadfailed)
                {
                    // Go for all patches
                    foreach (TexturePatch p in patches)
                    {
                        // Get the patch data stream
                        Stream patchdata = General.Map.Data.GetPatchData(p.lumpname);
                        if (patchdata != null)
                        {
                            // Copy patch data to memory
                            patchdata.Seek(0, SeekOrigin.Begin);
                            membytes = new byte[(int)patchdata.Length];
                            patchdata.Read(membytes, 0, (int)patchdata.Length);
                            mem = new MemoryStream(membytes);
                            mem.Seek(0, SeekOrigin.Begin);

                            // Get a reader for the data
                            reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
                            if (reader is UnknownImageReader)
                            {
                                // Data is in an unknown format!
                                General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'");
                                loadfailed = true;
                            }
                            else
                            {
                                // Get the patch
                                mem.Seek(0, SeekOrigin.Begin);
                                Bitmap patchbmp = null;
                                try { patchbmp = reader.ReadAsBitmap(mem); }
                                catch (InvalidDataException)
                                {
                                    // Data cannot be read!
                                    General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'");
                                    loadfailed = true;
                                }
                                if (patchbmp != null)
                                {
                                    // Adjust patch alpha
                                    if (p.alpha < 1.0f)
                                    {
                                        BitmapData bmpdata = null;
                                        try
                                        {
                                            bmpdata = patchbmp.LockBits(new Rectangle(0, 0, patchbmp.Size.Width, patchbmp.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                                        }
                                        catch (Exception e)
                                        {
                                            General.ErrorLogger.Add(ErrorType.Error, "Cannot lock image '" + p.lumpname + "' for alpha adjustment. " + e.GetType().Name + ": " + e.Message);
                                        }

                                        if (bmpdata != null)
                                        {
                                            PixelColor *pixels    = (PixelColor *)(bmpdata.Scan0.ToPointer());
                                            int         numpixels = bmpdata.Width * bmpdata.Height;
                                            for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                                            {
                                                cp->a = (byte)((((float)cp->a * PixelColor.BYTE_TO_FLOAT) * p.alpha) * 255.0f);
                                            }
                                            patchbmp.UnlockBits(bmpdata);
                                        }
                                    }

                                    // Draw the patch on the texture image
                                    Rectangle tgtrect = new Rectangle(p.x, p.y, patchbmp.Size.Width, patchbmp.Size.Height);
                                    g.DrawImageUnscaledAndClipped(patchbmp, tgtrect);
                                    patchbmp.Dispose();
                                }
                            }

                            // Done
                            mem.Dispose();
                        }
                        else
                        {
                            // Missing a patch lump!
                            General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump '" + p.lumpname + "' while loading texture '" + this.Name + "'");
                            loadfailed = true;
                        }
                    }
                }

                // Dispose bitmap if load failed
                if (loadfailed && (bitmap != null))
                {
                    bitmap.Dispose();
                    bitmap = null;
                }

                // Pass on to base
                base.LocalLoadImage();
            }
        }
Ejemplo n.º 17
0
        //mxd
        private Bitmap TransformPatch(Bitmap bitmap, TexturePatch p, Bitmap patchbmp)
        {
            //mxd. Flip
            if (p.FlipX || p.FlipY)
            {
                RotateFlipType flip;
                if (p.FlipX && !p.FlipY)
                {
                    flip = RotateFlipType.RotateNoneFlipX;
                }
                else if (!p.FlipX && p.FlipY)
                {
                    flip = RotateFlipType.RotateNoneFlipY;
                }
                else
                {
                    flip = RotateFlipType.RotateNoneFlipXY;
                }
                patchbmp.RotateFlip(flip);
            }

            //mxd. Then rotate. I do it this way because RotateFlip function rotates THEN flips, and GZDoom does it the other way around.
            if (p.Rotate != 0)
            {
                RotateFlipType rotate;
                switch (p.Rotate)
                {
                case 90:  rotate = RotateFlipType.Rotate90FlipNone; break;

                case 180: rotate = RotateFlipType.Rotate180FlipNone; break;

                default:  rotate = RotateFlipType.Rotate270FlipNone; break;
                }
                patchbmp.RotateFlip(rotate);
            }

            // Adjust patch alpha, apply tint or blend
            if (p.BlendStyle != TexturePathBlendStyle.NONE || p.RenderStyle != TexturePathRenderStyle.COPY)
            {
                BitmapData bmpdata = null;

                try
                {
                    bmpdata = patchbmp.LockBits(new Rectangle(0, 0, patchbmp.Size.Width, patchbmp.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                }
                catch (Exception e)
                {
                    General.ErrorLogger.Add(ErrorType.Error, "Cannot lock image \"" + p.LumpName + "\" for alpha adjustment. " + e.GetType().Name + ": " + e.Message);
                }

                if (bmpdata != null)
                {
                    PixelColor *pixels     = (PixelColor *)(bmpdata.Scan0.ToPointer());
                    int         numpixels  = bmpdata.Width * bmpdata.Height;
                    int         patchalpha = (int)Math.Round(General.Clamp(p.Alpha, 0f, 1f) * 255);             //convert alpha to [0-255] range

                    //mxd. Blend/Tint support
                    if (p.BlendStyle == TexturePathBlendStyle.BLEND)
                    {
                        for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                        {
                            cp->r = (byte)((cp->r * p.BlendColor.r) * PixelColor.BYTE_TO_FLOAT);
                            cp->g = (byte)((cp->g * p.BlendColor.g) * PixelColor.BYTE_TO_FLOAT);
                            cp->b = (byte)((cp->b * p.BlendColor.b) * PixelColor.BYTE_TO_FLOAT);
                        }
                    }
                    else if (p.BlendStyle == TexturePathBlendStyle.TINT)
                    {
                        float tintammount = p.BlendColor.a * PixelColor.BYTE_TO_FLOAT;                        // -0.1f;

                        if (tintammount > 0)
                        {
                            float br             = p.BlendColor.r * PixelColor.BYTE_TO_FLOAT * tintammount;
                            float bg             = p.BlendColor.g * PixelColor.BYTE_TO_FLOAT * tintammount;
                            float bb             = p.BlendColor.b * PixelColor.BYTE_TO_FLOAT * tintammount;
                            float invtintammount = 1.0f - tintammount;

                            for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                            {
                                cp->r = (byte)(((cp->r * PixelColor.BYTE_TO_FLOAT) * invtintammount + br) * 255.0f);
                                cp->g = (byte)(((cp->g * PixelColor.BYTE_TO_FLOAT) * invtintammount + bg) * 255.0f);
                                cp->b = (byte)(((cp->b * PixelColor.BYTE_TO_FLOAT) * invtintammount + bb) * 255.0f);
                            }
                        }
                    }

                    //mxd. Apply RenderStyle
                    if (p.RenderStyle == TexturePathRenderStyle.BLEND)
                    {
                        for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                        {
                            cp->a = (byte)((cp->a * patchalpha) * PixelColor.BYTE_TO_FLOAT);
                        }
                    }
                    //mxd. We need a copy of underlying part of texture for these styles
                    else if (p.RenderStyle != TexturePathRenderStyle.COPY)
                    {
                        // Copy portion of texture
                        int lockWidth  = (p.X + patchbmp.Size.Width > bitmap.Width) ? bitmap.Width - p.X : patchbmp.Size.Width;
                        int lockHeight = (p.Y + patchbmp.Size.Height > bitmap.Height) ? bitmap.Height - p.Y : patchbmp.Size.Height;

                        Bitmap source = new Bitmap(patchbmp.Size.Width, patchbmp.Size.Height);
                        using (Graphics sg = Graphics.FromImage(source))
                            sg.DrawImageUnscaled(bitmap, new Rectangle(-p.X, -p.Y, lockWidth, lockHeight));

                        // Lock texture
                        BitmapData texturebmpdata = null;

                        try
                        {
                            texturebmpdata = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                        }
                        catch (Exception e)
                        {
                            General.ErrorLogger.Add(ErrorType.Error, "Cannot lock texture \"" + this.Name + "\" to apply render style. " + e.GetType().Name + ": " + e.Message);
                        }

                        if (texturebmpdata != null)
                        {
                            PixelColor *texturepixels = (PixelColor *)(texturebmpdata.Scan0.ToPointer());
                            PixelColor *tcp           = texturepixels + numpixels - 1;

                            switch (p.RenderStyle)
                            {
                            case TexturePathRenderStyle.ADD:
                                for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                                {
                                    cp->r = (byte)Math.Min(255, cp->r + tcp->r);
                                    cp->g = (byte)Math.Min(255, cp->g + tcp->g);
                                    cp->b = (byte)Math.Min(255, cp->b + tcp->b);
                                    cp->a = (byte)((cp->a * patchalpha) * PixelColor.BYTE_TO_FLOAT);
                                    tcp--;
                                }
                                break;

                            case TexturePathRenderStyle.SUBTRACT:
                                for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                                {
                                    cp->r = (byte)Math.Max(0, tcp->r - cp->r);
                                    cp->g = (byte)Math.Max(0, tcp->g - cp->g);
                                    cp->b = (byte)Math.Max(0, tcp->b - cp->b);
                                    cp->a = (byte)((cp->a * patchalpha) * PixelColor.BYTE_TO_FLOAT);
                                    tcp--;
                                }
                                break;

                            case TexturePathRenderStyle.REVERSE_SUBTRACT:
                                for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                                {
                                    cp->r = (byte)Math.Max(0, cp->r - tcp->r);
                                    cp->g = (byte)Math.Max(0, cp->g - tcp->g);
                                    cp->b = (byte)Math.Max(0, cp->b - tcp->b);
                                    cp->a = (byte)((cp->a * patchalpha) * PixelColor.BYTE_TO_FLOAT);
                                    tcp--;
                                }
                                break;

                            case TexturePathRenderStyle.MODULATE:
                                for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                                {
                                    cp->r = (byte)((cp->r * tcp->r) * PixelColor.BYTE_TO_FLOAT);
                                    cp->g = (byte)((cp->g * tcp->g) * PixelColor.BYTE_TO_FLOAT);
                                    cp->b = (byte)((cp->b * tcp->b) * PixelColor.BYTE_TO_FLOAT);
                                    tcp--;
                                }
                                break;
                            }

                            source.UnlockBits(texturebmpdata);
                        }
                    }

                    patchbmp.UnlockBits(bmpdata);
                }
            }

            return(patchbmp);
        }
Ejemplo n.º 18
0
        // This loads the image
        protected override LocalLoadResult LocalLoadImage()
        {
            // Checks
            if (width == 0 || height == 0)
            {
                return(new LocalLoadResult(null));
            }

            Graphics g = null;

            Bitmap            bitmap   = null;
            List <LogMessage> messages = new List <LogMessage>();

            // Create texture bitmap
            try
            {
                if (bitmap != null)
                {
                    bitmap.Dispose();
                }
                bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                BitmapData  bitmapdata = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                PixelColor *pixels     = (PixelColor *)bitmapdata.Scan0.ToPointer();
                General.ZeroPixels(pixels, width * height);
                bitmap.UnlockBits(bitmapdata);
                g = Graphics.FromImage(bitmap);
            }
            catch (Exception e)
            {
                // Unable to make bitmap
                messages.Add(new LogMessage(ErrorType.Error, "Unable to load texture image \"" + this.Name + "\". " + e.GetType().Name + ": " + e.Message));
            }

            int missingpatches = 0;            //mxd

            if (patches.Count == 0)            //mxd
            {
                //mxd. Empty image will suffice here, I suppose...
                if (nulltexture)
                {
                    return(new LocalLoadResult(bitmap, messages));
                }

                // No patches!
                messages.Add(new LogMessage(ErrorType.Error, "No patches are defined for texture \"" + this.Name + "\""));
            }
            else if (!messages.Any(x => x.Type == ErrorType.Error))
            {
                // Go for all patches
                foreach (TexturePatch p in patches)
                {
                    //mxd. Some patches (like "TNT1A0") should be skipped
                    if (p.Skip)
                    {
                        continue;
                    }

                    // Get the patch data stream
                    string patchlocation = string.Empty;                     //mxd
                    Stream patchdata     = General.Map.Data.GetPatchData(p.LumpName, p.HasLongName, ref patchlocation);
                    if (patchdata != null)
                    {
                        // Copy patch data to memory
                        byte[] membytes = new byte[(int)patchdata.Length];

                        lock (patchdata)                        //mxd
                        {
                            patchdata.Seek(0, SeekOrigin.Begin);
                            patchdata.Read(membytes, 0, (int)patchdata.Length);
                        }

                        MemoryStream mem = new MemoryStream(membytes);
                        mem.Seek(0, SeekOrigin.Begin);

                        Bitmap patchbmp = ImageDataFormat.TryLoadImage(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
                        if (patchbmp == null)
                        {
                            //mxd. Probably that's a flat?..
                            if (General.Map.Config.MixTexturesFlats)
                            {
                                patchbmp = ImageDataFormat.TryLoadImage(mem, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette);
                            }

                            if (patchbmp == null)
                            {
                                // Data is in an unknown format!
                                if (!nulltexture)
                                {
                                    messages.Add(new LogMessage(optional ? ErrorType.Warning : ErrorType.Error, "Patch lump \"" + Path.Combine(patchlocation, p.LumpName) + "\" data format could not be read, while loading texture \"" + this.Name + "\""));
                                }
                                missingpatches++;                                 //mxd
                            }
                        }

                        if (patchbmp != null)
                        {
                            //mxd. Apply transformations from TexturePatch
                            patchbmp = TransformPatch(bitmap, p, patchbmp);

                            // Draw the patch on the texture image
                            Rectangle tgtrect = new Rectangle(p.X, p.Y, patchbmp.Size.Width, patchbmp.Size.Height);
                            g.DrawImageUnscaledAndClipped(patchbmp, tgtrect);
                            patchbmp.Dispose();
                        }

                        // Done
                        mem.Dispose();
                    }
                    else
                    {
                        //mxd. ZDoom can use any known graphic as patch
                        if (General.Map.Config.MixTexturesFlats)
                        {
                            ImageData img = General.Map.Data.GetTextureImage(p.LumpName);
                            if (!(img is UnknownImage) && img != this)
                            {
                                //mxd. Apply transformations from TexturePatch. We don't want to modify the original bitmap here, so make a copy
                                Bitmap bmp      = new Bitmap(img.LocalGetBitmap());
                                Bitmap patchbmp = TransformPatch(bitmap, p, bmp);

                                // Draw the patch on the texture image
                                Rectangle tgtrect = new Rectangle(p.X, p.Y, patchbmp.Size.Width, patchbmp.Size.Height);
                                g.DrawImageUnscaledAndClipped(patchbmp, tgtrect);
                                patchbmp.Dispose();

                                continue;
                            }
                        }

                        // Missing a patch lump!
                        if (!nulltexture)
                        {
                            messages.Add(new LogMessage(optional ? ErrorType.Warning : ErrorType.Error, "Missing patch lump \"" + p.LumpName + "\" while loading texture \"" + this.Name + "\""));
                        }
                        missingpatches++;                         //mxd
                    }
                }
            }

            // Dispose bitmap if load failed
            if (!nulltexture && (bitmap != null) && (messages.Any(x => x.Type == ErrorType.Error) || missingpatches >= patches.Count))            //mxd. We can still display texture if at least one of the patches was loaded
            {
                bitmap.Dispose();
                bitmap = null;
            }

            return(new LocalLoadResult(bitmap, messages));
        }
Ejemplo n.º 19
0
        // Background downloading and processing
        private unsafe void UpdateThread()
        {
            HttpWebResponse webresponse = null;
            bool            failed      = false;
            string          failmsg     = "";
            Image           downloadimg = null;
            DateTime        starttime   = new DateTime();

            // Make the GET request
            HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(ADDRESS);

            webrequest.Referer     = REFERRER;
            webrequest.Method      = "GET";
            webrequest.KeepAlive   = false;
            webrequest.Timeout     = 5000;
            webrequest.UserAgent   = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.14) Gecko/2009082707 Firefox/3.0.14 GTB5 (.NET CLR 3.5.30729)";
            webrequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);

            try
            {
                // Download!
                webresponse = (HttpWebResponse)webrequest.GetResponse();
            }
            catch (Exception e)
            {
                failed      = true;
                failmsg     = "Failed to update buienradar. Web request " + e.GetType().Name + ": " + e.Message;
                webresponse = null;
            }

            if (!failed)
            {
                try
                {
                    // Make image
                    downloadimg = Image.FromStream(webresponse.GetResponseStream());
                    webresponse.Close();
                }
                catch (Exception e)
                {
                    failed      = true;
                    failmsg     = "Failed to update buienradar. Image read " + e.GetType().Name + ": " + e.Message;
                    downloadimg = null;
                }
            }

            if (!failed)
            {
                // Dispose old images
                if (images != null)
                {
                    for (int i = 0; i < images.Length; i++)
                    {
                        if (images[i] != null)
                        {
                            images[i].Dispose();
                        }
                    }
                }

                images         = null;
                arrowlocations = null;

                //#if !DEBUG
                try
                {
                    //#endif
                    // Time at which the animation starts
                    DateTime now         = DateTime.Now.AddMinutes(ADJUST_TIME_MINUTES);
                    int      nearest5min = (int)(Math.Round((double)now.Minute / (double)5) * (double)5);
                    starttime = new DateTime(now.Year, now.Month, now.Day, now.Hour, 0, 0);
                    starttime = starttime.AddMinutes(nearest5min);

                    // Prepare variables to track the rain
                    DateTime incomingtime    = new DateTime();
                    bool     isincoming      = false;
                    DateTime cleartime       = new DateTime();
                    int      clearframecount = 0;

                    // Disassemble the image into separate images
                    FrameDimension fd        = new FrameDimension(downloadimg.FrameDimensionsList[0]);
                    int            numimages = downloadimg.GetFrameCount(fd);
                    images = new Image[numimages];
                    downloadimg.SelectActiveFrame(fd, 0);
                    Bitmap     firstbmp     = new Bitmap(downloadimg);
                    Size       sz           = firstbmp.Size;
                    BitmapData firstbmpdata = firstbmp.LockBits(new Rectangle(0, 0, sz.Width, sz.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                    for (int i = 0; i < numimages; i++)
                    {
                        downloadimg.SelectActiveFrame(fd, i);
                        Bitmap imgbmp = new Bitmap(downloadimg);
                        Bitmap newbmp = new Bitmap(sz.Width, sz.Height, PixelFormat.Format32bppArgb);

                        // Start processing the image
                        BitmapData  imgbmpdata = imgbmp.LockBits(new Rectangle(0, 0, sz.Width, sz.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                        BitmapData  newbmpdata = newbmp.LockBits(new Rectangle(0, 0, sz.Width, sz.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                        PixelColor *fpixels    = (PixelColor *)(firstbmpdata.Scan0.ToPointer());
                        PixelColor *ipixels    = (PixelColor *)(imgbmpdata.Scan0.ToPointer());
                        PixelColor *npixels    = (PixelColor *)(newbmpdata.Scan0.ToPointer());

                        // Go for all pixels
                        bool wholeframeclear = true;
                        for (int y = 0; y < sz.Height; y++)
                        {
                            for (int x = 0; x < sz.Width; x++)
                            {
                                // We compare the pixel of the first image (no clouds) with
                                // the current image to determine if there are clouds here
                                bool isclear = (ipixels->b == fpixels->b) &&
                                               (ipixels->g == fpixels->g) &&
                                               (ipixels->r == fpixels->r);

                                // Detect rain at current location
                                if (!isclear && (x >= LOCATION_X - LOCATION_RADIUS) && (x <= LOCATION_X + LOCATION_RADIUS) &&
                                    (y >= LOCATION_Y - LOCATION_RADIUS) && (y <= LOCATION_Y + LOCATION_RADIUS) && (i > 0))
                                {
                                    wholeframeclear = false;

                                    if (!isincoming)
                                    {
                                        // Rain!
                                        incomingtime    = starttime.AddMinutes(i * 10);
                                        isincoming      = true;
                                        clearframecount = 0;
                                    }

                                    if (clearframecount < CLEAR_FRAMES)
                                    {
                                        clearframecount = 0;
                                    }
                                }

                                // Clear pixel?
                                if (isclear)
                                {
                                    // This pixel is normal.
                                    PixelColor ds      = PixelColor.Desaturate(*ipixels);
                                    *          npixels = PixelColor.Lerp(ds, *ipixels, 0.1f);
                                    *          npixels = PixelColor.Scale(*npixels, 1.1f);
                                    PixelColor add     = new PixelColor(0, 10, 10, 10);
                                    *          npixels = PixelColor.Add(*npixels, add);
                                }
                                else
                                {
                                    // This pixel is a cloud.
                                    PixelColor mod     = new PixelColor(255, 160, 160, 250);
                                    *          npixels = PixelColor.Modulate(*ipixels, mod);
                                    *          npixels = PixelColor.Scale(*npixels, 1.8f);
                                }

                                // Next pixel
                                fpixels++;
                                ipixels++;
                                npixels++;
                            }
                        }

                        // Whole frame clear of rain at current location?
                        if (wholeframeclear)
                        {
                            // Count this frame as a clear frame
                            clearframecount++;

                            if (clearframecount == CLEAR_FRAMES)
                            {
                                // The clear time is 3 frames ago
                                cleartime = starttime.AddMinutes((i - 3) * 10);
                            }
                        }

                        // Clean up
                        imgbmp.UnlockBits(imgbmpdata);
                        newbmp.UnlockBits(newbmpdata);
                        images[i] = newbmp;
                        imgbmp.Dispose();
                        imgbmp = null;
                    }

                    // Show incoming time
                    if (isincoming)
                    {
                        incomingtext  = incomingtime.Hour + ":" + incomingtime.Minute.ToString("00");
                        flashincoming = true;
                    }
                    else
                    {
                        incomingtext  = "N / A";
                        flashincoming = false;
                    }

                    // Show clear time
                    if (clearframecount >= CLEAR_FRAMES)
                    {
                        cleartext  = cleartime.Hour + ":" + cleartime.Minute.ToString("00");
                        flashclear = true;
                    }
                    else
                    {
                        cleartext  = "N / A";
                        flashclear = false;
                    }

                    // Clean up
                    firstbmp.UnlockBits(firstbmpdata);
                    firstbmp.Dispose();
                    firstbmp = null;
                    downloadimg.Dispose();
                    downloadimg = null;
                    //#if !DEBUG
                }
                catch (Exception e)
                {
                    failed      = true;
                    failmsg     = "Failed to update buienradar. Image processing " + e.GetType().Name + ": " + e.Message;
                    downloadimg = null;
                }
                //#endif

                if (images != null)
                {
                    // Set up some random arrow locations, for decorative reason
                    Random rnd = new Random();
                    arrowlocations = new Size[images.Length];
                    Size offset = new Size(radar.Left + 100 + rnd.Next(radar.Width - movearrow1.Width - 100), radar.Top + 100 + rnd.Next(radar.Height - movearrow1.Height - 100));
                    for (int i = 0; i < images.Length; i++)
                    {
                        arrowlocations[i] = offset + new Size(rnd.Next(100) - 50, rnd.Next(100) - 50);
                    }
                }

                // Done
                firstimagetime  = starttime;
                nextupdatedelay = NORMAL_UPDATE_DELAY;
            }

            // Handle failure
            if (failed)
            {
                HandleFail(failmsg);
            }
            else
            {
                updatefailed = false;
            }

            // We're done updating (either successful or failed)
            UpdateComplete();
        }
Ejemplo n.º 20
0
        // This requests loading the image
        protected virtual void LocalLoadImage()
        {
            BitmapData bmpdata = null;

            lock (this)
            {
                // Bitmap loaded successfully?
                if (bitmap != null)
                {
                    // Bitmap has incorrect format?
                    if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
                    {
                        if (dynamictexture)
                        {
                            throw new Exception("Dynamic images must be in 32 bits ARGB format.");
                        }

                        //General.ErrorLogger.Add(ErrorType.Warning, "Image '" + name + "' does not have A8R8G8B8 pixel format. Conversion was needed.");
                        Bitmap oldbitmap = bitmap;
                        try
                        {
                            // Convert to desired pixel format
                            bitmap = new Bitmap(oldbitmap.Size.Width, oldbitmap.Size.Height, PixelFormat.Format32bppArgb);
                            Graphics g = Graphics.FromImage(bitmap);
                            g.PageUnit           = GraphicsUnit.Pixel;
                            g.CompositingQuality = CompositingQuality.HighQuality;
                            g.InterpolationMode  = InterpolationMode.NearestNeighbor;
                            g.SmoothingMode      = SmoothingMode.None;
                            g.PixelOffsetMode    = PixelOffsetMode.None;
                            g.Clear(Color.Transparent);
                            g.DrawImage(oldbitmap, 0, 0, oldbitmap.Size.Width, oldbitmap.Size.Height);
                            g.Dispose();
                            oldbitmap.Dispose();
                        }
                        catch (Exception e)
                        {
                            bitmap = oldbitmap;
                            General.ErrorLogger.Add(ErrorType.Warning, "Cannot lock image '" + name + "' for pixel format conversion. The image may not be displayed correctly.\n" + e.GetType().Name + ": " + e.Message);
                        }
                    }

                    // This applies brightness correction on the image
                    if (usecolorcorrection)
                    {
                        try
                        {
                            // Try locking the bitmap
                            bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                        }
                        catch (Exception e)
                        {
                            General.ErrorLogger.Add(ErrorType.Warning, "Cannot lock image '" + name + "' for color correction. The image may not be displayed correctly.\n" + e.GetType().Name + ": " + e.Message);
                        }

                        // Bitmap locked?
                        if (bmpdata != null)
                        {
                            // Apply color correction
                            PixelColor *pixels = (PixelColor *)(bmpdata.Scan0.ToPointer());
                            General.Colors.ApplColorCorrection(pixels, bmpdata.Width * bmpdata.Height);
                            bitmap.UnlockBits(bmpdata);
                        }
                    }
                }
                else
                {
                    // Loading failed
                    // We still mark the image as ready so that it will
                    // not try loading again until Reload Resources is used
                    loadfailed = true;
                    bitmap     = new Bitmap(Properties.Resources.Failed);
                }

                if (bitmap != null)
                {
                    width  = bitmap.Size.Width;
                    height = bitmap.Size.Height;

                    if (dynamictexture)
                    {
                        if ((width != General.NextPowerOf2(width)) || (height != General.NextPowerOf2(height)))
                        {
                            throw new Exception("Dynamic images must have a size in powers of 2.");
                        }
                    }

                    // Do we still have to set a scale?
                    if ((scale.x == 0.0f) && (scale.y == 0.0f))
                    {
                        if ((General.Map != null) && (General.Map.Config != null))
                        {
                            scale.x = General.Map.Config.DefaultTextureScale;
                            scale.y = General.Map.Config.DefaultTextureScale;
                        }
                        else
                        {
                            scale.x = 1.0f;
                            scale.y = 1.0f;
                        }
                    }
                }

                // Image is ready
                imagestate = ImageLoadState.Ready;
            }
        }
Ejemplo n.º 21
0
        // This requests loading the image
        protected virtual void LocalLoadImage()
        {
            lock (this)
            {
                // Bitmap loaded successfully?
                if (bitmap != null)
                {
                    // Bitmap has incorrect format?
                    if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
                    {
                        if (dynamictexture)
                        {
                            throw new Exception("Dynamic images must be in 32 bits ARGB format.");
                        }

                        //General.ErrorLogger.Add(ErrorType.Warning, "Image '" + name + "' does not have A8R8G8B8 pixel format. Conversion was needed.");
                        Bitmap oldbitmap = bitmap;
                        try
                        {
                            // Convert to desired pixel format
                            bitmap = new Bitmap(oldbitmap.Size.Width, oldbitmap.Size.Height, PixelFormat.Format32bppArgb);
                            Graphics g = Graphics.FromImage(bitmap);
                            g.PageUnit           = GraphicsUnit.Pixel;
                            g.CompositingQuality = CompositingQuality.HighQuality;
                            g.InterpolationMode  = InterpolationMode.NearestNeighbor;
                            g.SmoothingMode      = SmoothingMode.None;
                            g.PixelOffsetMode    = PixelOffsetMode.None;
                            g.Clear(Color.Transparent);
                            g.DrawImage(oldbitmap, 0, 0, oldbitmap.Size.Width, oldbitmap.Size.Height);
                            g.Dispose();
                            oldbitmap.Dispose();
                        }
                        catch (Exception e)
                        {
                            bitmap = oldbitmap;
                            General.ErrorLogger.Add(ErrorType.Warning, "Cannot lock image \"" + name + "\" for pixel format conversion. The image may not be displayed correctly.\n" + e.GetType().Name + ": " + e.Message);
                        }
                    }

                    // This applies brightness correction on the image
                    if (usecolorcorrection)
                    {
                        BitmapData bmpdata = null;

                        try
                        {
                            // Try locking the bitmap
                            bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                        }
                        catch (Exception e)
                        {
                            General.ErrorLogger.Add(ErrorType.Warning, "Cannot lock image \"" + name + "\" for color correction. The image may not be displayed correctly.\n" + e.GetType().Name + ": " + e.Message);
                        }

                        // Bitmap locked?
                        if (bmpdata != null)
                        {
                            // Apply color correction
                            PixelColor *pixels = (PixelColor *)(bmpdata.Scan0.ToPointer());
                            General.Colors.ApplyColorCorrection(pixels, bmpdata.Width * bmpdata.Height);
                            bitmap.UnlockBits(bmpdata);
                        }
                    }
                }
                else
                {
                    // Loading failed
                    // We still mark the image as ready so that it will
                    // not try loading again until Reload Resources is used
                    loadfailed = true;
                    bitmap     = new Bitmap(Properties.Resources.Failed);
                }

                if (bitmap != null)
                {
                    width  = bitmap.Size.Width;
                    height = bitmap.Size.Height;

                    if (dynamictexture)
                    {
                        if ((width != General.NextPowerOf2(width)) || (height != General.NextPowerOf2(height)))
                        {
                            throw new Exception("Dynamic images must have a size in powers of 2.");
                        }
                    }

                    // Do we still have to set a scale?
                    if ((scale.x == 0.0f) && (scale.y == 0.0f))
                    {
                        if ((General.Map != null) && (General.Map.Config != null))
                        {
                            scale.x = General.Map.Config.DefaultTextureScale;
                            scale.y = General.Map.Config.DefaultTextureScale;
                        }
                        else
                        {
                            scale.x = 1.0f;
                            scale.y = 1.0f;
                        }
                    }

                    //mxd. Calculate average color?
                    if (General.Map != null && General.Map.Data != null && General.Map.Data.GlowingFlats != null &&
                        General.Map.Data.GlowingFlats.ContainsKey(longname) &&
                        General.Map.Data.GlowingFlats[longname].CalculateTextureColor)
                    {
                        BitmapData bmpdata = null;
                        try { bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); }
                        catch (Exception e) { General.ErrorLogger.Add(ErrorType.Error, "Cannot lock image \"" + this.filepathname + "\" for glow color calculation. " + e.GetType().Name + ": " + e.Message); }

                        if (bmpdata != null)
                        {
                            PixelColor *pixels    = (PixelColor *)(bmpdata.Scan0.ToPointer());
                            int         numpixels = bmpdata.Width * bmpdata.Height;
                            uint        r         = 0;
                            uint        g         = 0;
                            uint        b         = 0;

                            for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                            {
                                r += cp->r;
                                g += cp->g;
                                b += cp->b;

                                // Also check alpha
                                if (cp->a > 0 && cp->a < 255)
                                {
                                    istranslucent = true;
                                }
                                else if (cp->a == 0)
                                {
                                    ismasked = true;
                                }
                            }

                            // Update glow data
                            int br = (int)(r / numpixels);
                            int bg = (int)(g / numpixels);
                            int bb = (int)(b / numpixels);

                            int max = Math.Max(br, Math.Max(bg, bb));

                            // Black can't glow...
                            if (max == 0)
                            {
                                General.Map.Data.GlowingFlats.Remove(longname);
                            }
                            else
                            {
                                // That's how it's done in GZDoom (and I may be totally wrong about this)
                                br = Math.Min(255, br * 153 / max);
                                bg = Math.Min(255, bg * 153 / max);
                                bb = Math.Min(255, bb * 153 / max);

                                General.Map.Data.GlowingFlats[longname].Color = new PixelColor(255, (byte)br, (byte)bg, (byte)bb);
                                General.Map.Data.GlowingFlats[longname].CalculateTextureColor = false;
                                if (!General.Map.Data.GlowingFlats[longname].Fullbright)
                                {
                                    General.Map.Data.GlowingFlats[longname].Brightness = (br + bg + bb) / 3;
                                }
                            }

                            // Release the data
                            bitmap.UnlockBits(bmpdata);
                        }
                    }
                    //mxd. Check if the texture is translucent
                    else if (!loadfailed)
                    {
                        BitmapData bmpdata = null;
                        try { bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); }
                        catch (Exception e) { General.ErrorLogger.Add(ErrorType.Error, "Cannot lock image \"" + this.filepathname + "\" for translucency check. " + e.GetType().Name + ": " + e.Message); }

                        if (bmpdata != null)
                        {
                            PixelColor *pixels    = (PixelColor *)(bmpdata.Scan0.ToPointer());
                            int         numpixels = bmpdata.Width * bmpdata.Height;

                            for (PixelColor *cp = pixels + numpixels - 1; cp >= pixels; cp--)
                            {
                                // Check alpha
                                if (cp->a > 0 && cp->a < 255)
                                {
                                    istranslucent = true;
                                }
                                else if (cp->a == 0)
                                {
                                    ismasked = true;
                                }
                            }

                            // Release the data
                            bitmap.UnlockBits(bmpdata);
                        }
                    }
                }

                // Image is ready
                imagestate = ImageLoadState.Ready;
            }
        }
Ejemplo n.º 22
0
        // This loads the image
        protected override void LocalLoadImage()
        {
            IImageReader reader;
            BitmapData   bitmapdata = null;
            MemoryStream mem;
            PixelColor * pixels = (PixelColor *)0;
            Stream       patchdata;

            byte[] membytes;

            // Checks
            if (this.IsImageLoaded)
            {
                return;
            }
            if ((width == 0) || (height == 0))
            {
                return;
            }

            lock (this)
            {
                // Create texture bitmap
                try
                {
                    if (bitmap != null)
                    {
                        bitmap.Dispose();
                    }
                    bitmap     = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    bitmapdata = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    pixels     = (PixelColor *)bitmapdata.Scan0.ToPointer();
                    General.ZeroMemory(new IntPtr(pixels), width * height * sizeof(PixelColor));
                }
                catch (Exception e)
                {
                    // Unable to make bitmap
                    General.ErrorLogger.Add(ErrorType.Error, "Unable to load texture image '" + this.Name + "'. " + e.GetType().Name + ": " + e.Message);
                    loadfailed = true;
                }

                if (!loadfailed)
                {
                    // Go for all patches
                    foreach (TexturePatch p in patches)
                    {
                        // Get the patch data stream
                        patchdata = General.Map.Data.GetPatchData(p.lumpname);
                        if (patchdata != null)
                        {
                            // Copy patch data to memory
                            patchdata.Seek(0, SeekOrigin.Begin);
                            membytes = new byte[(int)patchdata.Length];
                            patchdata.Read(membytes, 0, (int)patchdata.Length);
                            mem = new MemoryStream(membytes);
                            mem.Seek(0, SeekOrigin.Begin);

                            // Get a reader for the data
                            reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
                            if (reader is UnknownImageReader)
                            {
                                // Data is in an unknown format!
                                General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'. Does this lump contain valid picture data at all?");
                                loadfailed = true;
                            }
                            else
                            {
                                // Draw the patch
                                mem.Seek(0, SeekOrigin.Begin);
                                try { reader.DrawToPixelData(mem, pixels, width, height, p.x, p.y); }
                                catch (InvalidDataException)
                                {
                                    // Data cannot be read!
                                    General.ErrorLogger.Add(ErrorType.Error, "Patch lump '" + p.lumpname + "' data format could not be read, while loading texture '" + this.Name + "'. Does this lump contain valid picture data at all?");
                                    loadfailed = true;
                                }
                            }

                            // Done
                            mem.Dispose();
                        }
                        else
                        {
                            // Missing a patch lump!
                            General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump '" + p.lumpname + "' while loading texture '" + this.Name + "'. Did you forget to include required resources?");
                            loadfailed = true;
                        }
                    }

                    // Done
                    bitmap.UnlockBits(bitmapdata);
                }

                // Dispose bitmap if load failed
                if (loadfailed && (bitmap != null))
                {
                    bitmap.Dispose();
                    bitmap = null;
                }

                // Pass on to base
                base.LocalLoadImage();
            }
        }
Ejemplo n.º 23
0
        // This loads the image
        protected unsafe override LocalLoadResult LocalLoadImage()
        {
            Bitmap bitmap = null;
            string error  = null;

            int imgoffsetx = 0;
            int pivotz     = 0;

            // Get the lump data stream
            string voxellocation = string.Empty; //mxd
            Stream lumpdata      = General.Map.Data.GetVoxelData(voxelname, ref voxellocation);

            if (lumpdata != null)
            {
                // Copy lump data to memory
                lumpdata.Seek(0, SeekOrigin.Begin);
                byte[] membytes = new byte[(int)lumpdata.Length];
                lumpdata.Read(membytes, 0, (int)lumpdata.Length);

                using (MemoryStream mem = new MemoryStream(membytes))
                {
                    mem.Seek(0, SeekOrigin.Begin);
                    PixelColor[] palette = new PixelColor[256];

                    // Create front projection image from the KVX
                    using (BinaryReader reader = new BinaryReader(mem, Encoding.ASCII))
                    {
                        reader.ReadInt32();                         //numbytes, we don't use that
                        int xsize = reader.ReadInt32();
                        int ysize = reader.ReadInt32();
                        int zsize = reader.ReadInt32();

                        // Sanity check
                        if (xsize == 0 || ysize == 0 || zsize == 0)
                        {
                            error = "Cannot create sprite image for voxel \"" + Path.Combine(voxellocation, voxelname)
                                    + "\" for voxel drawing: voxel has invalid size (width: " + xsize + ", height: " + zsize + ", depth: " + ysize;

                            return(new LocalLoadResult(null, error));
                        }

                        int pivotx = (int)Math.Round(reader.ReadInt32() / 256f);
                        int pivoty = (int)Math.Round(reader.ReadInt32() / 256f);
                        pivotz = (int)Math.Round(reader.ReadInt32() / 256f);

                        // Read offsets
                        int[] xoffset = new int[xsize + 1];                         // why is it xsize + 1, not xsize?..
                        short[,] xyoffset = new short[xsize, ysize + 1];            // why is it ysize + 1, not ysize?..

                        for (int i = 0; i < xoffset.Length; i++)
                        {
                            xoffset[i] = reader.ReadInt32();
                        }

                        for (int x = 0; x < xsize; x++)
                        {
                            for (int y = 0; y < ysize + 1; y++)
                            {
                                xyoffset[x, y] = reader.ReadInt16();
                            }
                        }

                        // Read slabs
                        List <int> offsets = new List <int>(xsize * ysize);
                        for (int x = 0; x < xsize; x++)
                        {
                            for (int y = 0; y < ysize; y++)
                            {
                                offsets.Add(xoffset[x] + xyoffset[x, y] + 28);                                 // for some reason offsets are counted from start of xoffset[]...
                            }
                        }

                        int counter  = 0;
                        int slabsend = (int)(reader.BaseStream.Length - 768);

                        // Read palette
                        if (!overridepalette)
                        {
                            reader.BaseStream.Position = slabsend;
                            for (int i = 0; i < 256; i++)
                            {
                                byte r = (byte)(reader.ReadByte() * 4);
                                byte g = (byte)(reader.ReadByte() * 4);
                                byte b = (byte)(reader.ReadByte() * 4);
                                palette[i] = new PixelColor(255, r, g, b);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < 256; i++)
                            {
                                palette[i] = General.Map.Data.Palette[i];
                            }
                        }

                        // Populate projection pixels array
                        int  imgwidth, imgheight;
                        bool checkalpha = false;

                        // Convert angleoffsets to the nearest cardinal direction...
                        angleoffset = General.ClampAngle((angleoffset + 45) / 90 * 90);

                        switch (angleoffset)
                        {
                        case 0:
                            imgwidth   = xsize;
                            imgheight  = zsize;
                            imgoffsetx = pivotx;
                            break;

                        case 90:
                            imgwidth   = ysize;
                            imgheight  = zsize;
                            imgoffsetx = imgwidth - pivoty;
                            checkalpha = true;
                            break;

                        case 180:
                            imgwidth   = xsize;
                            imgheight  = zsize;
                            imgoffsetx = imgwidth - pivotx;
                            checkalpha = true;
                            break;

                        case 270:
                            imgwidth   = ysize;
                            imgheight  = zsize;
                            imgoffsetx = pivoty;
                            break;

                        default: throw new InvalidDataException("Invalid AngleOffset");
                        }

                        int          numpixels = imgwidth * imgheight;
                        PixelColor[] pixelsarr = new PixelColor[numpixels];

                        // Read pixel colors
                        for (int x = 0; x < xsize; x++)
                        {
                            for (int y = 0; y < ysize; y++)
                            {
                                reader.BaseStream.Position = offsets[counter];
                                int next = (counter < offsets.Count - 1 ? offsets[counter + 1] : slabsend);

                                // Read first color from the slab
                                while (reader.BaseStream.Position < next)
                                {
                                    int ztop  = reader.ReadByte();
                                    int zleng = reader.ReadByte();
                                    if (ztop + zleng > zsize)
                                    {
                                        break;
                                    }
                                    byte flags = reader.ReadByte();

                                    if (zleng > 0)
                                    {
                                        // Skip slab if no flags are given (otherwise some garbage pixels may be drawn)
                                        if (flags == 0)
                                        {
                                            reader.BaseStream.Position += zleng;
                                            continue;
                                        }

                                        List <int> colorindices = new List <int>(zleng);
                                        for (int i = 0; i < zleng; i++)
                                        {
                                            colorindices.Add(reader.ReadByte());
                                        }

                                        int z      = ztop;
                                        int cstart = 0;
                                        while (z < ztop + zleng)
                                        {
                                            // Get pixel position
                                            int pixelpos;
                                            switch (angleoffset)
                                            {
                                            case 0:   pixelpos = x + z * xsize; break;

                                            case 90:  pixelpos = y + z * ysize; break;

                                            case 180: pixelpos = xsize - x - 1 + z * xsize; break;

                                            case 270: pixelpos = ysize - y - 1 + z * ysize; break;

                                            default: throw new InvalidDataException("Invalid AngleOffset");
                                            }

                                            // Add to projection pixels array
                                            if ((checkalpha && pixelsarr[pixelpos].a == 0) || !checkalpha)
                                            {
                                                pixelsarr[pixelpos] = palette[colorindices[cstart]];
                                            }

                                            // Increment counters
                                            cstart++;
                                            z++;
                                        }
                                    }
                                }

                                counter++;
                            }
                        }

                        // Draw to bitmap
                        bitmap = new Bitmap(imgwidth, imgheight, PixelFormat.Format32bppArgb);
                        BitmapData bmpdata = null;

                        try
                        {
                            bmpdata = bitmap.LockBits(new Rectangle(0, 0, imgwidth, imgheight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                        }
                        catch (Exception e)
                        {
                            error = "Cannot lock image for drawing voxel \""
                                    + Path.Combine(voxellocation, voxelname) + "\". " + e.GetType().Name + ": " + e.Message;
                            bitmap = null;
                        }

                        if (bmpdata != null)
                        {
                            // Apply pixels to image
                            PixelColor *pixels = (PixelColor *)bmpdata.Scan0.ToPointer();
                            int         i      = 0;

                            for (PixelColor *cp = pixels; cp < pixels + numpixels; cp++, i++)
                            {
                                if (pixelsarr[i].a == 255)
                                {
                                    cp->r = pixelsarr[i].r;
                                    cp->g = pixelsarr[i].g;
                                    cp->b = pixelsarr[i].b;
                                    cp->a = 255;
                                }
                            }

                            bitmap.UnlockBits(bmpdata);
                        }
                    }
                }

                lumpdata.Dispose();
            }
            else
            {
                // Missing voxel lump!
                error = "Missing voxel lump \"" + voxelname + "\". Forgot to include required resources?";
            }

            return(new LocalLoadResult(bitmap, error, () =>
            {
                scale.x = 1.0f;
                scale.y = 1.0f;
                offsetx = imgoffsetx;
                offsety = pivotz;
            }));
        }
Ejemplo n.º 24
0
        // This loads the image
        protected override void LocalLoadImage()
        {
            // Checks
            if (this.IsImageLoaded || width == 0 || height == 0)
            {
                return;
            }

            BitmapData  bitmapdata = null;
            PixelColor *pixels     = (PixelColor *)0;

            lock (this)
            {
                // Create texture bitmap
                try
                {
                    if (bitmap != null)
                    {
                        bitmap.Dispose();
                    }
                    bitmap     = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    bitmapdata = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    pixels     = (PixelColor *)bitmapdata.Scan0.ToPointer();
                    General.ZeroMemory(new IntPtr(pixels), width * height * sizeof(PixelColor));
                }
                catch (Exception e)
                {
                    // Unable to make bitmap
                    General.ErrorLogger.Add(ErrorType.Error, "Unable to load texture image \"" + this.Name + "\". " + e.GetType().Name + ": " + e.Message);
                    loadfailed = true;
                }

                int missingpatches = 0;                 //mxd

                if (!loadfailed)
                {
                    // Go for all patches
                    foreach (TexturePatch p in patches)
                    {
                        // Get the patch data stream
                        string patchlocation = string.Empty;                         //mxd
                        Stream patchdata     = General.Map.Data.GetPatchData(p.LumpName, p.HasLongName, ref patchlocation);
                        if (patchdata != null)
                        {
                            // Copy patch data to memory
                            byte[] membytes = new byte[(int)patchdata.Length];

                            lock (patchdata)                            //mxd
                            {
                                patchdata.Seek(0, SeekOrigin.Begin);
                                patchdata.Read(membytes, 0, (int)patchdata.Length);
                            }

                            MemoryStream mem = new MemoryStream(membytes);
                            mem.Seek(0, SeekOrigin.Begin);

                            // Get a reader for the data
                            IImageReader reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
                            if (reader is UnknownImageReader)
                            {
                                //mxd. Probably that's a flat?..
                                if (General.Map.Config.MixTexturesFlats)
                                {
                                    reader = ImageDataFormat.GetImageReader(mem, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette);
                                }
                                if (reader is UnknownImageReader)
                                {
                                    // Data is in an unknown format!
                                    General.ErrorLogger.Add(ErrorType.Error, "Patch lump \"" + Path.Combine(patchlocation, p.LumpName) + "\" data format could not be read, while loading texture \"" + this.Name + "\". Does this lump contain valid picture data at all?");
                                    loadfailed = true;
                                    missingpatches++;                                     //mxd
                                }
                            }

                            if (!(reader is UnknownImageReader))
                            {
                                // Draw the patch
                                mem.Seek(0, SeekOrigin.Begin);
                                try { reader.DrawToPixelData(mem, pixels, width, height, p.X, p.Y); }
                                catch (InvalidDataException)
                                {
                                    // Data cannot be read!
                                    General.ErrorLogger.Add(ErrorType.Error, "Patch lump \"" + p.LumpName + "\" data format could not be read, while loading texture \"" + this.Name + "\". Does this lump contain valid picture data at all?");
                                    loadfailed = true;
                                    missingpatches++;                                     //mxd
                                }
                            }

                            // Done
                            mem.Dispose();
                        }
                        else
                        {
                            // Missing a patch lump!
                            General.ErrorLogger.Add(ErrorType.Error, "Missing patch lump \"" + p.LumpName + "\" while loading texture \"" + this.Name + "\". Did you forget to include required resources?");
                            loadfailed = true;
                            missingpatches++;                             //mxd
                        }
                    }

                    // Done
                    bitmap.UnlockBits(bitmapdata);
                }

                // Dispose bitmap if load failed
                if ((bitmap != null) && (loadfailed || missingpatches >= patches.Count))                //mxd. We can still display texture if at least one of the patches was loaded
                {
                    bitmap.Dispose();
                    bitmap     = null;
                    loadfailed = true;
                }

                // Pass on to base
                base.LocalLoadImage();
            }
        }
Ejemplo n.º 25
0
        // This requests loading the image
        protected virtual void LocalLoadImage()
        {
            BitmapData bmpdata = null;

            lock (this)
            {
                // Bitmap loaded successfully?
                if (bitmap != null)
                {
                    // Bitmap has incorrect format?
                    if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
                    {
                        // villsa
                        if (General.Map.FormatInterface.InDoom64Mode)
                        {
                            ColorPalette ncp = bitmap.Palette;

                            foreach (TextureIndexInfo tp in General.Map.Config.ThingPalettes)
                            {
                                // sprite contains alternate palette?
                                if (General.Map.Data.ThingPalette.ContainsKey(tp.Title) &&
                                    tp.Index == palindex)
                                {
                                    Playpal pal = General.Map.Data.ThingPalette[tp.Title];
                                    for (int i = 0; i < 255; i++)
                                    {
                                        // copy alternate palette over
                                        ncp.Entries[i] = pal[i].ToColor();
                                    }
                                }
                            }
                        }

                        //General.ErrorLogger.Add(ErrorType.Warning, "Image '" + name + "' does not have A8R8G8B8 pixel format. Conversion was needed.");
                        Bitmap oldbitmap = bitmap;
                        try
                        {
                            // Convert to desired pixel format
                            bitmap = new Bitmap(oldbitmap.Size.Width, oldbitmap.Size.Height, PixelFormat.Format32bppArgb);
                            Graphics g = Graphics.FromImage(bitmap);
                            g.PageUnit           = GraphicsUnit.Pixel;
                            g.CompositingQuality = CompositingQuality.HighQuality;
                            g.InterpolationMode  = InterpolationMode.NearestNeighbor;
                            g.SmoothingMode      = SmoothingMode.None;
                            g.PixelOffsetMode    = PixelOffsetMode.None;
                            g.Clear(Color.Transparent);
                            g.DrawImage(oldbitmap, 0, 0, oldbitmap.Size.Width, oldbitmap.Size.Height);
                            g.Dispose();
                            oldbitmap.Dispose();
                        }
                        catch (Exception e)
                        {
                            bitmap = oldbitmap;
                            General.ErrorLogger.Add(ErrorType.Warning, "Cannot lock image '" + name + "' for pixel format conversion. The image may not be displayed correctly.\n" + e.GetType().Name + ": " + e.Message);
                        }
                    }

                    // This applies brightness correction on the image
                    if (usecolorcorrection)
                    {
                        try
                        {
                            // Try locking the bitmap
                            bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                        }
                        catch (Exception e)
                        {
                            General.ErrorLogger.Add(ErrorType.Warning, "Cannot lock image '" + name + "' for color correction. The image may not be displayed correctly.\n" + e.GetType().Name + ": " + e.Message);
                        }

                        // Bitmap locked?
                        if (bmpdata != null)
                        {
                            // Apply color correction
                            PixelColor *pixels = (PixelColor *)(bmpdata.Scan0.ToPointer());
                            General.Colors.ApplColorCorrection(pixels, bmpdata.Width * bmpdata.Height);
                            bitmap.UnlockBits(bmpdata);
                        }
                    }
                }
                else
                {
                    // Loading failed
                    // We still mark the image as ready so that it will
                    // not try loading again until Reload Resources is used
                    loadfailed = true;
                    bitmap     = new Bitmap(Properties.Resources.Failed);
                }

                if (bitmap != null)
                {
                    width  = bitmap.Size.Width;
                    height = bitmap.Size.Height;

                    // Do we still have to set a scale?
                    if ((scale.x == 0.0f) && (scale.y == 0.0f))
                    {
                        if ((General.Map != null) && (General.Map.Config != null))
                        {
                            scale.x = General.Map.Config.DefaultTextureScale;
                            scale.y = General.Map.Config.DefaultTextureScale;
                        }
                        else
                        {
                            scale.x = 1.0f;
                            scale.y = 1.0f;
                        }
                    }
                }

                // Image is ready
                imagestate = ImageLoadState.Ready;
            }
        }
Ejemplo n.º 26
0
        // This loads the image
        protected override LocalLoadResult LocalLoadImage()
        {
            // Checks
            if (width == 0 || height == 0)
            {
                return(new LocalLoadResult(null));
            }

            BitmapData  bitmapdata = null;
            PixelColor *pixels     = (PixelColor *)0;

            Bitmap            bitmap   = null;
            List <LogMessage> messages = new List <LogMessage>();

            // Create texture bitmap
            try
            {
                if (bitmap != null)
                {
                    bitmap.Dispose();
                }
                bitmap     = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                bitmapdata = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                pixels     = (PixelColor *)bitmapdata.Scan0.ToPointer();
                General.ZeroMemory(new IntPtr(pixels), width * height * sizeof(PixelColor));
            }
            catch (Exception e)
            {
                // Unable to make bitmap
                messages.Add(new LogMessage(ErrorType.Error, "Unable to load texture image \"" + this.Name + "\". " + e.GetType().Name + ": " + e.Message));
            }

            int missingpatches = 0;             //mxd

            if (!messages.Any(x => x.Type == ErrorType.Error))
            {
                // Go for all patches
                foreach (TexturePatch p in patches)
                {
                    // Get the patch data stream
                    string patchlocation = string.Empty;                     //mxd
                    Stream patchdata     = General.Map.Data.GetPatchData(p.LumpName, p.HasLongName, ref patchlocation);
                    if (patchdata != null)
                    {
                        // Get a reader for the data
                        Bitmap patchbmp = ImageDataFormat.TryLoadImage(patchdata, ImageDataFormat.DOOMPICTURE, General.Map.Data.Palette);
                        if (patchbmp == null)
                        {
                            //mxd. Probably that's a flat?..
                            if (General.Map.Config.MixTexturesFlats)
                            {
                                patchbmp = ImageDataFormat.TryLoadImage(patchdata, ImageDataFormat.DOOMFLAT, General.Map.Data.Palette);
                            }
                            if (patchbmp == null)
                            {
                                // Data is in an unknown format!
                                messages.Add(new LogMessage(ErrorType.Error, "Patch lump \"" + Path.Combine(patchlocation, p.LumpName) + "\" data format could not be read, while loading texture \"" + this.Name + "\". Does this lump contain valid picture data at all?"));
                                missingpatches++;                                 //mxd
                            }
                        }

                        if (patchbmp != null)
                        {
                            // Draw the patch
                            DrawToPixelData(patchbmp, pixels, width, height, p.X, p.Y);
                            patchbmp.Dispose();
                        }

                        // Done
                        patchdata.Dispose();
                    }
                    else
                    {
                        // Missing a patch lump!
                        messages.Add(new LogMessage(ErrorType.Error, "Missing patch lump \"" + p.LumpName + "\" while loading texture \"" + this.Name + "\". Did you forget to include required resources?"));
                        missingpatches++;                         //mxd
                    }
                }

                // Done
                bitmap.UnlockBits(bitmapdata);
            }

            // Dispose bitmap if load failed
            if ((bitmap != null) && (messages.Any(x => x.Type == ErrorType.Error) || missingpatches >= patches.Count))            //mxd. We can still display texture if at least one of the patches was loaded
            {
                bitmap.Dispose();
                bitmap = null;
            }

            return(new LocalLoadResult(bitmap, messages));
        }