Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Original: https://gist.github.com/soeminnminn/e9c4c99867743a717f5b
- using System;
- using System.Drawing;
- using KKtIO = KKt.IO.KKtIO;
- namespace DIVAsprTool
- {
- public class DDS
- {
- public static byte[,] ReadDXTColors(ushort Max16, ushort Min16)
- {
- byte[,] Col = new byte[4,3];
- if (Max16 == 0 && Min16 == 0)
- return Col;
- byte R5 = (byte)(Max16 >> 11 & 0x1F);
- byte G6 = (byte)(Max16 >> 5 & 0x3F);
- byte B5 = (byte)(Max16 & 0x1F);
- Col[0, 0] = (byte)(R5 != 0 ? (R5 + 1) * 8 - 1 : 0);
- Col[0, 1] = (byte)(G6 != 0 ? (G6 + 1) * 4 - 1 : 0);
- Col[0, 2] = (byte)(B5 != 0 ? (B5 + 1) * 8 - 1 : 0);
- R5 = (byte)(Min16 >> 11 & 0x1F);
- G6 = (byte)(Min16 >> 5 & 0x3F);
- B5 = (byte)(Min16 & 0x1F);
- Col[1, 0] = (byte)(R5 != 0 ? (R5 + 1) * 8 - 1 : 0);
- Col[1, 1] = (byte)(G6 != 0 ? (G6 + 1) * 4 - 1 : 0);
- Col[1, 2] = (byte)(B5 != 0 ? (B5 + 1) * 8 - 1 : 0);
- for (int i = 0; i < 3; i++)
- {
- if (Max16 > Min16)
- Col[2, i] = (byte)Math.Ceiling((2 * Col[0, i] + Col[1, i]) / 3.0);
- else
- Col[2, i] = (byte)Math.Ceiling((Col[0, i] + Col[1, i]) / 2.0);
- Col[3, i] = (byte)Math.Ceiling((Col[0, i] + 2 * Col[1, i]) / 3.0);
- }
- return Col;
- }
- public static Bitmap DecompressBCn(int I, Bitmap bitmap, byte BCn, ref KKtIO reader)
- {
- byte[,] block;
- byte[,] block2;
- byte[,] Colors;
- long bits;
- uint bitmask;
- uint select;
- byte j;
- byte i;
- byte k;
- for (int y = 0; y < bitmap.Height; y += 4)
- for (int x = 0; x < bitmap.Width; x += 4)
- {
- block = new byte[4, 4];
- if (BCn > 2)
- {
- bits = reader.ReadInt64(true, true);
- block = ATI2Block(I, bits, BCn == 3, ref reader);
- if (BCn == 4)
- for (j = 0; j < 4 && y + j < bitmap.Height; j++)
- for (i = 0; i < 4 && x + i < bitmap.Width; i++)
- bitmap.SetPixel(x + i, y + j, Color.FromArgb(0xFF,
- block[j, i], 0, 0));
- else if (BCn == 5)
- {
- bits = reader.ReadInt64(true, true);
- block2 = ATI2Block(I, bits, false, ref reader);
- for (j = 0; j < 4 && y + j < bitmap.Height; j++)
- for (i = 0; i < 4 && x + i < bitmap.Width; i++)
- bitmap.SetPixel(x + i, y + j, Color.FromArgb(0xFF,
- block2[j, i], block[j, i], 0));
- }
- }
- if (BCn < 4)
- {
- Colors = ReadDXTColors(reader.ReadUInt16(), reader.ReadUInt16());
- bitmask = reader.ReadUInt32();
- for (j = 0, k = 0; j < 4 && y + j < bitmap.Height; j++)
- for (i = 0; i < 4 && x + i < bitmap.Width; i++, k++)
- {
- select = (uint)((bitmask & (0x03 << k * 2)) >> k * 2);
- bitmap.SetPixel(x + i, y + j, Color.FromArgb(BCn == 1 ? 0xFF : block[j, i],
- Colors[select, 0], Colors[select, 1], Colors[select, 2]));
- }
- }
- }
- return bitmap;
- }
- public static byte[,] ATI2Block(int I, long bits, bool isBC3, ref KKtIO reader)
- {
- byte[,] block = new byte[4, 4];
- if (bits >> 48 != 0)
- {
- long Color = CalcATI2Block(bits);
- long mask = bits & 0xFFFFFFFFFFFF;
- if (isBC3)
- mask = ((long)(reader.Endian((uint)(bits & 0xFFFFFF), true) >> 8) << 24) |
- (long)reader.Endian((uint)((bits >> 24) & 0xFFFFFF), true) >> 8;
- else
- {
- long In = 0;
- for (int i = 0; i < 6; i++)
- In = 256 * (((mask >> i * 8) & 0xFF) + In);
- In /= 256;
- mask = In;
- }
- for (byte j = 0; j < 4; j++)
- for (byte i = 0; i < 4; i++, mask >>= 3)
- block[j, i] = (byte)(Color >> (byte)((7 - (mask & 0x07)) * 8) & 0xFF);
- return block;
- }
- return block;
- }
- public static long CalcATI2Block(long bits)
- {
- byte a = (byte)(bits >> 56 & 0xFF);
- byte b = (byte)(bits >> 48 & 0xFF);
- double mode = a > b ? 7 : 5;
- bits = a << 8 | b;
- for (int i = 1; i < mode; i++)
- bits = bits << 8 | CDTB(((mode - i) * a + i * b) / 7.0);
- if (a <= b)
- bits = bits << 16 | 0xFF;
- return bits;
- }
- static byte CDTB(double c)
- {
- if (c * 10 % 10 > 5)
- c = Math.Ceiling(c);
- else
- c = Math.Floor(c);
- c = Math.Max(0, Math.Min(0xFF, c));
- return (byte)c;
- }
- public static unsafe void WriteARGB(ref byte* ptr, int stride, Color col, int x, int y)
- {
- ptr[(x * 4) + y * stride + 0] = col.B;
- ptr[(x * 4) + y * stride + 1] = col.G;
- ptr[(x * 4) + y * stride + 2] = col.R;
- ptr[(x * 4) + y * stride + 3] = col.A;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement