Beispiel #1
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);
 }
Beispiel #2
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));
        }
Beispiel #3
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)));
            }
        }
Beispiel #4
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;
        }
Beispiel #5
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)));
            }
        }
Beispiel #6
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);
        }