• PNG Storage issues

    From Popping mad@21:1/5 to All on Tue Dec 6 14:25:26 2016
    Hello

    I'm having trouble with this imput of data from a PNG image. The
    specification says that "chunks" have a 4 byte field that is the length
    of the attached data segment. I tried to read the length in for a chunk
    that has a length of 13, which was confirmed in a hexdump

    0000000 211 120 116 107 015 012 032 012 -->>000 000 000 015<<-- 111 110
    104 122
    0000010 000 000 041 215 000 000 007 165 010 006 000 000 001 206 055 074
    0000020 336 000 000 000 004 147 101 115 101 000 000 261 217 013 374 141

    I am storing the data in a uint32_t variable using the following code,
    but the value keeps showing up with a huge number 218103808 which
    happens to be the number that is evaluated by iostream for the value of
    the whole chunk


    done reading header



    Sizeof Chunk 4
    Raw Chunk Number 0: 218103808
    ***LENGTH****
    Length value => 218103808
    Sizeof Byte 1
    Character 0::
    ^@
    Byte 0::
    0
    Character 1::
    ^@
    Byte 1::
    0
    Character 2::
    ^@
    Byte 2::
    0
    Character 3::
    Byte 3::
    13


    As yet, when I break it down by single bytes, it returns 0 0 0 13, which
    is correct. ddd seems to say the same thing, and I don't know why.
    When evaluated as 4 bytes, you get this large number, but when you
    evaluate them seperately, each byte, it comes out right.

    The code snippet I'm using looks like this

    in the .h file #ifndef PNGPRJ
    #define PNGPRJ
    #include <inttypes.h>
    namespace png_proj{
    typedef uint32_t CHUNK;



    In the .cpp file
    void Image::read_chunk()
    {
    char * cur = get_index();
    CHUNK * tmp = reinterpret_cast<CHUNK *>(cur);
    std::cout << std::endl << "Sizeof Chunk " << sizeof(*tmp)
    << std::endl;
    for(int j = 0; j<4; j++){
    std::cout << "Raw Chunk Number " << j << ": " <<
    *tmp << std::endl;


    switch ( j ) {
    case 0:
    std::cout << "***LENGTH****" << std::endl;
    set_length(static_cast<int32_t> (*tmp));
    std::cout << "Length value => "
    << static_cast<int>(*tmp) << std::endl;
    break;

    case 1:
    std::cout << "***TYPE****" << std::endl;
    set_type(static_cast<int32_t>
    (*tmp));
    break;

    case 2:
    {
    std::cout << "***DATA****" << std::endl;
    unsigned long int l = static_cast<unsigned long int>(get_length());
    std::cout << "buffer size should
    be " << get_length() << std::endl;
    int8_t * buffer = new int8_t[l];
    std::cout << "buffer element size
    is " << *buffer << std::endl;
    std::cout << "buffer size is " <<
    l << std::endl;
    for(unsigned int k = 0; k < get_length(); k++){
    buffer[k] = static_cast<int8_t>(tmp[k]);
    std::cout << "data " <<
    *buffer << std::endl;
    }
    set_data(buffer);
    }
    break;

    case 3:
    std::cout << "***CRC****" <<
    std::endl;
    set_crc(static_cast<int32_t>
    (*tmp));
    break;

    default:
    std::cout << "***NOMANDSLAND****"
    << std::endl;
    break;
    } /* ----- end
    switch ----- */

    char * tmp2 = reinterpret_cast<char *>(tmp); //
    reading each byte
    std::cout << "Sizeof Byte " << sizeof(*tmp2) << std::endl;
    //std::cout << "Mark ==>>" << __LINE__ <<
    std::endl;
    for(int i=0; i<4; i++){
    std::cout << "Character " << i << "::" << std::endl << "\t" << *tmp2
    << std::endl;
    std::cout << "Byte " << i << "::" <<
    std::endl << "\t" <<
    static_cast<unsigned long int>(*tmp2) << std::endl;
    tmp2++;
    }
    std::cout<<std::endl;
    std::cout<<std::endl;
    tmp++;
    cur = ( reinterpret_cast<char*>(tmp) );
    }
    set_index(cur);
    }



    I dug through libpng since this seems to not being doing what I
    expected. They seem to set it up as 4 byte array

    void /* PRIVATE */
    png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
    {
    png_uint_32 chunk_name;
    #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    int keep; /* unknown handling method */
    #endif

    /* First we make sure we have enough data for the 4-byte chunk name
    * and the 4-byte chunk length before proceeding with decoding the
    * chunk data. To fully decode each of these chunks, we also make
    * sure we have enough data in the buffer for the 4-byte CRC at the
    * end of every chunk (except IDAT, which is handled separately).
    */
    if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
    {
    png_byte chunk_length[4];
    png_byte chunk_tag[4];

    PNG_PUSH_SAVE_BUFFER_IF_LT(8)
    png_push_fill_buffer(png_ptr, chunk_length, 4);
    png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
    png_reset_crc(png_ptr);
    png_crc_read(png_ptr, chunk_tag, 4);
    png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
    png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    }


    I'm obviously not understanding something I'm evaluation here. So I'm wondering if anyone can shed light on this. http://www.nylxs.com/docs/grad_school/parallel/src/png/png_proj.h http://www.nylxs.com/docs/grad_school/parallel/src/png/png_proj.cpp http://www.nylxs.com/docs/grad_school/parallel/src/png/main_png.cpp http://www.nylxs.com/docs/grad_school/parallel/src/png/makefile

    ruben

    let.me.in


    Ruben

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Johann Klammer@21:1/5 to Popping mad on Wed Dec 7 14:25:37 2016
    On 12/06/2016 03:25 PM, Popping mad wrote:


    Sizeof Chunk 4
    Raw Chunk Number 0: 218103808
    ***LENGTH****
    Length value => 218103808
    Sizeof Byte 1
    Character 0::
    ^@
    Byte 0::
    0
    Character 1::
    ^@
    Byte 1::
    0
    Character 2::
    ^@
    Byte 2::
    0
    Character 3::
    Byte 3::
    13


    Looks byteswapped. Try ntohl() or similar.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)