charleysdrpepper

GS2 Huffman (Variant) Decompression

Sep 24th, 2019
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.21 KB | None | 0 0
  1.         static public byte[] decompText(byte[] src)
  2.         { //, int srcInd) { // int srcPos) {
  3.             //return decompTextOld2(src);
  4.             int total = 0; int total2 = 0;
  5.             DateTime c = DateTime.Now;
  6.             //Scan char data to generate data for faster decompression than old method.
  7.             int asmpchar = Bits.getInt32(src, 0x38578) - 0x8000000;
  8.             int asmptext = Bits.getInt32(src, 0x385DC) - 0x8000000;
  9.             int chardata = Bits.getInt32(src, asmpchar) - 0x08000000;
  10.             int charpntrs = Bits.getInt32(src, asmpchar + 4) - 0x08000000;
  11.  
  12.             //Do a pre-scan of char tables to determine array sizes.
  13.             int maxLetter = 0;
  14.             int cTreeSize = 0;
  15.             int maxDepth = 0;
  16.             for (int char1 = 0; char1 <= maxLetter; char1++)
  17.             {
  18.                 if ((char1 & 0xFF) == 0)
  19.                 {
  20.                     chardata = Bits.getInt32(src, asmpchar + (char1 >> 8) * 8) - 0x08000000;
  21.                     charpntrs = Bits.getInt32(src, asmpchar + (char1 >> 8) * 8 + 4) - 0x08000000;
  22.                 }
  23.                 //if (charpntrs == asmpchar) { break; }
  24.                 if (Bits.getInt16(src, charpntrs) == 0x8000) { charpntrs += 2; continue; }
  25.                 total2 += 1;
  26.                 int charTree = (chardata + Bits.getInt16(src, charpntrs)) << 3; charpntrs += 2;
  27.                 int charSlot = charTree - 12;
  28.                 int depth = 0;
  29.                 while (true)
  30.                 {
  31.                     while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { depth++; cTreeSize++; }
  32.                     int letter = ((Bits.getInt16(src, charSlot >> 3) >> (charSlot & 7)) & 0xFFF); charSlot -= 12; total += 1;
  33.                     cTreeSize++;
  34.                     if (letter > maxLetter) { maxLetter = letter; }
  35.                     if (depth > maxDepth) { maxDepth = depth; }
  36.                     //if ((char1 == 0) && (letter == 7))
  37.                     //    Console.WriteLine("0-7 depth: " + depth);
  38.                     if (depth <= 0) break;
  39.                     --depth;
  40.                 } //while (depth > 0);
  41.             }
  42.             Console.WriteLine("Total letter combos: " + total + "  \nTotal unique letters: " + total2 + "\nMax letter: " + maxLetter + "\nMax depth: " + maxDepth + "\ncTreeSize: " + cTreeSize);
  43.  
  44.             chardata = Bits.getInt32(src, asmpchar) - 0x08000000;
  45.             charpntrs = Bits.getInt32(src, asmpchar + 4) - 0x08000000;
  46.             int[] ctOffsets = new int[maxLetter + 1];// 0x1000];
  47.             int[] cTree = new int[cTreeSize];// 0x10000];
  48.             int[] nodeOffsets = new int[maxDepth]; //0x100]; //For temp use as we label leaves first, and iterate backwards.
  49.             //int[] ctOffsets = new int[0x1000];
  50.             //int[] cTree = new int[0x10000];
  51.             //int[] nodeOffsets = new int[0x100]; //For temp use as we label leaves first, and iterate backwards.
  52.             //int depth = 0;
  53.             int pos = 0;
  54.             for (int char1 = 0; char1 <= maxLetter; char1++)
  55.             {
  56.                 if ((char1 & 0xFF) == 0)
  57.                 {
  58.                     chardata = Bits.getInt32(src, asmpchar + (char1 >> 8) * 8) - 0x08000000;
  59.                     charpntrs = Bits.getInt32(src, asmpchar + (char1 >> 8) * 8 + 4) - 0x08000000;
  60.                 }
  61.                 //if (charpntrs == asmpchar) { break; }
  62.                 if (Bits.getInt16(src, charpntrs) == 0x8000) { charpntrs += 2; continue; }
  63.                 //total2 += 1;
  64.                 int charTree = (chardata + Bits.getInt16(src, charpntrs)) << 3; charpntrs += 2;
  65.                 int charSlot = charTree - 12;
  66.                 int depth = 0;
  67.  
  68.                 ctOffsets[char1] = pos;
  69.                 while (true)
  70.                 {
  71.                     while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { nodeOffsets[depth++] = pos++; }
  72.                     cTree[pos++] = -((Bits.getInt16(src, charSlot >> 3) >> (charSlot & 7)) & 0xFFF); charSlot -= 12; //total += 1;
  73.  
  74.                     if (depth <= 0) break;
  75.                     cTree[nodeOffsets[--depth]] = pos;
  76.                 } //while (depth > 0);
  77.             }
  78.  
  79.             //Console.WriteLine(DateTime.Now - c);
  80.             //c = DateTime.Now;
  81.             int textTree = 0, textLenAddr = 0;
  82.             byte[] des = new byte[0x800000]; int desEntry = 0, desPos = 0xC300;
  83.             for (int srcI = 0; srcI < 12461; srcI++)
  84.             {
  85.                 Bits.setInt32(des, desEntry, desPos - 0xC300); desEntry += 4;
  86.                 int srcInd = srcI;
  87.                 if ((srcInd & 0xFF) == 0)
  88.                 {
  89.                     textTree = Bits.getInt32(src, asmptext + ((srcInd >> 8) << 3)) - 0x08000000;
  90.                     textLenAddr = Bits.getInt32(src, asmptext + ((srcInd >> 8) << 3) + 4) - 0x08000000;
  91.                 }
  92.                 else
  93.                 {
  94.                     int cLen;
  95.                     do
  96.                     {
  97.                         cLen = src[textLenAddr++];
  98.                         textTree += cLen;
  99.                     } while (cLen == 0xFF);
  100.                 }
  101.                 int initChar = 0, textTree2 = textTree << 3;//, bitnum = 1, val = 0;
  102.                 do
  103.                 {
  104.                     pos = ctOffsets[initChar];
  105.                     while (cTree[pos] > 0)
  106.                     {
  107.                         if ((src[textTree2 >> 3] >> (textTree2++ & 7) & 1) == 0) { pos++; }
  108.                         else { pos = cTree[pos]; }
  109.                         //--- if using textTree2 = textTree; ---
  110.                         //if (bitnum >= 0x100) { bitnum = 1; textTree2++; }
  111.                         //if ((src[textTree2] & bitnum) == 0) { pos++; }
  112.                         //else { pos = cTree[pos]; }
  113.                         //bitnum <<= 1;
  114.                     }
  115.                     initChar = -cTree[pos]; //bitChar[entry]; val >>= bitLen[entry]; bitnum -= bitLen[entry];
  116.                     des[desPos++] = (byte)initChar;
  117.                     if (srcI == 5468)
  118.                         Console.Write(initChar.ToString("X2")+" ");
  119.                 } while (initChar != 0);
  120.             }
  121.             Console.WriteLine(DateTime.Now - c + " (Text Decompression)");
  122.             return des;
  123.         }
Advertisement
Add Comment
Please, Sign In to add comment