コード例 #1
0
ファイル: Txf.cs プロジェクト: refox1/NisAnim
        private void ApplyColorPalette(Bitmap bitmap, byte[] paletteData, TxfDataFormat paletteFormat)
        {
            ColorPalette palette = bitmap.Palette;

            switch (paletteFormat)
            {
            case TxfDataFormat.Argb8888:
            {
                for (int i = 0, j = 0; i < palette.Entries.Length; i++, j += 4)
                {
                    palette.Entries[i] = Color.FromArgb(paletteData[j + 3], paletteData[j + 2], paletteData[j + 1], paletteData[j]);
                }
            }
            break;

            case TxfDataFormat.Argb4444:
            {
                for (int i = 0, j = 0; i < palette.Entries.Length; i++, j += 2)
                {
                    palette.Entries[i] = Color.FromArgb(
                        (byte)((paletteData[j] & 0xF0) | ((paletteData[j] & 0xF0) >> 4)),
                        (byte)((paletteData[j + 1] & 0x0F) | ((paletteData[j + 1] & 0x0F) << 4)),
                        (byte)((paletteData[j + 1] & 0xF0) | ((paletteData[j + 1] & 0xF0) >> 4)),
                        (byte)((paletteData[j] & 0x0F) | ((paletteData[j] & 0x0F) << 4)));
                }
            }
            break;

            default:
                throw new Exception(string.Format("Cannot generate color palette from data format '{0}'.", paletteFormat));
            }
            bitmap.Palette = palette;
        }
コード例 #2
0
ファイル: Txf.cs プロジェクト: refox1/NisAnim
        private byte[] DecompressDxt(EndianBinaryReader reader, TxfDataFormat format, int width, int height)
        {
            byte[] pixelData = new byte[CalculatePixelDataSize(TxfDataFormat.Argb8888, width, height)];

            for (int y = 0; y < height; y += 4)
            {
                for (int x = 0; x < width; x += 4)
                {
                    byte[] decompressedBlock = DecompressDxtBlock(reader, format);

                    for (int py = 0; py < 4; py++)
                    {
                        for (int px = 0; px < 4; px++)
                        {
                            int ix = (x + px);
                            int iy = (y + py);

                            if (ix >= width || iy >= height)
                            {
                                continue;
                            }

                            for (int c = 0; c < 4; c++)
                            {
                                pixelData[(((iy * width) + ix) * 4) + c] = decompressedBlock[(((py * 4) + px) * 4) + c];
                            }
                        }
                    }
                }
            }

            return(pixelData);
        }
コード例 #3
0
ファイル: Txf.cs プロジェクト: refox1/NisAnim
        private byte[] GetPixelData(EndianBinaryReader reader, TxfDataFormat format, uint dataSize)
        {
            byte[] pixelData     = new byte[dataSize];
            int    bytesPerPixel = (BitsPerPixel[format] >> 3);

            for (int i = 0; i < pixelData.Length; i += bytesPerPixel)
            {
                for (int j = bytesPerPixel - 1; j >= 0; j--)
                {
                    pixelData[i + j] = reader.ReadByte();
                }
            }

            return(pixelData);
        }
コード例 #4
0
ファイル: Txf.cs プロジェクト: refox1/NisAnim
        private byte[] DecompressDxtBlock(EndianBinaryReader reader, TxfDataFormat format)
        {
            byte[] outputData = new byte[(4 * 4) * 4];
            byte[] colorData  = null, alphaData = null;

            if (format != TxfDataFormat.RgbaDxt1)
            {
                alphaData = DecompressDxtAlpha(reader, format);
            }

            colorData = DecompressDxtColor(reader, format);

            for (int i = 0; i < colorData.Length; i += 4)
            {
                outputData[i]     = colorData[i];
                outputData[i + 1] = colorData[i + 1];
                outputData[i + 2] = colorData[i + 2];
                outputData[i + 3] = (alphaData != null ? alphaData[i + 3] : colorData[i + 3]);
            }

            return(outputData);
        }
コード例 #5
0
ファイル: Txf.cs プロジェクト: refox1/NisAnim
        private uint CalculatePaletteDataSize(TxfDataFormat pixelFormat, TxfDataFormat paletteFormat)
        {
            uint colorCount, bytesPerColor;

            switch (pixelFormat)
            {
            case TxfDataFormat.Indexed8bpp: colorCount = 256; break;

            default: throw new Exception(string.Format("Unknown color count for pixel format '{0}'.", pixelFormat));
            }

            switch (paletteFormat)
            {
            case TxfDataFormat.Argb8888: bytesPerColor = 4; break;

            case TxfDataFormat.Argb4444: bytesPerColor = 2; break;

            default: throw new Exception(string.Format("Unknown bytes/color for palette format '{0}'.", paletteFormat));
            }

            return(colorCount * bytesPerColor);
        }
コード例 #6
0
ファイル: Txf.cs プロジェクト: refox1/NisAnim
        private byte[] DecompressDxtAlpha(EndianBinaryReader reader, TxfDataFormat format)
        {
            byte[] alphaOut = new byte[(4 * 4) * 4];

            switch (format)
            {
            case TxfDataFormat.RgbaDxt3:
            {
                ulong alpha = reader.ReadUInt64();
                for (int i = 0; i < alphaOut.Length; i += 4)
                {
                    alphaOut[i + 3] = (byte)(((alpha & 0xF) << 4) | (alpha & 0xF));
                    alpha         >>= 4;
                }
            }
            break;

            case TxfDataFormat.RgbaDxt5:
            {
                byte alpha0 = reader.ReadByte();
                byte alpha1 = reader.ReadByte();
                byte bits_5 = reader.ReadByte();
                byte bits_4 = reader.ReadByte();
                byte bits_3 = reader.ReadByte();
                byte bits_2 = reader.ReadByte();
                byte bits_1 = reader.ReadByte();
                byte bits_0 = reader.ReadByte();

                ulong bits = (ulong)(((ulong)bits_0 << 40) | ((ulong)bits_1 << 32) | ((ulong)bits_2 << 24) | ((ulong)bits_3 << 16) | ((ulong)bits_4 << 8) | (ulong)bits_5);

                byte[] bitsExt = new byte[16];
                for (int i = 0; i < bitsExt.Length; i++)
                {
                    bitsExt[i] = (byte)((bits >> (i * 3)) & 0x7);
                }

                for (int y = 0; y < 4; y++)
                {
                    for (int x = 0; x < 4; x++)
                    {
                        byte code       = bitsExt[(y * 4) + x];
                        int  destOffset = (((y * 4) + x) * 4) + 3;

                        if (alpha0 > alpha1)
                        {
                            switch (code)
                            {
                            case 0x00: alphaOut[destOffset] = alpha0; break;

                            case 0x01: alphaOut[destOffset] = alpha1; break;

                            case 0x02: alphaOut[destOffset] = (byte)((6 * alpha0 + 1 * alpha1) / 7); break;

                            case 0x03: alphaOut[destOffset] = (byte)((5 * alpha0 + 2 * alpha1) / 7); break;

                            case 0x04: alphaOut[destOffset] = (byte)((4 * alpha0 + 3 * alpha1) / 7); break;

                            case 0x05: alphaOut[destOffset] = (byte)((3 * alpha0 + 4 * alpha1) / 7); break;

                            case 0x06: alphaOut[destOffset] = (byte)((2 * alpha0 + 5 * alpha1) / 7); break;

                            case 0x07: alphaOut[destOffset] = (byte)((1 * alpha0 + 6 * alpha1) / 7); break;
                            }
                        }
                        else
                        {
                            switch (code)
                            {
                            case 0x00: alphaOut[destOffset] = alpha0; break;

                            case 0x01: alphaOut[destOffset] = alpha1; break;

                            case 0x02: alphaOut[destOffset] = (byte)((4 * alpha0 + 1 * alpha1) / 5); break;

                            case 0x03: alphaOut[destOffset] = (byte)((3 * alpha0 + 2 * alpha1) / 5); break;

                            case 0x04: alphaOut[destOffset] = (byte)((2 * alpha0 + 3 * alpha1) / 5); break;

                            case 0x05: alphaOut[destOffset] = (byte)((1 * alpha0 + 4 * alpha1) / 5); break;

                            case 0x06: alphaOut[destOffset] = 0x00; break;

                            case 0x07: alphaOut[destOffset] = 0xFF; break;
                            }
                        }
                    }
                }
            }
            break;
            }

            return(alphaOut);
        }
コード例 #7
0
ファイル: Txf.cs プロジェクト: refox1/NisAnim
        private byte[] DecompressDxtColor(EndianBinaryReader reader, TxfDataFormat format)
        {
            byte[] colorOut = new byte[(4 * 4) * 4];

            ushort color0 = reader.ReadUInt16(Endian.LittleEndian);
            ushort color1 = reader.ReadUInt16(Endian.LittleEndian);
            uint   bits   = reader.ReadUInt32(Endian.LittleEndian);

            byte c0r, c0g, c0b, c1r, c1g, c1b;

            UnpackRgb565(color0, out c0r, out c0g, out c0b);
            UnpackRgb565(color1, out c1r, out c1g, out c1b);

            byte[] bitsExt = new byte[16];
            for (int i = 0; i < bitsExt.Length; i++)
            {
                bitsExt[i] = (byte)((bits >> (i * 2)) & 0x3);
            }

            for (int y = 0; y < 4; y++)
            {
                for (int x = 0; x < 4; x++)
                {
                    byte code       = bitsExt[(y * 4) + x];
                    int  destOffset = ((y * 4) + x) * 4;

                    if (format == TxfDataFormat.RgbaDxt1)
                    {
                        colorOut[destOffset + 3] = (byte)((color0 <= color1 && code == 3) ? 0 : 0xFF);
                    }

                    if (format == TxfDataFormat.RgbaDxt1 && color0 <= color1)
                    {
                        switch (code)
                        {
                        case 0x00:
                            colorOut[destOffset + 0] = c0b;
                            colorOut[destOffset + 1] = c0g;
                            colorOut[destOffset + 2] = c0r;
                            break;

                        case 0x01:
                            colorOut[destOffset + 0] = c1b;
                            colorOut[destOffset + 1] = c1g;
                            colorOut[destOffset + 2] = c1r;
                            break;

                        case 0x02:
                            colorOut[destOffset + 0] = (byte)((c0b + c1b) / 2);
                            colorOut[destOffset + 1] = (byte)((c0g + c1g) / 2);
                            colorOut[destOffset + 2] = (byte)((c0r + c1r) / 2);
                            break;

                        case 0x03:
                            colorOut[destOffset + 0] = 0;
                            colorOut[destOffset + 1] = 0;
                            colorOut[destOffset + 2] = 0;
                            break;
                        }
                    }
                    else
                    {
                        switch (code)
                        {
                        case 0x00:
                            colorOut[destOffset + 0] = c0b;
                            colorOut[destOffset + 1] = c0g;
                            colorOut[destOffset + 2] = c0r;
                            break;

                        case 0x01:
                            colorOut[destOffset + 0] = c1b;
                            colorOut[destOffset + 1] = c1g;
                            colorOut[destOffset + 2] = c1r;
                            break;

                        case 0x02:
                            colorOut[destOffset + 0] = (byte)((2 * c0b + c1b) / 3);
                            colorOut[destOffset + 1] = (byte)((2 * c0g + c1g) / 3);
                            colorOut[destOffset + 2] = (byte)((2 * c0r + c1r) / 3);
                            break;

                        case 0x03:
                            colorOut[destOffset + 0] = (byte)((c0b + 2 * c1b) / 3);
                            colorOut[destOffset + 1] = (byte)((c0g + 2 * c1g) / 3);
                            colorOut[destOffset + 2] = (byte)((c0r + 2 * c1r) / 3);
                            break;
                        }
                    }
                }
            }

            return(colorOut);
        }
コード例 #8
0
ファイル: Txf.cs プロジェクト: refox1/NisAnim
 private uint CalculatePixelDataSize(TxfDataFormat pixelFormat, int width, int height)
 {
     return((uint)(width * height * (BitsPerPixel[pixelFormat] >> 3)));
 }