Results 1 to 14 of 14

Thread: Png?

  1. #1

    Thread Starter
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134

    Png?

    I've gotten pretty far with my PNG programming, with the help of a document I found on wotsit simply called "draft-bo". However, I'm stuck on one part - I'm at IDAT (where data lies), and I'm trying to use zLib to decompress it. I want to make my own PNG decompression library for myself, for use with VB, as VB doesn't have any good freeware implementations that do alpha well (and dont crash).

    Anyway, my dilemma is this. This is the structure of an IDAT data chunk:
    Code:
    Compression method/flags code: 1 byte
    Additional flags/check bits:   1 byte
    Compressed data blocks:        n bytes
    Check value:                   4 bytes
    Unfortunately, the zlib call requires you to know the size of the uncompressed data as well.

    This would be no problem if there was only one IDAT in the file (uncompressed data would be channels * bytes_per_channel * width * height). However, there can be several, and there are no definate schemes as to how they're split up. Thus my dilemma; what should I pass for the uncompressed value?
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  2. #2
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    I don't remember much about the PNG format, but isn't there a field/header/something that specifies the length of a section?

  3. #3

    Thread Starter
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Yes, and that's how I'm able to get the compressed data out - by reading that so I know when to stop retrieving information. But zLib needs to know how many bytes the data uncompresses to. That's where I'm stuck.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  4. #4
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    Oh...
    I'm not that familiar with zLib either but I'd guess either there's a way to find out the right length (maybe pass 0 and check the return value or something?), or you should pass a buffer that's "big enough", and if the function fails, make it bigger.

  5. #5

    Thread Starter
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    I've already tried to do that (65536 is the biggest size it could be uncompressed). However, it tells me that the data is invalid when I use it (returns -3).
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  6. #6
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Why can't you use a VB binding to libpng?
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  7. #7
    Fanatic Member riis's Avatar
    Join Date
    Nov 2001
    Posts
    551
    Maybe a stupid question, but why do you have multiple IDAT blocks? I know the PNG definition supports it. Personally, I don't like it, since you can't split up the entire file in parts and compress every part alone. From experience I can tell that zlib becomes increasingly slower when the data block becomes larger.
    (The only reason I can figure out for multiple IDAT blocks is that you also get more CRC values, so you can better check data integrity.)

    Hmm, shouldn't you just append all data together and pass it to its whole to zlib? From the IHDR block you're able to guess how large the uncompressed data block will be. (width * height * bits per sample * samples per pixel)

    Good luck!

  8. #8
    Fanatic Member riis's Avatar
    Join Date
    Nov 2001
    Posts
    551

    Re: Png?

    Originally posted by Sastraxi
    This would be no problem if there was only one IDAT in the file (uncompressed data would be channels * bytes_per_channel * width * height). However, there can be several, and there are no definate schemes as to how they're split up. Thus my dilemma; what should I pass for the uncompressed value?
    From the PNG specs (p. 26, avaliable at the W3C):
    In a PNG file, the concatenation of the contents of all the IDAT chunks makes up a zlib datastream as specified
    above. This datastream decompresses to filtered image data as described elsewhere in this document.
    So, this should be simple now

  9. #9

    Thread Starter
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Riis, thank you. You've saved me

    parksie: I've come across 5 or 6 libpng 'bindings' that simply don't work. Plus, I want to further understand the format
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  10. #10
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Originally posted by riis
    Maybe a stupid question, but why do you have multiple IDAT blocks?
    If he's making a complete PNG viewer than he doesn't have the choice. If the definition allows it then a good viewer should support it.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  11. #11

    Thread Starter
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134

    Angry

    I can't get it to work. I think I'll have to redo how I'm loading it, as right now I'm loading a chunk and then processing it. I think I could find out how many IDATs, etc. there were and check the order for correctness if I loaded all of the chunks first and then worked on them. Right now, even though I'm processing a PNG with only 1 IDAT, it gives me invalid source data (-3).
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  12. #12
    Fanatic Member riis's Avatar
    Join Date
    Nov 2001
    Posts
    551
    Originally posted by CornedBee
    If the definition allows it then a good viewer should support it.
    It is required indeed. However, the specs don't mention the background reasons for this decision. At first it confused me, since I thought it was possible to split the raw rgb data into parts and then compress each part individually. Later, it turned to be out that the compression should come first, and then the splitting. The only reason I can figure out, as stated before, is with the use of the CRC values it is possible to check integrity of every chunk better.

  13. #13
    Fanatic Member riis's Avatar
    Join Date
    Nov 2001
    Posts
    551
    Originally posted by Sastraxi
    I think I could find out how many IDATs, etc. there were and check the order for correctness if I loaded all of the chunks first and then worked on them.
    That's a very good idea to do. This way you can check if you process the file correct. And it's also a first check if the PNG file itself is correct. You should have enough information with the length field in the chunk header. Note that the length only contains the number of bytes of the chunk data, not of the length, chunk type and crc fields! Also a value of zero is valid. (For example the length of the chunk data in the IEND chunk is always zero!)

  14. #14

    Thread Starter
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Riis: The multiple IDATs are for older computers and older PNG 'encoders' to have a buffer size, so they don't have to fit a whopping great file into memory (which wouldn't exist anyway). Therefore, "the length of an IDAT chunk is usually the size of the encoder's buffer".
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width