Sprite compression Tool

Here is the sprite compression tool I created for my 2007 entry I have made it a little more user friendly and thought I would give it to the community.

The tool is useful for entrants who are using (or going to use) pre generated sprites in their game.

Features:

-Single or Multiple images can be stored in one output file
-When used with DataInjector can be embedded in the class file.
-Generates java source code for loading the images tailored for input images. This is to reduce overhead.
-1 bit transparancy
-Images are stored in a highly compressable format. For most sprites the file size is significantly less than crushed pngs.
-By using command line options you are able to reduce the file size even further by removing known properties from the images’ header portions. E.g. constant sprite dimensions, No transparancy, etc
-Able to store pixel colours in HSB format to cheaply generate different coloured versions of sprites by adding an offset to the HSB colour.

Download the tool here

Further information on the Image Format:

The main Idea to convert the image into a highly compressable format is to store an index of the different colours used in the image by order of similarity, thus pink is stored closer to red, different shades of yellow are next to each other and so forth. As it is likely that pixels with similar shades of colour are located near eachother due to shading and gradients in the sprites we can now record the difference between the previous pixel’s colour index and the current pixel’s colour index instead of recording the index of the colour used by each pixel.

This process can make long strings of similar bytes which Deflate can then compress extreamly well.

Comparision Results:

Each image format had been compressed into a ZIP file using KZIP to simulate embedding into a class file in a JAR

The BMP as been created using the 4 bit RLE option
The PNG has been passed though pngcrush using the brute and reduce options
The GIF has no extra options
The Ordered Index Differences version used the -auto and -noTrans options

Image Sprite used:

http://www.cuteandcuddlypet.com.au/moogie/toad_crushed.png



FORMAT       BYTES

GIF.zip      1060   
BMP.zip      1074
PNG.zip      1111
OID.zip      625


[quote=“moogie,post:1,topic:31078”]
Using SuperPackME:

SME.zip     594

I used InfoZip with the -9 option, so you can probably get better compression using 7Zip or KZip. (For comparison, I got 681 bytes for OID using InfoZip.)

Not to steal your thunder. This looks like a pretty cool tool! Do you know if the decompresser compiles any smaller than SuperPackME? That was where I was always losing some of my space. I did optimize the decompresser over the officially released version, but I always felt that it should be possible to get just a smidge more out of it. :slight_smile:

interesting thought!

I have not actually made a simple test to see how much overhead the decomression code introduces.

I have actually improved the tool somewhat since i posted it. The image format is unchanged however there is now three different schemes on how to order the colour index.

Can you provide a set of sprites which you have used to test the superpackme tool?

the image in simple gif format 449 … with appropriate option, you can grab it by right click than “save image as”

449 bytes

or in raw format :wink:

47 49 46 38 39 61 40 00 26 00 83 00 00 00 00 00 3f 26 26 10 56 63 04 90 77 4a d6 ad a5 bd c6 bd 84 4a ce ef d6 f7 de 5a ff ff ff 00 ff 00 ff ff 00 00 00 ff ff 00 ff 00 ff ff ff ff ff 21 f9 04 00 00 00 ff 00 2c 00 00 00 00 40 00 26 00 00 04 ff 30 c9 49 ab bd 38 eb cd bb ff 60 28 8e 64 d9 01 a8 e9 a1 6c 0b 9c 80 30 0c ac 8a b1 02 2a e4 ed 16 cf bc d9 cb 26 69 f1 02 06 43 00 70 38 30 87 17 00 50 37 4d a9 62 3b 20 12 61 60 3a 9d d0 ca 6f 20 ab 96 c3 a2 b1 94 40 20 ef 00 81 65 8d 42 6d 1f da e4 3a ad b4 a6 c9 9a 64 33 78 79 2e 6b 04 77 77 40 6e 87 6c 68 1f 63 39 7f 33 33 4d 78 32 02 05 28 82 6c 9c 93 03 6d 87 82 8e 30 58 9a 9f 78 6c 89 81 a5 65 9b 77 9d 9e 53 69 6f 2c 9e ad 53 b4 46 93 87 95 b6 65 39 23 00 05 3c 02 6c 84 bf 3f 2e bf 65 b0 84 52 79 24 46 a1 3c 46 3c c3 85 63 93 3b d4 97 a3 2b 7a 39 72 85 b9 ca da e4 52 c0 d1 3f 96 48 e2 2f 3d 16 3a e7 59 34 de 1c 54 aa 70 4b 21 d8 09 f2 56 c1 ca 1c 98 b2 2f cd 9c 22 07 67 51 6a 43 8d 88 c3 22 9b 84 c0 7b 78 e5 54 95 84 14 1f b9 f8 34 a9 9a bd 8c f1 6e 20 51 b9 d8 0d e4 bd 31 78 b0 51 99 68 32 5e ab 4e d4 54 c6 f8 98 f1 87 0c 46 66 62 16 6a e9 52 c8 36 72 98 46 ba 01 c8 b3 c8 19 99 38 b4 61 2c 1a a3 cd 47 4d b9 8a f6 84 76 a3 14 51 a9 08 3b 7a 7b b6 14 ab bf 62 17 c5 1c dd e9 b5 a9 1f 02 33 e9 dc 34 86 8b a6 43 a8 9a d2 4e 90 f7 93 d8 d5 96 35 5c 88 41 ea d6 ab df bf 52 23 00 00 3b

interesting!

I thought the output gif was the same from any paint program… i used paint shop pro 5 to save as gif. What did you use?

I will also add the test to see whether either the superpackme or the ordered index differences image compressed images + decompressors can beat embedded gifs.

no gif can have several options:
version 87/version 89
interlaced/not interlaced
type of palette:system,custom,etc…
number of color: 1-256
transparency: on/off

looking at your gif, I see they was not a lot of color so I simply reduce the number of color to 10 with PSP8, can be done by most picture editor, also using it in raw format you can remove some bytes for multiple gif by removing identical header “GIF89a…” that will always contain same info width/height/nb color etc…

NB: in most case zipping a gif/png/jpg should not reduce it as gif is viewing by zipper as random number, without pattern. zipping an already compressed file is ususally not necessary.

NB2: I would recommend using animated gif for multiple sprites with low color, so palette will be only encoded once and use jpg with low chrominance channel sampling 4:4:1 for complexe sprite as photo or such.

good point, however not all sprites are the same size so will not work in an animated gif unless you increase the the size of all sprites to match the largest which may introduce more overhead by reducing the sprite sizes when decompressed.

while embedding the gif inside the class will cause it to be “zipped” again and probably add a few bytes, the size of the embedded class when JARed sould still be quite a bit smaller than a JAR with the class and the gif in seperate files

from my testing it seems that my decompression algorithm is cheaper than SuperPackME decompression algorithm so for small number of sprites the ordered index differences compresses better, however the story changes with larger number of sprites as the SuperPackME compresses better and over comes the cost of the decompression algorithm.

I wonder if i can merge the two algorithms and get even better compression :slight_smile: