0

I get image png, this image has been compressed using the following method:

the first two pixels and all the odd pixels are false pixels:

  • the first pixel is actually an integer that represents the total number of pixel colors that must be repeated to build the decompressed image;
  • the second pixel is an integer which determines the height of the image once decompressed (its width is the same as that of the compressed image);
  • the third pixel and all subsequent odd pixels (pixels [2n +1] with n> = 1), are integers representing the number of repetitions to be performed on the following pixels (pixels [2n +2] with n> = 1 ).

I'm trying to get information about a PNG file.

BufferedImage img= ImageIO.read(new File("D://rle.png"));
        Raster raster=img.getData();
        int w=raster.getWidth();
        int h=raster.getHeight();

enter image description here

I'm looking for the fastest way to get pixel data and way to uncompress this image with this method.

Hassan Bendouj
  • 311
  • 1
  • 8
  • 14

1 Answers1

1

You have been had, or you have not been given (or are not giving us) the correct unpacking instructions, or (possibly) this image has gone through some processing, such as resampling or resizing, before or after it was posted here.

  • The image is a regular true-color + alpha PNG, 258 x 98 pixels.
  • According to its "tEXt", it has been created with "Software:Microsoft Office". It contains a 1-byte sRGB chunk, and the rest are all IDAT chunks -- plain data.
  • The plain data decompresses into 101234 bytes, which is the correct number for the size of the image.

That takes care of the preliminaries. Now on to decoding the raw data; and here come the discrepancies.

  • "the first pixel is actually an integer" -- the 'first pixel' value is 01 5A A5 FF. The last byte FF is not significant; it's the image alpha, and this is FF for all pixels. The remaining bytes can be read as Big Endian (10,836,481) or as Little Endian (88,741).
  • "the second pixel is an integer which determines the height" -- the 'second pixel' value is 08 08 83 FF. That would be a "height" of either 526,467 or 8,587,272 pixels -- take your pick.
  • "the third pixel [..] are integers representing the number of repetitions", well, the third pixel has an RGBA value of 1C 19 2E FF. Can you indicate which byte is 'the' integer value? Picking either one gives bad results (the image is not the expected 'size', and is not recognizable as an image anyway); using the full 3 byte value of 1,841,454 or 3,021,084 seems a bit too much for a plain RLE repetition value.

After getting a link to the correct image

Okay, it works as per original specification. The first 'pixel' values are to be interpreted as a 3-byte integer, Big Endian. The first value is 25,258 -- the number of repeat/data pairs to be unpacked. The next value is 400, the new image height. Note that supplying both is actually redundant; but you should use both to verify your algorithm.

In your own attempt, you are acquiring a pointer to the 'raw data' (correct) and reading the original width (also correct). But the height should be read from the raw data, as the guidelines stated.

Write a function read_3bytes_as_int that returns the next 'value' to be read. Use this to get (a) the 'unpacked' length, (b) the new height, and (c) each repeat count. The last one should be in a loop: read the repeat count, then read an RGB pixel and write this repeatedly to an output file. Keep a count of how many pixel/pairs you read, so you know when to stop.

Jongware
  • 22,200
  • 8
  • 54
  • 100
  • Alas -- unless my high school French deceives me, your translation appears to be correct. Is this all they say on the subject? To inspect the actual RLE data, you can open the PNG in Photoshop and save as a ".RAW" file. That way, the PNG encoding is out of the picture. – Jongware Jan 09 '14 at 00:02
  • You are right image resize before it was posted here, this is image with right data : isn.codelab.info/site/assets/files/1531/rle.png can you recalculate thanks, my translation it good – Hassan Bendouj Jan 09 '14 at 00:04
  • I save as a ".RAW" and is not recognizable as an image anyway) – Hassan Bendouj Jan 09 '14 at 00:08
  • Yes, but that is because this RAW data itself is RLE compressed. Gotta go to sleep now, will check the original file tomorrow if I can. – Jongware Jan 09 '14 at 00:11
  • What about signature of png ? – Hassan Bendouj Jan 09 '14 at 13:40
  • You are not interested in the PNG part. [This older question](http://stackoverflow.com/questions/6444869/how-do-i-read-pixels-from-a-png-file) shows how to access actual 'raw' pixels, without having to bother about what format the original image was. – Jongware Jan 09 '14 at 13:47
  • can you give me example how i can read byte to byte from raw data – Hassan Bendouj Jan 09 '14 at 13:57
  • when I call a getRGB method on a pixel, it returns a negative int. what is the meaning of this negative number? how can get 3 bytes from pixel ? – Hassan Bendouj Jan 09 '14 at 14:19
  • with getPixel always it ruturn a number >=0 && <=255 – Hassan Bendouj Jan 09 '14 at 14:30