I solved it with a PNG header description and a hex editor, was not that hard.
Fortunately the error was quite at the beginning so it took only a few minutes
And yes, I've had the "can't edit post because I started the thread"-problem too, maybe an admin can fix that bug?
I thought that the error would be (very probably) in the data not in the header...
That's why I wrote my png "analyser" to find out what chunk is broken.
Then I just wanted to insert the correct CRC and see.
I was very supprised that my analyser stopped working in the middle of the data
Finally a hex editor did the job for me.
my first thought was to perform a brute force substitution, but the size of the image is too large.
so i had to checkout wiki for specifications of png format.
after knowing a bit of the structure of png, i tried to trace the Python Imaging Lib reading that png file.
when an error comes, the lib is NOT processing the checksum but chunkname
so i knew that the problem was the previous chunksize and wrote a piece of python code to fix it.
the output of my code is:
Chunkname=IHDR, Chunksize=13
Chunkname=tEXt, Chunksize=71
Chunkname=sRGB, Chunksize=1
Chunkname=IDAT, Chunksize=8192
Chunkname=IDAT, Chunksize=4096
True size should be 8192
I used the well-known 'pngckeck' tool under linux.
Thought the size of the second idat chunk was weird... So I tried to resize 0x10 -> 0x20, and it worked. I got quite lucky!
Force4 wrote:I used the well-known 'pngckeck' tool under linux.
Thought the size of the second idat chunk was weird... So I tried to resize 0x10 -> 0x20, and it worked. I got quite lucky!
I think I got even luckier because I just copied the length from the other chunk and it was thankfully the same.
Well, I done it by bruteforce. I wrote a short Matlab-script, which manipulated each byte and checked, if there was a readable png. It took about 10 hours. However the picture still seemed to be broken, though the text was readable. Can somebody verify, that the position of the broken byte was at about 8336 (dez.)? Thanks!
Check m!nus' post! Chunk no. 004 is nearly there. Since only the chunk size was wrong you should be able to view the whole png... and yes, it displayed a broken/cut film strip.
This one took me quite long and I analyzed much more than this. I thought the size might be ok and checked many other things ... but a post in the forum got me back on the right track.
this challenge took me quite a while to figure out, what to do -- i than wrote a little php script to test the IDAT chunks ... und fixed the byte in some hex editor. anyway -- i learned a lot interesting stuff about the png format because of this challenge ...
I have chosen brute force, just needed to detect if the resulting muted image is valid.
... but the file was too huge and some mutations shut down the "validator".
So I had to do it propper way ... I have decided to find the broken chunk so I start with creating the list of chunks ... and broken byte appeared.
I have expected the problem to be elsewhere ...
... made another mutation on other place and was able to correct it ... checksum calculation was several orders of magnitude faster than writing image and checking it's correctness.
I found the broken IDAT using pngcheck, and I was convinced this had to do with a bad CRC code. I got tired of trying to change bytes manually, so I started looking at the length field and it worked!
Actually, brute-force works quite well, since the changed byte is at the beginning of the file. I used Python and the Pillow library which is really great for anything image-related:
import io
from PIL import Image
def fixit():
byts = open('BrokenImage.png', 'rb').read()
for i in range(0, len(byts)):
x = bytearray(byts)
for c in range(256):
x[i] = c
f = io.BytesIO(x)
try:
Image.open(f).verify()
except (SyntaxError, OSError, IndexError):
continue
finally:
f.close()
print('Done! Replaced bit {} with {:#x}.'.format(i, c))
with open('FixedImage.png', 'wb') as f:
f.write(x)
return
fixit()
It finds the corrupted Byte within 7 minutes on my laptop. Searching the whole file would probably need half a day.[/url]