示例#1
0
        /*
        ======================
        =
        = 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);
                }
            }
        }
示例#2
0
        /*
        ===========================
        =
        = MakeShape
        =
        = Takes a raw bit map of width bytes by height and creates a scaleable shape
        =
        = Returns the length of the shape in bytes
        =
        ===========================
        */
        private void SC_MakeShape(memptr src, short width, short height, ref memptr shapeseg)
        {
            short pixwidth = (short) (width * 8);

            memptr tempseg_memptr = new memptr(); // as: added
            MMGetPtr(ref tempseg_memptr, pixwidth * (height + 20)); // larger than needed buffer

            scaleshape tempseg = new scaleshape(tempseg_memptr);

            tempseg.width = pixwidth; // pixel dimensions
            tempseg.height = height;

            //
            // convert ega pixels to byte color values in a temp buffer
            //
            // Stored in a collumn format, not rows!
            //
            memptr byteseg = new memptr();
            MMGetPtr(ref byteseg, pixwidth * height);

            memptr byteptr = new memptr(byteseg);

            memptr plane0 = new memptr(src);
            memptr plane1 = new memptr(plane0, width * height);
            memptr plane2 = new memptr(plane1, width * height);
            memptr plane3 = new memptr(plane2, width * height);

            for(short x = 0; x < width; x++)
            {
                for(ushort b = 0; b < 8; b++)
                {
                    ushort shift = (ushort) (8 - b);
                    ushort offset = (ushort) x;

                    for(short y = 0; y < height; y++)
                    {
                        byte by0 = plane0.GetUInt8(offset);
                        byte by1 = plane1.GetUInt8(offset);
                        byte by2 = plane2.GetUInt8(offset);
                        byte by3 = plane3.GetUInt8(offset);
                        offset += (ushort) width;

                        ushort color = 0;

                        // as: converted from asm
                        color |= AsmRotate(by3, shift);
                        color <<= 1;
                        color |= AsmRotate(by2, shift);
                        color <<= 1;
                        color |= AsmRotate(by1, shift);
                        color <<= 1;
                        color |= AsmRotate(by0, shift);

                        byteptr.SetUInt8(0, (byte) color);
                        byteptr.Offset(1);
                    } // Y
                } // B
            } // X

            //
            // convert byte map to sparse scaling format
            //
            memptr saveptr = tempseg.PointerTofirst(pixwidth);

            // start filling in data after all pointers to line segments
            byteptr = new memptr(byteseg); // first pixel in byte array

            for(short x = 0; x < pixwidth; x++)
            {
                //
                // each vertical line can have 0 or more segments of pixels in it
                //
                short y = 0;
                memptr segptr = tempseg.PointerTofirst(x);
                segptr.SetUInt16(0, 0); // in case there are no segments on line
                do
                {
                    // scan for first pixel to be scaled
                    while(y < height && byteptr.GetUInt8(0) == BACKGROUND) // as: bugfix - re-ordered to prevent out of bounds read
                    {
                        byteptr.Offset(1);
                        y++;
                    }

                    if(y == height) // if not, the line is finished
                        continue;

                    //
                    // start a segment by pointing the last link (either shape.first[x] if it
                    // is the first segment, or a seg.next if not) to the current spot in
                    // the tempseg, setting segptr to this segments next link, and copying
                    // all the pixels in the segment
                    //
                    segptr.SetUInt16(0, _sys.FP_OFF(saveptr)); // pointer to start of this segment

                    short start = y;
                    short length = 0;

                    scaleseg scale_seg = new scaleseg(saveptr);

                    memptr dataptr = scale_seg.PointerToData(0);

                    //
                    // copy bytes in the segment to the shape
                    //
                    while(y < height && byteptr.GetUInt8(0) != BACKGROUND) // as: bugfix - re-ordered to prevent out of bounds read
                    {
                        length++;
                        dataptr.SetUInt8(0, byteptr.GetUInt8(0));
                        dataptr.Offset(1);
                        byteptr.Offset(1);
                        y++;
                    }

                    scale_seg.start = start;
                    scale_seg.length = length;
                    scale_seg.next = 0;

                    // get ready for next segment
                    segptr = new memptr(saveptr, scaleseg.FieldOffset_next);

                    saveptr = dataptr; // next free byte to be used

                } while(y < height);
            }

            //
            // allocate exact space needed and copy shape to it, then free buffers
            //
            MMGetPtr(ref shapeseg, _sys.FP_OFF(saveptr));
            Array.Copy(tempseg.Pointer.Buffer, shapeseg.Buffer, _sys.FP_OFF(saveptr));
            MMFreePtr(ref byteseg);
            MMFreePtr(ref tempseg_memptr);
        }