Beispiel #1
0
        public static JSPImage FromBitmap( Bitmap image )
        {
            byte[] JSPbytes = new byte[image.Width * image.Height];

            int bytesPerPixel = image.PixelFormat == PixelFormat.Format8bppIndexed ? 1 : 3;
            PixelFormat loadformat;
            if ( image.PixelFormat == PixelFormat.Format8bppIndexed )
                loadformat = PixelFormat.Format8bppIndexed;
            else
                loadformat = PixelFormat.Format24bppRgb;

            BitmapData imgdata = image.LockBits( new Rectangle( 0, 0, image.Width, image.Height ), ImageLockMode.ReadOnly, loadformat );

            byte[] imagebytes = new byte[bytesPerPixel * image.Width * image.Height];
            int numRows = image.Height;
            int numBytesPerRow = image.Width * bytesPerPixel;

            for ( int n = 0; n < image.Height; n++ )
            {
                Marshal.Copy(
                source: new IntPtr( imgdata.Scan0.ToInt64() + n * imgdata.Stride ),
                destination: imagebytes,
                startIndex: n * numBytesPerRow,
                length: numBytesPerRow
                );
            }

            if ( image.PixelFormat == PixelFormat.Format8bppIndexed )
            {
                JSPbytes = imagebytes;
            }
            else
            {
                for ( int i = 0; i < JSPbytes.Length; i++ )
                {
                    byte r, g, b;
                    b = imagebytes[3 * i];
                    g = imagebytes[3 * i + 1];
                    r = imagebytes[3 * i + 2];

                    JSPbytes[i] = (byte) CalculateNearestColor( r, g, b );
                }
            }
            image.UnlockBits( imgdata );

            JSPImage output = new JSPImage( (short) image.Width, (short) image.Height );
            output.SetData( JSPbytes );
            output.SetOffSet( 0, 0 );
            return output;
        }
Beispiel #2
0
        /*
        Jamul Sprite - JSP

        header:
        count		1 word	how many frames in this sprite
        data:
        count structures:
            width	1 word		width of sprite in pixels
            height	1 word		height of sprite in pixels
            ofsX	1 short		x-coord of hotspot relative to left
            ofsY	1 short		y-coord of hotspot relative to top
            size	1 dword		how big the sprite data is in bytes
            data	size bytes	transparency RLE'd sprite data

            The RLE format is as follows:

            count	1 byte	if count is positive, this is considered
                    a run of data, negative is a run of
                    transparency.  If the run is data, it is
                    followed by count bytes of data.  If
                    it is transparent, the next RLE tag
                    simply follows it.
                    Runs do not cross line boundaries. */
        /*
         * 00:52 - SpaceManiac: for each image you read its metadata then its data
        00:52 - SpaceManiac: you want to read all the metadata first
        00:52 - Blue Canary: ...oh.
        00:52 - Blue Canary: And then all the data is contiguous?
        00:52 - SpaceManiac: yeah
        00:52 - SpaceManiac: thought I mentioned that before
        00:52 - Blue Canary: ..no
        00:52 - Blue Canary: the opposite is implied by your spec
        */
        public static JSP Load( BinaryReader stream )
        {
            int pos = 0;

            Int16 ImageCount = stream.ReadInt16();
            pos += 2;
            if ( ImageCount < 1 )
                throw new InvalidDataException( "Non-positive image count" );

            int[] dataLengths = new int[ImageCount];

            JSP Collection = new JSP();

            for ( int im = 0; im < ImageCount; im++ )
            {
                Int16 width = stream.ReadInt16();
                Int16 height = stream.ReadInt16();
                pos += 2 + 2;
                if ( width < 1 || height < 1 )
                    throw new InvalidDataException( string.Format( "Image {0} has a height/width of {1},{2}. This doesn't make sense.", im, height, width ) );

                Int16 ofsX = stream.ReadInt16();
                Int16 ofsY = stream.ReadInt16();
                pos += 2 + 2;

                Int32 dataSize = stream.ReadInt32();
                pos += 4;

                stream.ReadInt32(); // Four blank bytes.
                pos += 4;

                dataLengths[im] = dataSize;

                JSPImage Image = new JSPImage( width, height );
                Image.SetOffSet( ofsX, ofsY );
                Collection.Images.Add( Image );

            }

            for ( int ImageNum = 0; ImageNum < ImageCount; ImageNum++ )
            {
                List<byte> imgdata = new List<byte>();

                for ( int byteIndex = 0; byteIndex < dataLengths[ImageNum]; byteIndex++ )
                {
                    byte sb = stream.ReadByte();
                    pos += 1;
                    bool negative = sb > 128;
                    byte usb = (byte) ( sb & 0x7F );

                    if ( negative )
                    {
                        for ( int i = 0; i < usb; i++ )
                        {
                            imgdata.Add( 0 );
                        }
                    }
                    else
                    {
                        for ( int i = 0; i < usb; i++ )
                        {
                            imgdata.Add( stream.ReadByte() );
                            pos += 1;
                            byteIndex++;
                        }
                    }
                }

                Collection.Images[ImageNum].SetData( imgdata.ToArray() );
            }

            return Collection;
        }