Page 1 of 1

PNG Width, Height, Depth

Posted: Thu Apr 23, 2009 8:24 pm
by nco2k
hi folks,

does anyone know, where the width, height and depth infos are stored in a png file? i would like to use ReadFile() and check those values first, before i decide whether or not, the image should be loaded.

c ya,
nco2k

Posted: Thu Apr 23, 2009 8:35 pm
by djes

Posted: Fri Apr 24, 2009 5:34 pm
by nco2k
ok, as far as i have understood, the first 8 Byte of a PNG file, represent the PNG Signature:

Code: Select all

89					;uByte 137
50 4E 47			;Ascii PNG
0D 0A				;CRLF
1A					;EOF
0A					;LF
followed by 4 Byte, which i really dont understand:

Code: Select all

00 00 00 0D		;whats the meaning of this?!
and now the IHDR Header:

Code: Select all

49 48 44 52		;Ascii IHDR
the IHDR Chunk contains following data:

Code: Select all

Width.l
Height.l
BitDepth.b
ColorType.b
CompressionMethod.b
FilterMethod.b
InterlaceMethod.b
so i thought of reading it like this, right after the IHDR Header:

Code: Select all

If ReadFile(0, "C:\test.png")
  FileSeek(0, 16)
  Debug ReadLong(0); Width
  Debug ReadLong(0); Height
  CloseFile(0)
EndIf : End
but the values dont look the way, i was expecting... do i have to shift something?? or am i reading it all wrong??

c ya,
nco2k

Posted: Fri Apr 24, 2009 6:35 pm
by Deeem2031
ReadLong reads it in wrong byte-order:

Code: Select all

If ReadFile(0, "C:\test.png") 
  FileSeek(0, 16) 
  w = ReadLong(0); Width 
  !MOV Eax, dword[v_w]
  !BSWAP Eax
  !MOV dword[v_w], Eax
  Debug w
  h = ReadLong(0); Height
  !MOV Eax, dword[v_h]
  !BSWAP Eax
  !MOV dword[v_h], Eax
  Debug h
  CloseFile(0) 
EndIf : End

Posted: Fri Apr 24, 2009 7:08 pm
by Kaeru Gaman
> ReadLong reads it in wrong byte-order:

I doubt this.

since I cannot read your code, I cannot see what byteorder you expect...

Posted: Fri Apr 24, 2009 7:26 pm
by Demivec
Kaeru Gaman wrote:> ReadLong reads it in wrong byte-order:

I doubt this.

since I cannot read your code, I cannot see what byteorder you expect...
PNG Specifications wrote:7 Encoding the PNG image as a PNG datastream
7.1 Integers and byte order

All integers that require more than one byte shall 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, MSB B2 B1 LSB for four-byte integers). The highest bit (value 128) of a byte is numbered bit 7; the lowest bit (value 1) is numbered bit 0. Values are unsigned unless otherwise noted. Values explicitly noted as signed are represented in two's complement notation.
This is opposite to the byte-order that ReadLong() returns.

Posted: Fri Apr 24, 2009 7:30 pm
by nco2k
@Deeem2031
thats it... thanks!

@Kaeru Gaman

Code: Select all

If ReadFile(0, #PB_Compiler_Home+"Examples\Sources\Data\flare.png")
  FileSeek(0, 16)
  
  w = ReadLong(0); Width
  Debug w; 65536 wrong
  !MOV Eax, dword[v_w]
  !BSWAP Eax
  !MOV dword[v_w], Eax
  Debug w; 256 correct
  
  Debug ""
  
  h = ReadLong(0); Height
  Debug h; 65536 wrong
  !MOV Eax, dword[v_h]
  !BSWAP Eax
  !MOV dword[v_h], Eax
  Debug h; 256 correct
  
  CloseFile(0)
EndIf : End
@Demivec
yea, i missed that part. :oops:

c ya,
nco2k

Posted: Fri Apr 24, 2009 8:24 pm
by djes
nco2k wrote:followed by 4 Byte, which i really dont understand:

Code: Select all

00 00 00 0D		;whats the meaning of this?!
Maybe the length, as stated in 5.3 "chunk layout"

Posted: Sat Apr 25, 2009 12:53 am
by nco2k
@djes
right, the returned value was way too big, so i was confused. but after reading it "backwards", it all makes sense now. :)

c ya,
nco2k

Posted: Sat Apr 25, 2009 1:12 am
by Ollivier
~|__/
..o.o..

Posted: Sat Apr 25, 2009 4:36 am
by Seymour Clufley
Do you have finished, usable code for this?

Posted: Sat Apr 25, 2009 8:01 pm
by nco2k
what do you mean? the above code is usable and all needed infos are given in this thread and the link posted by djes.

example for the lazy ones:

Code: Select all

Procedure.l SwapLong(Value.l)
  b1.w = Value & $FF
  b2.w = (Value >>  8) & $FF
  b3.w = (Value >> 16) & $FF
  b4.w = (Value >> 24) & $FF
  ProcedureReturn (b1 << 24) + (b2 << 16) + (b3 << 8) + b4
EndProcedure

If ReadFile(0, #PB_Compiler_Home+"Examples\Sources\Data\flare.png")
  
  If ReadQuad(0) = $0A1A0A0D474E5089 And ReadQuad(0) = $524448490D000000
    
    ;FileSeek(0, 16)
    
    Width = SwapLong(ReadLong(0))
    Debug "Width: "+Str(Width)+" px"
    
    Height = SwapLong(ReadLong(0))
    Debug "Height: "+Str(Height)+" px"
    
    BitDepth = ReadByte(0) & $FF
    Debug "BitDepth: "+Str(BitDepth)+" Bit"
    
    ColorType = ReadByte(0) & $FF
    Select ColorType
      Case 0
        Debug "ColorType: Greyscale"
      Case 2
        Debug "ColorType: Truecolor"
      Case 3
        Debug "ColorType: Indexed"
      Case 4
        Debug "ColorType: Greyscale with Alpha"
      Case 6
        Debug "ColorType: Truecolor with Alpha"
    EndSelect
    
    CompressionMethod = ReadByte(0) & $FF
    Debug "CompressionMethod: "+Str(CompressionMethod)
    
    FilterMethod = ReadByte(0) & $FF
    Debug "FilterMethod: "+Str(FilterMethod)
    
    InterlaceMethod = ReadByte(0) & $FF
    Debug "InterlaceMethod: "+Str(InterlaceMethod)
    
  EndIf
  
  CloseFile(0)
EndIf : End
c ya,
nco2k