/// <summary>Creates a shallow copy of a huffnode.</summary> /// <param name="other">Another huffnode to copy.</param> public huffnode(huffnode other) : this(other._pointer.Buffer, other._pointer.BaseIndex) { }
/// <summary>Creates a new huffnode for the nth element in an array of huffnodes.</summary> /// <param name="array">The huffnode that is the first element in the array.</param> /// <param name="elementIndex">The element index.</param> public huffnode(huffnode array, int elementIndex) : this(array._pointer.Buffer, array._pointer.BaseIndex + SizeOf * elementIndex) { }
public static void HuffExpand(memptr source, memptr dest, int length, huffnode hufftable) { HuffExpand(source.Buffer, source.BaseIndex, dest.Buffer, dest.BaseIndex, length, hufftable); }
/* ====================== = = HuffExpand = ====================== */ public static void HuffExpand(byte[] sourceBuffer, int sourceIndex, byte[] destBuffer, int destIndex, int length, huffnode hufftable) { memptr source = new memptr(sourceBuffer, sourceIndex); memptr dest = new memptr(destBuffer, destIndex); ushort bit, _byte, code; huffnode nodeon, headptr; headptr = new huffnode(hufftable, 254); // head node is allways node 254 // as: The disabled C code that was in this function appears to be the C version of the asm code // this came in handy during the conversion nodeon = new huffnode(headptr); // as: bugfix - refactored to prevent the out of bounds read that can occur occasionally with the final byte bit = 256; _byte = 0; while(length != 0) { if(bit == 256) { bit = 1; _byte = source.GetUInt8(0); source.Offset(1); } if((_byte & bit) != 0) code = nodeon.bit1; else code = nodeon.bit0; bit <<= 1; if(code < 256) { dest.SetUInt8(0, (byte) code); dest.Offset(1); nodeon = headptr; length--; } else { nodeon = new huffnode(hufftable, code - 256); } } }
/* ============================================================================ COMPRESSION routines, see JHUFF.C for more ============================================================================ */ /* =============== = = OptimizeNodes = = Goes through a huffman table and changes the 256-511 node numbers to the = actular address of the node. Must be called before HuffExpand = =============== */ private void OptimizeNodes(huffnode table) { // as: Leave nodes as they are, HuffExpand has been modified to handle this }
//========================================================================== ///////////////////////////////////////////////////////// // // InitGrFile // ///////////////////////////////////////////////////////// private void InitGrFile() { // // calculate some offsets in the header // grhuffman = new huffnode(grhead); grstarts = new memptr(grhead.Buffer, grhead.dataoffsets); OptimizeNodes(grhuffman); // // Open the graphics file, leaving it open until the game is finished // grhandle = _sys.open("EGAGRAPH." + EXTENSION); if(grhandle.IsNull) Quit("Cannot open EGAGRAPH." + EXTENSION + "!"); memptr buffer = new memptr(); // // load the pic and sprite headers into the data segment // needgr[STRUCTPIC] = 1; // make sure this chunk never reloads grsegs[STRUCTPIC] = new memptr(null, 0xffff); GetChunkLength(STRUCTPIC); // position file pointer MMGetPtr(ref buffer, chunkcomplen); SegRead(ref grhandle, buffer, chunkcomplen); // as: Added temp pointer memptr temp = new memptr(new byte[pictable.Length * pictype.SizeOf], 0); HuffExpand(buffer.Buffer, buffer.BaseIndex, temp.Buffer, 0, temp.Buffer.Length, grhuffman); // as: Initialise pictypes for(int i = 0; i < pictable.Length; i++) { pictable[i] = new pictype(temp); temp.Offset(pictype.SizeOf); } MMFreePtr(ref buffer); }