TO LOAD THIS PICO-8 CART
in immediate mode type out:
Hello. There have been a few picture compressors running around Pico-8 haven't there ? And a good chunk of them years ago were written by myself.
Well with inspiration in seeing code from @JadeLombax and others, I believe I have come up with a very perfect compressor. For one thing is it does not compress 4-bit, 5-bit. Not even 6-bit or 7-bit ! No it compresses pretty darned close to 8-bit. And in strings !
You can find our conversation HERE:
So what does it mean ? Well it means you're gonna get more bang for your byte than any of my previous 6-bit and even 7-bit compressors.
Included in this cart are images from some popular NES and Sega games to demonstrate its ability.
Run the cart to get the full 50 cent tour.
What separates this from most compressors though is the ability to CHOOSE the number of colors you want to compress. Naturally the less colors there are in your picture, the greater the compression.
The compressor and decompressor are pretty compact in themselves with the compressor at 152-tokens and the decompressor at 98-tokens.
Instructions are fully included in the cart. As always if you have any questions, comments, or kerosene :) feel free to enter them below.
Nice job on the algorithm, I've used some color indexing logic like this in my tweetcart sprite storage routines, but for some reason I didn't think to plug it in to my more substantial version.
Speaking of that, I have a new version that I was going to post that takes just 60 tokens and allows full 8-bit values, but it seems to take around 3% more byte space for strings than yours here, so I'll go ahead and see about making it used indexed colors for more efficiency.
Thanks much !
That's what I like to hear though, @JadeLombax. Good healthy competition. I can't claim to code correctly all the time, but sometimes I have ideas on things.
Now what would be epic but take a ton more code at least for me would be to scan the entire image for colors. Find which ones aren't even being used. Then create a compression algorithm and table based upon their absence.
I gotta feeling you're gonna do something like that. I almost want to congratulate you before you do it. :)
I must admit I really did look at your decompression code closely to try and figure out what you were doing. So a big part of my 8-bit compression is because I understood yours.
Teamwork. Anxious to see what you're gonna do.
Well, I got a new version (mostly) working. It finds the number of colors present in a picture and adds this list as a short color lookup table at the start of the image string. There's some kind of a glitch with the encoder which is causing the images to be a bit distorted, but I'll work that out somehow.
Weirdly, though, while the string character size is down a bit, the compressed byte size of the strings is consistently a bit higher than your examples here, which are around the same size as strings produced by the base-240 system I've been using. I've known that the base-240 system gives very slightly smaller data sizes than the base-256 system I just made, but the images in your examples seem to be making that difference more noticeable.
Yikes, dealing with multiple compression layers is a very fickle thing.
@JadeLombax, look to my code at line # 340. See where that is being used. This is what is giving me the edge in compression. And yeah I couldn't calculate it in the code so I had to manually build that string for the answers I needed.
Thanks for the shout-out @dw817, though I am very much not an artist. All I did was follow a tutorial (this one) and adapt it slightly to work on PICO-8. The real credit belongs to Inigo Quilez—not that I expect he'll ever see this or care—but credit where credit is due.
Also, entirely unrelated to the topic of the thread, but I really like the text typing/scroll effect you're using here!
Okay, so I fixed the issues with my variable-palette-size algorithm, made versions of it that use both 251 chars and the full 256 chars, and made comparisons of the compressed data sizes of these along with your compressor and my earlier fixed-palette 240 char version. Results below.(AP on the last two codecs stands for Adaptive Palette, since they use only the colors needed for each image)
Hillsfar (13 colors) dw817's codec - 2930 bytes Base 240 - 2931 bytes Base 251 AP - 2938 bytes Base 256 AP - 3020 bytes Looney Tunes (16 colors) dw817's codec - 2366 bytes Base 240 - 2368 bytes Base 251 AP - 2386 bytes Base 256 AP - 2435 bytes Accelebrid (10 colors) dw817's codec - 784 bytes Base 240 - 787 bytes Base 251 AP - 772 bytes Base 256 AP - 790 bytes Batman & Robin (11 colors) dw817's codec - 1504 bytes Base 240 - 1504 bytes Base 251 AP - 1519 bytes Base 256 AP - 1552 bytes Aladdin (14 colors) dw817's codec - 2155 bytes Base 240 - 2157 bytes Base 251 AP - 2169 bytes Base 256 AP - 2191 bytes Palm tree (4 colors) dw817's codec - 815 bytes Base 240 - 821 bytes Base 251 AP - 717 bytes Base 256 AP - 750 bytes
Basically, it seems that adapting the number of colors to fit the image in order to increase potential span length can be of some use, but it's only really noticeable on images with significantly less than 16 colors, and here the last two entries shine. In general, though, unless the number of colors is pretty low, they actually produce strings that take up more space. The base 251 AP codec consistently does better than base 256, so the loss of the extra few characters is more than made up for by not needing lots of escape chars in the strings. In general, strings from the fixed palette base 240 codec are within a few bytes of those from your base 251 codec.
One last thing, the 251-char adaptive palette codec does seem to produce strings of notiecably fewer characters than the rest, but this isn't a big factor unless you'd want to compress images directly to cart memory.
hi @jasondelaat. Well the palm tree belongs to Inigo then. That's fine.
And yes long before Pico-8 was even started I was having slow-type text with sound and having special characters and ability appear based upon unique characters like * _ and / for both Apple ][ and IBM-pc.
I got the idea originally from watching Beagle Bros ads. They were so neat. With the speaker chirping and letters appear for every click. They would scroll up, down, all around.
Lots of fun for that time period.
I know I did something more robust for Pico-8 years back. Let me see ...
Looks good ! And yes, until @zep actually allows us to enter true 8-bit characters into our code, we'll have to stick with something like what we wrote.
And and just FYI I did try out this which gave worse results. But was interesting to experiment with.
35-220 = raw pixel
221-254 = make up for 0-34
255 = marker (must be on even pixels, x=0, 2, 4, etc)
With marker you then state how many pixels you want in a byte, 2-220 based on char 35-255, then the next 4-bits is color and the process starts again.
Did quite worse in compression than the 4-bit pixel length 4-bit color I wrote above though which surprised me. I think this method might be quite useful on 8-bit or 24-bit color though. Although if you have 24-bit color available there's an excellent chance you already have .PNGs to work with.
Not now but later I'll see just how difficult it is to jam the color table up in there. I think it can be done efficiently though as you stated in your numbers.
Yes, I've had many compression ideas that seemed like they would work better than basic RLE, only to have them not work as well due to the particulars of Pico-8's built-in compression.
I don't think it's all a loss, though, since I'm thinking about making a compressor that stores map data in cart memory for a lightweight version of my map-building system.
You're very welcome !
But yep. I can see it's 6-bit, not 8-bit. Ah, I never really did like maps, @JadeLombax. Just about every game I had written after the age of 14 I wanted the computer to generate the maps every time.
Not only cause I was awful at designing levels :) but because I wanted the game to be different every time.
[Please log in to post a comment]