AmaroK86.ImageFormat.DDSImage.UncompressATI2 C# (CSharp) Method

UncompressATI2() private static method

private static UncompressATI2 ( byte imgData, int w, int h ) : Bitmap
imgData byte
w int
h int
return System.Drawing.Bitmap
        private static Bitmap UncompressATI2(byte[] imgData, int w, int h)
        {
            const int bufferSize = 16;
            const int bytesPerPixel = 3;
            byte[] blockStorage = new byte[bufferSize];
            MemoryStream bitmapStream = new MemoryStream(w * h * 2);

            int ptr = 0;
            for (int s = 0; s < h; s += 4)
            {
                for (int t = 0; t < w; t += 4)
                {
                    Buffer.BlockCopy(imgData, ptr, blockStorage, 0, bufferSize);
                    ptr += bufferSize;
                    #region Block Decompression Loop
                    byte[][] rgbVals = new byte[3][];
                    byte[] blueVals = new byte[bufferSize];
                    for (int j = 1; j >= 0; j--)
                    {
                        byte colour0 = blockStorage[j * 8]; // First 2 bytes are the min and max vals to be interpolated between
                        byte colour1 = blockStorage[1 + (j * 8)];
                        ulong longRep = BitConverter.ToUInt64(blockStorage, j * 8);
                        byte[] colVals = new byte[bufferSize];

                        //for (int k = 0; k < bufferSize; k++)
                        for (int k = bufferSize - 1; k >= 0; k--)
                        {
                            ulong tempLong = longRep | (ulong)ATI2BitCodes.interpColor5; // Set all trailing bits to 1

                            if ((tempLong ^ (ulong)ATI2BitCodes.color0) == (ulong)ATI2BitCodes.result) // First 2 values mean to use the specified min or max values
                            {
                                colVals[k] = colour0;
                            }
                            else if ((tempLong ^ (ulong)ATI2BitCodes.color1) == (ulong)ATI2BitCodes.result)
                            {
                                colVals[k] = colour1;
                            }
                            else if ((tempLong ^ (ulong)ATI2BitCodes.interpColor0) == (ulong)ATI2BitCodes.result) // Remaining values interpolate the min/max
                            {
                                if (colour0 > colour1)
                                    colVals[k] = (byte)((6 * colour0 + colour1) / 7);
                                else
                                    colVals[k] = (byte)((4 * colour0 + colour1) / 5);
                            }
                            else if ((tempLong ^ (ulong)ATI2BitCodes.interpColor1) == (ulong)ATI2BitCodes.result)
                            {
                                if (colour0 > colour1)
                                    colVals[k] = (byte)((5 * colour0 + 2 * colour1) / 7);
                                else
                                    colVals[k] = (byte)((3 * colour0 + 2 * colour1) / 5);
                            }
                            else if ((tempLong ^ (ulong)ATI2BitCodes.interpColor2) == (ulong)ATI2BitCodes.result)
                            {
                                if (colour0 > colour1)
                                    colVals[k] = (byte)((4 * colour0 + 3 * colour1) / 7);
                                else
                                    colVals[k] = (byte)((2 * colour0 + 3 * colour1) / 5);
                            }
                            else if ((tempLong ^ (ulong)ATI2BitCodes.interpColor3) == (ulong)ATI2BitCodes.result)
                            {
                                if (colour0 > colour1)
                                    colVals[k] = (byte)((3 * colour0 + 4 * colour1) / 7);
                                else
                                    colVals[k] = (byte)((colour0 + 4 * colour1) / 5);
                            }
                            else if ((tempLong ^ (ulong)ATI2BitCodes.interpColor4) == (ulong)ATI2BitCodes.result)
                            {
                                if (colour0 > colour1)
                                    colVals[k] = (byte)((2 * colour0 + 5 * colour1) / 7);
                                else
                                    colVals[k] = 0;
                            }
                            else if ((tempLong ^ (ulong)ATI2BitCodes.interpColor5) == (ulong)ATI2BitCodes.result)
                            {
                                if (colour0 > colour1)
                                    colVals[k] = (byte)((colour0 + 6 * colour1) / 7);
                                else
                                    colVals[k] = 255;
                            }
                            else
                            {
                                //MessageBox.Show("Error. Bitwise value not found."); // Safety catch. Shouldn't ever be encountered
                                throw new FormatException("Unknown bit value found. This shouldn't be possible...");
                            }
                            longRep <<= 3;
                        }
                        int index = (j == 0) ? 0 : 1;
                        rgbVals[index] = colVals;
                    }
                    for (int j = 0; j < bufferSize; j++)
                    {
                        if (rgbVals[0][j] <= 20 && rgbVals[1][j] <= 20)
                            blueVals[j] = 128;
                        else
                            blueVals[j] = 255;
                    }
                    rgbVals[2] = blueVals;
                    #endregion

                    for (int i = 0; i < 4; i++)
                    {
                        bitmapStream.Seek(((s + i) * w * bytesPerPixel) + (t * bytesPerPixel), SeekOrigin.Begin);
                        for (int j = 0; j < 4; j++)
                        {
                            //for (int k = 0; k < 3; k++)
                            for (int k = 2; k >= 0; k--)
                                bitmapStream.WriteByte(rgbVals[k][(i * 4) + j]);
                        }
                    }
                }
            }

            byte[] imageData = bitmapStream.ToArray();
            if (imageData.Length != (w * h * bytesPerPixel))
                throw new FormatException("Incorect length of generated data array");
            var bmp = new Bitmap(w, h, PixelFormat.Format24bppRgb);
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat);
            Marshal.Copy(imageData, 0, bmpData.Scan0, imageData.Length);
            bmp.UnlockBits(bmpData);

            return bmp;
        }
        #endregion