PNG Dimensions Question

General FreeBASIC programming questions.
datwill310
Posts: 355
Joined: May 29, 2015 20:37

PNG Dimensions Question

Postby datwill310 » Aug 14, 2017 16:28

Hi all,

In my program I load dozens of images. Rn I have to hard-code all the dimensions of each PNG image along with the loading code. But to help me add more images to this list faster, I was wondering if I could gather such dimensional information with each file instead.

I have researched into the PNG format, and I have found this, the IHDR chunk. I figured reading the figures directly from the file instead of having to use FreeImage functions was preferable. Within the chunk is supposed to be the information I am after (i.e. the width and height of the image), right after the declaration of the chunk using the bytes "IHDR".
I have used a hex editor with a few images and I can't seem to find their dimensions at all within the chunk, using any sized register i.e. 4bytes, 8bytes etc., and at any position within the chunk.
AFAI knew, this chunk wasn't compressed because it is "(13 data bytes total)" and the wiki page doesn't mention compression at this point of the article.

In short, where exactly are these bytes of information (width and height of image) located in a PNG file, and what size are the values storing the width and height (I am assuming 4 bytes but idrk)?

Thanks for reading
srvaldez
Posts: 2063
Joined: Sep 25, 2005 21:54

Re: PNG Dimensions Question

Postby srvaldez » Aug 14, 2017 17:07

try this, no guarantee it will work on all your png's

Code: Select all

dim as ubyte n
dim as long x, y
open "yourimage.png" for binary as 1
   Get #1,19 , n
   x=n*256
   Get #1,20 , n
   x=x+n
   ? x
   Get #1,23 , n
   y=n*256
   Get #1,24 , n
   y=y+n
   ? y
close 1
srvaldez
Posts: 2063
Joined: Sep 25, 2005 21:54

Re: PNG Dimensions Question

Postby srvaldez » Aug 14, 2017 17:27

the image I looked at had the bytes 17 and 18 as 0 and bytes 21 and 22 as 0 so I don't know if they are part of the image dimension or not.
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Re: PNG Dimensions Question

Postby datwill310 » Aug 14, 2017 17:34

srvaldez wrote:the image I looked at had the bytes 17 and 18 as 0 and bytes 21 and 22 as 0 so I don't know if they are part of the image dimension or not.

It appears as 0 too for all the images I've tried with it...
EDIT: Whoops... I used the wrong path for the image files, that's why it wasn't working xD.
Fixed that and it works very well! Thanks srvaldez!
srvaldez
Posts: 2063
Joined: Sep 25, 2005 21:54

Re: PNG Dimensions Question

Postby srvaldez » Aug 14, 2017 18:04

the problem is that the size info is big endian?
I thought FB had a byte-swap macro but can't find it in the help.

Code: Select all

dim as ushort x, y

open "yourimage.png" for binary as 1
   Get #1,19 , x
   asm
      mov      ax, [x]
      xchg   al, ah
      mov      [x], ax
   end asm
   ? x
   Get #1,23 , y
   asm
      mov      ax, [y]
      xchg   al, ah
      mov      [y], ax
   end asm
   ? y
close 1
fxm
Posts: 9126
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: PNG Dimensions Question

Postby fxm » Aug 14, 2017 18:22

For example:

Code: Select all

#macro byte_swap(short_variable)
  Swap Cptr(Byte Ptr, @(short_variable))[0], Cptr(Byte Ptr, @(short_variable))[1]
#endmacro
srvaldez
Posts: 2063
Joined: Sep 25, 2005 21:54

Re: PNG Dimensions Question

Postby srvaldez » Aug 14, 2017 19:17

thank you fxm :-)
srvaldez
Posts: 2063
Joined: Sep 25, 2005 21:54

Re: PNG Dimensions Question

Postby srvaldez » Aug 14, 2017 20:39

after thinking about it, more than likely the size info is a long, though you'd have to have a really huge image, nevertheless thanks to fxm's macro modified a bit.

Code: Select all

dim as ulong x, y

#macro byte_reverse(long_variable)
   Swap Cptr(Byte Ptr, @(long_variable))[0], Cptr(Byte Ptr, @(long_variable))[3]
    Swap Cptr(Byte Ptr, @(long_variable))[1], Cptr(Byte Ptr, @(long_variable))[2]
#endmacro

open "yourimage.png" for binary as 1
   Get #1,17 , x
   byte_reverse(x)
   Print x
   Get #1,21 , y
   byte_reverse(y)
   Print y
close 1
MrSwiss
Posts: 3222
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: PNG Dimensions Question

Postby MrSwiss » Aug 14, 2017 21:11

PNG can easily be loaded with FBImage (by D.J.Peters), thereafter, because it's a FBImage,
one can use ImageInfo(), to obtain the Image's sizes (if still required, after loading).
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Re: PNG Dimensions Question

Postby datwill310 » Aug 15, 2017 12:42

Thanks for the help guys, and the info!
counting_pine
Site Admin
Posts: 6170
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: PNG Dimensions Question

Postby counting_pine » Aug 15, 2017 13:50

From an endian-neutral point of view, it would be better to avoid byte-swapping, and just compose the bytes into a long yourself. e.g. a(0) shl 24 + a(1) shl 16 + a(2) shl 8 + a(3).
fxm
Posts: 9126
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: PNG Dimensions Question

Postby fxm » Aug 15, 2017 14:39

Yes:
-The faster:

Code: Select all

#macro byte_reverse(long_variable)
   long_variable = Cptr(Byte Ptr, @(long_variable))[0] Shl 24 + _
                   Cptr(Byte Ptr, @(long_variable))[1] Shl 16 + _
                   Cptr(Byte Ptr, @(long_variable))[2] Shl 08 + _
                   Cptr(Byte Ptr, @(long_variable))[3]
#endmacro
- The slower:

Code: Select all

#macro byte_reverse(long_variable)
   long_variable = ((long_variable) And &h000000FF) Shl 24 + _
                   ((long_variable) And &h0000FF00) Shl 08 + _
                   ((long_variable) And &h00FF0000) Shr 08 + _
                   ((long_variable) And &hFF000000) Shr 24
#endmacro
- Between the two previous ones:

Code: Select all

#macro byte_reverse(long_variable)
   Swap Cptr(Byte Ptr, @(long_variable))[0], Cptr(Byte Ptr, @(long_variable))[3]
   Swap Cptr(Byte Ptr, @(long_variable))[1], Cptr(Byte Ptr, @(long_variable))[2]
#endmacro

Return to “General”

Who is online

Users browsing this forum: Google [Bot] and 3 guests