/// <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);
        }