Page 1 of 1

Wavelet Image Compression

Posted: Thu Feb 24, 2011 3:01 am
by keymasher
Today I was trying to pull off IƱigo's wavelet image comprssion in zge (scroll down to see the colour images) since my textures raw data are huge in zges final output.

The idea is to separate the chroma(greyscale) and luminance and blend them back together.

But I had some troubles combining a 32x32 image with a 256x256 image. I was hoping to BitmapFromFile then BitmapZoomRotate then BitmapCombine with another BitmapFromFile.

Or is there someway of compressing the textures? From the threads I read i saw either go procedural or hope upx compresses it enough.

Posted: Thu Feb 24, 2011 1:29 pm
by Kjell
Hmm,

The only way for that to make sense is when you "pack" 4 greyscale pixels per integer in a Array, and construct your Bitmap from that. When importing a greyscale image using BitmapFromFile, ZGE still treats it as a 24-bit per pixel source ( although it will compress better using UPX at that point ) causing you to end up with more data then the original full-size color image.

And UPX can actually increase* the size of your image data depending on their nature .. there's always the option of porting / writing your own compression library though.

*If that's the case, give the UPX LZMA option a try in Tools>Settings.

K

Posted: Thu Feb 24, 2011 1:37 pm
by keymasher
thats a great idea, i have to pass out now, but ill make that my exercise for tomorrow and post my work :)

try this,. .

Posted: Thu Feb 24, 2011 2:01 pm
by jph_wacheski
I had wanted to do something similar for different reasons, previously,. but you question gave me an idea,. I just store the image data in an array and then pull it back out in the larger bitmap. Seems to work great.

Perhaps both the BitmapLoad and the BitmapFromFile components could have an "Upscale" tick box? It could be usefull to also have them load smaller images, and just place them in the top left of the larger bitmap,. . then flips and stuff could be preformed..,

The luma/chroma compresion is very interesting,. the human mind is a strange object eh. face recognition is also an interesting field of study.. ,

NOTE: the F5 key is your friend when working with bitmaps,. esp. like this,. .

Posted: Thu Feb 24, 2011 2:57 pm
by Kjell
:)

Yea that approach works just fine ( in fact, you have to take that route when loading external images during runtime ).

Seems like keymasher wants to interpolate between the pixels though instead of simply using nearest neighbor. Attached is a example ( written for performance, not for clarity ).

K

Posted: Thu Feb 24, 2011 4:49 pm
by Kjell
@keymasher

By the way, in case you're wondering how to store & retrieve 4 grayscale pixels from a single integer .. use something like this.

Code: Select all

int P, P1, P2, P3, P4;

// Four unsigned 8-bit values ( 0-255 range )

P1 = 16;
P2 = 32;
P3 = 48;
P4 = 64;

// Generate 32-bit integer from four 8-bit values.

P = (P1<<24)+(P2<<16)+(P3<<8)+P4;

// Generate four 8-bit values from 32-bit integer

P1 = (P & 0xFF000000) >> 24; // P1 = P >> 24
P2 = (P & 0x00FF0000) >> 16;
P3 = (P & 0x0000FF00) >>  8;
P4 = (P & 0x000000FF) >>  0; // P4 = P & 0xFF
K

Posted: Fri Feb 25, 2011 8:27 am
by keymasher
I figured directly populating an array would be slow and horrible to manage in zge script, so I decided to pack all the data into an image. I tried using grayscale(8 bit values) but I noticed the amount of data just overshot the previous bitmap size.

I also noticed than adaptive indexed colour of chroma actually didnt look to bad, and then when you overlay the luminance its pretty damn good!

I figured I could then split up a 24 bit integer(pixel information) into 6, 4bit indexed colours AND save the 16 colour palette with room to spare. Doing this I could fit all the data I needed into the next smallest texture size - i.e a 256x256 image became a 128x128 'image' with palette data.

So I wrote a python script to pack all the data in an image and output it (its in the attached zip), requires pil. Just feed it your grayscale image and it'll do the rest.

Now I had this image I had to unpack it in ZGE, and I thought I got pretty close, but something went horribly wrong, my ChromaPalette Array seems to be all 0's.

Also, as it stands it would be abit cumbersome to setup for multiple textures.

I've attached all my work - hoping that someone can see where I went wrong.

Posted: Fri Feb 25, 2011 8:43 am
by VilleK
Found one thing, changed:

Code: Select all

int v = ChromaPalette[ChromaOutput[xpos*ypos]];
To:

Code: Select all

float v = ChromaPalette[ChromaOutput[xpos*ypos]] / 256.0;
Because when you assign this.r etc in a bitmapexpression it expects colors in float values.

Posted: Sat Feb 26, 2011 2:07 am
by keymasher
Alright so i fixed my ghetto encoder/decoder and working great, tho it had nothing to do with wavelets.

While searching for more information I found that haar wavelet compression has already been implemented in delphi by another demoscene coder(toxic avenger/ainc) and he released source to public domain

http://ainc.de/Wavelet.htm

Would it be worth implementing into zge?

Posted: Sun Feb 27, 2011 12:10 pm
by Kjell
Well,

One of the reasons that ZGE has such a small footprint is because the runner doesn't include any format decoders. If we're going to break that, I think it should be for something a little more conventional .. like JPG.

A wavelet ZLibrary can certainly be useful though. Here's a size comparison based on a 512x512 image ( 64x64 chroma ).

Image

JPG brings it down to only 37 KB though ( uncompressed & similar quality ), compared to the 151 KB of the Wavelet ( LZMA compressed ).

K

Smallest public domain JPEG library, in C

Posted: Thu Mar 03, 2011 11:33 am
by luminarious
Could this be used as inspiration in providing some support for JPEG/ PNG/ BMP/ TGA without considerably bloating things? http://nothings.org/stb_image.c

Posted: Thu Mar 03, 2011 1:27 pm
by Kjell
:?

There's some major overlap in features between those formats. PNG & TGA both do the same thing as BMP / PIC + GIF combined, but use a different ( lossless ) compression method. And HDR is a straight-up Bitmap ( RGBE ) format with a re-purposed Alpha Channel. JPG is the only truly different one ( as it is lossy ).

Don't get me wrong, I use external TGA / PIC ( Softimage ) files in my ZGE projects all the time, nor do I care much about footprint ..

K