1

I am trying to decode a PNG file coming as an Uint8Array from the backend using javascript in the browser. Slicing the Uint8Array from 15~28 and console.logging the values prints this : [82, 0, 0, 1, 0, 0, 0, 1, 0, 8, 6, 0, 0]. If I sum the bytes from 0~4 in this array I obtain 83 which should be the value for the width, but the width is 256px.

With the same file I tried decoding it on this website https://www.nayuki.io/page/png-file-chunk-inspector it show [00 00 00 0d 49 48 44 52 00 00 01 00 00] these values for 15~28. But it correctly says that the png has a width of 256px. Which I also don't understand how, adding 00+00+00+0d results a value of 13 in decimal.

So far I don't really understand what happens. The PNG standard says that http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html the IHDR width is a 4-byte integer from 15~19 but in practice it is not working.

enter image description here

Lupexlol
  • 63
  • 7
  • "All integers that require more than one byte must be in network byte order: the most significant byte comes first, then the less significant bytes in descending order of significance (MSB LSB for two-byte integers, B3 B2 B1 B0 for four-byte integers)." -- http://www.libpng.org/pub/png/spec/1.2/PNG-DataRep.html – Nayuki Jun 20 '22 at 17:28

1 Answers1

1

Looking through the image decoding website you linked, it seems that the first 4 hex values represent how many bytes are in the rest of the string: this is why the first 4 work out to 13, because there should be 13 bytes in the IHDR. Additionally, the next 4 [49, 48, 44, 52] stay the same between your image and all of the 'good' examples on the website. The real place where the width and height are stored are the two bytes after that, which are both 00 00 01 00. This value 00000100 works out to be 256, as per this converter

sami-amer
  • 254
  • 3
  • 9
  • OK, this helped me understand a bit more of what happens and I now look for the data bytes starting from 16 but I am still confused. My uintarray first 4 values are 0, 0, 1, 0. Which should be representing the width. What I don't understand is why is the decoder transforming 0 to 00 and 0 to 01 and then concatenating the values and parse them to decimal from hex. Why is it even in hex? – Lupexlol Jun 17 '22 at 17:24
  • 1
    How are you reading the hex data? These values are not `uint8`, so it is converting them from 00 to 0, and from 01 to 1, because 00 and 01 are not valid `uint8` values. You need to read them as hex to get the right values. As to why they are in hex, I thin you would need to ask whoever created the png format. The first four values of the width are NOT `0,0,1,0`, they are `00 00 01 00` or 256 in hex. Something is converting the hex to integers incorrectly – sami-amer Jun 17 '22 at 17:31
  • The file is being uploaded on the backend by using the FILE javascript web api. The file gets converted on the frontend to an uint8array by calling the uint8array constructor with file.arrayBuffer() . The file gets stored as uint8array on the backend, no further processing is happening there. Then I simply do an api request for the file which gets back like this. I did a check and the file before uploading and after getting it back look exactly the same. I tried loading the img as data url in a img src tag and it worked so it is not corrupted. – Lupexlol Jun 17 '22 at 17:40
  • from what I understand it happens is that my uint8array is actually an array full of decimals that get converted to hexa and if they are single digit then a 0 is added in front – Lupexlol Jun 17 '22 at 18:00