Advertisement
kujikita

DDS.cs

Dec 14th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.93 KB | None | 0 0
  1. //Original: https://gist.github.com/soeminnminn/e9c4c99867743a717f5b
  2.  
  3. using System;
  4. using System.Drawing;
  5. using KKtIO = KKt.IO.KKtIO;
  6.  
  7. namespace DIVAsprTool
  8. {
  9.     public class DDS
  10.     {
  11.         public static byte[,] ReadDXTColors(ushort Max16, ushort Min16)
  12.         {
  13.             byte[,] Col = new byte[4,3];
  14.             if (Max16 == 0 && Min16 == 0)
  15.                 return Col;
  16.             byte R5 = (byte)(Max16 >> 11 & 0x1F);
  17.             byte G6 = (byte)(Max16 >> 5 & 0x3F);
  18.             byte B5 = (byte)(Max16 & 0x1F);
  19.             Col[0, 0] = (byte)(R5 != 0 ? (R5 + 1) * 8 - 1 : 0);
  20.             Col[0, 1] = (byte)(G6 != 0 ? (G6 + 1) * 4 - 1 : 0);
  21.             Col[0, 2] = (byte)(B5 != 0 ? (B5 + 1) * 8 - 1 : 0);
  22.             R5 = (byte)(Min16 >> 11 & 0x1F);
  23.             G6 = (byte)(Min16 >> 5 & 0x3F);
  24.             B5 = (byte)(Min16 & 0x1F);
  25.             Col[1, 0] = (byte)(R5 != 0 ? (R5 + 1) * 8 - 1 : 0);
  26.             Col[1, 1] = (byte)(G6 != 0 ? (G6 + 1) * 4 - 1 : 0);
  27.             Col[1, 2] = (byte)(B5 != 0 ? (B5 + 1) * 8 - 1 : 0);
  28.             for (int i = 0; i < 3; i++)
  29.             {
  30.                 if (Max16 > Min16)
  31.                     Col[2, i] = (byte)Math.Ceiling((2 * Col[0, i] + Col[1, i]) / 3.0);
  32.                 else
  33.                     Col[2, i] = (byte)Math.Ceiling((Col[0, i] + Col[1, i]) / 2.0);
  34.                 Col[3, i] = (byte)Math.Ceiling((Col[0, i] + 2 * Col[1, i]) / 3.0);
  35.             }
  36.             return Col;
  37.         }
  38.  
  39.         public static Bitmap DecompressBCn(int I, Bitmap bitmap, byte BCn, ref KKtIO reader)
  40.         {
  41.             byte[,] block;
  42.             byte[,] block2;
  43.             byte[,] Colors;
  44.             long bits;
  45.             uint bitmask;
  46.             uint select;
  47.             byte j;
  48.             byte i;
  49.             byte k;
  50.  
  51.             for (int y = 0; y < bitmap.Height; y += 4)
  52.                 for (int x = 0; x < bitmap.Width; x += 4)
  53.                 {
  54.                     block = new byte[4, 4];
  55.                     if (BCn > 2)
  56.                     {
  57.                         bits = reader.ReadInt64(true, true);
  58.                         block = ATI2Block(I, bits, BCn == 3, ref reader);
  59.                         if (BCn == 4)
  60.                             for (j = 0; j < 4 && y + j < bitmap.Height; j++)
  61.                                 for (i = 0; i < 4 && x + i < bitmap.Width; i++)
  62.                                     bitmap.SetPixel(x + i, y + j, Color.FromArgb(0xFF,
  63.                                         block[j, i], 0, 0));
  64.                         else if (BCn == 5)
  65.                         {
  66.                             bits = reader.ReadInt64(true, true);
  67.                             block2 = ATI2Block(I, bits, false, ref reader);
  68.                             for (j = 0; j < 4 && y + j < bitmap.Height; j++)
  69.                                 for (i = 0; i < 4 && x + i < bitmap.Width; i++)
  70.                                     bitmap.SetPixel(x + i, y + j, Color.FromArgb(0xFF,
  71.                                         block2[j, i], block[j, i], 0));
  72.                         }
  73.                     }
  74.                     if (BCn < 4)
  75.                     {
  76.                         Colors = ReadDXTColors(reader.ReadUInt16(), reader.ReadUInt16());
  77.                         bitmask = reader.ReadUInt32();
  78.  
  79.                         for (j = 0, k = 0; j < 4 && y + j < bitmap.Height; j++)
  80.                             for (i = 0; i < 4 && x + i < bitmap.Width; i++, k++)
  81.                             {
  82.                                 select = (uint)((bitmask & (0x03 << k * 2)) >> k * 2);
  83.                                 bitmap.SetPixel(x + i, y + j, Color.FromArgb(BCn == 1 ? 0xFF : block[j, i],
  84.                                     Colors[select, 0], Colors[select, 1], Colors[select, 2]));
  85.                             }
  86.                     }
  87.                 }
  88.             return bitmap;
  89.         }
  90.  
  91.         public static byte[,] ATI2Block(int I, long bits, bool isBC3, ref KKtIO reader)
  92.         {
  93.             byte[,] block = new byte[4, 4];
  94.  
  95.             if (bits >> 48 != 0)
  96.             {
  97.                 long Color = CalcATI2Block(bits);
  98.                 long mask = bits & 0xFFFFFFFFFFFF;
  99.                 if (isBC3)
  100.                     mask = ((long)(reader.Endian((uint)(bits & 0xFFFFFF), true) >> 8) << 24) |
  101.                         (long)reader.Endian((uint)((bits >> 24) & 0xFFFFFF), true) >> 8;
  102.                 else
  103.                 {
  104.                     long In = 0;
  105.                     for (int i = 0; i < 6; i++)
  106.                         In = 256 * (((mask >> i * 8) & 0xFF) + In);
  107.                     In /= 256;
  108.                     mask = In;
  109.                 }
  110.  
  111.                 for (byte j = 0; j < 4; j++)
  112.                     for (byte i = 0; i < 4; i++, mask >>= 3)
  113.                         block[j, i] = (byte)(Color >> (byte)((7 - (mask & 0x07)) * 8) & 0xFF);
  114.                 return block;
  115.             }
  116.             return block;
  117.         }
  118.  
  119.         public static long CalcATI2Block(long bits)
  120.         {
  121.             byte a = (byte)(bits >> 56 & 0xFF);
  122.             byte b = (byte)(bits >> 48 & 0xFF);
  123.             double mode = a > b ? 7 : 5;
  124.             bits = a << 8 | b;
  125.             for (int i = 1; i < mode; i++)
  126.                 bits = bits << 8 | CDTB(((mode - i) * a + i * b) / 7.0);
  127.             if (a <= b)
  128.                 bits = bits << 16 | 0xFF;
  129.             return bits;
  130.         }
  131.  
  132.         static byte CDTB(double c)
  133.         {
  134.             if (c * 10 % 10 > 5)
  135.                 c = Math.Ceiling(c);
  136.             else
  137.                 c = Math.Floor(c);
  138.             c = Math.Max(0, Math.Min(0xFF, c));
  139.             return (byte)c;
  140.         }
  141.  
  142.         public static unsafe void WriteARGB(ref byte* ptr, int stride, Color col, int x, int y)
  143.         {
  144.             ptr[(x * 4) + y * stride + 0] = col.B;
  145.             ptr[(x * 4) + y * stride + 1] = col.G;
  146.             ptr[(x * 4) + y * stride + 2] = col.R;
  147.             ptr[(x * 4) + y * stride + 3] = col.A;
  148.         }
  149.     }
  150. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement