private HuffVal[] decodeHuff(int tableOffset) { HuffVal[] huffOut = new HuffVal[256]; int table1Len = DataUtil.getLEInt(fileData, tableOffset) * 2; int table1Start = tableOffset + 4; int table2Start = table1Start + table1Len; int table3Start = table2Start + 0x48; for (int i = 0; i < 256; ++i) { int bit = 1; int a = i >> (8 - bit); int v = DataUtil.getLEInt(fileData, table3Start + bit * 4); while (v < a) { ++bit; if (bit > 8) { break; } a = i >> (8 - bit); v = DataUtil.getLEInt(fileData, table3Start + bit * 4); } huffOut[i] = new HuffVal(); if (bit <= 8) { int val = DataUtil.getLEInt(fileData, table2Start + bit * 4); int table1Index = a + val; huffOut[i].val = DataUtil.getLEShort(fileData, table1Start + table1Index * 2); huffOut[i].numBits = (short)bit; } } return(huffOut); }
private HuffVal[] decodeHuff(int tableOffset) { HuffVal[] huffOut = new HuffVal[256]; int table1Len = DataUtil.getLEInt(fileData, tableOffset) * 2; int table1Start = tableOffset + 4; int table2Start = table1Start + table1Len; int table3Start = table2Start + 0x48; for (int i=0; i<256; ++i){ int bit=1; int a = i >> (8-bit); int v = DataUtil.getLEInt(fileData, table3Start + bit*4); while (v < a){ ++bit; if (bit > 8){ break; } a = i >> (8-bit); v = DataUtil.getLEInt(fileData, table3Start + bit*4); } huffOut[i] = new HuffVal(); if (bit <= 8){ int val = DataUtil.getLEInt(fileData, table2Start + bit*4); int table1Index = a + val; huffOut[i].val = DataUtil.getLEShort(fileData, table1Start + table1Index * 2 ); huffOut[i].numBits = (short)bit; } } return huffOut; }
private void decodeBlock(int xblock, int yblock, int blockDataStart, int table0Start, WriteableBitmap image, PalEntry[] palette, HuffVal[] huffVals) { int tableOffset = table0Start + 0x800; int table1Len = DataUtil.getLEInt(fileData, tableOffset) * 2; int table1Start = tableOffset + 4; int table2Start = table1Start + table1Len; int table3Start = table2Start + 0x48; int[] pix8s = new int[16*16]; int curpix8=0; int startBit=0; int prevPixel=0; for (int y=0; y<16; ++y){ for (int x=0; x < 16; ++x){ int startWordIdx = startBit / 16; int word1 = DataUtil.getLEUShort(fileData, blockDataStart + startWordIdx * 2); int word2 = DataUtil.getLEUShort(fileData, blockDataStart + startWordIdx * 2 + 2); // if startBit is 0, word == word1 // if startBit is 1, word is 15 bits of word1 and 1 bit of word2 int word = ((word1 << 16 | word2) >> (16 - (startBit & 0x0f))) & 0xFFFF; int byte1 = (word >> 8) & 0xff; HuffVal hv = huffVals[byte1]; int pixCmd; if (hv.numBits != 0){ pixCmd = hv.val; startBit += hv.numBits; } else { // Must be more than an 8 bit code int bit=9; int a = word >> (16-bit); int v = DataUtil.getLEInt(fileData, table3Start + bit*4); while (v < a){ ++bit; if (bit > 16){ throw new Exception("A decoding error occured"); } a = word >> (16-bit); v = DataUtil.getLEInt(fileData, table3Start + bit*4); } startBit += bit; int val = DataUtil.getLEInt(fileData, table2Start + bit*4); int table1Index = a + val; pixCmd = DataUtil.getLEShort(fileData, table1Start + table1Index*2); } int pix8 = 0; if (pixCmd < 0x100){ pix8 = pixCmd; } else if (pixCmd < 0x105){ int backjump = backJumpTable[pixCmd - 0x100]; if ((curpix8 + backjump) >= 0){ pix8 = pix8s[curpix8 + backjump]; } else { throw new Exception("Something went wrong"); } } else { int table0Index = (pixCmd - 0x105) + prevPixel * 8; pix8 = fileData[table0Start + table0Index] & 0xFF; } pix8s[curpix8++] = pix8; prevPixel = pix8 & 0xFF; PalEntry pixel = palette[pix8 & 0xFF]; var pBackBuffer = image.BackBuffer; int xpos = xblock * 16 + x; int ypos = yblock * 16 + y; var p = pBackBuffer + ypos * image.BackBufferStride + xpos * 4; unsafe { *((int*)p) = pixel.argb(); } } } }
private void decodeBlock(int xblock, int yblock, int blockDataStart, int table0Start, WriteableBitmap image, PalEntry[] palette, HuffVal[] huffVals) { int tableOffset = table0Start + 0x800; int table1Len = DataUtil.getLEInt(fileData, tableOffset) * 2; int table1Start = tableOffset + 4; int table2Start = table1Start + table1Len; int table3Start = table2Start + 0x48; int[] pix8s = new int[16 * 16]; int curpix8 = 0; int startBit = 0; int prevPixel = 0; for (int y = 0; y < 16; ++y) { for (int x = 0; x < 16; ++x) { int startWordIdx = startBit / 16; int word1 = DataUtil.getLEUShort(fileData, blockDataStart + startWordIdx * 2); int word2 = DataUtil.getLEUShort(fileData, blockDataStart + startWordIdx * 2 + 2); // if startBit is 0, word == word1 // if startBit is 1, word is 15 bits of word1 and 1 bit of word2 int word = ((word1 << 16 | word2) >> (16 - (startBit & 0x0f))) & 0xFFFF; int byte1 = (word >> 8) & 0xff; HuffVal hv = huffVals[byte1]; int pixCmd; if (hv.numBits != 0) { pixCmd = hv.val; startBit += hv.numBits; } else { // Must be more than an 8 bit code int bit = 9; int a = word >> (16 - bit); int v = DataUtil.getLEInt(fileData, table3Start + bit * 4); while (v < a) { ++bit; if (bit > 16) { throw new Exception("A decoding error occured"); } a = word >> (16 - bit); v = DataUtil.getLEInt(fileData, table3Start + bit * 4); } startBit += bit; int val = DataUtil.getLEInt(fileData, table2Start + bit * 4); int table1Index = a + val; pixCmd = DataUtil.getLEShort(fileData, table1Start + table1Index * 2); } int pix8 = 0; if (pixCmd < 0x100) { pix8 = pixCmd; } else if (pixCmd < 0x105) { int backjump = backJumpTable[pixCmd - 0x100]; if ((curpix8 + backjump) >= 0) { pix8 = pix8s[curpix8 + backjump]; } else { throw new Exception("Something went wrong"); } } else { int table0Index = (pixCmd - 0x105) + prevPixel * 8; pix8 = fileData[table0Start + table0Index] & 0xFF; } pix8s[curpix8++] = pix8; prevPixel = pix8 & 0xFF; PalEntry pixel = palette[pix8 & 0xFF]; var pBackBuffer = image.BackBuffer; int xpos = xblock * 16 + x; int ypos = yblock * 16 + y; var p = pBackBuffer + ypos * image.BackBufferStride + xpos * 4; unsafe { *((int *)p) = pixel.argb(); } } } }