HaloMap.DDSFunctions.DecodeDXT.DecodeDXT45 C# (CSharp) Method

DecodeDXT45() public method

The decode dx t 45.
public DecodeDXT45 ( int height, int width, byte SourceData ) : byte[]
height int The height.
width int The width.
SourceData byte The source data.
return byte[]
        public byte[] DecodeDXT45(int height, int width, byte[] SourceData)
        {
            byte[] DestData;
            ImageLib.RGBA_COLOR_STRUCT[] Color = new ImageLib.RGBA_COLOR_STRUCT[4];
            int i;
            ImageLib.RGBA_COLOR_STRUCT CColor;
            int CData;
            int ChunksPerHLine = width / 4;
            //ImageLib.RGBA_COLOR_STRUCT zeroColor = new ImageLib.RGBA_COLOR_STRUCT();
            DestData = new byte[(width * height) * 4];

            if (ChunksPerHLine == 0)
            {
                ChunksPerHLine += 1;
            }

            for (i = 0; i < (width * height); i += 16)
            {
                Color[0] = il.short_to_rgba(SourceData[i + 8] | (SourceData[i + 9] << 8));
                Color[1] = il.short_to_rgba(SourceData[i + 10] | (SourceData[i + 11] << 8));
                Color[2] = il.GradientColors(Color[0], Color[1]);
                Color[3] = il.GradientColors(Color[1], Color[0]);

                CData = (SourceData[i + 12] << 0) | (SourceData[i + 13] << 8) | (SourceData[i + 14] << 16) |
                        (SourceData[i + 15] << 24);

                byte[] Alpha = new byte[8];
                Alpha[0] = SourceData[i];
                Alpha[1] = SourceData[i + 1];

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

                // Byte	Alpha
                // 0	Alpha_0
                // 1	Alpha_1
                // 2	(0)(2) (2 LSBs), (0)(1), (0)(0)
                // 3	(1)(1) (1 LSB), (1)(0), (0)(3), (0)(2) (1 MSB)
                // 4	(1)(3), (1)(2), (1)(1) (2 MSBs)
                // 5	(2)(2) (2 LSBs), (2)(1), (2)(0)
                // 6	(3)(1) (1 LSB), (3)(0), (2)(3), (2)(2) (1 MSB)
                // 7	(3)(3), (3)(2), (3)(1) (2 MSBs)
                // (0
                // Read an int and a short
                long tmpdword;
                int tmpword;
                long alphaDat;
                tmpword = SourceData[i + 2] | (SourceData[i + 3] << 8);
                tmpdword = SourceData[i + 4] | (SourceData[i + 5] << 8) | (SourceData[i + 6] << 16) |
                           (SourceData[i + 7] << 24);

                alphaDat = tmpword | (tmpdword << 16);

                int ChunkNum = i / 16;
                long XPos = ChunkNum % ChunksPerHLine;
                long YPos = (ChunkNum - XPos) / ChunksPerHLine;
                long ttmp;
                int sizeh = height < 4 ? height : 4;
                int sizew = width < 4 ? width : 4;
                int x, y;
                for (x = 0; x < sizeh; x++)
                {
                    for (y = 0; y < sizew; y++)
                    {
                        CColor = Color[CData & 3];
                        CData >>= 2;
                        CColor.a = Alpha[alphaDat & 7];
                        alphaDat >>= 3;
                        ttmp = ((YPos * 4 + x) * width + XPos * 4 + y) * 4;
                        if ((CColor.a != 0) |
                            ((CColor.b != 0 | CColor.g != 0 | CColor.r != 0) &
                             (CColor.b != 255 | CColor.g != 255 | CColor.r != 255)))
                        {
                            //int fdfd = 0;
                        }

                        DestData[ttmp] = (byte)CColor.b;
                        DestData[ttmp + 1] = (byte)CColor.g;
                        DestData[ttmp + 2] = (byte)CColor.r;
                        DestData[ttmp + 3] = (byte)CColor.a;
                    }
                }
            }

            return DestData;
        }

Usage Example

示例#1
0
        /// <summary>
        /// The decode dds.
        /// </summary>
        /// <param name="sourceBytes">The source bytes.</param>
        /// <param name="b2">The b 2.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public static Bitmap DecodeDDS(byte[] sourceBytes, ParsedBitmap.BitmapInfo b2)
        {
            ////
            //// Check type name and handle 2D, 3D & Cubemaps
            ////
            // b2.typename;
            ////
            byte[] poo = new byte[0];
            IntPtr ptr = new IntPtr();

            PixelFormat o = new PixelFormat();
            int poolength;
            byte[] fu;
            DecodeDXT decode = new DecodeDXT();

            int oldwidth = b2.width;

            if (b2.width % 16 != 0)
                b2.width = (ushort)(b2.width + (16 - (b2.width % 16)));

            int stride = b2.width;

            if (b2.swizzle)
            {
                sourceBytes = Swizzler.Swizzle(sourceBytes, b2.width, b2.height, b2.depth, b2.bitsPerPixel, true);
            }

            switch (b2.formatname)
            {
                    #region DXT1

                case (ParsedBitmap.BitmapFormat)14:
                    if (b2.swizzle)
                    {
                        MessageBox.Show("Swizzled");
                    }

                    sourceBytes = decode.DecodeDXT1(b2.height, b2.width, sourceBytes);
                    stride *= 4;
                    o = PixelFormat.Format32bppArgb;
                    break;

                    #endregion

                    #region DXT2/3

                case (ParsedBitmap.BitmapFormat)15:
                    if (b2.swizzle)
                    {
                        MessageBox.Show("Swizzled");
                    }

                    sourceBytes = decode.DecodeDXT23(b2.height, b2.width, sourceBytes);
                    stride *= 4;
                    o = PixelFormat.Format32bppArgb;
                    break;

                    #endregion

                    #region DXT 4/5

                case (ParsedBitmap.BitmapFormat)16:
                    if (b2.swizzle)
                    {
                        MessageBox.Show("Swizzled");
                    }

                    sourceBytes = decode.DecodeDXT45(b2.height, b2.width, sourceBytes);
                    stride *= 4;
                    o = PixelFormat.Format32bppArgb;
                    break;

                    #endregion

                    #region A8R8G8B8

                case (ParsedBitmap.BitmapFormat)11:
                    stride *= 4;
                    o = PixelFormat.Format32bppArgb;
                    break;

                    #endregion

                    #region X8R8G8B8

                case (ParsedBitmap.BitmapFormat)10:
                    stride *= 4;
                    o = PixelFormat.Format32bppArgb;
                    break;

                    #endregion

                    #region // 16 bit \\

                    #region A4R4G4B4

                case (ParsedBitmap.BitmapFormat)9:
                    stride *= 4;
                    o = PixelFormat.Format32bppArgb;
                    poolength = sourceBytes.Length;
                    fu = new byte[poolength * 2];
                    for (int e = 0; e < poolength / 2; e++)
                    {
                        int r = e * 2;
                        fu[r * 2 + 0] = (byte)((sourceBytes[r + 1] & 0xFF) >> 0); // Blue
                        fu[r * 2 + 1] = (byte)((sourceBytes[r + 0] & 0xFF) >> 0); // Green
                        fu[r * 2 + 2] = (byte)((sourceBytes[r + 0] & 0xFF) >> 0); // Red
                        fu[r * 2 + 3] = 255; // (byte)(((sourceBytes[r + 1] & 0xFF) >> 0));        // Alpha
                    }

                    sourceBytes = fu;
                    break;

                    #endregion

                    #region G8B8

                case (ParsedBitmap.BitmapFormat)22:
                    stride *= 4;
                    o = PixelFormat.Format32bppArgb;
                    poolength = sourceBytes.Length;
                    fu = new byte[poolength / 2 * 4];

                    // These are actually signed (+/-128), so convert to unsigned
                    for (int e = 0; e < poolength / 2; e++)
                    {
                        int r = e * 2;
                        fu[r * 2 + 0] = (byte)(sourceBytes[r + 1] + 128); // Blue
                        fu[r * 2 + 1] = (byte)(sourceBytes[r + 1] + 128); // Green
                        fu[r * 2 + 2] = (byte)(sourceBytes[r + 0] + 128); // Red
                        fu[r * 2 + 3] = (byte)(sourceBytes[r + 0] + 128); // Alpha
                    }

                    sourceBytes = fu;
                    break;

                    #endregion

                    #region A1R5G5B5

                case (ParsedBitmap.BitmapFormat)8:
                    stride *= 2;
                    o = PixelFormat.Format16bppRgb555;
                    break;

                    #endregion

                    #region R5G6B5

                case (ParsedBitmap.BitmapFormat)6:
                    stride *= 2;
                    o = PixelFormat.Format16bppRgb565;
                    break;

                    #endregion

                    #region A8Y8

                case (ParsedBitmap.BitmapFormat)3:
                    o = PixelFormat.Format32bppArgb;
                    poolength = sourceBytes.Length;
                    fu = new byte[poolength / 2 * 4];
                    for (int e = 0; e < poolength / 2; e++)
                    {
                        int r = e * 2;
                        fu[r * 2 + 0] = sourceBytes[r + 1];
                        fu[r * 2 + 1] = sourceBytes[r + 1];
                        fu[r * 2 + 2] = sourceBytes[r + 1];
                        fu[r * 2 + 3] = sourceBytes[r + 0];
                    }

                    sourceBytes = fu;
                    stride *= 4;
                    break;

                    #endregion

                    #endregion

                    #region // 8 bit \\

                    #region P8

                case ParsedBitmap.BitmapFormat.BITM_FORMAT_P8:
                    o = PixelFormat.Format32bppArgb;
                    poolength = sourceBytes.Length;
                    fu = new byte[poolength * 4];
                    for (int e = 0; e < poolength; e++)
                    {
                        int r = e * 4;
                        fu[r + 0] = sourceBytes[e];
                        fu[r + 1] = sourceBytes[e];
                        fu[r + 2] = sourceBytes[e];
                        fu[r + 3] = 255;
                    }

                    sourceBytes = fu;
                    stride *= 4;
                    break;

                    #endregion

                    #region A8

                case ParsedBitmap.BitmapFormat.BITM_FORMAT_A8:
                    o = PixelFormat.Format32bppArgb;
                    poolength = sourceBytes.Length;
                    fu = new byte[poolength * 4];
                    for (int e = 0; e < poolength; e++)
                    {
                        int r = e * 4;
                        fu[r + 0] = sourceBytes[e];
                        fu[r + 1] = sourceBytes[e];
                        fu[r + 2] = sourceBytes[e];
                        fu[r + 3] = 255;
                    }

                    sourceBytes = fu;
                    stride *= 4;
                    break;

                    #endregion

                    #region AY8

                case ParsedBitmap.BitmapFormat.BITM_FORMAT_AY8:
                    o = PixelFormat.Format32bppArgb;
                    poolength = sourceBytes.Length;
                    fu = new byte[poolength * 4];
                    for (int e = 0; e < poolength; e++)
                    {
                        int r = e * 4;

                        /*
                        fu[r + 0] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15 + 128);
                        fu[r + 1] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15 + 128);
                        fu[r + 2] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15 + 128);
                        */
                        fu[r + 0] = (byte)(((sourceBytes[e] & 0xF0) >> 4) * 255 / 15);
                        fu[r + 1] = (byte)(((sourceBytes[e] & 0xF0) >> 4) * 255 / 15);
                        fu[r + 2] = (byte)(((sourceBytes[e] & 0xF0) >> 4) * 255 / 15);
                        fu[r + 3] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15);

                        /*
                        fu[r + 0] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15);
                        fu[r + 1] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15);
                        fu[r + 2] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15);
                        fu[r + 3] = (byte)(((sourceBytes[e] & 0xF0) >> 3) * 255 / 15);
                        if (sourceBytes[e] == 0)
                            fu[r + 3] = 0;
                        else
                            fu[r + 3] = 255;
                        */
                    }

                    sourceBytes = fu;
                    stride *= 4;
                    break;

                    #endregion

                    #region Y8

                case (ParsedBitmap.BitmapFormat)1:
                    o = PixelFormat.Format32bppArgb;
                    poolength = sourceBytes.Length;
                    fu = new byte[poolength * 4];
                    for (int e = 0; e < poolength; e++)
                    {
                        int r = e * 4;
                        fu[r + 0] = sourceBytes[e];
                        fu[r + 1] = sourceBytes[e];
                        fu[r + 2] = sourceBytes[e];
                        fu[r + 3] = 255;
                    }

                    sourceBytes = fu;
                    stride *= 4;
                    break;

                    #endregion

                    /*
                #region LightMap
                case ParsedBitmap.BitmapFormat.BITM_FORMAT_LIGHTMAP:
                    o = PixelFormat.Format32bppArgb;// Format32bppArgb;
                    poolength = sourceBytes.Length;
                    fu = new byte[poolength * 4];
                    int bspnumber = ident;
                    int paletteindex = -1;

                    if (visualchunkindex < 0)
                    {
                        int wtf = 0 - (visualchunkindex + 1);
                        paletteindex = map.BSP.sbsp[bspnumber].SceneryChunk_LightMap_Index[wtf];
                    }
                    if (paletteindex == -1)
                        for (int i = 0; i < map.BSP.sbsp[bspnumber].VisualChunk_Bitmap_Index.Length; i++)
                            if (map.BSP.sbsp[bspnumber].VisualChunk_Bitmap_Index[i] == visualchunkindex)
                            {
                                paletteindex = map.BSP.sbsp[bspnumber].VisualChunk_LightMap_Index[visualchunkindex];
                                break;
                            }

                    if (paletteindex == -1)
                        for (int i = 0; i < map.BSP.sbsp[bspnumber].SceneryChunk_Bitmap_Index.Length; i++)
                            if (map.BSP.sbsp[bspnumber].SceneryChunk_Bitmap_Index[i] == visualchunkindex)
                            {
                                paletteindex = map.BSP.sbsp[bspnumber].SceneryChunk_LightMap_Index[i];
                                break;
                            }

                    if (paletteindex == 255) return null;
                    for (int e = 0; e < poolength; e++)
                    {
                        int r = e * 4;
                        fu[r + 0] = (byte)map.BSP.sbsp[bspnumber].LightMap_Palettes[paletteindex][sourceBytes[e]].r;
                        fu[r + 1] = (byte)map.BSP.sbsp[bspnumber].LightMap_Palettes[paletteindex][sourceBytes[e]].g;
                        fu[r + 2] = (byte)map.BSP.sbsp[bspnumber].LightMap_Palettes[paletteindex][sourceBytes[e]].b;
                        fu[r + 3] = (byte)map.BSP.sbsp[bspnumber].LightMap_Palettes[paletteindex][sourceBytes[e]].a;

                    }
                    sourceBytes = fu;
                    stride *= 4;
                    break;
                #endregion
                */
                    #endregion

                default:
                    return null;
            }

            Marshal.FreeHGlobal(ptr);
            ptr = Marshal.AllocHGlobal(sourceBytes.Length);

            RtlMoveMemory(ptr, sourceBytes, sourceBytes.Length);

            return new Bitmap(b2.width, b2.height, stride, o, ptr);
        }
All Usage Examples Of HaloMap.DDSFunctions.DecodeDXT::DecodeDXT45