Example #1
0
        public DDSImage(CR2WBinaryReader reader, DDSStruct header, bool alpha)
        {
            Utils.PixelFormat pixelFormat = Utils.PixelFormat.UNKNOWN;
            byte[]            data        = null;

            if (header.depth == 0)
            {
                header.depth = 1;
            }

            _isValid = true;
            _alpha   = alpha;

            uint blocksize = 0;

            pixelFormat = GetFormat(header, ref blocksize);
            if (pixelFormat == Utils.PixelFormat.UNKNOWN)
            {
                throw new InvalidFileHeaderException();
            }

            data = ReadData(reader, header);
            if (data != null)
            {
                byte[] rawData = DDSDecompressor.Expand(header, data, pixelFormat);
                _bitmap = CreateBitmap((int)header.width, (int)header.height, rawData);
            }
        }
Example #2
0
        /// <summary>
        /// Checks for the most common issues and provides an easier to read error message
        /// </summary>
        /// <param name="structA"></param>
        /// <param name="structB"></param>
        private void handleKnownDDSFields(DDSStruct structA, DDSStruct structB)
        {
            var errors = new List <string>();

            // If any dw flag is four CC, try to be more precise
            string formatA = structA.Header.ddspf.dwFlags == DDSPixelFormat.EPixelFlags.DDPF_FOURCC
                ? structA.Header.ddspf.dwFourCCString.ToString()
                : structA.Header.ddspf.dwFlags.ToString();

            string formatB = structB.Header.ddspf.dwFlags == DDSPixelFormat.EPixelFlags.DDPF_FOURCC
                ? structB.Header.ddspf.dwFourCCString.ToString()
                : structB.Header.ddspf.dwFlags.ToString();


            if (formatA != formatB)
            {
                errors.Add($"Format different: {formatA} not equal to {formatB}");
            }


            if (structA.Header.DwMipMapCount != structB.Header.DwMipMapCount)
            {
                errors.Add($"Mips different: {structA.Header.DwMipMapCount} not equal to {structB.Header.DwMipMapCount}");
            }

            if (errors.Any())
            {
                throw new Exception($"Differences found:{Environment.NewLine}{string.Join(Environment.NewLine, errors)}");
            }
        }
Example #3
0
        public override void ParseBytes(CR2WBinaryReader br, uint size)
        {
            base.ParseClass(br, this);

            var zero        = br.ReadUInt32();
            var mipCount    = br.ReadUInt32();
            var width       = br.ReadUInt32();
            var height      = br.ReadUInt32();
            var unknown5    = br.ReadUInt32();
            var sizeorpitch = br.ReadUInt32();

            //var unknown7    = br.ReadUInt32();

            Console.WriteLine("zero        {0}", zero);
            Console.WriteLine("mipCount    {0}", mipCount);
            Console.WriteLine("width       {0}", width);
            Console.WriteLine("height      {0}", height);
            Console.WriteLine("unknown5    {0}", unknown5);
            Console.WriteLine("sizeorpitch {0}", sizeorpitch);
            //Console.WriteLine("unknown7    {0}", sizeorpitch);

            var ddsheader = new DDSStruct
            {
                size        = 124,
                flags       = 659463,
                width       = width,
                height      = height,
                sizeorpitch = sizeorpitch,
                depth       = 1,
                mipmapcount = 1,
                reserved    = new uint[10],
            };

            ddsheader.ddscaps.caps1      = 4096;
            ddsheader.pixelformat.size   = 32;
            ddsheader.pixelformat.flags  = 5;
            ddsheader.pixelformat.fourcc = DDSHelper.FOURCC_DXT1;

            var dds = new DDSImage(br, ddsheader, true);

            Form form = new Form
            {
                Text       = LinkageName,
                ClientSize = new Size((int)width, (int)height),
            };
            PictureBox pictureBox = new PictureBox
            {
                Image  = dds.BitmapImage,
                Width  = (int)width,
                Height = (int)height
            };

            form.Controls.Add(pictureBox);
            var t = new Task(() =>
            {
                Application.Run(form);
            });

            t.Start();
        }
Example #4
0
        private byte[] ReadData(BinaryReader reader, DDSStruct header)
        {
            byte[] compdata = null;
            uint   compsize = 0;

            if ((header.flags & Helper.DDSD_LINEARSIZE) > 1)
            {
                compdata = reader.ReadBytes((int)header.sizeorpitch);
                compsize = (uint)compdata.Length;
            }
            else
            {
                uint bps = header.width * header.pixelformat.rgbbitcount / 8;
                compsize = bps * header.height * header.depth;
                compdata = new byte[compsize];

                MemoryStream mem = new MemoryStream((int)compsize);

                byte[] temp;
                for (int z = 0; z < header.depth; z++)
                {
                    for (int y = 0; y < header.height; y++)
                    {
                        temp = reader.ReadBytes((int)bps);
                        mem.Write(temp, 0, temp.Length);
                    }
                }
                mem.Seek(0, SeekOrigin.Begin);

                mem.Read(compdata, 0, compdata.Length);
                mem.Close();
            }

            return(compdata);
        }
    public static byte[] DecompressLum(DDSStruct header, byte[] data, PixelFormat pixelFormat)
    {
        // allocate bitmap
        int bpp         = (int)(PixelFormatToBpp(pixelFormat, header.pixelformat.rgbbitcount));
        int bps         = (int)(header.width * bpp * PixelFormatToBpc(pixelFormat));
        int sizeofplane = (int)(bps * header.height);
        int width       = (int)header.width;
        int height      = (int)header.height;
        int depth       = (int)header.depth;

        byte[] rawData = new byte[depth * sizeofplane + height * bps + width * bpp];

        int lShift1 = 0; int lMul = 0; int lShift2 = 0;

        ComputeMaskParams(header.pixelformat.rbitmask, ref lShift1, ref lMul, ref lShift2);

        int offset = 0;
        int pixnum = width * height * depth;
        int temp   = 0;

        while (pixnum-- > 0)
        {
            byte px = data[temp++];
            rawData[offset + 0] = (byte)(((px >> lShift1) * lMul) >> lShift2);
            rawData[offset + 1] = (byte)(((px >> lShift1) * lMul) >> lShift2);
            rawData[offset + 2] = (byte)(((px >> lShift1) * lMul) >> lShift2);
            rawData[offset + 3] = (byte)(((px >> lShift1) * lMul) >> lShift2);
            offset += 4;
        }
        return(rawData);
    }
Example #6
0
 public static void PrintHeader(DDSStruct header)
 {
     Console.WriteLine("header.");
     Console.WriteLine("\tsize             {0}", header.size);
     Console.WriteLine("\tflags            {0}", header.flags);
     Console.WriteLine("\twidth            {0}", header.width);
     Console.WriteLine("\theight           {0}", header.height);
     Console.WriteLine("\tsizeorpitch      {0}", header.sizeorpitch);
     Console.WriteLine("\tdepth            {0}", header.depth);
     Console.WriteLine("\tmipmapcount      {0}", header.mipmapcount);
     Console.WriteLine("\talphabitdepth    {0}", header.alphabitdepth);
     for (int i = 0; i < header.reserved.Length; i++)
     {
         Console.WriteLine("\treserved[{0}]      {1}", i, header.reserved[i]);
     }
     Console.WriteLine("header.pixelformat");
     Console.WriteLine("\tsize             {0}", header.pixelformat.size);
     Console.WriteLine("\tflags            {0}", header.pixelformat.flags);
     Console.WriteLine("\tfourcc           {0}", header.pixelformat.fourcc);
     Console.WriteLine("\trgbbitcount      {0}", header.pixelformat.rgbbitcount);
     Console.WriteLine("\trbitmask         {0}", header.pixelformat.rbitmask);
     Console.WriteLine("\tgbitmask         {0}", header.pixelformat.gbitmask);
     Console.WriteLine("\tbbitmask         {0}", header.pixelformat.bbitmask);
     Console.WriteLine("\talphabitmask     {0}", header.pixelformat.alphabitmask);
     Console.WriteLine("header.ddscaps");
     Console.WriteLine("\tcaps1            {0}", header.ddscaps.caps1);
     Console.WriteLine("\tcaps2            {0}", header.ddscaps.caps2);
     Console.WriteLine("\tcaps3            {0}", header.ddscaps.caps3);
     Console.WriteLine("\tcaps4            {0}", header.ddscaps.caps4);
     Console.WriteLine();
 }
Example #7
0
        private void Parse(BinaryReader reader)
        {
            DDSStruct header = new DDSStruct();

            Utils.PixelFormat pixelFormat = Utils.PixelFormat.UNKNOWN;
            byte[]            data        = null;

            if (ReadHeader(reader, ref header))
            {
                _isValid = true;
                // patches for stuff
                if (header.depth == 0)
                {
                    header.depth = 1;
                }

                uint blocksize = 0;
                pixelFormat = GetFormat(header, ref blocksize);
                if (pixelFormat == Utils.PixelFormat.UNKNOWN)
                {
                    throw new InvalidFileHeaderException();
                }

                data = ReadData(reader, header);
                if (data != null)
                {
                    byte[] rawData = Decompressor.Expand(header, data, pixelFormat);
                    _bitmap = CreateBitmap((int)header.width, (int)header.height, rawData);
                }
            }
        }
Example #8
0
            public static DDSStruct Create(BinaryReader reader)
            {
                DDSStruct header = new DDSStruct();

                if (ReadHeader(reader, ref header))
                {
                    return(header);
                }
                throw new System.Exception("DDS header is invalid.");
            }
Example #9
0
        private static unsafe byte[] DecompressRGBA(DDSStruct header, byte[] data, DDSPixelFormat pixelFormat)
        {
            // allocate bitmap
            int bpp         = (int)(DDSHelper.PixelFormatToBpp(pixelFormat, header.pixelformat.rgbbitcount));
            int bps         = (int)(header.width * bpp * DDSHelper.PixelFormatToBpc(pixelFormat));
            int sizeofplane = (int)(bps * header.height);
            int width       = (int)header.width;
            int height      = (int)header.height;
            int depth       = (int)header.depth;

            byte[] rawData = new byte[depth * sizeofplane + height * bps + width * bpp];

            uint valMask = (uint)((header.pixelformat.rgbbitcount == 32) ? ~0 : (1 << (int)header.pixelformat.rgbbitcount) - 1);
            // Funny x86s, make 1 << 32 == 1
            uint pixSize = (header.pixelformat.rgbbitcount + 7) / 8;
            int  rShift1 = 0; int rMul = 0; int rShift2 = 0;

            DDSHelper.ComputeMaskParams(header.pixelformat.rbitmask, ref rShift1, ref rMul, ref rShift2);
            int gShift1 = 0; int gMul = 0; int gShift2 = 0;

            DDSHelper.ComputeMaskParams(header.pixelformat.gbitmask, ref gShift1, ref gMul, ref gShift2);
            int bShift1 = 0; int bMul = 0; int bShift2 = 0;

            DDSHelper.ComputeMaskParams(header.pixelformat.bbitmask, ref bShift1, ref bMul, ref bShift2);
            int aShift1 = 0; int aMul = 0; int aShift2 = 0;

            DDSHelper.ComputeMaskParams(header.pixelformat.alphabitmask, ref aShift1, ref aMul, ref aShift2);

            int offset = 0;
            int pixnum = width * height * depth;

            fixed(byte *bytePtr = data)
            {
                byte *temp = bytePtr;

                while (pixnum-- > 0)
                {
                    uint px = *((uint *)temp) & valMask;
                    temp += pixSize;
                    uint pxc = px & header.pixelformat.rbitmask;
                    rawData[offset + 0] = (byte)(((pxc >> rShift1) * rMul) >> rShift2);
                    pxc = px & header.pixelformat.gbitmask;
                    rawData[offset + 1] = (byte)(((pxc >> gShift1) * gMul) >> gShift2);
                    pxc = px & header.pixelformat.bbitmask;
                    rawData[offset + 2] = (byte)(((pxc >> bShift1) * bMul) >> bShift2);
                    pxc = px & header.pixelformat.alphabitmask;
                    rawData[offset + 3] = (byte)(((pxc >> aShift1) * aMul) >> aShift2);
                    offset += 4;
                }
            }

            return(rawData);
        }
Example #10
0
        private static byte[] DecompressDXT4(DDSStruct header, byte[] data, DDSPixelFormat pixelFormat)
        {
            // allocate bitmap
            int width  = (int)header.width;
            int height = (int)header.height;
            int depth  = (int)header.depth;

            // Can do color & alpha same as dxt5, but color is pre-multiplied
            // so the result will be wrong unless corrected.
            byte[] rawData = DecompressDXT5(header, data, pixelFormat);
            DDSHelper.CorrectPremult((uint)(width * height * depth), ref rawData);

            return(rawData);
        }
Example #11
0
        private bool ReadHeader(BinaryReader reader, ref DDSStruct header)
        {
            byte[] signature = reader.ReadBytes(4);
            if (!(signature[0] == 'D' && signature[1] == 'D' && signature[2] == 'S' && signature[3] == ' '))
            {
                return(false);
            }

            header.size = reader.ReadUInt32();
            if (header.size != 124)
            {
                return(false);
            }

            //convert the data
            header.flags         = reader.ReadUInt32();
            header.height        = reader.ReadUInt32();
            header.width         = reader.ReadUInt32();
            header.sizeorpitch   = reader.ReadUInt32();
            header.depth         = reader.ReadUInt32();
            header.mipmapcount   = reader.ReadUInt32();
            header.alphabitdepth = reader.ReadUInt32();

            header.reserved = new uint[10];
            for (int i = 0; i < 10; i++)
            {
                header.reserved[i] = reader.ReadUInt32();
            }

            //pixelfromat
            header.pixelformat.size         = reader.ReadUInt32();
            header.pixelformat.flags        = reader.ReadUInt32();
            header.pixelformat.fourcc       = reader.ReadUInt32();
            header.pixelformat.rgbbitcount  = reader.ReadUInt32();
            header.pixelformat.rbitmask     = reader.ReadUInt32();
            header.pixelformat.gbitmask     = reader.ReadUInt32();
            header.pixelformat.bbitmask     = reader.ReadUInt32();
            header.pixelformat.alphabitmask = reader.ReadUInt32();

            //caps
            header.ddscaps.caps1 = reader.ReadUInt32();
            header.ddscaps.caps2 = reader.ReadUInt32();
            header.ddscaps.caps3 = reader.ReadUInt32();
            header.ddscaps.caps4 = reader.ReadUInt32();
            header.texturestage  = reader.ReadUInt32();

            PrintHeader(header);

            return(true);
        }
Example #12
0
        private static SurfaceFormat GetSurfaceFormat(ref DDSStruct header)
        {
            uint        blockSize = 0;
            PixelFormat format    = GetFormatInternal(ref header, ref blockSize);

            switch (format)
            {
            case PixelFormat.DXT1:
                return(SurfaceFormat.Dxt1);

            case PixelFormat.DXT5:
                return(SurfaceFormat.Dxt5);

            default:
                throw new System.Exception("Unsupported format.");
            }
        }
    public static byte[] DecompressRGB(DDSStruct header, byte[] data, PixelFormat pixelFormat)
    {
        // allocate bitmap
        int bpp         = (int)(PixelFormatToBpp(pixelFormat, header.pixelformat.rgbbitcount));
        int bps         = (int)(header.width * bpp * PixelFormatToBpc(pixelFormat));
        int sizeofplane = (int)(bps * header.height);
        int width       = (int)header.width;
        int height      = (int)header.height;
        int depth       = (int)header.depth;

        byte[] rawData = new byte[depth * sizeofplane + height * bps + width * bpp];

        uint valMask = (uint)((header.pixelformat.rgbbitcount == 32) ? ~0 : (1 << (int)header.pixelformat.rgbbitcount) - 1);
        uint pixSize = (uint)(((int)header.pixelformat.rgbbitcount + 7) / 8);
        int  rShift1 = 0; int rMul = 0; int rShift2 = 0;

        ComputeMaskParams(header.pixelformat.rbitmask, ref rShift1, ref rMul, ref rShift2);
        int gShift1 = 0; int gMul = 0; int gShift2 = 0;

        ComputeMaskParams(header.pixelformat.gbitmask, ref gShift1, ref gMul, ref gShift2);
        int bShift1 = 0; int bMul = 0; int bShift2 = 0;

        ComputeMaskParams(header.pixelformat.bbitmask, ref bShift1, ref bMul, ref bShift2);

        int offset = 0;
        int pixnum = width * height * depth;
        int temp   = 0;

        while (pixnum-- > 0)
        {
            uint px = BitConverter.ToUInt32(data, temp) & valMask;
            temp += (int)pixSize;
            uint pxc = px & header.pixelformat.rbitmask;
            rawData[offset + 0] = (byte)(((pxc >> rShift1) * rMul) >> rShift2);
            pxc = px & header.pixelformat.gbitmask;
            rawData[offset + 1] = (byte)(((pxc >> gShift1) * gMul) >> gShift2);
            pxc = px & header.pixelformat.bbitmask;
            rawData[offset + 2] = (byte)(((pxc >> bShift1) * bMul) >> bShift2);
            rawData[offset + 3] = 0xff;
            offset += 4;
        }
        return(rawData);
    }
Example #14
0
        internal static bool Check16BitComponents(DDSStruct header)
        {
            if (header.pixelformat.rgbbitcount != 32)
            {
                return(false);
            }
            // a2b10g10r10 format
            if (header.pixelformat.rbitmask == 0x3FF00000 && header.pixelformat.gbitmask == 0x000FFC00 && header.pixelformat.bbitmask == 0x000003FF &&
                header.pixelformat.alphabitmask == 0xC0000000)
            {
                return(true);
            }
            // a2r10g10b10 format
            else if (header.pixelformat.rbitmask == 0x000003FF && header.pixelformat.gbitmask == 0x000FFC00 && header.pixelformat.bbitmask == 0x3FF00000 &&
                     header.pixelformat.alphabitmask == 0xC0000000)
            {
                return(true);
            }

            return(false);
        }
Example #15
0
        private void Parse()
        {
            var idString = new byte[4];

            m_stream.Read(idString, 0, 4);
            var signature = BitConverter.ToUInt32(idString, 0);

            if (signature != MAGIC)
            {
                throw new InvalidFileHeaderException();
            }

            m_header = ReadHeader();


            m_isValid = true;

            if (m_header.depth == 0)
            {
                m_header.depth = 1;
            }

            uint blocksize   = 0;
            var  pixelFormat = GetFormat(ref blocksize);

            if (pixelFormat == Utils.DDSPixelFormat.UNKNOWN)
            {
                throw new InvalidFileHeaderException();
            }

            var data = ReadData();

            if (data == null)
            {
                throw new InvalidDataException();
            }

            byte[] rawData = DDSDecompressor.Expand(m_header, data, pixelFormat);
            m_bitmap = CreateBitmap((int)m_header.width, (int)m_header.height, rawData);
        }
Example #16
0
        protected override bool LoadFile(GraphicsDevice gfxDevice, BinaryReader reader, ref SEFileHeader header, out object obj)
        {
            if (gfxDevice == null)
            {
                throw new HeadlessNotSupportedException($"Texture '{reader}' was not loaded in headless display mode.");
            }

            Texture2D tex;

            if (header.OriginalExtension == ".dds")
            {
                DDSStruct ddsHeader = DDSStruct.Create(reader);
                tex = new Texture2D(gfxDevice, (int)ddsHeader.width, (int)ddsHeader.height, false, ddsHeader.GetSurfaceFormat());
                byte[] textureData = reader.ReadBytes((int)header.FileSize);
                tex.SetData(textureData, 0, textureData.Length);
            }
            else
            {
                tex = Texture2D.FromStream(gfxDevice, reader.BaseStream);
            }

            obj = tex;
            return(true);
        }
Example #17
0
        private static unsafe byte[] DecompressRXGB(DDSStruct header, byte[] data, DDSPixelFormat pixelFormat)
        {
            // allocate bitmap
            int bpp         = (int)(DDSHelper.PixelFormatToBpp(pixelFormat, header.pixelformat.rgbbitcount));
            int bps         = (int)(header.width * bpp * DDSHelper.PixelFormatToBpc(pixelFormat));
            int sizeofplane = (int)(bps * header.height);
            int width       = (int)header.width;
            int height      = (int)header.height;
            int depth       = (int)header.depth;

            byte[] rawData = new byte[depth * sizeofplane + height * bps + width * bpp];

            Colour565 color_0 = new Colour565();
            Colour565 color_1 = new Colour565();

            Colour8888[] colours = new Colour8888[4];
            byte[]       alphas  = new byte[8];

            fixed(byte *bytePtr = data)
            {
                byte *temp = bytePtr;

                for (int z = 0; z < depth; z++)
                {
                    for (int y = 0; y < height; y += 4)
                    {
                        for (int x = 0; x < width; x += 4)
                        {
                            if (y >= height || x >= width)
                            {
                                break;
                            }
                            alphas[0] = temp[0];
                            alphas[1] = temp[1];
                            byte *alphamask = temp + 2;
                            temp += 8;

                            DDSHelper.DxtcReadColors(temp, ref color_0, ref color_1);
                            temp += 4;

                            uint bitmask = ((uint *)temp)[1];
                            temp += 4;

                            colours[0].red   = (byte)(color_0.red << 3);
                            colours[0].green = (byte)(color_0.green << 2);
                            colours[0].blue  = (byte)(color_0.blue << 3);
                            colours[0].alpha = 0xFF;

                            colours[1].red   = (byte)(color_1.red << 3);
                            colours[1].green = (byte)(color_1.green << 2);
                            colours[1].blue  = (byte)(color_1.blue << 3);
                            colours[1].alpha = 0xFF;

                            // Four-color block: derive the other two colors.
                            // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3
                            // These 2-bit codes correspond to the 2-bit fields
                            // stored in the 64-bit block.
                            colours[2].blue  = (byte)((2 * colours[0].blue + colours[1].blue + 1) / 3);
                            colours[2].green = (byte)((2 * colours[0].green + colours[1].green + 1) / 3);
                            colours[2].red   = (byte)((2 * colours[0].red + colours[1].red + 1) / 3);
                            colours[2].alpha = 0xFF;

                            colours[3].blue  = (byte)((colours[0].blue + 2 * colours[1].blue + 1) / 3);
                            colours[3].green = (byte)((colours[0].green + 2 * colours[1].green + 1) / 3);
                            colours[3].red   = (byte)((colours[0].red + 2 * colours[1].red + 1) / 3);
                            colours[3].alpha = 0xFF;

                            int k = 0;
                            for (int j = 0; j < 4; j++)
                            {
                                for (int i = 0; i < 4; i++, k++)
                                {
                                    int        select = (int)((bitmask & (0x03 << k * 2)) >> k * 2);
                                    Colour8888 col    = colours[select];

                                    // only put pixels out < width or height
                                    if (((x + i) < width) && ((y + j) < height))
                                    {
                                        uint offset = (uint)(z * sizeofplane + (y + j) * bps + (x + i) * bpp);
                                        rawData[offset + 0] = col.red;
                                        rawData[offset + 1] = col.green;
                                        rawData[offset + 2] = col.blue;
                                    }
                                }
                            }

                            // 8-alpha or 6-alpha block?
                            if (alphas[0] > alphas[1])
                            {
                                // 8-alpha block:  derive the other six alphas.
                                // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
                                alphas[2] = (byte)((6 * alphas[0] + 1 * alphas[1] + 3) / 7);    // bit code 010
                                alphas[3] = (byte)((5 * alphas[0] + 2 * alphas[1] + 3) / 7);    // bit code 011
                                alphas[4] = (byte)((4 * alphas[0] + 3 * alphas[1] + 3) / 7);    // bit code 100
                                alphas[5] = (byte)((3 * alphas[0] + 4 * alphas[1] + 3) / 7);    // bit code 101
                                alphas[6] = (byte)((2 * alphas[0] + 5 * alphas[1] + 3) / 7);    // bit code 110
                                alphas[7] = (byte)((1 * alphas[0] + 6 * alphas[1] + 3) / 7);    // bit code 111
                            }
                            else
                            {
                                // 6-alpha block.
                                // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
                                alphas[2] = (byte)((4 * alphas[0] + 1 * alphas[1] + 2) / 5); // Bit code 010
                                alphas[3] = (byte)((3 * alphas[0] + 2 * alphas[1] + 2) / 5); // Bit code 011
                                alphas[4] = (byte)((2 * alphas[0] + 3 * alphas[1] + 2) / 5); // Bit code 100
                                alphas[5] = (byte)((1 * alphas[0] + 4 * alphas[1] + 2) / 5); // Bit code 101
                                alphas[6] = 0x00;                                            // Bit code 110
                                alphas[7] = 0xFF;                                            // Bit code 111
                            }

                            // Note: Have to separate the next two loops,
                            //	it operates on a 6-byte system.
                            // First three bytes
                            uint bits = *((uint *)alphamask);
                            for (int j = 0; j < 2; j++)
                            {
                                for (int i = 0; i < 4; i++)
                                {
                                    // only put pixels out < width or height
                                    if (((x + i) < width) && ((y + j) < height))
                                    {
                                        uint offset = (uint)(z * sizeofplane + (y + j) * bps + (x + i) * bpp + 3);
                                        rawData[offset] = alphas[bits & 0x07];
                                    }
                                    bits >>= 3;
                                }
                            }

                            // Last three bytes
                            bits = *((uint *)&alphamask[3]);
                            for (int j = 2; j < 4; j++)
                            {
                                for (int i = 0; i < 4; i++)
                                {
                                    // only put pixels out < width or height
                                    if (((x + i) < width) && ((y + j) < height))
                                    {
                                        uint offset = (uint)(z * sizeofplane + (y + j) * bps + (x + i) * bpp + 3);
                                        rawData[offset] = alphas[bits & 0x07];
                                    }
                                    bits >>= 3;
                                }
                            }
                        }
                    }
                }
            }

            return(rawData);
        }
Example #18
0
        private static unsafe byte[] DecompressAti1n(DDSStruct header, byte[] data, DDSPixelFormat pixelFormat)
        {
            // allocate bitmap
            int bpp         = (int)(DDSHelper.PixelFormatToBpp(pixelFormat, header.pixelformat.rgbbitcount));
            int bps         = (int)(header.width * bpp * DDSHelper.PixelFormatToBpc(pixelFormat));
            int sizeofplane = (int)(bps * header.height);
            int width       = (int)header.width;
            int height      = (int)header.height;
            int depth       = (int)header.depth;

            byte[] rawData = new byte[depth * sizeofplane + height * bps + width * bpp];
            byte[] colours = new byte[8];

            uint offset = 0;

            fixed(byte *bytePtr = data)
            {
                byte *temp = bytePtr;

                for (int z = 0; z < depth; z++)
                {
                    for (int y = 0; y < height; y += 4)
                    {
                        for (int x = 0; x < width; x += 4)
                        {
                            //Read palette
                            int t1 = colours[0] = temp[0];
                            int t2 = colours[1] = temp[1];
                            temp += 2;
                            if (t1 > t2)
                            {
                                for (int i = 2; i < 8; ++i)
                                {
                                    colours[i] = (byte)(t1 + ((t2 - t1) * (i - 1)) / 7);
                                }
                            }
                            else
                            {
                                for (int i = 2; i < 6; ++i)
                                {
                                    colours[i] = (byte)(t1 + ((t2 - t1) * (i - 1)) / 5);
                                }
                                colours[6] = 0;
                                colours[7] = 255;
                            }

                            //decompress pixel data
                            uint currOffset = offset;
                            for (int k = 0; k < 4; k += 2)
                            {
                                // First three bytes
                                uint bitmask = ((uint)(temp[0]) << 0) | ((uint)(temp[1]) << 8) | ((uint)(temp[2]) << 16);
                                for (int j = 0; j < 2; j++)
                                {
                                    // only put pixels out < height
                                    if ((y + k + j) < height)
                                    {
                                        for (int i = 0; i < 4; i++)
                                        {
                                            // only put pixels out < width
                                            if (((x + i) < width))
                                            {
                                                t1          = (int)(currOffset + (x + i));
                                                rawData[t1] = colours[bitmask & 0x07];
                                            }
                                            bitmask >>= 3;
                                        }
                                        currOffset += (uint)bps;
                                    }
                                }
                                temp += 3;
                            }
                        }
                        offset += (uint)(bps * 4);
                    }
                }
            }

            return(rawData);
        }
Example #19
0
        private static unsafe byte[] DecompressDXT1(DDSStruct header, byte[] data, DDSPixelFormat pixelFormat)
        {
            // allocate bitmap
            int bpp         = (int)(DDSHelper.PixelFormatToBpp(pixelFormat, header.pixelformat.rgbbitcount));
            int bps         = (int)(header.width * bpp * DDSHelper.PixelFormatToBpc(pixelFormat));
            int sizeofplane = (int)(bps * header.height);
            int width       = (int)header.width;
            int height      = (int)header.height;
            int depth       = (int)header.depth;

            // DXT1 decompressor
            byte[] rawData = new byte[depth * sizeofplane + height * bps + width * bpp];

            Colour8888[] colours = new Colour8888[4];
            colours[0].alpha = 0xFF;
            colours[1].alpha = 0xFF;
            colours[2].alpha = 0xFF;

            fixed(byte *bytePtr = data)
            {
                byte *temp = bytePtr;

                for (int z = 0; z < depth; z++)
                {
                    for (int y = 0; y < height; y += 4)
                    {
                        for (int x = 0; x < width; x += 4)
                        {
                            ushort colour0 = *((ushort *)temp);
                            ushort colour1 = *((ushort *)(temp + 2));
                            DDSHelper.DxtcReadColor(colour0, ref colours[0]);
                            DDSHelper.DxtcReadColor(colour1, ref colours[1]);

                            uint bitmask = ((uint *)temp)[1];
                            temp += 8;

                            if (colour0 > colour1)
                            {
                                // Four-color block: derive the other two colors.
                                // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3
                                // These 2-bit codes correspond to the 2-bit fields
                                // stored in the 64-bit block.
                                colours[2].blue  = (byte)((2 * colours[0].blue + colours[1].blue + 1) / 3);
                                colours[2].green = (byte)((2 * colours[0].green + colours[1].green + 1) / 3);
                                colours[2].red   = (byte)((2 * colours[0].red + colours[1].red + 1) / 3);
                                //colours[2].alpha = 0xFF;

                                colours[3].blue  = (byte)((colours[0].blue + 2 * colours[1].blue + 1) / 3);
                                colours[3].green = (byte)((colours[0].green + 2 * colours[1].green + 1) / 3);
                                colours[3].red   = (byte)((colours[0].red + 2 * colours[1].red + 1) / 3);
                                colours[3].alpha = 0xFF;
                            }
                            else
                            {
                                // Three-color block: derive the other color.
                                // 00 = color_0,  01 = color_1,  10 = color_2,
                                // 11 = transparent.
                                // These 2-bit codes correspond to the 2-bit fields
                                // stored in the 64-bit block.
                                colours[2].blue  = (byte)((colours[0].blue + colours[1].blue) / 2);
                                colours[2].green = (byte)((colours[0].green + colours[1].green) / 2);
                                colours[2].red   = (byte)((colours[0].red + colours[1].red) / 2);
                                //colours[2].alpha = 0xFF;

                                colours[3].blue  = (byte)((colours[0].blue + 2 * colours[1].blue + 1) / 3);
                                colours[3].green = (byte)((colours[0].green + 2 * colours[1].green + 1) / 3);
                                colours[3].red   = (byte)((colours[0].red + 2 * colours[1].red + 1) / 3);
                                colours[3].alpha = 0x00;
                            }

                            for (int j = 0, k = 0; j < 4; j++)
                            {
                                for (int i = 0; i < 4; i++, k++)
                                {
                                    int        select = (int)((bitmask & (0x03 << k * 2)) >> k * 2);
                                    Colour8888 col    = colours[select];
                                    if (((x + i) < width) && ((y + j) < height))
                                    {
                                        uint offset = (uint)(z * sizeofplane + (y + j) * bps + (x + i) * bpp);
                                        rawData[offset + 0] = (byte)col.red;
                                        rawData[offset + 1] = (byte)col.green;
                                        rawData[offset + 2] = (byte)col.blue;
                                        rawData[offset + 3] = (byte)col.alpha;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(rawData);
        }
Example #20
0
        private static unsafe byte[] Decompress3Dc(DDSStruct header, byte[] data, DDSPixelFormat pixelFormat)
        {
            // allocate bitmap
            int bpp         = (int)(DDSHelper.PixelFormatToBpp(pixelFormat, header.pixelformat.rgbbitcount));
            int bps         = (int)(header.width * bpp * DDSHelper.PixelFormatToBpc(pixelFormat));
            int sizeofplane = (int)(bps * header.height);
            int width       = (int)header.width;
            int height      = (int)header.height;
            int depth       = (int)header.depth;

            byte[] rawData  = new byte[depth * sizeofplane + height * bps + width * bpp];
            byte[] yColours = new byte[8];
            byte[] xColours = new byte[8];

            int offset = 0;

            fixed(byte *bytePtr = data)
            {
                byte *temp = bytePtr;

                for (int z = 0; z < depth; z++)
                {
                    for (int y = 0; y < height; y += 4)
                    {
                        for (int x = 0; x < width; x += 4)
                        {
                            byte *temp2 = temp + 8;

                            //Read Y palette
                            int t1 = yColours[0] = temp[0];
                            int t2 = yColours[1] = temp[1];
                            temp += 2;
                            if (t1 > t2)
                            {
                                for (int i = 2; i < 8; ++i)
                                {
                                    yColours[i] = (byte)(t1 + ((t2 - t1) * (i - 1)) / 7);
                                }
                            }
                            else
                            {
                                for (int i = 2; i < 6; ++i)
                                {
                                    yColours[i] = (byte)(t1 + ((t2 - t1) * (i - 1)) / 5);
                                }
                                yColours[6] = 0;
                                yColours[7] = 255;
                            }

                            // Read X palette
                            t1     = xColours[0] = temp2[0];
                            t2     = xColours[1] = temp2[1];
                            temp2 += 2;
                            if (t1 > t2)
                            {
                                for (int i = 2; i < 8; ++i)
                                {
                                    xColours[i] = (byte)(t1 + ((t2 - t1) * (i - 1)) / 7);
                                }
                            }
                            else
                            {
                                for (int i = 2; i < 6; ++i)
                                {
                                    xColours[i] = (byte)(t1 + ((t2 - t1) * (i - 1)) / 5);
                                }
                                xColours[6] = 0;
                                xColours[7] = 255;
                            }

                            //decompress pixel data
                            int currentOffset = offset;
                            for (int k = 0; k < 4; k += 2)
                            {
                                // First three bytes
                                uint bitmask  = ((uint)(temp[0]) << 0) | ((uint)(temp[1]) << 8) | ((uint)(temp[2]) << 16);
                                uint bitmask2 = ((uint)(temp2[0]) << 0) | ((uint)(temp2[1]) << 8) | ((uint)(temp2[2]) << 16);
                                for (int j = 0; j < 2; j++)
                                {
                                    // only put pixels out < height
                                    if ((y + k + j) < height)
                                    {
                                        for (int i = 0; i < 4; i++)
                                        {
                                            // only put pixels out < width
                                            if (((x + i) < width))
                                            {
                                                int  t;
                                                byte tx, ty;

                                                t1 = currentOffset + (x + i) * 3;
                                                rawData[t1 + 1] = ty = yColours[bitmask & 0x07];
                                                rawData[t1 + 0] = tx = xColours[bitmask2 & 0x07];

                                                //calculate b (z) component ((r/255)^2 + (g/255)^2 + (b/255)^2 = 1
                                                t = 127 * 128 - (tx - 127) * (tx - 128) - (ty - 127) * (ty - 128);
                                                if (t > 0)
                                                {
                                                    rawData[t1 + 2] = (byte)(Math.Sqrt(t) + 128);
                                                }
                                                else
                                                {
                                                    rawData[t1 + 2] = 0x7F;
                                                }
                                            }
                                            bitmask  >>= 3;
                                            bitmask2 >>= 3;
                                        }
                                        currentOffset += bps;
                                    }
                                }
                                temp  += 3;
                                temp2 += 3;
                            }

                            //skip bytes that were read via Temp2
                            temp += 8;
                        }
                        offset += bps * 4;
                    }
                }
            }

            return(rawData);
        }
    public static byte[] DecompressDXT5(DDSStruct header, byte[] data, PixelFormat pixelFormat = PixelFormat.DXT5)
    {
        // allocate bitmap
        int bpp         = (int)(PixelFormatToBpp(pixelFormat, header.pixelformat.rgbbitcount));
        int bps         = (int)(header.width * bpp * PixelFormatToBpc(pixelFormat));
        int sizeofplane = (int)(bps * header.height);
        int width       = (int)header.width;
        int height      = (int)header.height;
        int depth       = (int)header.depth;

        byte[]       rawData = new byte[depth * sizeofplane + height * bps + width * bpp];
        Colour8888[] colours = new Colour8888[4];
        ushort[]     alphas  = new ushort[8];

        int temp = 0;

        for (int z = 0; z < depth; z++)
        {
            for (int y = 0; y < height; y += 4)
            {
                for (int x = 0; x < width; x += 4)
                {
                    if (y >= height || x >= width)
                    {
                        break;
                    }
                    alphas[0] = data[temp + 0];
                    alphas[1] = data[temp + 1];
                    int alphamask = (temp + 2);
                    temp += 8;

                    DxtcReadColors(data, temp, ref colours);
                    uint bitmask = BitConverter.ToUInt32(data, temp + 4);
                    temp += 8;

                    // Four-color block: derive the other two colors.
                    // 00 = color_0, 01 = color_1, 10 = color_2, 11	= color_3
                    // These 2-bit codes correspond to the 2-bit fields
                    // stored in the 64-bit block.
                    colours[2].blue  = (byte)((2 * colours[0].blue + colours[1].blue + 1) / 3);
                    colours[2].green = (byte)((2 * colours[0].green + colours[1].green + 1) / 3);
                    colours[2].red   = (byte)((2 * colours[0].red + colours[1].red + 1) / 3);
                    //colours[2].alpha = 0xFF;

                    colours[3].blue  = (byte)((colours[0].blue + 2 * colours[1].blue + 1) / 3);
                    colours[3].green = (byte)((colours[0].green + 2 * colours[1].green + 1) / 3);
                    colours[3].red   = (byte)((colours[0].red + 2 * colours[1].red + 1) / 3);
                    //colours[3].alpha = 0xFF;

                    int k = 0;
                    for (int j = 0; j < 4; j++)
                    {
                        for (int i = 0; i < 4; k++, i++)
                        {
                            int        select = (int)((bitmask & (0x03 << k * 2)) >> k * 2);
                            Colour8888 col    = colours[select];
                            // only put pixels out < width or height
                            if (((x + i) < width) && ((y + j) < height))
                            {
                                uint offset = (uint)(z * sizeofplane + (y + j) * bps + (x + i) * bpp);
                                rawData[offset]     = col.red;
                                rawData[offset + 1] = col.green;
                                rawData[offset + 2] = col.blue;
                            }
                        }
                    }

                    // 8-alpha or 6-alpha block?
                    if (alphas[0] > alphas[1])
                    {
                        // 8-alpha block:  derive the other six alphas.
                        // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
                        alphas[2] = (ushort)((6 * alphas[0] + 1 * alphas[1] + 3) / 7); // bit code 010
                        alphas[3] = (ushort)((5 * alphas[0] + 2 * alphas[1] + 3) / 7); // bit code 011
                        alphas[4] = (ushort)((4 * alphas[0] + 3 * alphas[1] + 3) / 7); // bit code 100
                        alphas[5] = (ushort)((3 * alphas[0] + 4 * alphas[1] + 3) / 7); // bit code 101
                        alphas[6] = (ushort)((2 * alphas[0] + 5 * alphas[1] + 3) / 7); // bit code 110
                        alphas[7] = (ushort)((1 * alphas[0] + 6 * alphas[1] + 3) / 7); // bit code 111
                    }
                    else
                    {
                        // 6-alpha block.
                        // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
                        alphas[2] = (ushort)((4 * alphas[0] + 1 * alphas[1] + 2) / 5); // Bit code 010
                        alphas[3] = (ushort)((3 * alphas[0] + 2 * alphas[1] + 2) / 5); // Bit code 011
                        alphas[4] = (ushort)((2 * alphas[0] + 3 * alphas[1] + 2) / 5); // Bit code 100
                        alphas[5] = (ushort)((1 * alphas[0] + 4 * alphas[1] + 2) / 5); // Bit code 101
                        alphas[6] = 0x00;                                              // Bit code 110
                        alphas[7] = 0xFF;                                              // Bit code 111
                    }

                    // Note: Have to separate the next two loops,
                    // it operates on a 6-byte system.

                    // First three bytes
                    //uint bits = (uint)(alphamask[0]);
                    uint bits = (uint)((data[alphamask + 0]) | (data[alphamask + 1] << 8) | (data[alphamask + 2] << 16));
                    for (int j = 0; j < 2; j++)
                    {
                        for (int i = 0; i < 4; i++)
                        {
                            // only put pixels out < width or height
                            if (((x + i) < width) && ((y + j) < height))
                            {
                                uint offset = (uint)(z * sizeofplane + (y + j) * bps + (x + i) * bpp + 3);
                                rawData[offset] = (byte)alphas[bits & 0x07];
                            }
                            bits >>= 3;
                        }
                    }

                    // Last three bytes
                    //bits = (uint)(alphamask[3]);
                    bits = (uint)((data[alphamask + 3]) | (data[alphamask + 4] << 8) | (data[alphamask + 5] << 16));
                    for (int j = 2; j < 4; j++)
                    {
                        for (int i = 0; i < 4; i++)
                        {
                            // only put pixels out < width or height
                            if (((x + i) < width) && ((y + j) < height))
                            {
                                uint offset = (uint)(z * sizeofplane + (y + j) * bps + (x + i) * bpp + 3);
                                rawData[offset] = (byte)alphas[bits & 0x07];
                            }
                            bits >>= 3;
                        }
                    }
                }
            }
        }

        return(rawData);
    }
Example #22
0
        internal static byte[] Expand(DDSStruct header, byte[] data, DDSPixelFormat pixelFormat)
        {
            System.Diagnostics.Debug.WriteLine(pixelFormat);
            // allocate bitmap
            byte[] rawData = null;

            switch (pixelFormat)
            {
            case DDSPixelFormat.RGBA:
                rawData = DecompressRGBA(header, data, pixelFormat);
                break;

            case DDSPixelFormat.RGB:
                rawData = DecompressRGB(header, data, pixelFormat);
                break;

            case DDSPixelFormat.LUMINANCE:
            case DDSPixelFormat.LUMINANCE_ALPHA:
                rawData = DecompressLum(header, data, pixelFormat);
                break;

            case DDSPixelFormat.DXT1:
                rawData = DecompressDXT1(header, data, pixelFormat);
                break;

            case DDSPixelFormat.DXT2:
                rawData = DecompressDXT2(header, data, pixelFormat);
                break;

            case DDSPixelFormat.DXT3:
                rawData = DecompressDXT3(header, data, pixelFormat);
                break;

            case DDSPixelFormat.DXT4:
                rawData = DecompressDXT4(header, data, pixelFormat);
                break;

            case DDSPixelFormat.DXT5:
                rawData = DecompressDXT5(header, data, pixelFormat);
                break;

            case DDSPixelFormat.THREEDC:
                rawData = Decompress3Dc(header, data, pixelFormat);
                break;

            case DDSPixelFormat.ATI1N:
                rawData = DecompressAti1n(header, data, pixelFormat);
                break;

            case DDSPixelFormat.RXGB:
                rawData = DecompressRXGB(header, data, pixelFormat);
                break;

            case DDSPixelFormat.R16F:
            case DDSPixelFormat.G16R16F:
            case DDSPixelFormat.A16B16G16R16F:
            case DDSPixelFormat.R32F:
            case DDSPixelFormat.G32R32F:
            case DDSPixelFormat.A32B32G32R32F:
                rawData = DecompressFloat(header, data, pixelFormat);
                break;

            default:
                throw new UnknownFileFormatException();
            }

            return(rawData);
        }
Example #23
0
        private static unsafe byte[] DecompressDXT3(DDSStruct header, byte[] data, DDSPixelFormat pixelFormat)
        {
            // allocate bitmap
            int bpp         = (int)(DDSHelper.PixelFormatToBpp(pixelFormat, header.pixelformat.rgbbitcount));
            int bps         = (int)(header.width * bpp * DDSHelper.PixelFormatToBpc(pixelFormat));
            int sizeofplane = (int)(bps * header.height);
            int width       = (int)header.width;
            int height      = (int)header.height;
            int depth       = (int)header.depth;

            // DXT3 decompressor
            byte[]       rawData = new byte[depth * sizeofplane + height * bps + width * bpp];
            Colour8888[] colours = new Colour8888[4];

            fixed(byte *bytePtr = data)
            {
                byte *temp = bytePtr;

                for (int z = 0; z < depth; z++)
                {
                    for (int y = 0; y < height; y += 4)
                    {
                        for (int x = 0; x < width; x += 4)
                        {
                            byte *alpha = temp;
                            temp += 8;

                            DDSHelper.DxtcReadColors(temp, ref colours);
                            temp += 4;

                            uint bitmask = ((uint *)temp)[1];
                            temp += 4;

                            // Four-color block: derive the other two colors.
                            // 00 = color_0, 01 = color_1, 10 = color_2, 11	= color_3
                            // These 2-bit codes correspond to the 2-bit fields
                            // stored in the 64-bit block.
                            colours[2].blue  = (byte)((2 * colours[0].blue + colours[1].blue + 1) / 3);
                            colours[2].green = (byte)((2 * colours[0].green + colours[1].green + 1) / 3);
                            colours[2].red   = (byte)((2 * colours[0].red + colours[1].red + 1) / 3);
                            //colours[2].alpha = 0xFF;

                            colours[3].blue  = (byte)((colours[0].blue + 2 * colours[1].blue + 1) / 3);
                            colours[3].green = (byte)((colours[0].green + 2 * colours[1].green + 1) / 3);
                            colours[3].red   = (byte)((colours[0].red + 2 * colours[1].red + 1) / 3);
                            //colours[3].alpha = 0xFF;

                            for (int j = 0, k = 0; j < 4; j++)
                            {
                                for (int i = 0; i < 4; k++, i++)
                                {
                                    int select = (int)((bitmask & (0x03 << k * 2)) >> k * 2);

                                    if (((x + i) < width) && ((y + j) < height))
                                    {
                                        uint offset = (uint)(z * sizeofplane + (y + j) * bps + (x + i) * bpp);
                                        rawData[offset + 0] = (byte)colours[select].red;
                                        rawData[offset + 1] = (byte)colours[select].green;
                                        rawData[offset + 2] = (byte)colours[select].blue;
                                    }
                                }
                            }

                            for (int j = 0; j < 4; j++)
                            {
                                //ushort word = (ushort)(alpha[2 * j] + 256 * alpha[2 * j + 1]);
                                ushort word = (ushort)(alpha[2 * j] | (alpha[2 * j + 1] << 8));
                                for (int i = 0; i < 4; i++)
                                {
                                    if (((x + i) < width) && ((y + j) < height))
                                    {
                                        uint offset = (uint)(z * sizeofplane + (y + j) * bps + (x + i) * bpp + 3);
                                        rawData[offset] = (byte)(word & 0x0F);
                                        rawData[offset] = (byte)(rawData[offset] | (rawData[offset] << 4));
                                    }
                                    word >>= 4;
                                }
                            }
                        }
                    }
                }
            }

            return(rawData);
        }
Example #24
0
        private Utils.PixelFormat GetFormat(DDSStruct header, ref uint blocksize)
        {
            Utils.PixelFormat format = Utils.PixelFormat.UNKNOWN;
            if ((header.pixelformat.flags & Helper.DDPF_FOURCC) == Helper.DDPF_FOURCC)
            {
                blocksize = ((header.width + 3) / 4) * ((header.height + 3) / 4) * header.depth;

                switch (header.pixelformat.fourcc)
                {
                case Helper.FOURCC_DXT1:
                    format     = Utils.PixelFormat.DXT1;
                    blocksize *= 8;
                    break;

                case Helper.FOURCC_DXT2:
                    format     = Utils.PixelFormat.DXT2;
                    blocksize *= 16;
                    break;

                case Helper.FOURCC_DXT3:
                    format     = Utils.PixelFormat.DXT3;
                    blocksize *= 16;
                    break;

                case Helper.FOURCC_DXT4:
                    format     = Utils.PixelFormat.DXT4;
                    blocksize *= 16;
                    break;

                case Helper.FOURCC_DXT5:
                    format     = Utils.PixelFormat.DXT5;
                    blocksize *= 16;
                    break;

                case Helper.FOURCC_ATI1:
                    format     = Utils.PixelFormat.ATI1N;
                    blocksize *= 8;
                    break;

                case Helper.FOURCC_ATI2:
                    format     = Utils.PixelFormat.THREEDC;
                    blocksize *= 16;
                    break;

                case Helper.FOURCC_RXGB:
                    format     = Utils.PixelFormat.RXGB;
                    blocksize *= 16;
                    break;

                case Helper.FOURCC_DOLLARNULL:
                    format    = Utils.PixelFormat.A16B16G16R16;
                    blocksize = header.width * header.height * header.depth * 8;
                    break;

                case Helper.FOURCC_oNULL:
                    format    = Utils.PixelFormat.R16F;
                    blocksize = header.width * header.height * header.depth * 2;
                    break;

                case Helper.FOURCC_pNULL:
                    format    = Utils.PixelFormat.G16R16F;
                    blocksize = header.width * header.height * header.depth * 4;
                    break;

                case Helper.FOURCC_qNULL:
                    format    = Utils.PixelFormat.A16B16G16R16F;
                    blocksize = header.width * header.height * header.depth * 8;
                    break;

                case Helper.FOURCC_rNULL:
                    format    = Utils.PixelFormat.R32F;
                    blocksize = header.width * header.height * header.depth * 4;
                    break;

                case Helper.FOURCC_sNULL:
                    format    = Utils.PixelFormat.G32R32F;
                    blocksize = header.width * header.height * header.depth * 8;
                    break;

                case Helper.FOURCC_tNULL:
                    format    = Utils.PixelFormat.A32B32G32R32F;
                    blocksize = header.width * header.height * header.depth * 16;
                    break;

                default:
                    format     = Utils.PixelFormat.UNKNOWN;
                    blocksize *= 16;
                    break;
                }
            }
            else
            {
                // uncompressed image
                if ((header.pixelformat.flags & Helper.DDPF_LUMINANCE) == Helper.DDPF_LUMINANCE)
                {
                    if ((header.pixelformat.flags & Helper.DDPF_ALPHAPIXELS) == Helper.DDPF_ALPHAPIXELS)
                    {
                        format = Utils.PixelFormat.LUMINANCE_ALPHA;
                    }
                    else
                    {
                        format = Utils.PixelFormat.LUMINANCE;
                    }
                }
                else
                {
                    if ((header.pixelformat.flags & Helper.DDPF_ALPHAPIXELS) == Helper.DDPF_ALPHAPIXELS)
                    {
                        format = Utils.PixelFormat.RGBA;
                    }
                    else
                    {
                        format = Utils.PixelFormat.RGB;
                    }
                }

                blocksize = (header.width * header.height * header.depth * (header.pixelformat.rgbbitcount >> 3));
            }

            return(format);
        }
Example #25
0
        private static unsafe byte[] DecompressFloat(DDSStruct header, byte[] data, DDSPixelFormat pixelFormat)
        {
            // allocate bitmap
            int bpp         = (int)(DDSHelper.PixelFormatToBpp(pixelFormat, header.pixelformat.rgbbitcount));
            int bps         = (int)(header.width * bpp * DDSHelper.PixelFormatToBpc(pixelFormat));
            int sizeofplane = (int)(bps * header.height);
            int width       = (int)header.width;
            int height      = (int)header.height;
            int depth       = (int)header.depth;

            byte[] rawData = new byte[depth * sizeofplane + height * bps + width * bpp];
            int    size    = 0;

            fixed(byte *bytePtr = data)
            {
                byte *temp = bytePtr;

                fixed(byte *destPtr = rawData)
                {
                    byte *destData = destPtr;

                    switch (pixelFormat)
                    {
                    case DDSPixelFormat.R32F:      // Red float, green = blue = max
                        size = width * height * depth * 3;
                        for (int i = 0, j = 0; i < size; i += 3, j++)
                        {
                            ((float *)destData)[i]     = ((float *)temp)[j];
                            ((float *)destData)[i + 1] = 1.0f;
                            ((float *)destData)[i + 2] = 1.0f;
                        }
                        break;

                    case DDSPixelFormat.A32B32G32R32F:      // Direct copy of float RGBA data
                        Array.Copy(data, rawData, data.Length);
                        break;

                    case DDSPixelFormat.G32R32F:      // Red float, green float, blue = max
                        size = width * height * depth * 3;
                        for (int i = 0, j = 0; i < size; i += 3, j += 2)
                        {
                            ((float *)destData)[i]     = ((float *)temp)[j];
                            ((float *)destData)[i + 1] = ((float *)temp)[j + 1];
                            ((float *)destData)[i + 2] = 1.0f;
                        }
                        break;

                    case DDSPixelFormat.R16F:      // Red float, green = blue = max
                        size = width * height * depth * bpp;
                        DDSHelper.ConvR16ToFloat32((uint *)destData, (ushort *)temp, (uint)size);
                        break;

                    case DDSPixelFormat.A16B16G16R16F:      // Just convert from half to float.
                        size = width * height * depth * bpp;
                        DDSHelper.ConvFloat16ToFloat32((uint *)destData, (ushort *)temp, (uint)size);
                        break;

                    case DDSPixelFormat.G16R16F:      // Convert from half to float, set blue = max.
                        size = width * height * depth * bpp;
                        DDSHelper.ConvG16R16ToFloat32((uint *)destData, (ushort *)temp, (uint)size);
                        break;

                    default:
                        break;
                    }
                }
            }

            return(rawData);
        }
Example #26
0
        public override void ParseBytes(CR2WBinaryReader br, uint size)
        {
            base.ParseBytes(br, size);

            /*
             *  This is a temporary solution for reading the contents of a CBitmapTexture
             *  What this does is contruct a dds header object and parse it and the raw bytes
             *  using the dds library.
             *
             *  The bitmap bytes from the cr2w has a header 28 bytes long, containing data about the
             *  image such as size and height etc...
             *  There are 4 unknown ones.
             *
             *  This class should in the end support reading all xbm files with means supporting not just
             *  dds but tga, bmp, png, and jpg.
             *
             */

            var zero        = br.ReadUInt32();
            var mipCount    = br.ReadUInt32();
            var width       = br.ReadUInt32();
            var height      = br.ReadUInt32();
            var unknown5    = br.ReadUInt32();
            var sizeorpitch = br.ReadUInt32();

            Console.WriteLine("zero        {0}", zero);
            Console.WriteLine("mipCount    {0}", mipCount);
            Console.WriteLine("width       {0}", width);
            Console.WriteLine("height      {0}", height);
            Console.WriteLine("unknown5    {0}", unknown5);
            Console.WriteLine("sizeorpitch {0}", sizeorpitch);

            var ddsheader = new DDSStruct
            {
                size        = 124,
                flags       = 659463,
                width       = width,
                height      = height,
                sizeorpitch = sizeorpitch,
                depth       = 1,
                mipmapcount = 1,
                reserved    = new uint[10],
            };

            ddsheader.ddscaps.caps1      = 4096;
            ddsheader.pixelformat.size   = 32;
            ddsheader.pixelformat.flags  = 5;
            ddsheader.pixelformat.fourcc = DDSHelper.FOURCC_DXT1;

            var dds = new DDSImage(br, ddsheader, true);

            Form form = new Form
            {
                Text       = "Image",
                ClientSize = new Size((int)width, (int)height),
            };
            PictureBox pictureBox = new PictureBox
            {
                Image  = dds.BitmapImage,
                Width  = (int)width,
                Height = (int)height
            };

            form.Controls.Add(pictureBox);
            var t = new Task(() =>
            {
                Application.Run(form);
            });

            t.Start();
        }