예제 #1
0
        private ImageByteArray32 ReadLinearImage(byte[] data, int w, int h)
        {
            ImageByteArray32 res = new ImageByteArray32(w, h);

            using (MemoryStream ms = new MemoryStream(data))
            {
                using (BinaryReader r = new BinaryReader(ms))
                {
                    for (int y = 0; y < h; y++)
                    {
                        for (int x = 0; x < w; x++)
                        {
                            res.SetPixel(x, y, Color.FromArgb(r.ReadInt32()));
                        }
                    }
                }
            }
            return(res);
        }
예제 #2
0
        private ImageByteArray32 UncompressDXT5(byte[] data, int w, int h)
        {
            ImageByteArray32 res = new ImageByteArray32((w < 4) ? 4 : w, (h < 4) ? 4 : h);

            using (MemoryStream ms = new MemoryStream(data))
            {
                using (BinaryReader r = new BinaryReader(ms))
                {
                    for (int j = 0; j < h; j += 4)
                    {
                        for (int i = 0; i < w; i += 4)
                        {
                            DecompressBlockDXT5(i, j, r.ReadBytes(16), res);
                        }
                    }
                }
            }
            return(res);
        }
예제 #3
0
        private ImageByteArray32 UncompressV8U8(byte[] data, int w, int h)
        {
            ImageByteArray32 res = new ImageByteArray32(w, h);

            using (MemoryStream ms = new MemoryStream(data))
            {
                using (BinaryReader r = new BinaryReader(ms))
                {
                    for (int y = 0; y < h; y++)
                    {
                        for (int x = 0; x < w; x++)
                        {
                            sbyte red   = r.ReadSByte();
                            sbyte green = r.ReadSByte();
                            byte  blue  = 0xFF;

                            res.SetPixel(x, y, Color.FromArgb(0x7F - red, 0x7F - green, blue));
                        }
                    }
                }
            }
            return(res);
        }
예제 #4
0
        void DecompressBlockDXT5(int x, int y, byte[] blockStorage, ImageByteArray32 image)
        {
            byte alpha0 = blockStorage[0];
            byte alpha1 = blockStorage[1];

            const int bitOffset  = 2;
            uint      alphaCode1 = (uint)(blockStorage[bitOffset + 2] | (blockStorage[bitOffset + 3] << 8) | (blockStorage[bitOffset + 4] << 16) | (blockStorage[bitOffset + 5] << 24));
            ushort    alphaCode2 = (ushort)(blockStorage[bitOffset + 0] | (blockStorage[bitOffset + 1] << 8));

            ushort color0 = (ushort)(blockStorage[8] | blockStorage[9] << 8);
            ushort color1 = (ushort)(blockStorage[10] | blockStorage[11] << 8);

            var  temp = (color0 >> 11) * 255 + 16;
            byte r0   = (byte)((temp / 32 + temp) / 32);

            temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
            byte g0 = (byte)((temp / 64 + temp) / 64);

            temp = (color0 & 0x001F) * 255 + 16;
            byte b0 = (byte)((temp / 32 + temp) / 32);

            temp = (color1 >> 11) * 255 + 16;
            byte r1 = (byte)((temp / 32 + temp) / 32);

            temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
            byte g1 = (byte)((temp / 64 + temp) / 64);

            temp = (color1 & 0x001F) * 255 + 16;
            byte b1 = (byte)((temp / 32 + temp) / 32);

            uint code = (uint)(blockStorage[12] | blockStorage[13] << 8 | blockStorage[14] << 16 | blockStorage[15] << 24);

            for (int j = 0; j < 4; j++)
            {
                for (int i = 0; i < 4; i++)
                {
                    int alphaCodeIndex = 3 * (4 * j + i);
                    int alphaCode;

                    if (alphaCodeIndex <= 12)
                    {
                        alphaCode = (alphaCode2 >> alphaCodeIndex) & 0x07;
                    }
                    else if (alphaCodeIndex == 15)
                    {
                        // JT changed this:
                        alphaCode = ((byte)(alphaCode2 >> 15) | (byte)((alphaCode1 << 1) & 0x06));
                    }
                    else
                    {
                        alphaCode = (int)((alphaCode1 >> (alphaCodeIndex - 16)) & 0x07);
                    }

                    byte finalAlpha;
                    if (alphaCode == 0)
                    {
                        finalAlpha = alpha0;
                    }
                    else if (alphaCode == 1)
                    {
                        finalAlpha = alpha1;
                    }
                    else
                    {
                        if (alpha0 > alpha1)
                        {
                            finalAlpha = (byte)(((8 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 7);
                        }
                        else
                        {
                            if (alphaCode == 6)
                            {
                                finalAlpha = 0;
                            }
                            else if (alphaCode == 7)
                            {
                                finalAlpha = 255;
                            }
                            else
                            {
                                finalAlpha = (byte)(((6 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 5);
                            }
                        }
                    }

                    byte colorCode = (byte)((code >> 2 * (4 * j + i)) & 0x03);

                    Color finalColor = new Color();
                    switch (colorCode)
                    {
                    case 0:
                        finalColor = Color.FromArgb(finalAlpha, r0, g0, b0);
                        break;

                    case 1:
                        finalColor = Color.FromArgb(finalAlpha, r1, g1, b1);
                        break;

                    case 2:
                        finalColor = Color.FromArgb(finalAlpha, (2 * r0 + r1) / 3, (2 * g0 + g1) / 3, (2 * b0 + b1) / 3);
                        break;

                    case 3:
                        finalColor = Color.FromArgb(finalAlpha, (r0 + 2 * r1) / 3, (g0 + 2 * g1) / 3, (b0 + 2 * b1) / 3);
                        break;
                    }
                    image.SetPixel(x + i, y + j, finalColor);
                }
            }
        }
예제 #5
0
        private void DecompressBlockDXT1(int x, int y, byte[] blockStorage, ImageByteArray32 image)
        {
            ushort color0 = (ushort)(blockStorage[0] | blockStorage[1] << 8);
            ushort color1 = (ushort)(blockStorage[2] | blockStorage[3] << 8);

            var  temp = (color0 >> 11) * 255 + 16;
            byte r0   = (byte)((temp / 32 + temp) / 32);

            temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
            byte g0 = (byte)((temp / 64 + temp) / 64);

            temp = (color0 & 0x001F) * 255 + 16;
            byte b0 = (byte)((temp / 32 + temp) / 32);

            temp = (color1 >> 11) * 255 + 16;
            byte r1 = (byte)((temp / 32 + temp) / 32);

            temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
            byte g1 = (byte)((temp / 64 + temp) / 64);

            temp = (color1 & 0x001F) * 255 + 16;
            byte b1 = (byte)((temp / 32 + temp) / 32);

            uint code = (uint)(blockStorage[4] | blockStorage[5] << 8 | blockStorage[6] << 16 | blockStorage[7] << 24);

            for (int j = 0; j < 4; j++)
            {
                for (int i = 0; i < 4; i++)
                {
                    Color finalColor   = Color.FromArgb(0);
                    byte  positionCode = (byte)((code >> 2 * (4 * j + i)) & 0x03);

                    if (color0 > color1)
                    {
                        switch (positionCode)
                        {
                        case 0:
                            finalColor = Color.FromArgb(255, r0, g0, b0);
                            break;

                        case 1:
                            finalColor = Color.FromArgb(255, r1, g1, b1);
                            break;

                        case 2:
                            finalColor = Color.FromArgb(255, (2 * r0 + r1) / 3, (2 * g0 + g1) / 3, (2 * b0 + b1) / 3);
                            break;

                        case 3:
                            finalColor = Color.FromArgb(255, (r0 + 2 * r1) / 3, (g0 + 2 * g1) / 3, (b0 + 2 * b1) / 3);
                            break;
                        }
                    }
                    else
                    {
                        switch (positionCode)
                        {
                        case 0:
                            finalColor = Color.FromArgb(255, r0, g0, b0);
                            break;

                        case 1:
                            finalColor = Color.FromArgb(255, r1, g1, b1);
                            break;

                        case 2:
                            finalColor = Color.FromArgb(255, (r0 + r1) / 2, (g0 + g1) / 2, (b0 + b1) / 2);
                            break;

                        case 3:
                            finalColor = Color.FromArgb(255, 0, 0, 0);
                            break;
                        }
                    }

                    image.SetPixel(x + i, y + j, finalColor);
                }
            }
        }