MESSAGE
DATE | 2016-12-06 |
FROM | Ruben Safir
|
SUBJECT | Re: [Hangout-NYLXS] [Learn] png data format
|
On 12/06/2016 09:32 AM, Christopher League wrote: > > Ah... I *can* confirm the 218103808 number now. The number you're seeing > in the dump *is* in octal: the three highest-order bytes are 000(oct) > and the low order byte is 015(oct) == 8+5 == 13(dec) == D(hex). > > So the full 32-bit number in hexadecimal is 0x0000000D. > > Intel architecture stores those bytes in the order 0x0D, 0x00, 0x00, > 0x00. > > This number, 0x0D000000 == 218103808. > > The D is in column 6 (counting from zero at the right), whose > place-value is 16^6 == 16777216, and 13*16777216 == 218103808. > > CL > > Christopher League writes: > >> I can't really confirm this based on the numbers you've given (218103808 >> isn't how I think it would come out) but it sounds A LOT like an >> endianness issue. That is, the 4 bytes are stored big-endian in the >> file, but you're operating on a system (Intel) that is little-endian. So >> if you read an entire uint32 at once, it doesn't come out correctly. >> Reading one byte at a time, you can then swap the bytes into the right >> order. >> >> Also, that's not a hex dump, right...? is it octal? decimal? >> >> CL >> >> ruben safir writes: >> >>> 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:: >>> ^-at- >>> Byte 0:: >>> 0 >>> Character 1:: >>> ^-at- >>> Byte 1:: >>> 0 >>> Character 2:: >>> ^-at- >>> 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 >>> namespace png_proj{ >>> typedef uint32_t CHUNK; >>> >>> >>> >>> In the .cpp file >>> void Image::read_chunk() >>> { >>> char * cur = get_index(); >>> CHUNK * tmp = reinterpret_cast(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(*tmp)); >>> std::cout << "Length value => " << static_cast(*tmp) << std::endl; >>> break; >>> >>> case 1: >>> std::cout << "***TYPE****" << std::endl; >>> set_type(static_cast(*tmp)); >>> break; >>> >>> case 2: >>> { >>> std::cout << "***DATA****" << std::endl; >>> unsigned long int l = static_cast(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(tmp[k]); >>> std::cout << "data " << *buffer << std::endl; >>> } >>> set_data(buffer); >>> } >>> break; >>> >>> case 3: >>> std::cout << "***CRC****" << std::endl; >>> set_crc(static_cast(*tmp)); >>> break; >>> >>> default: >>> std::cout << "***NOMANDSLAND****" << std::endl; >>> break; >>> } /* ----- end switch ----- */ >>> >>> char * tmp2 = reinterpret_cast(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(*tmp2) << std::endl; >>> tmp2++; >>> } >>> std::cout<>>> std::cout<>>> tmp++; >>> cur = ( reinterpret_cast(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 >>> _______________________________________________ >>> Learn mailing list >>> Learn-at-nylxs.com >>> http://lists.mrbrklyn.com/mailman/listinfo/learn >
There is an aspect of this I just don't understand. Why does the order remain intact without ntohl when you look byte by byte through the allocated memory, but the order is reversed when you evaluate it as a continuous 32 bit unsigned int variable
-- So many immigrant groups have swept through our town that Brooklyn, like Atlantis, reaches mythological proportions in the mind of the world - RI Safir 1998 http://www.mrbrklyn.com
DRM is THEFT - We are the STAKEHOLDERS - RI Safir 2002 http://www.nylxs.com - Leadership Development in Free Software http://www2.mrbrklyn.com/resources - Unpublished Archive http://www.coinhangout.com - coins! http://www.brooklyn-living.com
Being so tracked is for FARM ANIMALS and and extermination camps, but incompatible with living as a free human being. -RI Safir 2013 _______________________________________________ hangout mailing list hangout-at-nylxs.com http://www.nylxs.com/
|
|