예제 #1
0
 internal override void Read(byte[] buffer)
 {
     var rleStream = new MemoryStream(rleData);
     var rleReader = new RleReader(rleStream);
     var bufferIndex = 0;
     for (int i = 0; i < Size.Height; i++)
     {
         var bytesRead = rleReader.Read(buffer, bufferIndex, BytesPerRow);
         if (bytesRead != BytesPerRow)
         {
             throw new Exception("RLE row decompressed to unexpected length.");
         }
         bufferIndex += bytesRead;
     }
 }
예제 #2
0
        private byte[] DecodeRleData(byte[] rleData, int[] dataLengths)
        {
            var totalDataLength = dataLengths.Sum();
            var data            = new byte[totalDataLength];

            var rleStream = new MemoryStream(rleData);
            var rleReader = new RleReader(rleStream);

            int offset = 0;

            for (int i = 0; i < dataLengths.Length; i++)
            {
                var count = dataLengths[i];
                rleReader.Read(data, offset, count);
                offset += count;
            }

            return(data);
        }
예제 #3
0
        /// <summary>
        /// Reads a Sun Raster (.RAS) image from a stream.
        /// </summary>
        /// <param name="stream">Stream from which to read the image.</param>
        /// <returns>Bitmap that contains the image that was read.</returns>
        public static Bitmap Load(Stream stream)
        {
            BinaryReader reader    = new BinaryReader(stream);
            UInt32       tempDword = Util.BigEndian(reader.ReadUInt32());

            if (tempDword != 0x59a66a95)
            {
                throw new ApplicationException("This is not a valid RAS file.");
            }

            int    imgWidth   = (int)Util.BigEndian(reader.ReadUInt32());
            int    imgHeight  = (int)Util.BigEndian(reader.ReadUInt32());
            int    imgBpp     = (int)Util.BigEndian(reader.ReadUInt32());
            UInt32 dataLength = Util.BigEndian(reader.ReadUInt32());
            UInt32 rasType    = Util.BigEndian(reader.ReadUInt32());
            UInt32 mapType    = Util.BigEndian(reader.ReadUInt32());
            UInt32 mapLength  = Util.BigEndian(reader.ReadUInt32());

            RleReader rleReader = new RleReader(stream, rasType == 2);

            if ((imgWidth < 1) || (imgHeight < 1) || (imgWidth > 32767) || (imgHeight > 32767) || (mapLength > 32767))
            {
                throw new ApplicationException("This RAS file appears to have invalid dimensions.");
            }

            if ((imgBpp != 32) && (imgBpp != 24) && (imgBpp != 8) && (imgBpp != 4) && (imgBpp != 1))
            {
                throw new ApplicationException("Only 1, 4, 8, 24, and 32 bit images are supported.");
            }

            byte[] bmpData = new byte[imgWidth * 4 * imgHeight];

            byte[] colorPalette = null;
            if (mapType > 0)
            {
                colorPalette = new byte[mapLength];
                stream.Read(colorPalette, 0, (int)mapLength);
            }

            try
            {
                if (imgBpp == 1)
                {
                    int  dx = 0, dy = 0;
                    int  b, bytePtr = 0;
                    byte val;
                    while (dy < imgHeight)
                    {
                        b = rleReader.ReadByte();
                        if (b == -1)
                        {
                            break;
                        }
                        for (int i = 7; i >= 0; i--)
                        {
                            if ((b & (1 << i)) != 0)
                            {
                                val = 0;
                            }
                            else
                            {
                                val = 255;
                            }
                            bmpData[bytePtr++] = val;
                            bmpData[bytePtr++] = val;
                            bmpData[bytePtr++] = val;
                            bytePtr++;

                            dx++;
                            if (dx == imgWidth)
                            {
                                dx = 0; dy++;
                                break;
                            }
                        }
                    }
                }
                else if (imgBpp == 4)
                {
                    int    bytePtr  = 0;
                    byte[] scanline = new byte[imgWidth + 1];
                    for (int dy = 0; dy < imgHeight; dy++)
                    {
                        int tempByte;
                        for (int i = 0; i < imgWidth; i++)
                        {
                            tempByte      = rleReader.ReadByte();
                            scanline[i++] = (byte)((tempByte >> 4) & 0xF);
                            scanline[i]   = (byte)(tempByte & 0xF);
                        }

                        if (imgWidth % 2 == 1)
                        {
                            rleReader.ReadByte();
                        }

                        if ((mapType > 0) && (mapLength == 48))
                        {
                            for (int dx = 0; dx < imgWidth; dx++)
                            {
                                bmpData[bytePtr++] = colorPalette[scanline[dx] + 32];
                                bmpData[bytePtr++] = colorPalette[scanline[dx] + 16];
                                bmpData[bytePtr++] = colorPalette[scanline[dx]];
                                bytePtr++;
                            }
                        }
                        else
                        {
                            for (int dx = 0; dx < imgWidth; dx++)
                            {
                                bmpData[bytePtr++] = scanline[dx];
                                bmpData[bytePtr++] = scanline[dx];
                                bmpData[bytePtr++] = scanline[dx];
                                bytePtr++;
                            }
                        }
                    }
                }
                else if (imgBpp == 8)
                {
                    int    bytePtr  = 0;
                    byte[] scanline = new byte[imgWidth];
                    for (int dy = 0; dy < imgHeight; dy++)
                    {
                        for (int i = 0; i < imgWidth; i++)
                        {
                            scanline[i] = (byte)rleReader.ReadByte();
                        }

                        if (imgWidth % 2 == 1)
                        {
                            rleReader.ReadByte();
                        }

                        if ((mapType > 0) && (mapLength == 768))
                        {
                            for (int dx = 0; dx < imgWidth; dx++)
                            {
                                bmpData[bytePtr++] = colorPalette[scanline[dx] + 512];
                                bmpData[bytePtr++] = colorPalette[scanline[dx] + 256];
                                bmpData[bytePtr++] = colorPalette[scanline[dx]];
                                bytePtr++;
                            }
                        }
                        else
                        {
                            for (int dx = 0; dx < imgWidth; dx++)
                            {
                                bmpData[bytePtr++] = scanline[dx];
                                bmpData[bytePtr++] = scanline[dx];
                                bmpData[bytePtr++] = scanline[dx];
                                bytePtr++;
                            }
                        }
                    }
                }
                else if (imgBpp == 24)
                {
                    int    bytePtr  = 0;
                    byte[] scanline = new byte[imgWidth * 3];
                    for (int dy = 0; dy < imgHeight; dy++)
                    {
                        for (int i = 0; i < imgWidth * 3; i++)
                        {
                            scanline[i] = (byte)rleReader.ReadByte();
                        }

                        if ((imgWidth * 3) % 2 == 1)
                        {
                            stream.ReadByte();
                        }

                        for (int dx = 0; dx < imgWidth; dx++)
                        {
                            bmpData[bytePtr++] = scanline[dx * 3];
                            bmpData[bytePtr++] = scanline[dx * 3 + 1];
                            bmpData[bytePtr++] = scanline[dx * 3 + 2];
                            bytePtr++;
                        }
                    }
                }
                else if (imgBpp == 32)
                {
                    int    bytePtr  = 0;
                    byte[] scanline = new byte[imgWidth * 4];
                    for (int dy = 0; dy < imgHeight; dy++)
                    {
                        for (int i = 0; i < imgWidth * 4; i++)
                        {
                            scanline[i] = (byte)rleReader.ReadByte();
                        }

                        for (int dx = 0; dx < imgWidth; dx++)
                        {
                            bmpData[bytePtr++] = scanline[dx * 4];
                            bmpData[bytePtr++] = scanline[dx * 4 + 1];
                            bmpData[bytePtr++] = scanline[dx * 4 + 2];
                            bmpData[bytePtr++] = scanline[dx * 4 + 3];
                        }
                    }
                }
            }
            catch (Exception e)
            {
                //give a partial image in case of unexpected end-of-file

                System.Diagnostics.Debug.WriteLine("Error while processing RAS file: " + e.Message);
            }

            Bitmap theBitmap = new Bitmap((int)imgWidth, (int)imgHeight, System.Drawing.Imaging.PixelFormat.Format32bppRgb);

            System.Drawing.Imaging.BitmapData bmpBits = theBitmap.LockBits(new Rectangle(0, 0, theBitmap.Width, theBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
            System.Runtime.InteropServices.Marshal.Copy(bmpData, 0, bmpBits.Scan0, bmpData.Length);
            theBitmap.UnlockBits(bmpBits);
            return(theBitmap);
        }
예제 #4
0
        public static Bitmap Load(Stream stream)
        {
            int          imgWidth  = -1;
            int          imgHeight = -1;
            int          imgBpp    = -1;
            Bitmap       theBitmap = null;
            BinaryReader reader    = new BinaryReader(stream);

            byte tempByte = (byte)stream.ReadByte();

            if (tempByte != 10)
            {
                throw new ApplicationException("This is not a  PCX file.");
            }

            tempByte = (byte)stream.ReadByte();
            if (tempByte < 0 || tempByte > 5)
            {
                throw new ApplicationException("Invalid PCX version.");
            }

            tempByte = (byte)stream.ReadByte();
            if (tempByte != 1)
            {
                throw new ApplicationException("Invalid encoding char.");
            }

            imgBpp = stream.ReadByte();


            UInt16 xmin = reader.ReadUInt16();
            UInt16 ymin = reader.ReadUInt16();
            UInt16 xmax = reader.ReadUInt16();
            UInt16 ymax = reader.ReadUInt16();

            imgWidth  = xmax - xmin + 1;
            imgHeight = ymax - ymin + 1;

            if ((imgWidth < 1) || (imgHeight < 1) || (imgWidth > 32767) || (imgHeight > 32767))
            {
                throw new ApplicationException("This PCX file appears to have invalid dimensions.");
            }

            reader.ReadUInt16(); //horiontal resolution
            reader.ReadUInt16(); //vertical resolution

            byte[] colorPalette = new byte[48];
            stream.Read(colorPalette, 0, 48);

            stream.ReadByte();

            int numPlanes    = stream.ReadByte();
            int bytesPerLine = reader.ReadUInt16();

            if (bytesPerLine == 0)
            {
                bytesPerLine = xmax - xmin + 1;
            }

            if (imgBpp == 8 && numPlanes == 1)
            {
                colorPalette = new byte[768];
                stream.Seek(-768, SeekOrigin.End);
                stream.Read(colorPalette, 0, 768);
            }

            //fix color palette if it's a 1-bit image, and there's no palette information
            if (imgBpp == 1)
            {
                if ((colorPalette[0] == colorPalette[3]) && (colorPalette[1] == colorPalette[4]) && (colorPalette[2] == colorPalette[5]))
                {
                    colorPalette[0] = colorPalette[1] = colorPalette[2] = 0;
                    colorPalette[3] = colorPalette[4] = colorPalette[5] = 0xFF;
                }
            }

            byte[] bmpData = new byte[(imgWidth + 1) * 4 * imgHeight];
            stream.Seek(128, SeekOrigin.Begin);
            int x = 0, y = 0, i, j;

            RleReader rleReader = new RleReader(stream);

            try
            {
                if (imgBpp == 1)
                {
                    int    b, p;
                    byte   val;
                    byte[] scanline     = new byte[bytesPerLine];
                    byte[] realscanline = new byte[bytesPerLine * 8];

                    for (y = 0; y < imgHeight; y++)
                    {
                        //add together all the planes...
                        Array.Clear(realscanline, 0, realscanline.Length);
                        for (p = 0; p < numPlanes; p++)
                        {
                            x = 0;
                            for (i = 0; i < bytesPerLine; i++)
                            {
                                scanline[i] = (byte)rleReader.ReadByte();

                                for (b = 7; b >= 0; b--)
                                {
                                    if ((scanline[i] & (1 << b)) != 0)
                                    {
                                        val = 1;
                                    }
                                    else
                                    {
                                        val = 0;
                                    }
                                    realscanline[x] |= (byte)(val << p);
                                    x++;
                                }
                            }
                        }

                        for (x = 0; x < imgWidth; x++)
                        {
                            i = realscanline[x];
                            bmpData[4 * (y * imgWidth + x)]     = colorPalette[i * 3 + 2];
                            bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[i * 3 + 1];
                            bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[i * 3];
                        }
                    }
                }
                else
                {
                    if (numPlanes == 1)
                    {
                        if (imgBpp == 8)
                        {
                            byte[] scanline = new byte[bytesPerLine];
                            for (y = 0; y < imgHeight; y++)
                            {
                                for (i = 0; i < bytesPerLine; i++)
                                {
                                    scanline[i] = (byte)rleReader.ReadByte();
                                }

                                for (x = 0; x < imgWidth; x++)
                                {
                                    i = scanline[x];
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[i * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[i * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[i * 3];
                                }
                            }
                        }
                        else if (imgBpp == 4)
                        {
                            byte[] scanline = new byte[bytesPerLine];
                            for (y = 0; y < imgHeight; y++)
                            {
                                for (i = 0; i < bytesPerLine; i++)
                                {
                                    scanline[i] = (byte)rleReader.ReadByte();
                                }

                                for (x = 0; x < imgWidth; x++)
                                {
                                    i = scanline[x / 2];
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[((i >> 4) & 0xF) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[((i >> 4) & 0xF) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[((i >> 4) & 0xF) * 3];
                                    x++;
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[(i & 0xF) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[(i & 0xF) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[(i & 0xF) * 3];
                                }
                            }
                        }
                        else if (imgBpp == 2)
                        {
                            byte[] scanline = new byte[bytesPerLine];
                            for (y = 0; y < imgHeight; y++)
                            {
                                for (i = 0; i < bytesPerLine; i++)
                                {
                                    scanline[i] = (byte)rleReader.ReadByte();
                                }

                                for (x = 0; x < imgWidth; x++)
                                {
                                    i = scanline[x / 4];
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[((i >> 6) & 0x3) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[((i >> 6) & 0x3) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[((i >> 6) & 0x3) * 3];
                                    x++;
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[((i >> 4) & 0x3) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[((i >> 4) & 0x3) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[((i >> 4) & 0x3) * 3];
                                    x++;
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[((i >> 2) & 0x3) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[((i >> 2) & 0x3) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[((i >> 2) & 0x3) * 3];
                                    x++;
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[(i & 0x3) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[(i & 0x3) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[(i & 0x3) * 3];
                                }
                            }
                        }
                    }
                    else if (numPlanes == 3)
                    {
                        byte[] scanlineR = new byte[bytesPerLine];
                        byte[] scanlineG = new byte[bytesPerLine];
                        byte[] scanlineB = new byte[bytesPerLine];
                        int    bytePtr   = 0;

                        for (y = 0; y < imgHeight; y++)
                        {
                            for (i = 0; i < bytesPerLine; i++)
                            {
                                scanlineR[i] = (byte)rleReader.ReadByte();
                            }
                            for (i = 0; i < bytesPerLine; i++)
                            {
                                scanlineG[i] = (byte)rleReader.ReadByte();
                            }
                            for (i = 0; i < bytesPerLine; i++)
                            {
                                scanlineB[i] = (byte)rleReader.ReadByte();
                            }

                            for (int n = 0; n < imgWidth; n++)
                            {
                                bmpData[bytePtr++] = scanlineB[n];
                                bmpData[bytePtr++] = scanlineG[n];
                                bmpData[bytePtr++] = scanlineR[n];
                                bytePtr++;
                            }
                        }
                    }
                }//bpp
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("Error while processing PCX file: " + e.Message);
            }

            theBitmap = new Bitmap((int)imgWidth, (int)imgHeight, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
            System.Drawing.Imaging.BitmapData bmpBits = theBitmap.LockBits(new Rectangle(0, 0, theBitmap.Width, theBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
            System.Runtime.InteropServices.Marshal.Copy(bmpData, 0, bmpBits.Scan0, imgWidth * 4 * imgHeight);
            theBitmap.UnlockBits(bmpBits);
            return(theBitmap);
        }
예제 #5
0
        public static Bitmap Load(Stream stream)
        {
            var binaryReader = new BinaryReader(stream);

            if (BigEndian(binaryReader.ReadUInt32()) != 1504078485u)
            {
                throw new ApplicationException("This is not a valid RAS file.");
            }
            var num  = (int)BigEndian(binaryReader.ReadUInt32());
            var num2 = (int)BigEndian(binaryReader.ReadUInt32());
            var num3 = (int)BigEndian(binaryReader.ReadUInt32());

            BigEndian(binaryReader.ReadUInt32());
            var num4      = BigEndian(binaryReader.ReadUInt32());
            var num5      = BigEndian(binaryReader.ReadUInt32());
            var num6      = BigEndian(binaryReader.ReadUInt32());
            var rleReader = new RleReader(stream, num4 == 2u);

            if (num < 1 || num2 < 1 || num > 32767 || num2 > 32767 || num6 > 32767u)
            {
                throw new ApplicationException("This RAS file appears to have invalid dimensions.");
            }
            if (num3 != 32 && num3 != 24 && num3 != 8 && num3 != 4 && num3 != 1)
            {
                throw new ApplicationException("Only 1, 4, 8, 24, and 32 bit images are supported.");
            }
            var array = new byte[num * 4 * num2];

            byte[] array2 = null;
            if (num5 > 0u)
            {
                array2 = new byte[num6];
                stream.Read(array2, 0, (int)num6);
            }
            try
            {
                if (num3 == 1)
                {
                    var num7 = 0;
                    var i    = 0;
                    var num8 = 0;
                    while (i < num2)
                    {
                        var num9 = rleReader.ReadByte();
                        if (num9 == -1)
                        {
                            break;
                        }
                        for (var j = 7; j >= 0; j--)
                        {
                            byte b;
                            if ((num9 & 1 << j) != 0)
                            {
                                b = 0;
                            }
                            else
                            {
                                b = byte.MaxValue;
                            }
                            array[num8++] = b;
                            array[num8++] = b;
                            array[num8++] = b;
                            num8++;
                            num7++;
                            if (num7 == num)
                            {
                                num7 = 0;
                                i++;
                                break;
                            }
                        }
                    }
                }
                else if (num3 == 4)
                {
                    var num10  = 0;
                    var array3 = new byte[num + 1];
                    for (var k = 0; k < num2; k++)
                    {
                        for (var l = 0; l < num; l++)
                        {
                            var num11 = rleReader.ReadByte();
                            array3[l++] = (byte)(num11 >> 4 & 15);
                            array3[l]   = (byte)(num11 & 15);
                        }
                        if (num % 2 == 1)
                        {
                            rleReader.ReadByte();
                        }
                        if (num5 > 0u && num6 == 48u)
                        {
                            for (var m = 0; m < num; m++)
                            {
                                array[num10++] = array2[(int)(array3[m] + 32)];
                                array[num10++] = array2[(int)(array3[m] + 16)];
                                array[num10++] = array2[(int)array3[m]];
                                num10++;
                            }
                        }
                        else
                        {
                            for (var n = 0; n < num; n++)
                            {
                                array[num10++] = array3[n];
                                array[num10++] = array3[n];
                                array[num10++] = array3[n];
                                num10++;
                            }
                        }
                    }
                }
                else if (num3 == 8)
                {
                    var num12  = 0;
                    var array4 = new byte[num];
                    for (var num13 = 0; num13 < num2; num13++)
                    {
                        for (var num14 = 0; num14 < num; num14++)
                        {
                            array4[num14] = (byte)rleReader.ReadByte();
                        }
                        if (num % 2 == 1)
                        {
                            rleReader.ReadByte();
                        }
                        if (num5 > 0u && num6 == 768u)
                        {
                            for (var num15 = 0; num15 < num; num15++)
                            {
                                array[num12++] = array2[(int)array4[num15] + 512];
                                array[num12++] = array2[(int)array4[num15] + 256];
                                array[num12++] = array2[(int)array4[num15]];
                                num12++;
                            }
                        }
                        else
                        {
                            for (var num16 = 0; num16 < num; num16++)
                            {
                                array[num12++] = array4[num16];
                                array[num12++] = array4[num16];
                                array[num12++] = array4[num16];
                                num12++;
                            }
                        }
                    }
                }
                else if (num3 == 24)
                {
                    var num17  = 0;
                    var array5 = new byte[num * 3];
                    for (var num18 = 0; num18 < num2; num18++)
                    {
                        for (var num19 = 0; num19 < num * 3; num19++)
                        {
                            array5[num19] = (byte)rleReader.ReadByte();
                        }
                        if (num * 3 % 2 == 1)
                        {
                            stream.ReadByte();
                        }
                        for (var num20 = 0; num20 < num; num20++)
                        {
                            array[num17++] = array5[num20 * 3];
                            array[num17++] = array5[num20 * 3 + 1];
                            array[num17++] = array5[num20 * 3 + 2];
                            num17++;
                        }
                    }
                }
                else if (num3 == 32)
                {
                    var num21  = 0;
                    var array6 = new byte[num * 4];
                    for (var num22 = 0; num22 < num2; num22++)
                    {
                        for (var num23 = 0; num23 < num * 4; num23++)
                        {
                            array6[num23] = (byte)rleReader.ReadByte();
                        }
                        for (var num24 = 0; num24 < num; num24++)
                        {
                            array[num21++] = array6[num24 * 4];
                            array[num21++] = array6[num24 * 4 + 1];
                            array[num21++] = array6[num24 * 4 + 2];
                            array[num21++] = array6[num24 * 4 + 3];
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
            var bitmap     = new Bitmap(num, num2, PixelFormat.Format32bppRgb);
            var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);

            Marshal.Copy(array, 0, bitmapData.Scan0, array.Length);
            bitmap.UnlockBits(bitmapData);
            return(bitmap);
        }
예제 #6
0
        public static Bitmap Load(Stream stream)
        {
            byte[] headerBytes = new byte[0x80];
            stream.Read(headerBytes, 0, headerBytes.Length);

            if (headerBytes[0] != 0)
            {
                throw new ApplicationException("This is not a valid MacPaint file.");
            }

            string fileType = Encoding.ASCII.GetString(headerBytes, 0x41, 4);

            if (fileType != "PNTG")
            {
                throw new ApplicationException("This is not a valid MacPaint file.");
            }

            int    fileNameLen = headerBytes[1];
            string fileName    = Encoding.ASCII.GetString(headerBytes, 2, fileNameLen);

            // Not much other useful stuff in the header...

            stream.Read(headerBytes, 0, 4);
            uint startMagic = Util.BigEndian(BitConverter.ToUInt32(headerBytes, 0));

            if (startMagic != 0x2)
            {
                // I have actually seen MacPaint files that do not have this magic value...
                //throw new ApplicationException("This is not a valid MacPaint file.");
            }

            // Skip over pattern data
            stream.Seek(304, SeekOrigin.Current);

            // Skip over padding data
            stream.Seek(204, SeekOrigin.Current);

            byte[]    bmpData = new byte[(MAC_PAINT_WIDTH + 1) * 4 * MAC_PAINT_HEIGHT];
            int       x = 0, y = 0;
            RleReader rleReader = new RleReader(stream);

            try
            {
                int  b;
                byte curByte;
                int  bmpPtr = 0;
                bool val;

                while (bmpPtr < bmpData.Length)
                {
                    curByte = (byte)rleReader.ReadByte();
                    for (b = 7; b >= 0; b--)
                    {
                        val = (curByte & (1 << b)) != 0;

                        bmpData[bmpPtr]     = (byte)(val ? 0 : 0xFF);
                        bmpData[bmpPtr + 1] = (byte)(val ? 0 : 0xFF);
                        bmpData[bmpPtr + 2] = (byte)(val ? 0 : 0xFF);
                        bmpPtr += 4;

                        x++;
                        if (x >= MAC_PAINT_WIDTH)
                        {
                            x = 0;
                            y++;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                //give a partial image in case of unexpected end-of-file
                System.Diagnostics.Debug.WriteLine("Error while processing MacPaint file: " + e.Message);
            }

            var bmp = new Bitmap(MAC_PAINT_WIDTH, MAC_PAINT_HEIGHT, System.Drawing.Imaging.PixelFormat.Format32bppRgb);

            System.Drawing.Imaging.BitmapData bmpBits = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
            System.Runtime.InteropServices.Marshal.Copy(bmpData, 0, bmpBits.Scan0, MAC_PAINT_WIDTH * 4 * MAC_PAINT_HEIGHT);
            bmp.UnlockBits(bmpBits);
            return(bmp);
        }
예제 #7
0
        /// <summary>
        /// Reads a PCX image from a stream.
        /// </summary>
        /// <param name="stream">Stream from which to read the image.</param>
        /// <returns>Bitmap that contains the image that was read.</returns>
        public static Bitmap Load(Stream stream)
        {
            int          imgWidth  = -1;
            int          imgHeight = -1;
            int          imgBpp    = -1;
            Bitmap       theBitmap = null;
            BinaryReader reader    = new BinaryReader(stream);

            byte tempByte = (byte)stream.ReadByte();

            if (tempByte != 10)
            {
                throw new ApplicationException("This is not a valid PCX file.");
            }

            tempByte = (byte)stream.ReadByte();
            if (tempByte < 3 || tempByte > 5)
            {
                throw new ApplicationException("Only Version 3, 4, and 5 PCX files are supported.");
            }

            tempByte = (byte)stream.ReadByte();
            if (tempByte != 1)
            {
                throw new ApplicationException("Invalid PCX compression type.");
            }

            imgBpp = stream.ReadByte();
            if (imgBpp != 8 && imgBpp != 4 && imgBpp != 2 && imgBpp != 1)
            {
                throw new ApplicationException("Only 8, 4, 2, and 1-bit PCX samples are supported.");
            }

            UInt16 xmin = Util.LittleEndian(reader.ReadUInt16());
            UInt16 ymin = Util.LittleEndian(reader.ReadUInt16());
            UInt16 xmax = Util.LittleEndian(reader.ReadUInt16());
            UInt16 ymax = Util.LittleEndian(reader.ReadUInt16());

            imgWidth  = xmax - xmin + 1;
            imgHeight = ymax - ymin + 1;

            if ((imgWidth < 1) || (imgHeight < 1) || (imgWidth > 32767) || (imgHeight > 32767))
            {
                throw new ApplicationException("This PCX file appears to have invalid dimensions.");
            }

            Util.LittleEndian(reader.ReadUInt16()); //hdpi
            Util.LittleEndian(reader.ReadUInt16()); //vdpi

            byte[] colorPalette = new byte[48];
            stream.Read(colorPalette, 0, 48);
            stream.ReadByte();

            int numPlanes    = stream.ReadByte();
            int bytesPerLine = Util.LittleEndian(reader.ReadUInt16());

            if (bytesPerLine == 0)
            {
                bytesPerLine = xmax - xmin + 1;
            }

            /*
             * HACK: Set the following parameter to true if you want to interpret the bit plane data as literal color states,
             * instead of indices into the palette. This was done by certain older versions of PaintBrush in EGA mode.
             * If the colors in your decoded picture look weird, try tweaking this setting.
             */
            bool bitPlanesLiteral = false;

            // TODO: use this for something? It doesn't seem to be consistent or meaningful between different versions.
            Util.LittleEndian(reader.ReadUInt16());

            if (imgBpp == 8 && numPlanes == 1)
            {
                colorPalette = new byte[768];
                stream.Seek(-768, SeekOrigin.End);
                stream.Read(colorPalette, 0, 768);
            }

            //fix color palette if it's a 1-bit image, and there's no palette information
            if (imgBpp == 1)
            {
                if ((colorPalette[0] == colorPalette[3]) && (colorPalette[1] == colorPalette[4]) && (colorPalette[2] == colorPalette[5]))
                {
                    colorPalette[0] = colorPalette[1] = colorPalette[2] = 0;
                    colorPalette[3] = colorPalette[4] = colorPalette[5] = 0xFF;
                }
            }

            byte[] bmpData = new byte[(imgWidth + 1) * 4 * imgHeight];
            stream.Seek(128, SeekOrigin.Begin);
            int x = 0, y = 0, i;

            RleReader rleReader = new RleReader(stream);

            try
            {
                if (imgBpp == 1)
                {
                    int    b, p;
                    byte   val;
                    byte[] scanline     = new byte[bytesPerLine];
                    byte[] realscanline = new byte[bytesPerLine * 8];

                    for (y = 0; y < imgHeight; y++)
                    {
                        //add together all the planes...
                        Array.Clear(realscanline, 0, realscanline.Length);
                        for (p = 0; p < numPlanes; p++)
                        {
                            x = 0;
                            for (i = 0; i < bytesPerLine; i++)
                            {
                                scanline[i] = (byte)rleReader.ReadByte();

                                for (b = 7; b >= 0; b--)
                                {
                                    if ((scanline[i] & (1 << b)) != 0)
                                    {
                                        val = 1;
                                    }
                                    else
                                    {
                                        val = 0;
                                    }
                                    realscanline[x] |= (byte)(val << p);
                                    x++;
                                }
                            }
                        }

                        for (x = 0; x < imgWidth; x++)
                        {
                            i = realscanline[x];

                            if (numPlanes == 1)
                            {
                                bmpData[4 * (y * imgWidth + x)]     = (byte)((i & 1) != 0 ? 0xFF : 0);
                                bmpData[4 * (y * imgWidth + x) + 1] = (byte)((i & 1) != 0 ? 0xFF : 0);
                                bmpData[4 * (y * imgWidth + x) + 2] = (byte)((i & 1) != 0 ? 0xFF : 0);
                            }
                            else
                            {
                                if (bitPlanesLiteral)
                                {
                                    bmpData[4 * (y * imgWidth + x)]     = (byte)((i & 1) != 0 ? 0xFF : 0);
                                    bmpData[4 * (y * imgWidth + x) + 1] = (byte)((i & 2) != 0 ? 0xFF : 0);
                                    bmpData[4 * (y * imgWidth + x) + 2] = (byte)((i & 4) != 0 ? 0xFF : 0);
                                }
                                else
                                {
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[i * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[i * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[i * 3];
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (numPlanes == 1)
                    {
                        if (imgBpp == 8)
                        {
                            byte[] scanline = new byte[bytesPerLine];
                            for (y = 0; y < imgHeight; y++)
                            {
                                for (i = 0; i < bytesPerLine; i++)
                                {
                                    scanline[i] = (byte)rleReader.ReadByte();
                                }

                                for (x = 0; x < imgWidth; x++)
                                {
                                    i = scanline[x];
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[i * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[i * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[i * 3];
                                }
                            }
                        }
                        else if (imgBpp == 4)
                        {
                            byte[] scanline = new byte[bytesPerLine];
                            for (y = 0; y < imgHeight; y++)
                            {
                                for (i = 0; i < bytesPerLine; i++)
                                {
                                    scanline[i] = (byte)rleReader.ReadByte();
                                }

                                for (x = 0; x < imgWidth; x++)
                                {
                                    i = scanline[x / 2];
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[((i >> 4) & 0xF) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[((i >> 4) & 0xF) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[((i >> 4) & 0xF) * 3];
                                    x++;
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[(i & 0xF) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[(i & 0xF) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[(i & 0xF) * 3];
                                }
                            }
                        }
                        else if (imgBpp == 2)
                        {
                            byte[] scanline = new byte[bytesPerLine];
                            for (y = 0; y < imgHeight; y++)
                            {
                                for (i = 0; i < bytesPerLine; i++)
                                {
                                    scanline[i] = (byte)rleReader.ReadByte();
                                }

                                for (x = 0; x < imgWidth; x++)
                                {
                                    i = scanline[x / 4];
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[((i >> 6) & 0x3) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[((i >> 6) & 0x3) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[((i >> 6) & 0x3) * 3];
                                    x++;
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[((i >> 4) & 0x3) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[((i >> 4) & 0x3) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[((i >> 4) & 0x3) * 3];
                                    x++;
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[((i >> 2) & 0x3) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[((i >> 2) & 0x3) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[((i >> 2) & 0x3) * 3];
                                    x++;
                                    bmpData[4 * (y * imgWidth + x)]     = colorPalette[(i & 0x3) * 3 + 2];
                                    bmpData[4 * (y * imgWidth + x) + 1] = colorPalette[(i & 0x3) * 3 + 1];
                                    bmpData[4 * (y * imgWidth + x) + 2] = colorPalette[(i & 0x3) * 3];
                                }
                            }
                        }
                    }
                    else if (numPlanes == 3)
                    {
                        byte[] scanlineR = new byte[bytesPerLine];
                        byte[] scanlineG = new byte[bytesPerLine];
                        byte[] scanlineB = new byte[bytesPerLine];
                        int    bytePtr   = 0;

                        for (y = 0; y < imgHeight; y++)
                        {
                            for (i = 0; i < bytesPerLine; i++)
                            {
                                scanlineR[i] = (byte)rleReader.ReadByte();
                            }
                            for (i = 0; i < bytesPerLine; i++)
                            {
                                scanlineG[i] = (byte)rleReader.ReadByte();
                            }
                            for (i = 0; i < bytesPerLine; i++)
                            {
                                scanlineB[i] = (byte)rleReader.ReadByte();
                            }

                            for (int n = 0; n < imgWidth; n++)
                            {
                                bmpData[bytePtr++] = scanlineB[n];
                                bmpData[bytePtr++] = scanlineG[n];
                                bmpData[bytePtr++] = scanlineR[n];
                                bytePtr++;
                            }
                        }
                    }
                }//bpp
            }
            catch (Exception e)
            {
                //give a partial image in case of unexpected end-of-file

                System.Diagnostics.Debug.WriteLine("Error while processing PCX file: " + e.Message);
            }

            theBitmap = new Bitmap((int)imgWidth, (int)imgHeight, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
            System.Drawing.Imaging.BitmapData bmpBits = theBitmap.LockBits(new Rectangle(0, 0, theBitmap.Width, theBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
            System.Runtime.InteropServices.Marshal.Copy(bmpData, 0, bmpBits.Scan0, imgWidth * 4 * imgHeight);
            theBitmap.UnlockBits(bmpBits);
            return(theBitmap);
        }
예제 #8
0
        public static Bitmap Load(Stream stream)
        {
            var num          = -1;
            var num2         = -1;
            var binaryReader = new BinaryReader(stream);
            var b            = (byte)stream.ReadByte();

            if (b != 10)
            {
                throw new ApplicationException("This is not a valid PCX file.");
            }
            b = (byte)stream.ReadByte();
            if (b < 3 || b > 5)
            {
                throw new ApplicationException("Only Version 3, 4, and 5 PCX files are supported.");
            }
            b = (byte)stream.ReadByte();
            if (b != 1)
            {
                throw new ApplicationException("Invalid PCX compression type.");
            }
            var num3 = stream.ReadByte();

            if (num3 != 8 && num3 != 4 && num3 != 2 && num3 != 1)
            {
                throw new ApplicationException("Only 8, 4, 2, and 1-bit PCX samples are supported.");
            }
            var num4 = LittleEndian(binaryReader.ReadUInt16());
            var num5 = LittleEndian(binaryReader.ReadUInt16());
            var num6 = LittleEndian(binaryReader.ReadUInt16());
            var num7 = (int)LittleEndian(binaryReader.ReadUInt16());

            num  = (int)(num6 - num4 + 1);
            num2 = num7 - (int)num5 + 1;
            if (num < 1 || num2 < 1 || num > 32767 || num2 > 32767)
            {
                throw new ApplicationException("This PCX file appears to have invalid dimensions.");
            }
            LittleEndian(binaryReader.ReadUInt16());
            LittleEndian(binaryReader.ReadUInt16());
            var array = new byte[48];

            stream.Read(array, 0, 48);
            stream.ReadByte();
            var num8 = stream.ReadByte();
            var num9 = (int)LittleEndian(binaryReader.ReadUInt16());

            if (num9 == 0)
            {
                num9 = (int)(num6 - num4 + 1);
            }
            if (num3 == 8 && num8 == 1)
            {
                array = new byte[768];
                stream.Seek(-768L, SeekOrigin.End);
                stream.Read(array, 0, 768);
            }
            if (num3 == 1 && array[0] == array[3] && array[1] == array[4] && array[2] == array[5])
            {
                array[0] = (array[1] = (array[2] = 0));
                array[3] = (array[4] = (array[5] = byte.MaxValue));
            }
            var array2 = new byte[(num + 1) * 4 * num2];

            stream.Seek(128L, SeekOrigin.Begin);
            var rleReader = new RleReader(stream);

            try
            {
                if (num3 == 1)
                {
                    var array3 = new byte[num9];
                    var array4 = new byte[num9 * 8];
                    for (var i = 0; i < num2; i++)
                    {
                        Array.Clear(array4, 0, array4.Length);
                        for (var j = 0; j < num8; j++)
                        {
                            var k = 0;
                            for (var l = 0; l < num9; l++)
                            {
                                array3[l] = (byte)rleReader.ReadByte();
                                for (var m = 7; m >= 0; m--)
                                {
                                    byte b2;
                                    if (((int)array3[l] & 1 << m) != 0)
                                    {
                                        b2 = 1;
                                    }
                                    else
                                    {
                                        b2 = 0;
                                    }
                                    var array5 = array4;
                                    var num10  = k;
                                    array5[num10] |= (byte)(b2 << j);
                                    k++;
                                }
                            }
                        }
                        for (var k = 0; k < num; k++)
                        {
                            var l = (int)array4[k];
                            array2[4 * (i * num + k)]     = array[l * 3 + 2];
                            array2[4 * (i * num + k) + 1] = array[l * 3 + 1];
                            array2[4 * (i * num + k) + 2] = array[l * 3];
                        }
                    }
                }
                else if (num8 == 1)
                {
                    if (num3 == 8)
                    {
                        var array6 = new byte[num9];
                        for (var i = 0; i < num2; i++)
                        {
                            for (var l = 0; l < num9; l++)
                            {
                                array6[l] = (byte)rleReader.ReadByte();
                            }
                            for (var k = 0; k < num; k++)
                            {
                                var l = (int)array6[k];
                                array2[4 * (i * num + k)]     = array[l * 3 + 2];
                                array2[4 * (i * num + k) + 1] = array[l * 3 + 1];
                                array2[4 * (i * num + k) + 2] = array[l * 3];
                            }
                        }
                    }
                    else if (num3 == 4)
                    {
                        var array7 = new byte[num9];
                        for (var i = 0; i < num2; i++)
                        {
                            for (var l = 0; l < num9; l++)
                            {
                                array7[l] = (byte)rleReader.ReadByte();
                            }
                            for (var k = 0; k < num; k++)
                            {
                                var l = (int)array7[k / 2];
                                array2[4 * (i * num + k)]     = array[(l >> 4 & 15) * 3 + 2];
                                array2[4 * (i * num + k) + 1] = array[(l >> 4 & 15) * 3 + 1];
                                array2[4 * (i * num + k) + 2] = array[(l >> 4 & 15) * 3];
                                k++;
                                array2[4 * (i * num + k)]     = array[(l & 15) * 3 + 2];
                                array2[4 * (i * num + k) + 1] = array[(l & 15) * 3 + 1];
                                array2[4 * (i * num + k) + 2] = array[(l & 15) * 3];
                            }
                        }
                    }
                    else if (num3 == 2)
                    {
                        var array8 = new byte[num9];
                        for (var i = 0; i < num2; i++)
                        {
                            for (var l = 0; l < num9; l++)
                            {
                                array8[l] = (byte)rleReader.ReadByte();
                            }
                            for (var k = 0; k < num; k++)
                            {
                                var l = (int)array8[k / 4];
                                array2[4 * (i * num + k)]     = array[(l >> 6 & 3) * 3 + 2];
                                array2[4 * (i * num + k) + 1] = array[(l >> 6 & 3) * 3 + 1];
                                array2[4 * (i * num + k) + 2] = array[(l >> 6 & 3) * 3];
                                k++;
                                array2[4 * (i * num + k)]     = array[(l >> 4 & 3) * 3 + 2];
                                array2[4 * (i * num + k) + 1] = array[(l >> 4 & 3) * 3 + 1];
                                array2[4 * (i * num + k) + 2] = array[(l >> 4 & 3) * 3];
                                k++;
                                array2[4 * (i * num + k)]     = array[(l >> 2 & 3) * 3 + 2];
                                array2[4 * (i * num + k) + 1] = array[(l >> 2 & 3) * 3 + 1];
                                array2[4 * (i * num + k) + 2] = array[(l >> 2 & 3) * 3];
                                k++;
                                array2[4 * (i * num + k)]     = array[(l & 3) * 3 + 2];
                                array2[4 * (i * num + k) + 1] = array[(l & 3) * 3 + 1];
                                array2[4 * (i * num + k) + 2] = array[(l & 3) * 3];
                            }
                        }
                    }
                }
                else if (num8 == 3)
                {
                    var array9  = new byte[num9];
                    var array10 = new byte[num9];
                    var array11 = new byte[num9];
                    var num11   = 0;
                    for (var i = 0; i < num2; i++)
                    {
                        for (var l = 0; l < num9; l++)
                        {
                            array9[l] = (byte)rleReader.ReadByte();
                        }
                        for (var l = 0; l < num9; l++)
                        {
                            array10[l] = (byte)rleReader.ReadByte();
                        }
                        for (var l = 0; l < num9; l++)
                        {
                            array11[l] = (byte)rleReader.ReadByte();
                        }
                        for (var n = 0; n < num; n++)
                        {
                            array2[num11++] = array11[n];
                            array2[num11++] = array10[n];
                            array2[num11++] = array9[n];
                            num11++;
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
            var bitmap     = new Bitmap(num, num2, PixelFormat.Format32bppRgb);
            var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);

            Marshal.Copy(array2, 0, bitmapData.Scan0, num * 4 * num2);
            bitmap.UnlockBits(bitmapData);
            return(bitmap);
        }