# What is this way of representing color in this unknown image format

All right, I have a PS3 image compressed with a variation of the LZ algoritm (magic bytes `43 5A 32 00`) (I have successfully decompressed it) and what I get from the decompressed form is a set of ARGB colors/pixels (The number of bytes in the compressed file is `4*width*height` thus I know that the decompressed file problably only contain the raw ARGB data).

Here is an image illustrating the result of rendering the ARGB data (transparency omitted to makes thing easier to make out).

Decompressed image:

PS3 edition screenshot:

PSP edition screenshot:

What I want to know is if any of you know what sort of logic this color structure use? To me, it looks like it looks at the last color in terms of the y-axis. Where zero value just gets the value of the last color of the y-axis. It kind of looks like I have to dif/sum colors together.

I have tried varies methods. For example, here I try storing a color array with zero color and for each line, sum the unsigned integer representation of ARGB of x position in the array with the new color' unsigned integer -> `A+B = C`.

A-B=C, just gives pinkish giberish..

Here are some samples of ARGB values that I use to try and find a solution:

``````x:0, y:24-27

R   G   B

137 195 255

240 254 000

014 000 255

001 001 001
``````

This should give a blueish color (comparing to Game screenshot) like: `145, 184, 219`.

*Please notice that my image for comparison isn't exact. That is to say that I got it from the same game of another platform where another format is used. Since the image sized are different. I can say that the colors aren't 100% the same as the new one.

``````x:4, y:22-28

R   G   B

137 195 255

118 168 201

255 204 161
``````

This too should give a dark bluerish color like: `020, 068, 096`.

*Please notice that the compared color in the game isn't exact, the image has transparency too, so the game has problably messed with the color values of the screenshot.

So if anybody have encountered stuff like this before and could give me a tip of some sort I would be very happy. :)

• Have you tried editing the bytes' values systemically? Do 0 0 0 0, 0 0 0 255 and/or 255 0 0 0 give you black? Do 255 255 255 0, 0 255 255 255 and/or 255 255 255 255 give you white? Have you tried setting the rest 3 bytes to zeros (or alpha can possibly be 255) and the setting only one byte at once to 127 and then to 255? Then do the same for all bytes, keeping other bytes' values zeros. This way you should be able to confirm the order of the red, green, blue and alpha channel bytes and see if their values have been flipped, for example.
– nrz
Mar 30, 2014 at 13:47
• The horizontal lines in what should be solid color, and the lack of vertical lines, suggests each "new" line is stored as the difference from the previous line. (Wait, you tried that 😳). Okay, you see you got something better. Do you process overflow correctly? Mar 30, 2014 at 16:21
• Overflow, I have tried saying that if the number goes below zero then it should make the result equals the absolute number.. that is to say, -35 would become 35. I have also tried saying that it should result in 255-35, but to no avail. nrz have given me an idea that I am currently trying out. I'll be back with the findings Mar 30, 2014 at 18:09
• In normal integer maths, overflow is simply ignored. When counting with bytes, -35 = 256-35 = 221. Mar 30, 2014 at 21:31
• Just an idea: could the 4 bytes be split into 2 bytes for "bad" hardware, and 2 bytes for "good" hardware? So a hex 12345678 would mean (alpha 1, red 2, green 3, blue 4) on a display that doesn't support full 8-bit RGB, and (alpha 15, red 26, green 37, blue 48) on a full color one? This type of encoding could enable the slow hardware to not read the "high-resolution-bits" at all, saving CPU time compared to throwing away those bits individually for each pixel. Mar 30, 2014 at 22:28

You asked this a couple of months ago, but I'm going to answer anyway.

First, I fear that your decompression code is buggy. There are several horizontal lines of noise, and I'm pretty sure they're not supposed to be there.

Your `A+B=C` guess was correct. A tell-tale sign are the visible horizontal edges but hidden vertical edges. I think your mistake was simply to do the addition with the wrong endianness.

I wrote a little Python script:

``````from PIL import Image
im = Image.open('orig.png')
w, h = im.size
# Convert (R,G,B) tuples to RGB integers, add them, and convert back
pp = (p[0] << 16) + (p[1] << 8) + p[2]
qq = (q[0] << 16) + (q[1] << 8) + q[2]
r = pp + qq
return ((r >> 16) & 0xFF, (r >> 8) & 0xFF, r & 0xFF)
for y in range(1, h):
for x in range(w):
pix[x,y] = add(pix[x, y], pix[x, y-1])
im.save('out.png')
``````

The result is this image. You can see that the top third matches the PSP image, but starting from the line of noise in the source image, the picture becomes distorted. Fix your decompression code and the picture will come out right :)

• You are correct, I noticed that there was a problem with my decompression algoritm and fixed it. After that this sum approach could be used without issue. Sep 24, 2014 at 11:09

Not sure how i would go about this but there is a tool called cantordust that can help with this, it can visualize binary information into pictograms. The link is down below.