BCH.BCHTool.getIMG_ETC1 C# (CSharp) Method

getIMG_ETC1() private static method

private static getIMG_ETC1 ( BCHTexture bchtex, byte data ) : Bitmap
bchtex BCHTexture
data byte
return System.Drawing.Bitmap
        private static Bitmap getIMG_ETC1(BCHTexture bchtex, byte[] data)
        {
            Bitmap img = new Bitmap(Math.Max(nlpo2(bchtex.Width), 16), Math.Max(nlpo2(bchtex.Height), 16));
            string dllpath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location).Replace('\\', '/') + "/ETC1.dll";
            if (!File.Exists(dllpath)) File.WriteAllBytes(dllpath, Resources.ETC1);
            try
            {
                /*
                 * Much of this code is taken/modified from Tharsis: http://jul.rustedlogic.net/thread.php?pid=436556#436556 Thank you to Tharsis's creator, xdaniel.
                 */
                byte[] temp = new byte[bchtex.Length];
                Array.Copy(data, bchtex.DataOffset, temp, 0, bchtex.Length);
                /* Get compressed data & handle to it */
                byte[] textureData = temp;
                //textureData = switchEndianness(textureData, 0x10);
                ushort[] input = new ushort[textureData.Length / sizeof(ushort)];
                Buffer.BlockCopy(textureData, 0, input, 0, textureData.Length);
                GCHandle pInput = GCHandle.Alloc(input, GCHandleType.Pinned);

                /* Marshal data around, invoke ETC1.dll for conversion, etc */
                UInt32 size1 = 0, size2 = 0;
                UInt16 wd = (ushort)img.Width, ht = (ushort)img.Height;
                ConvertETC1(IntPtr.Zero, ref size1, IntPtr.Zero, ref size2, wd, ht, bchtex.Format == 0xD || bchtex.Format == 0xB); //true = etc1a4, false = etc1
                uint[] output = new uint[size1];
                GCHandle pOutput = GCHandle.Alloc(output, GCHandleType.Pinned);
                ConvertETC1(pOutput.AddrOfPinnedObject(), ref size1, pInput.AddrOfPinnedObject(), ref size2, wd, ht, bchtex.Format == 0xD || bchtex.Format == 0xB);
                pOutput.Free();
                pInput.Free();

                /* Unscramble if needed // could probably be done in ETC1.dll, it's probably pretty damn ugly, but whatever... */
                /* Non-square code blocks could need some cleanup, verification, etc. as well... */
                uint[] finalized = new uint[output.Length];

                //Act if it's square because BCLIM swizzling is stupid
                Buffer.BlockCopy(output, 0, finalized, 0, finalized.Length);

                byte[] tmp = new byte[finalized.Length];
                Buffer.BlockCopy(finalized, 0, tmp, 0, tmp.Length);
                int h = img.Height;
                int w = img.Width;
                byte[] imgData = tmp;
                for (int i = 0; i < img.Width; i++)
                {
                    for (int j = 0; j < img.Height; j++)
                    {
                        int k = (j + i * img.Height) * 4;
                        Color c = Color.FromArgb(imgData[k + 3], imgData[k], imgData[k + 1], imgData[k + 2]);
                        if (imgData[k] == imgData[k + 1] && imgData[k + 1] == imgData[k + 2] && imgData[k + 1] == 0)
                        {
                            if (imgData[k + 3] == 0)
                            {
                                c = Color.Transparent;
                            }
                        }
                        img.SetPixel(i, j, c);
                        /*if (bchtex.Format == 0xD)
                        {
                            img.SetPixel(i, j, Color.FromArgb(0xFF, imgData[k], imgData[k + 1], imgData[k + 2]));
                        }*/
                    }
                }
                //image is 13  instead of 12
                //         24             34
                img.RotateFlip(RotateFlipType.Rotate90FlipX);
                if (wd > ht)
                {
                    //image is now in appropriate order, but the shifting done been fucked up. Let's fix that.
                    Bitmap img2 = new Bitmap(Math.Max(nlpo2(bchtex.Width), 16), Math.Max(nlpo2(bchtex.Height), 16));
                    for (int y = 0; y < Math.Max(nlpo2(bchtex.Width), 16); y += 8)
                    {
                        for (int x = 0; x < Math.Max(nlpo2(bchtex.Height), 16); x++)
                        {
                            for (int j = 0; j < 8; j++) //treat every 8 vertical pixels as 1 pixel for purposes of calculation, add to offset later.
                            {
                                int x1 = (x + ((y / 8) * h)) % img2.Width; //reshift x
                                int y1 = ((x + ((y / 8) * h)) / img2.Width) * 8; //reshift y
                                img2.SetPixel(x1, y1 + j, img.GetPixel(x, y + j)); //reswizzle
                            }
                        }
                    }
                    return img2;
                }
                else if (ht > wd)
                {
                    //image is now in appropriate order, but the shifting done been fucked up. Let's fix that.
                    Bitmap img2 = new Bitmap(Math.Max(nlpo2(bchtex.Width), 16), Math.Max(nlpo2(bchtex.Height), 16));
                    for (int y = 0; y < Math.Max(nlpo2(bchtex.Width), 16); y += 8)
                    {
                        for (int x = 0; x < Math.Max(nlpo2(bchtex.Height), 16); x++)
                        {
                            for (int j = 0; j < 8; j++) //treat every 8 vertical pixels as 1 pixel for purposes of calculation, add to offset later.
                            {
                                int x1 = x % img2.Width; //reshift x
                                int y1 = ((x + ((y / 8) * h)) / img2.Width) * 8; //reshift y
                                img2.SetPixel(x1, y1 + j, img.GetPixel(x, y + j)); //reswizzle
                            }
                        }
                    }
                    return img2;
                }
            }
            catch (IndexOutOfRangeException)
            {
                //
            }
            catch (AccessViolationException)
            {
                //
            }
            return img;
        }