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: enter image description here

PS3 edition screenshot:

enter image description here

PSP edition screenshot:

enter image description here

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.

enter image description here

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. :)

  • 1
    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 '14 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? – Jongware Mar 30 '14 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 – patr0805 Mar 30 '14 at 18:09
  • 1
    In normal integer maths, overflow is simply ignored. When counting with bytes, -35 = 256-35 = 221. – Jongware Mar 30 '14 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. – Guntram Blohm Mar 30 '14 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
pix = im.load()
def add(p, q):
    # 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])

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 :)

processed image

| improve this answer | |
  • 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. – patr0805 Sep 24 '14 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.


| improve this answer | |
  • 1
    I don't think cantordust will help much with this, because it's creating different graphic output from different types of input; it doesn't translate the input to an image bit by bit. Still, it seems like an interesting tool. Am i missing something, or doesn't the site have a download/tryout/contact link? – Guntram Blohm Mar 30 '14 at 22:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.