예제 #1
0
 public void WriteTo(Stream stream)
 {
     using (SubStream tmpstream = new SubStream(new MemoryStream()))
     {
         WriteTo(tmpstream);
         tmpstream.Seek(0, SeekOrigin.Begin);
         tmpstream.CopyTo(stream);
     }
 }
예제 #2
0
 protected List<int> ProcessInt32List(SubStream data)
 {
     List<int> vals = new List<int>();
     int nents = data.ReadInt32();
     for (int i = 0; i < nents; i++)
     {
         vals.Add(data.ReadInt32());
     }
     return vals;
 }
예제 #3
0
        protected Dictionary<string, dynamic> ProcessKeyValuePairs(SubStream data, List<string> path)
        {
            Dictionary<string, object> ret = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);

            while (true)
            {
                string key = data.ReadString();

                if (key == "")
                {
                    return ret;
                }

                List<string> _path = path.ToList();
                _path.Add(key);
                dynamic val = ProcessValue(data, _path);
                ret[key] = val;
            }
        }
예제 #4
0
 protected void WriteInt32List(SubStream outstream, List<int> data)
 {
     outstream.WriteInt32(data.Count);
     foreach (int val in data)
     {
         outstream.WriteInt32(val);
     }
 }
예제 #5
0
 protected dynamic ProcessValue(SubStream data, List<string> path)
 {
     int type = data.ReadByte();
     switch ((char)type)
     {
         case 'T': return ProcessKeyValuePairs(data, path);
         case 'I': return ProcessInt32List(data);
         case 'i': return data.ReadInt32();
         case 'F': return ProcessSingleList(data);
         case 'f': return data.ReadSingle();
         case 'S': return ProcessStringList(data);
         case 's': return data.ReadString();
         case 'M': return ProcessList(data, path);
         case '.': return null;
         case 'R': return ProcessRawBinary(data);
         default:
             throw new NotImplementedException(String.Format("Unknown type {0} ({0:X8}) at position {1}", (char)type, data.Position));
     }
 }
예제 #6
0
 public RS5Environment(SubStream data)
 {
     data.Position = 0;
     Data = ProcessValue(data, new List<string>());
 }
예제 #7
0
 public void WriteTo(SubStream stream)
 {
     WriteValue(stream, this.Data);
 }
예제 #8
0
        protected static Bitmap GetBitmapFromDDS_DXT1(SubStream data, int offset, int width, int height, out bool hasalpha)
        {
            Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            byte[] bmpraw = new byte[width * height * 4];
            hasalpha = false;

            for (int y = 0; y < height; y += 4)
            {
                for (int x = 0; x < width; x += 4)
                {
                    Color[,] colourdata = GetDXT1ColourBlock(data, offset, false);
                    for (int v = 0; v < 4; v++)
                    {
                        for (int u = 0; u < 4; u++)
                        {
                            if (x + u < width && y + v < height)
                            {
                                int i = ((y + v) * width + (x + u)) * 4;
                                bmpraw[i] = colourdata[u, v].B;
                                bmpraw[i + 1] = colourdata[u, v].G;
                                bmpraw[i + 2] = colourdata[u, v].R;
                                bmpraw[i + 3] = colourdata[u, v].A;
                                hasalpha |= colourdata[u, v].A != 255;
                            }
                        }
                    }
                    offset += 8;
                }
            }

            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            for (int y = 0; y < height; y++)
            {
                Marshal.Copy(bmpraw, y * width * 4, bmpdata.Scan0 + y * bmpdata.Stride, width * 4);
            }

            bmp.UnlockBits(bmpdata);

            return bmp;
        }
예제 #9
0
 protected void WriteRawBinary(SubStream outstream, byte[] data)
 {
     outstream.WriteInt32(data.Length);
     outstream.WriteBytes(data.Length, data);
 }
예제 #10
0
 protected void WriteStringList(SubStream outstream, List<string> data)
 {
     outstream.WriteInt32(data.Count);
     foreach (string val in data)
     {
         outstream.WriteString(val);
     }
 }
예제 #11
0
 protected RS5Chunk(SubStream data, long offset)
     : this(GetChunkData(data, offset))
 {
 }
예제 #12
0
        private static SubStream GetChunkData(SubStream data, long offset)
        {
            int totalsize = (((12 + (int)data.GetByte(offset + 6) + 7) & -8) + data.GetInt32(offset + 8) + 7) & -8;

            return(new SubStream(data, offset, totalsize));
        }
예제 #13
0
        public DDSImage(SubStream data)
        {
            if (data.GetByte(0) == 'D' && data.GetByte(1) == 'D' && data.GetByte(2) == 'S' && data.GetByte(3) == ' ')
            {
                Height = data.GetInt32(12);
                Width = data.GetInt32(16);
                Depth = data.GetInt32(24);
                Flags = data.GetUInt32(8);
                Pitch = data.GetInt32(20);
                FourCC = Encoding.ASCII.GetString(data.GetBytes(84, 4));
                RGBBitCount = data.GetInt32(88);
                RedMask = data.GetUInt32(92);
                GreenMask = data.GetUInt32(96);
                BlueMask = data.GetUInt32(100);
                AlphaMask = data.GetUInt32(104);
                Data = data;
                ImageOffset = 128;

                if (Depth == 0)
                {
                    Depth = 1;
                }

                if ((Flags & 8) == 0)
                {
                    Pitch = Width * RGBBitCount / 8;
                }

                IsARGB32 = (FourCC == "DXT1" || FourCC == "DXT2" || FourCC == "DXT3" || FourCC == "DXT4" || FourCC == "DXT5" || FourCC == "\0\0\0\0");
                IntensityFactor = 1.0;

                try
                {
                    FailureReason = null;
                    switch (FourCC)
                    {
                        case "DXT1":
                            Bitmap = GetBitmapFromDDS_DXT1(Data, ImageOffset, Width, Height, out HasAlpha);
                            break;
                        case "DXT2":
                            Bitmap = GetBitmapFromDDS_DXT3(Data, ImageOffset, Width, Height, true, out HasAlpha);
                            break;
                        case "DXT3":
                            Bitmap = GetBitmapFromDDS_DXT3(Data, ImageOffset, Width, Height, false, out HasAlpha);
                            break;
                        case "DXT4":
                            Bitmap = GetBitmapFromDDS_DXT5(Data, ImageOffset, Width, Height, true, out HasAlpha);
                            break;
                        case "DXT5":
                            Bitmap = GetBitmapFromDDS_DXT5(Data, ImageOffset, Width, Height, false, out HasAlpha);
                            break;
                        case "\0\0\0\0":
                            Bitmap = GetBitmapFromDDS_RAW(Data, ImageOffset, Width, Height, Pitch, RGBBitCount, RedMask, GreenMask, BlueMask, AlphaMask, out HasAlpha, out IsARGB32);
                            break;
                        case "q\0\0\0":
                            Bitmap = GetBitmapFromDDS_ARGB16F(Data, ImageOffset, Width, Height, out HasAlpha, out IntensityFactor);
                            break;
                        default:
                            Bitmap = null;
                            FailureReason = String.Format("Unknown DDS FourCC {0:X2}:{1:X2}:{2:X2}:{3:X2}", Data.GetByte(84), Data.GetByte(85), Data.GetByte(86), Data.GetByte(87));
                            break;
                    }
                }
                catch (Exception ex)
                {
                    Bitmap = null;
                    FailureReason = ex.Message;
                }
            }
            else
            {
                throw new NotImplementedException(String.Format("Unknown file format {0:X2}:{1:X2}:{2:X2}:{3:X2}", data.GetByte(0), data.GetByte(1), data.GetByte(2), data.GetByte(3)));
            }
        }
예제 #14
0
        protected static Color[,] GetDXT1ColourBlock(SubStream data, int offset, bool IsDXT3)
        {
            ushort c0v = data.GetUInt16(offset);
            ushort c1v = data.GetUInt16(offset + 2);
            Color[] c = new Color[4];

            c[0] = Color.FromArgb(0xFF, (c0v >> 8) & 0xF8, (c0v >> 3) & 0xFC, (c0v << 3) & 0xF8);
            c[1] = Color.FromArgb(0xFF, (c1v >> 8) & 0xF8, (c1v >> 3) & 0xFC, (c1v << 3) & 0xF8);

            if (c0v > c1v || IsDXT3)
            {
                c[2] = Color.FromArgb(0xFF, ((int)c[0].R * 2 + c[1].R + 1) / 3, ((int)c[0].G * 2 + c[1].G + 1) / 3, ((int)c[0].B * 2 + c[1].B + 1) / 3);
                c[3] = Color.FromArgb(0xFF, ((int)c[1].R * 2 + c[0].R + 1) / 3, ((int)c[1].G * 2 + c[0].G + 1) / 3, ((int)c[1].B * 2 + c[0].B + 1) / 3);
            }
            else
            {
                c[2] = Color.FromArgb(0xFF, ((int)c[0].R + c[1].R) / 2, ((int)c[0].G + c[1].G) / 2, ((int)c[0].B + c[1].B) / 2);
                c[3] = Color.FromArgb(0, 0, 0, 0);
            }

            ulong lookup = data.GetUInt32(offset + 4);
            Color[,] output = new Color[4, 4];

            for (int i = 0; i < 16; i++)
            {
                output[i % 4, i / 4] = c[(lookup >> (i * 2)) & 3];
            }

            return output;
        }
예제 #15
0
        protected static Bitmap GetBitmapFromDDS_RAW(SubStream Data, int Offset, int Width, int Height, int Pitch, int RGBBitCount, uint RedMask, uint GreenMask, uint BlueMask, uint AlphaMask, out bool hasalpha, out bool isargb32)
        {
            uint RGBBitMask = (uint)((1L << RGBBitCount) - 1);
            int RedShift = MostSignificantBitPosition(RedMask) - 7;
            int GreenShift = MostSignificantBitPosition(GreenMask) - 7;
            int BlueShift = MostSignificantBitPosition(BlueMask) - 7;
            int AlphaShift = MostSignificantBitPosition(AlphaMask) - 7;
            int RedBits = RedMask == 0 ? 0 : MostSignificantBitPosition(RedMask) - LeastSignificantBitPosition(RedMask) + 1;
            int GreenBits = GreenMask == 0 ? 0 : MostSignificantBitPosition(GreenMask) - LeastSignificantBitPosition(GreenMask) + 1;
            int BlueBits = BlueMask == 0 ? 0 : MostSignificantBitPosition(BlueMask) - LeastSignificantBitPosition(BlueMask) + 1;
            int AlphaBits = AlphaMask == 0 ? 0 : MostSignificantBitPosition(AlphaMask) - LeastSignificantBitPosition(AlphaMask) + 1;
            hasalpha = false;
            isargb32 = RedBits <= 8 && GreenBits <= 8 && BlueBits <= 8 && AlphaBits <= 8;

            Bitmap bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
            byte[] bmpraw = new byte[Width * Height * 4];

            for (int y = 0; y < Height; y++)
            {
                for (int x = 0; x < Width; x++)
                {
                    int w = (4 - ((RGBBitCount + 7) / 8));
                    int bitpos = y * Pitch * 8 + x * RGBBitCount;
                    int i = ((bitpos + RGBBitCount - 1) / 8 - 7);
                    int b = (bitpos - i * 8);
                    int o = (y * Width + x) * 4;
                    uint v = (uint)((Data.GetUInt64(i + 128) >> b) & RGBBitMask);
                    bmpraw[o + 0] = GetMaskShiftVal(v, BlueMask, BlueShift, 0x00);
                    bmpraw[o + 1] = GetMaskShiftVal(v, GreenMask, GreenShift, 0x00);
                    bmpraw[o + 2] = GetMaskShiftVal(v, RedMask, RedShift, 0x00);
                    bmpraw[o + 3] = GetMaskShiftVal(v, AlphaMask, AlphaShift, 0xFF);
                    hasalpha = bmpraw[o + 3] != 255;
                }
            }
            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            for (int y = 0; y < Height; y++)
            {
                Marshal.Copy(bmpraw, y * Width * 4, bmpdata.Scan0 + y * bmpdata.Stride, Width * 4);
            }

            bmp.UnlockBits(bmpdata);

            return bmp;
        }
예제 #16
0
        protected static Bitmap GetBitmapFromDDS_DXT5(SubStream data, int offset, int width, int height, bool IsDXT4, out bool hasalpha)
        {
            Bitmap bmp = new Bitmap(width, height, IsDXT4 ? PixelFormat.Format32bppPArgb : PixelFormat.Format32bppArgb);
            byte[] bmpraw = new byte[width * height * 4];
            hasalpha = false;

            for (int y = 0; y < height; y += 4)
            {
                for (int x = 0; x < width; x += 4)
                {
                    byte[] a = new byte[8];
                    a[0] = data.GetByte(offset);
                    a[1] = data.GetByte(offset + 1);

                    if (a[0] > a[1])
                    {
                        a[2] = (byte)(((int)a[0] * 6 + a[1] * 1 + 3) / 7);
                        a[3] = (byte)(((int)a[0] * 5 + a[1] * 2 + 3) / 7);
                        a[4] = (byte)(((int)a[0] * 4 + a[1] * 3 + 3) / 7);
                        a[5] = (byte)(((int)a[0] * 3 + a[1] * 4 + 3) / 7);
                        a[6] = (byte)(((int)a[0] * 2 + a[1] * 5 + 3) / 7);
                        a[7] = (byte)(((int)a[0] * 1 + a[1] * 6 + 3) / 7);
                    }
                    else
                    {
                        a[2] = (byte)(((int)a[0] * 4 + a[1] * 1 + 2) / 5);
                        a[3] = (byte)(((int)a[0] * 3 + a[1] * 2 + 2) / 5);
                        a[4] = (byte)(((int)a[0] * 2 + a[1] * 3 + 2) / 5);
                        a[5] = (byte)(((int)a[0] * 1 + a[1] * 4 + 2) / 5);
                        a[6] = 0x00;
                        a[7] = 0xFF;
                    }

                    ulong alphasel = data.GetUInt64(offset) >> 16;
                    byte[,] alphadata = new byte[4, 4];

                    for (int i = 0; i < 16; i++)
                    {
                        alphadata[i % 4, i / 4] = a[(alphasel >> (i * 3)) & 7];
                    }

                    Color[,] colourdata = GetDXT1ColourBlock(data, offset + 8, true);

                    for (int v = 0; v < 4; v++)
                    {
                        for (int u = 0; u < 4; u++)
                        {
                            if (x + u < width && y + v < height)
                            {
                                int i = ((y + v) * width + (x + u)) * 4;
                                bmpraw[i] = colourdata[u, v].B;
                                bmpraw[i + 1] = colourdata[u, v].G;
                                bmpraw[i + 2] = colourdata[u, v].R;
                                bmpraw[i + 3] = alphadata[u, v];
                                hasalpha |= alphadata[u, v] != 255;
                            }
                        }
                    }

                    offset += 16;
                }
            }

            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, IsDXT4 ? PixelFormat.Format32bppPArgb : PixelFormat.Format32bppArgb);

            for (int y = 0; y < height; y++)
            {
                Marshal.Copy(bmpraw, y * width * 4, bmpdata.Scan0 + y * bmpdata.Stride, width * 4);
            }

            bmp.UnlockBits(bmpdata);

            return bmp;
        }
예제 #17
0
        protected static Bitmap GetBitmapFromDDS_DXT3(SubStream data, int offset, int width, int height, bool IsDXT2, out bool hasalpha)
        {
            Bitmap bmp = new Bitmap(width, height, IsDXT2 ? PixelFormat.Format32bppPArgb : PixelFormat.Format32bppArgb);
            byte[] bmpraw = new byte[width * height * 4];
            hasalpha = false;

            for (int y = 0; y < height; y += 4)
            {
                for (int x = 0; x < width; x += 4)
                {
                    ulong alpharaw = data.GetUInt64(offset);
                    byte[,] alphadata = new byte[4, 4];

                    for (int i = 0; i < 16; i++)
                    {
                        alphadata[i % 4, i / 4] = (byte)(((alpharaw >> (i * 4)) & 0x0F) * 0x11);
                    }

                    Color[,] colourdata = GetDXT1ColourBlock(data, offset + 8, true);

                    for (int v = 0; v < 4; v++)
                    {
                        for (int u = 0; u < 4; u++)
                        {
                            if (x + u < width && y + v < height)
                            {
                                int i = ((y + v) * width + (x + u)) * 4;
                                bmpraw[i] = colourdata[u, v].B;
                                bmpraw[i + 1] = colourdata[u, v].G;
                                bmpraw[i + 2] = colourdata[u, v].R;
                                bmpraw[i + 3] = alphadata[u, v];
                                hasalpha |= alphadata[u, v] != 255;
                            }
                        }
                    }

                    offset += 16;
                }
            }

            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, IsDXT2 ? PixelFormat.Format32bppPArgb : PixelFormat.Format32bppArgb);

            for (int y = 0; y < height; y++)
            {
                Marshal.Copy(bmpraw, y * width * 4, bmpdata.Scan0 + y * bmpdata.Stride, width * 4);
            }

            bmp.UnlockBits(bmpdata);

            return bmp;
        }
예제 #18
0
        protected void WriteKeyValuePairs(SubStream outstream, IDictionary data)
        {
            foreach (DictionaryEntry de in data)
            {
                outstream.WriteString(de.Key.ToString());
                WriteValue(outstream, de.Value);
            }

            outstream.WriteByte(0);
        }
예제 #19
0
 protected RS5Chunk(SubStream chunkdata)
 {
     this.ChunkData = chunkdata;
     this._Data     = new Lazy <SubStream>(() => GetData());
     this._Chunks   = new Lazy <Dictionary <string, RS5Chunk> >(() => GetChunks());
 }
예제 #20
0
 protected void WriteList(SubStream outstream, IList data)
 {
     outstream.WriteInt32(data.Count);
     foreach (object val in data)
     {
         WriteValue(outstream, val);
     }
 }
예제 #21
0
        protected static Bitmap GetBitmapFromDDS_ARGB16F(SubStream data, int offset, int width, int height, out bool hasalpha, out double intensity)
        {
            float[] fdata       = new float[width * height * 4];
            double  maxval      = Double.NegativeInfinity;
            double  minval      = Double.PositiveInfinity;
            double  maxalpha    = Double.NegativeInfinity;
            double  minalpha    = Double.PositiveInfinity;
            double  alphaoffset = 0.0;

            hasalpha = false;

            for (int i = 0; i < width * height * 4; i += 4)
            {
                for (int j = 0; j < 4; j++)
                {
                    fdata[i + j] = HalfToFloat(data.GetUInt16(offset + (i + j) * 2));
                }

                for (int j = 0; j < 3; j++)
                {
                    if (fdata[i + j] > maxval)
                    {
                        maxval = fdata[i + j];
                    }
                    if (fdata[i + j] < minval)
                    {
                        minval = fdata[i + j];
                    }
                }

                if (fdata[i + 3] > maxalpha)
                {
                    maxalpha = fdata[i + 3];
                }
                if (fdata[i + 3] < minalpha)
                {
                    minalpha = fdata[i + 3];
                }
            }

            if (minval < 0 || minalpha < 0)
            {
                throw new NotImplementedException("ARGB16F with negative values not supported");
            }

            if (maxval == 0)
            {
                maxval = 1.0;
            }

            if (maxalpha == 0)
            {
                maxalpha = 1.0;
                //alphaoffset = 1.0;
            }

            intensity = maxval;

            Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);

            byte[] bmpraw = new byte[width * height * 4];

            for (int i = 0; i < width * height * 4; i += 4)
            {
                bmpraw[i + 0] = (byte)(fdata[i + 2] * 255 / maxval);
                bmpraw[i + 1] = (byte)(fdata[i + 1] * 255 / maxval);
                bmpraw[i + 2] = (byte)(fdata[i + 0] * 255 / maxval);
                bmpraw[i + 3] = (byte)((fdata[i + 3] + alphaoffset) * 255 / maxalpha);
                hasalpha     |= bmpraw[i + 3] != 255;
            }

            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            for (int y = 0; y < height; y++)
            {
                Marshal.Copy(bmpraw, y * width * 4, bmpdata.Scan0 + y * bmpdata.Stride, width * 4);
            }

            bmp.UnlockBits(bmpdata);

            return(bmp);
        }
예제 #22
0
 protected void WriteSingleList(SubStream outstream, List<float> data)
 {
     outstream.WriteInt32(data.Count);
     foreach (float val in data)
     {
         outstream.WriteSingle(val);
     }
 }
예제 #23
0
 protected List<dynamic> ProcessList(SubStream data, List<string> path)
 {
     List<object> vals = new List<object>();
     int nents = data.ReadInt32();
     for (int i = 0; i < nents; i++)
     {
         List<string> _path = path.ToList();
         _path.Add("");
         vals.Add(ProcessValue(data, _path));
     }
     return vals;
 }
예제 #24
0
 protected void WriteValue(SubStream outstream, object data)
 {
     if (data == null)
     {
         outstream.WriteByte((byte)'.');
     }
     else if (data is string)
     {
         outstream.WriteByte((byte)'s');
         outstream.WriteString((string)data);
     }
     else if (data is float)
     {
         outstream.WriteByte((byte)'f');
         outstream.WriteSingle((float)data);
     }
     else if (data is int)
     {
         outstream.WriteByte((byte)'i');
         outstream.WriteInt32((int)data);
     }
     else if (data is byte[])
     {
         outstream.WriteByte((byte)'R');
         WriteRawBinary(outstream, (byte[])data);
     }
     else if (data is List<string>)
     {
         outstream.WriteByte((byte)'S');
         WriteStringList(outstream, (List<string>)data);
     }
     else if (data is List<float>)
     {
         outstream.WriteByte((byte)'F');
         WriteSingleList(outstream, (List<float>)data);
     }
     else if (data is List<int>)
     {
         outstream.WriteByte((byte)'I');
         WriteInt32List(outstream, (List<int>)data);
     }
     else if (data is IList)
     {
         outstream.WriteByte((byte)'M');
         WriteList(outstream, (IList)data);
     }
     else if (data is IDictionary)
     {
         outstream.WriteByte((byte)'T');
         WriteKeyValuePairs(outstream, (IDictionary)data);
     }
     else
     {
         throw new InvalidOperationException(String.Format("Unable to write value of type {0}", data.GetType().ToString()));
     }
 }
예제 #25
0
        public DDSImage(SubStream data)
        {
            if (data.GetByte(0) == 'D' && data.GetByte(1) == 'D' && data.GetByte(2) == 'S' && data.GetByte(3) == ' ')
            {
                Height      = data.GetInt32(12);
                Width       = data.GetInt32(16);
                Depth       = data.GetInt32(24);
                Flags       = data.GetUInt32(8);
                Pitch       = data.GetInt32(20);
                FourCC      = Encoding.ASCII.GetString(data.GetBytes(84, 4));
                RGBBitCount = data.GetInt32(88);
                RedMask     = data.GetUInt32(92);
                GreenMask   = data.GetUInt32(96);
                BlueMask    = data.GetUInt32(100);
                AlphaMask   = data.GetUInt32(104);
                Data        = data;
                ImageOffset = 128;

                if (Depth == 0)
                {
                    Depth = 1;
                }

                if ((Flags & 8) == 0)
                {
                    Pitch = Width * RGBBitCount / 8;
                }

                IsARGB32        = (FourCC == "DXT1" || FourCC == "DXT2" || FourCC == "DXT3" || FourCC == "DXT4" || FourCC == "DXT5" || FourCC == "\0\0\0\0");
                IntensityFactor = 1.0;

                try
                {
                    FailureReason = null;
                    switch (FourCC)
                    {
                    case "DXT1":
                        Bitmap = GetBitmapFromDDS_DXT1(Data, ImageOffset, Width, Height, out HasAlpha);
                        break;

                    case "DXT2":
                        Bitmap = GetBitmapFromDDS_DXT3(Data, ImageOffset, Width, Height, true, out HasAlpha);
                        break;

                    case "DXT3":
                        Bitmap = GetBitmapFromDDS_DXT3(Data, ImageOffset, Width, Height, false, out HasAlpha);
                        break;

                    case "DXT4":
                        Bitmap = GetBitmapFromDDS_DXT5(Data, ImageOffset, Width, Height, true, out HasAlpha);
                        break;

                    case "DXT5":
                        Bitmap = GetBitmapFromDDS_DXT5(Data, ImageOffset, Width, Height, false, out HasAlpha);
                        break;

                    case "\0\0\0\0":
                        Bitmap = GetBitmapFromDDS_RAW(Data, ImageOffset, Width, Height, Pitch, RGBBitCount, RedMask, GreenMask, BlueMask, AlphaMask, out HasAlpha, out IsARGB32);
                        break;

                    case "q\0\0\0":
                        Bitmap = GetBitmapFromDDS_ARGB16F(Data, ImageOffset, Width, Height, out HasAlpha, out IntensityFactor);
                        break;

                    default:
                        Bitmap        = null;
                        FailureReason = String.Format("Unknown DDS FourCC {0:X2}:{1:X2}:{2:X2}:{3:X2}", Data.GetByte(84), Data.GetByte(85), Data.GetByte(86), Data.GetByte(87));
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Bitmap        = null;
                    FailureReason = ex.Message;
                }
            }
            else
            {
                throw new NotImplementedException(String.Format("Unknown file format {0:X2}:{1:X2}:{2:X2}:{3:X2}", data.GetByte(0), data.GetByte(1), data.GetByte(2), data.GetByte(3)));
            }
        }
예제 #26
0
 private static SubStream GetChunkData(SubStream data, long offset)
 {
     int totalsize = (((12 + (int)data.GetByte(offset + 6) + 7) & -8) + data.GetInt32(offset + 8) + 7) & -8;
     return new SubStream(data, offset, totalsize);
 }
예제 #27
0
        protected static Bitmap GetBitmapFromDDS_ARGB16F(SubStream data, int offset, int width, int height, out bool hasalpha, out double intensity)
        {
            float[] fdata = new float[width * height * 4];
            double maxval = Double.NegativeInfinity;
            double minval = Double.PositiveInfinity;
            double maxalpha = Double.NegativeInfinity;
            double minalpha = Double.PositiveInfinity;
            double alphaoffset = 0.0;
            hasalpha = false;

            for (int i = 0; i < width * height * 4; i+=4)
            {
                for (int j = 0; j < 4; j++)
                {
                    fdata[i + j] = HalfToFloat(data.GetUInt16(offset + (i + j) * 2));
                }

                for (int j = 0; j < 3; j++)
                {
                    if (fdata[i + j] > maxval)
                    {
                        maxval = fdata[i + j];
                    }
                    if (fdata[i + j] < minval)
                    {
                        minval = fdata[i + j];
                    }
                }

                if (fdata[i + 3] > maxalpha)
                {
                    maxalpha = fdata[i + 3];
                }
                if (fdata[i + 3] < minalpha)
                {
                    minalpha = fdata[i + 3];
                }
            }

            if (minval < 0 || minalpha < 0)
            {
                throw new NotImplementedException("ARGB16F with negative values not supported");
            }

            if (maxval == 0)
            {
                maxval = 1.0;
            }

            if (maxalpha == 0)
            {
                maxalpha = 1.0;
                //alphaoffset = 1.0;
            }

            intensity = maxval;

            Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            byte[] bmpraw = new byte[width * height * 4];

            for (int i = 0; i < width * height * 4; i += 4)
            {
                bmpraw[i + 0] = (byte)(fdata[i + 2] * 255 / maxval);
                bmpraw[i + 1] = (byte)(fdata[i + 1] * 255 / maxval);
                bmpraw[i + 2] = (byte)(fdata[i + 0] * 255 / maxval);
                bmpraw[i + 3] = (byte)((fdata[i + 3] + alphaoffset) * 255 / maxalpha);
                hasalpha |= bmpraw[i + 3] != 255;
            }

            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            for (int y = 0; y < height; y++)
            {
                Marshal.Copy(bmpraw, y * width * 4, bmpdata.Scan0 + y * bmpdata.Stride, width * 4);
            }

            bmp.UnlockBits(bmpdata);

            return bmp;
        }
예제 #28
0
 protected RS5Chunk(SubStream chunkdata)
 {
     this.ChunkData = chunkdata;
     this._Data = new Lazy<SubStream>(() => GetData());
     this._Chunks = new Lazy<Dictionary<string, RS5Chunk>>(() => GetChunks());
 }
예제 #29
0
 protected RS5Chunk(SubStream data, long offset)
     : this(GetChunkData(data, offset))
 {
 }
예제 #30
0
 protected byte[] ProcessRawBinary(SubStream data)
 {
     List<object> vals = new List<object>();
     int nents = data.ReadInt32();
     byte[] rawdata = data.ReadBytes(nents);
     return rawdata;
 }
예제 #31
0
        protected static Bitmap GetBitmapFromDDS_DXT5(SubStream data, int offset, int width, int height, bool IsDXT4, out bool hasalpha)
        {
            Bitmap bmp = new Bitmap(width, height, IsDXT4 ? PixelFormat.Format32bppPArgb : PixelFormat.Format32bppArgb);

            byte[] bmpraw = new byte[width * height * 4];
            hasalpha = false;

            for (int y = 0; y < height; y += 4)
            {
                for (int x = 0; x < width; x += 4)
                {
                    byte[] a = new byte[8];
                    a[0] = data.GetByte(offset);
                    a[1] = data.GetByte(offset + 1);

                    if (a[0] > a[1])
                    {
                        a[2] = (byte)(((int)a[0] * 6 + a[1] * 1 + 3) / 7);
                        a[3] = (byte)(((int)a[0] * 5 + a[1] * 2 + 3) / 7);
                        a[4] = (byte)(((int)a[0] * 4 + a[1] * 3 + 3) / 7);
                        a[5] = (byte)(((int)a[0] * 3 + a[1] * 4 + 3) / 7);
                        a[6] = (byte)(((int)a[0] * 2 + a[1] * 5 + 3) / 7);
                        a[7] = (byte)(((int)a[0] * 1 + a[1] * 6 + 3) / 7);
                    }
                    else
                    {
                        a[2] = (byte)(((int)a[0] * 4 + a[1] * 1 + 2) / 5);
                        a[3] = (byte)(((int)a[0] * 3 + a[1] * 2 + 2) / 5);
                        a[4] = (byte)(((int)a[0] * 2 + a[1] * 3 + 2) / 5);
                        a[5] = (byte)(((int)a[0] * 1 + a[1] * 4 + 2) / 5);
                        a[6] = 0x00;
                        a[7] = 0xFF;
                    }

                    ulong alphasel = data.GetUInt64(offset) >> 16;
                    byte[,] alphadata = new byte[4, 4];

                    for (int i = 0; i < 16; i++)
                    {
                        alphadata[i % 4, i / 4] = a[(alphasel >> (i * 3)) & 7];
                    }

                    Color[,] colourdata = GetDXT1ColourBlock(data, offset + 8, true);

                    for (int v = 0; v < 4; v++)
                    {
                        for (int u = 0; u < 4; u++)
                        {
                            if (x + u < width && y + v < height)
                            {
                                int i = ((y + v) * width + (x + u)) * 4;
                                bmpraw[i]     = colourdata[u, v].B;
                                bmpraw[i + 1] = colourdata[u, v].G;
                                bmpraw[i + 2] = colourdata[u, v].R;
                                bmpraw[i + 3] = alphadata[u, v];
                                hasalpha     |= alphadata[u, v] != 255;
                            }
                        }
                    }

                    offset += 16;
                }
            }

            BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, IsDXT4 ? PixelFormat.Format32bppPArgb : PixelFormat.Format32bppArgb);

            for (int y = 0; y < height; y++)
            {
                Marshal.Copy(bmpraw, y * width * 4, bmpdata.Scan0 + y * bmpdata.Stride, width * 4);
            }

            bmp.UnlockBits(bmpdata);

            return(bmp);
        }