Extracting/reading PNG iTXt chunks with Exiv2
Added by Arnold Wiegert about 5 years ago
Being a newb to Exiv2, I have been trying to find a way to check for and extract or read the various chunks, particularly the iTXt chunks, in a PNG, file using the current Exiv2 library.
Any comments or pointer will much appreciated.
TIA
Replies (4)
RE: Extracting/reading PNG iTXt chunks with Exiv2 - Added by Robin Mills about 5 years ago
Arnold
Yes, you can do this with the -pS (printStructure in v0.25) and -pR (printRecursive in trunk/v0.26) options.
951 rmills@rmillsmbp:~/gnu/exiv2/trunk $ exiv2 -pS test/data/imagemagick.png STRUCTURE OF PNG FILE: test/data/imagemagick.png address | index | chunk_type | length | data 8 | 0 | IHDR | 13 | ...@........ 33 | 1 | iCCP | 1404 | icc..x...i8.......af\...w_3...+ 1449 | 2 | sBIT | 3 | ... 1464 | 3 | zTXt | 87 | Software..x...A.. ......B....}.N 1563 | 4 | tEXt | 24482 | Raw profile type exif..exif. 1 26057 | 5 | tEXt | 471 | Raw profile type iptc..iptc. 26540 | 6 | IDAT | 8192 | x...Y.$Wv&v.{.{l.T.......[w.=m$G 34744 | 7 | IDAT | 8192 | .4X.y.AR...4....:Ue..U.|1..:..D. 42948 | 8 | IDAT | 8192 | 'g.!... ...n...s..Jdz.........6. 51152 | 9 | IDAT | 8192 | ........k....CY/75I..u;.. .z...} 59356 | 10 | IDAT | 8192 | .f>..]....UKqD2s.(.q....=x.l.\V. 67560 | 11 | IDAT | 8192 | .i.{!!B0...C!4.p..`D g`......... 75764 | 12 | IDAT | 8192 | .*.].4..Q..}(9...S0&.......T.9.+ 83968 | 13 | IDAT | 8192 | ..k...6....g.1..}.].&.H........ 92172 | 14 | IDAT | 8192 | .j..S.........z..!U.G0*.m%..09<, 100376 | 15 | IDAT | 8192 | .....t.>!.....6^.<..;..?$I..M.9 108580 | 16 | IDAT | 8192 | W.&5.5J........FW`....3.N.9Pk;.s 116784 | 17 | IDAT | 8192 | .....d.z".`...v=g-..-.c8...Z.5.x 124988 | 18 | IDAT | 8192 | .."...o<&."....1M....1&. ..5.... 133192 | 19 | IDAT | 8192 | k........!..B*.....\*.(!..0.s..B 141396 | 20 | IDAT | 3346 | .Y.L@I$M.Z[.0A ...K#.t.0+.G(.jX. 144754 | 21 | IEND | 0 | 952 rmills@rmillsmbp:~/gnu/exiv2/trunk $I don't know for which purpose you are interested in the iTXt chunks. Some can be extracted by exiv2. For example, the following command will extract an ICC profile to stdout.
$ exiv2 -pC foo.pngThe following command will extract XMP (xml) to stdout:
$ exiv2 -pX foo.pngIf you have other chunks of interest, you can write a script to parse the output of
$ exiv2 -pS foo.png
to obtain the offset and length of a chunk which can then be extracted with dd. This is discussed in relation to TIFF files in this article: http://dev.exiv2.org/projects/exiv2/wiki/The_Metadata_in_TIFF_files
Print Recursive -pR
on the trunk and heading for v0.26 shows the same information and descends into data structures it recognises.
953 rmills@rmillsmbp:~/gnu/exiv2/trunk $ exiv2 -pR test/data/imagemagick.pngSTRUCTURE OF PNG FILE: test/data/imagemagick.png address | index | chunk_type | length | data 8 | 0 | IHDR | 13 | ...@........ 33 | 1 | iCCP | 1404 | icc..x...i8.......af\...w_3...+ 1449 | 2 | sBIT | 3 | ... 1464 | 3 | zTXt | 87 | Software..x...A.. ......B....}.N Software: digiKam 0.9.0-svn ( libpng version 1.2.8 - December 3, 2004 (header) ) 1563 | 4 | tEXt | 24482 | Raw profile type exif..exif. 1 STRUCTURE OF TIFF FILE (MM): MemIo address | tag | type | count | offset | value 10 | 0x0100 ImageWidth | SLONG | 1 | 320 | 320 22 | 0x0101 ImageLength | SLONG | 1 | 211 | 211 34 | 0x010f Make | ASCII | 18 | 146 | NIKON CORPORATION 46 | 0x0110 Model | ASCII | 10 | 164 | NIKON D70 58 | 0x0112 Orientation | SHORT | 1 | 65536 | 1 70 | 0x011a XResolution | RATIONAL | 1 | 174 | 174/0 82 | 0x011b YResolution | RATIONAL | 1 | 182 | 182/0 94 | 0x0128 ResolutionUnit | SHORT | 1 | 131072 | 2 106 | 0x0131 Software | ASCII | 18 | 190 | digiKam-0.9.0-svn 118 | 0x0132 DateTime | ASCII | 20 | 208 | 2006:02:04 16:09:30 130 | 0x8769 ExifTag | LONG | 1 | 228 | 228 STRUCTURE OF TIFF FILE (MM): MemIo address | tag | type | count | offset | value 230 | 0x829a ExposureTime | RATIONAL | 1 | 546 | 546/0 242 | 0x829d FNumber | RATIONAL | 1 | 554 | 554/0 254 | 0x8822 ExposureProgram | SHORT | 1 | 262144 | 4 266 | 0x8827 ISOSpeedRatings | SHORT | 1 | 13107200 | 200 278 | 0x9003 DateTimeOriginal | ASCII | 20 | 562 | 2006:02:04 16:09:30 290 | 0x9004 DateTimeDigitized | ASCII | 20 | 582 | 2006:02:04 16:09:30 302 | 0x9201 ShutterSpeedValue | RATIONAL | 1 | 602 | 602/0 314 | 0x9202 ApertureValue | RATIONAL | 1 | 610 | 610/0 326 | 0x9204 ExposureBiasValue | RATIONAL | 1 | 618 | 618/0 338 | 0x9205 MaxApertureValue | RATIONAL | 1 | 626 | 626/0 350 | 0x9208 LightSource | SHORT | 1 | 0 | 0 362 | 0x9209 Flash | SHORT | 1 | 0 | 0 374 | 0x920a FocalLength | RATIONAL | 1 | 634 | 634/0 386 | 0x927c MakerNote | UNDEFINED | 6989 | 642 | Nikon.....MM.*.....+........0210 ... STRUCTURE OF TIFF FILE (MM): MemIo address | tag | type | count | offset | value 10 | 0x0001 Version | UNDEFINED | 4 | 808595760 | 0210 22 | 0x0002 ISOSpeed | SHORT | 2 | 200 | 0 200 34 | 0x0004 Quality | ASCII | 8 | 530 | RAW 46 | 0x0005 WhiteBalance | ASCII | 13 | 538 | AUTO 58 | 0x0006 Sharpening | ASCII | 7 | 551 | NORMAL 70 | 0x0007 Focus | ASCII | 7 | 558 | AF-S 82 | 0x0008 FlashSetting | ASCII | 13 | 565 | NORMAL 94 | 0x0009 GPSStatus | ASCII | 13 | 578 | 106 | 0x000b ProcessingSoftware | SSHORT | 1 | 0 | 0 118 | 0x000d GPSSpeed | UNDEFINED | 4 | 67072 | ... 130 | 0x000e GPSTrackRef | UNDEFINED | 4 | 68608 | ... 142 | 0x0011 GPSImgDirection | LONG | 1 | 7006 | 7006 154 | 0x0012 GPSMapDatum | UNDEFINED | 4 | 67072 | ... 166 | 0x0013 GPSDestLatitudeRef | SHORT | 2 | 200 | 0 200 178 | 0x0017 GPSDestBearingRef | UNDEFINED | 4 | 67072 | ... 190 | 0x0018 GPSDestBearing | UNDEFINED | 4 | 67072 | ... 202 | 0x0019 GPSDestDistanceRef | SRATIONAL | 1 | 591 | 591/0 214 | 0x0081 | ASCII | 9 | 599 | NORMAL 226 | 0x0083 | BYTE | 1 | 100663296 | . 238 | 0x0084 | RATIONAL | 4 | 608 | 180/0 10/0 500/0 10/0 250 | 0x0087 | BYTE | 1 | 0 | 262 | 0x0088 AFFocusPos | UNDEFINED | 4 | 16777217 | .... 274 | 0x0089 | SHORT | 1 | 0 | 0 286 | 0x008b | UNDEFINED | 4 |1208028160 | H.. 298 | 0x008c | UNDEFINED | 4160 | 640 | I.............................. ... 310 | 0x008d | ASCII | 9 | 4800 | MODE2 322 | 0x0090 | ASCII | 12 | 4809 | NATURAL 334 | 0x0091 | UNDEFINED | 465 | 4821 | 0103........................... ... 346 | 0x0092 | SSHORT | 1 | 0 | 0 358 | 0x0093 | SHORT | 1 | 65536 | 1 370 | 0x0095 | ASCII | 5 | 5286 | OFF 382 | 0x0096 | UNDEFINED | 1412 | 5291 | D..H.H.H.H...................... ... 394 | 0x0097 | UNDEFINED | 140 | 6703 | 0103.................:...z...... ... 406 | 0x0098 | UNDEFINED | 31 | 6843 | ............................... 418 | 0x0099 | SHORT | 2 | 99615728 | 1520 1008 430 | 0x009a | RATIONAL | 2 | 6874 | 3/296 1/0 442 | 0x00a0 | ASCII | 21 | 6890 | .........2........... 454 | 0x00a4 | UNDEFINED | 4 | 808595504 | 0200 466 | 0x00a7 | LONG | 1 | 5670 | 5670 478 | 0x00a8 | UNDEFINED | 20 | 6911 | ..........a~NIKON CO 490 | 0x00a9 | ASCII | 16 | 6931 | RPORATION.NIKON 502 | 0x00aa | ASCII | 16 | 6947 | D70....,......., 514 | 0x00ab | ASCII | 16 | 6963 | ....Bibble 4.5. END MemIo 398 | 0xa002 PixelXDimension | SLONG | 1 | 320 | 320 410 | 0xa003 PixelYDimension | SLONG | 1 | 211 | 211 422 | 0xa217 SensingMethod | BYTE | 1 | 33554432 | . 434 | 0xa301 SceneType | BYTE | 1 | 16777216 | . 446 | 0xa402 ExposureMode | SHORT | 1 | 0 | 0 458 | 0xa403 WhiteBalance | SHORT | 1 | 0 | 0 470 | 0xa405 FocalLengthIn35mmFilm | SHORT | 1 | 4915200 | 75 482 | 0xa406 SceneCaptureType | SHORT | 1 | 0 | 0 494 | 0xa408 Contrast | SHORT | 1 | 0 | 0 506 | 0xa409 Saturation | SHORT | 1 | 0 | 0 518 | 0xa40a Sharpness | SHORT | 1 | 0 | 0 530 | 0xa40c SubjectDistanceRange | SHORT | 1 | 0 | 0 END MemIo 7633 | 0x0103 Compression | SHORT | 1 | 393216 | 6 7645 | 0x0201 JPEGInterchangeFormat | LONG | 1 | 7673 | 7673 7657 | 0x0202 JPEGInterchangeFormatLeng | LONG | 1 | 4376 | 4376 END MemIo 26057 | 5 | tEXt | 471 | Raw profile type iptc..iptc. Record | DataSet | Name | Length | Data 2 | 5 | ObjectName | 4 | ovni 2 | 10 | Urgency | 1 | 0 2 | 15 | Category | 3 | I - 2 | 20 | SuppCategory | 13 | SPCL Specials 2 | 116 | Copyright | 4 | E.T. 2 | 110 | Credit | 9 | Spielberg 2 | 122 | Writer | 21 | L'ovni de la Bastille 2 | 90 | City | 5 | Paris 2 | 95 | ProvinceState | 13 | ..le de Franc 2 | 101 | CountryName | 12 | FRA - France 2 | 100 | CountryCode | 3 | 750 2 | 40 | SpecialInstructions | 10 | Y'en a pas 2 | 103 | TransmissionReference | 2 | 36 2 | 115 | Source | 8 | Chez moi 2 | 55 | DateCreated | 8 | 20060204 2 | 60 | TimeCreated | 11 | 160930+0000 2 | 0 | RecordVersion | 2 | .. 26540 | 6 | IDAT | 8192 | x...Y.$Wv&v.{.{l.T.......[w.=m$G 34744 | 7 | IDAT | 8192 | .4X.y.AR...4....:Ue..U.|1..:..D. 42948 | 8 | IDAT | 8192 | 'g.!... ...n...s..Jdz.........6. 51152 | 9 | IDAT | 8192 | ........k....CY/75I..u;.. .z...} 59356 | 10 | IDAT | 8192 | .f>..]....UKqD2s.(.q....=x.l.\V. 67560 | 11 | IDAT | 8192 | .i.{!!B0...C!4.p..`D g`......... 75764 | 12 | IDAT | 8192 | .*.].4..Q..}(9...S0&.......T.9.+ 83968 | 13 | IDAT | 8192 | ..k...6....g.1..}.].&.H........ 92172 | 14 | IDAT | 8192 | .j..S.........z..!U.G0*.m%..09<, 100376 | 15 | IDAT | 8192 | .....t.>!.....6^.<..;..?$I..M.9 108580 | 16 | IDAT | 8192 | W.&5.5J........FW`....3.N.9Pk;.s 116784 | 17 | IDAT | 8192 | .....d.z".`...v=g-..-.c8...Z.5.x 124988 | 18 | IDAT | 8192 | .."...o<&."....1M....1&. ..5.... 133192 | 19 | IDAT | 8192 | k........!..B*.....\*.(!..0.s..B 141396 | 20 | IDAT | 3346 | .Y.L@I$M.Z[.0A ...K#.t.0+.G(.jX. 144754 | 21 | IEND | 0 | STRUCTURE OF PNG FILE: test/data/imagemagick.png address | index | chunk_type | length | data 8 | 0 | IHDR | 13 | ...@........ 33 | 1 | iCCP | 1404 | icc..x...i8.......af\...w_3...+ 1449 | 2 | sBIT | 3 | ... 1464 | 3 | zTXt | 87 | Software..x...A.. ......B....}.N Software: digiKam 0.9.0-svn ( libpng version 1.2.8 - December 3, 2004 (header) ) 1563 | 4 | tEXt | 24482 | Raw profile type exif..exif. 1 STRUCTURE OF TIFF FILE (MM): MemIo address | tag | type | count | offset | value 10 | 0x0100 ImageWidth | SLONG | 1 | 320 | 320 22 | 0x0101 ImageLength | SLONG | 1 | 211 | 211 34 | 0x010f Make | ASCII | 18 | 146 | NIKON CORPORATION 46 | 0x0110 Model | ASCII | 10 | 164 | NIKON D70 58 | 0x0112 Orientation | SHORT | 1 | 65536 | 1 70 | 0x011a XResolution | RATIONAL | 1 | 174 | 174/0 82 | 0x011b YResolution | RATIONAL | 1 | 182 | 182/0 94 | 0x0128 ResolutionUnit | SHORT | 1 | 131072 | 2 106 | 0x0131 Software | ASCII | 18 | 190 | digiKam-0.9.0-svn 118 | 0x0132 DateTime | ASCII | 20 | 208 | 2006:02:04 16:09:30 130 | 0x8769 ExifTag | LONG | 1 | 228 | 228 STRUCTURE OF TIFF FILE (MM): MemIo address | tag | type | count | offset | value 230 | 0x829a ExposureTime | RATIONAL | 1 | 546 | 546/0 242 | 0x829d FNumber | RATIONAL | 1 | 554 | 554/0 254 | 0x8822 ExposureProgram | SHORT | 1 | 262144 | 4 266 | 0x8827 ISOSpeedRatings | SHORT | 1 | 13107200 | 200 278 | 0x9003 DateTimeOriginal | ASCII | 20 | 562 | 2006:02:04 16:09:30 290 | 0x9004 DateTimeDigitized | ASCII | 20 | 582 | 2006:02:04 16:09:30 302 | 0x9201 ShutterSpeedValue | RATIONAL | 1 | 602 | 602/0 314 | 0x9202 ApertureValue | RATIONAL | 1 | 610 | 610/0 326 | 0x9204 ExposureBiasValue | RATIONAL | 1 | 618 | 618/0 338 | 0x9205 MaxApertureValue | RATIONAL | 1 | 626 | 626/0 350 | 0x9208 LightSource | SHORT | 1 | 0 | 0 362 | 0x9209 Flash | SHORT | 1 | 0 | 0 374 | 0x920a FocalLength | RATIONAL | 1 | 634 | 634/0 386 | 0x927c MakerNote | UNDEFINED | 6989 | 642 | Nikon.....MM.*.....+........0210 ... STRUCTURE OF TIFF FILE (MM): MemIo address | tag | type | count | offset | value 10 | 0x0001 Version | UNDEFINED | 4 | 808595760 | 0210 22 | 0x0002 ISOSpeed | SHORT | 2 | 200 | 0 200 34 | 0x0004 Quality | ASCII | 8 | 530 | RAW 46 | 0x0005 WhiteBalance | ASCII | 13 | 538 | AUTO 58 | 0x0006 Sharpening | ASCII | 7 | 551 | NORMAL 70 | 0x0007 Focus | ASCII | 7 | 558 | AF-S 82 | 0x0008 FlashSetting | ASCII | 13 | 565 | NORMAL 94 | 0x0009 GPSStatus | ASCII | 13 | 578 | 106 | 0x000b ProcessingSoftware | SSHORT | 1 | 0 | 0 118 | 0x000d GPSSpeed | UNDEFINED | 4 | 67072 | ... 130 | 0x000e GPSTrackRef | UNDEFINED | 4 | 68608 | ... 142 | 0x0011 GPSImgDirection | LONG | 1 | 7006 | 7006 154 | 0x0012 GPSMapDatum | UNDEFINED | 4 | 67072 | ... 166 | 0x0013 GPSDestLatitudeRef | SHORT | 2 | 200 | 0 200 178 | 0x0017 GPSDestBearingRef | UNDEFINED | 4 | 67072 | ... 190 | 0x0018 GPSDestBearing | UNDEFINED | 4 | 67072 | ... 202 | 0x0019 GPSDestDistanceRef | SRATIONAL | 1 | 591 | 591/0 214 | 0x0081 | ASCII | 9 | 599 | NORMAL 226 | 0x0083 | BYTE | 1 | 100663296 | . 238 | 0x0084 | RATIONAL | 4 | 608 | 180/0 10/0 500/0 10/0 250 | 0x0087 | BYTE | 1 | 0 | 262 | 0x0088 AFFocusPos | UNDEFINED | 4 | 16777217 | .... 274 | 0x0089 | SHORT | 1 | 0 | 0 286 | 0x008b | UNDEFINED | 4 |1208028160 | H.. 298 | 0x008c | UNDEFINED | 4160 | 640 | I.............................. ... 310 | 0x008d | ASCII | 9 | 4800 | MODE2 322 | 0x0090 | ASCII | 12 | 4809 | NATURAL 334 | 0x0091 | UNDEFINED | 465 | 4821 | 0103........................... ... 346 | 0x0092 | SSHORT | 1 | 0 | 0 358 | 0x0093 | SHORT | 1 | 65536 | 1 370 | 0x0095 | ASCII | 5 | 5286 | OFF 382 | 0x0096 | UNDEFINED | 1412 | 5291 | D..H.H.H.H...................... ... 394 | 0x0097 | UNDEFINED | 140 | 6703 | 0103.................:...z...... ... 406 | 0x0098 | UNDEFINED | 31 | 6843 | ............................... 418 | 0x0099 | SHORT | 2 | 99615728 | 1520 1008 430 | 0x009a | RATIONAL | 2 | 6874 | 3/296 1/0 442 | 0x00a0 | ASCII | 21 | 6890 | .........2........... 454 | 0x00a4 | UNDEFINED | 4 | 808595504 | 0200 466 | 0x00a7 | LONG | 1 | 5670 | 5670 478 | 0x00a8 | UNDEFINED | 20 | 6911 | ..........a~NIKON CO 490 | 0x00a9 | ASCII | 16 | 6931 | RPORATION.NIKON 502 | 0x00aa | ASCII | 16 | 6947 | D70....,......., 514 | 0x00ab | ASCII | 16 | 6963 | ....Bibble 4.5. END MemIo 398 | 0xa002 PixelXDimension | SLONG | 1 | 320 | 320 410 | 0xa003 PixelYDimension | SLONG | 1 | 211 | 211 422 | 0xa217 SensingMethod | BYTE | 1 | 33554432 | . 434 | 0xa301 SceneType | BYTE | 1 | 16777216 | . 446 | 0xa402 ExposureMode | SHORT | 1 | 0 | 0 458 | 0xa403 WhiteBalance | SHORT | 1 | 0 | 0 470 | 0xa405 FocalLengthIn35mmFilm | SHORT | 1 | 4915200 | 75 482 | 0xa406 SceneCaptureType | SHORT | 1 | 0 | 0 494 | 0xa408 Contrast | SHORT | 1 | 0 | 0 506 | 0xa409 Saturation | SHORT | 1 | 0 | 0 518 | 0xa40a Sharpness | SHORT | 1 | 0 | 0 530 | 0xa40c SubjectDistanceRange | SHORT | 1 | 0 | 0 END MemIo 7633 | 0x0103 Compression | SHORT | 1 | 393216 | 6 7645 | 0x0201 JPEGInterchangeFormat | LONG | 1 | 7673 | 7673 7657 | 0x0202 JPEGInterchangeFormatLeng | LONG | 1 | 4376 | 4376 END MemIo 26057 | 5 | tEXt | 471 | Raw profile type iptc..iptc. Record | DataSet | Name | Length | Data 2 | 5 | ObjectName | 4 | ovni 2 | 10 | Urgency | 1 | 0 2 | 15 | Category | 3 | I - 2 | 20 | SuppCategory | 13 | SPCL Specials 2 | 116 | Copyright | 4 | E.T. 2 | 110 | Credit | 9 | Spielberg 2 | 122 | Writer | 21 | L'ovni de la Bastille 2 | 90 | City | 5 | Paris 2 | 95 | ProvinceState | 13 | ..le de Franc 2 | 101 | CountryName | 12 | FRA - France 2 | 100 | CountryCode | 3 | 750 2 | 40 | SpecialInstructions | 10 | Y'en a pas 2 | 103 | TransmissionReference | 2 | 36 2 | 115 | Source | 8 | Chez moi 2 | 55 | DateCreated | 8 | 20060204 2 | 60 | TimeCreated | 11 | 160930+0000 2 | 0 | RecordVersion | 2 | .. 26540 | 6 | IDAT | 8192 | x...Y.$Wv&v.{.{l.T.......[w.=m$G 34744 | 7 | IDAT | 8192 | .4X.y.AR...4....:Ue..U.|1..:..D. 42948 | 8 | IDAT | 8192 | 'g.!... ...n...s..Jdz.........6. 51152 | 9 | IDAT | 8192 | ........k....CY/75I..u;.. .z...} 59356 | 10 | IDAT | 8192 | .f>..]....UKqD2s.(.q....=x.l.\V. 67560 | 11 | IDAT | 8192 | .i.{!!B0...C!4.p..`D g`......... 75764 | 12 | IDAT | 8192 | .*.].4..Q..}(9...S0&.......T.9.+ 83968 | 13 | IDAT | 8192 | ..k...6....g.1..}.].&.H........ 92172 | 14 | IDAT | 8192 | .j..S.........z..!U.G0*.m%..09<, 100376 | 15 | IDAT | 8192 | .....t.>!.....6^.<..;..?$I..M.9 108580 | 16 | IDAT | 8192 | W.&5.5J........FW`....3.N.9Pk;.s 116784 | 17 | IDAT | 8192 | .....d.z".`...v=g-..-.c8...Z.5.x 124988 | 18 | IDAT | 8192 | .."...o<&."....1M....1&. ..5.... 133192 | 19 | IDAT | 8192 | k........!..B*.....\*.(!..0.s..B 141396 | 20 | IDAT | 3346 | .Y.L@I$M.Z[.0A ...K#.t.0+.G(.jX. 144754 | 21 | IEND | 0 |
RE: Extracting/reading PNG iTXt chunks with Exiv2 - Added by Arnold Wiegert about 5 years ago
Thank you, Robin,
but I should have been clearer, I want to do this from within C_++ code, not the command line.
RE: Extracting/reading PNG iTXt chumnks with Exiv2 - Added by Robin Mills about 5 years ago
The API that performs this work in PngImage::printStructure()
. The output of -pS is captured in a stream which you can easily parse. If you wish to process the chunks in some complex way, you may wish to copy the code from printStructure() to your application.
void PngImage::printStructure(std::ostream& out, PrintStructureOption option, int depth)
{
if (io_->open() != 0) {
throw Error(9, io_->path(), strError());
}
IoCloser closer(*io_);
// Ensure that this is the correct image type
if (!isPngType(*io_, true)) {
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "PNG");
}
char chType[5];
chType[0]=0;
chType[4]=0;
if ( option == kpsBasic || option == kpsXMP || option == kpsIccProfile || option == kpsRecursive ) {
const std::string xmpKey = "XML:com.adobe.xmp";
const std::string exifKey = "Raw profile type exif";
const std::string iptcKey = "Raw profile type iptc";
const std::string iccKey = "icc";
const std::string softKey = "Software";
if ( option == kpsBasic || option == kpsRecursive ) {
out << "STRUCTURE OF PNG FILE: " << io_->path() << std::endl;
out << " address | index | chunk_type | length | data" << std::endl;
}
long index = 0;
const long imgSize = io_->size();
DataBuf cheaderBuf(8);
while( !io_->eof() && ::strcmp(chType,"IEND") ) {
size_t address = io_->tell();
std::memset(cheaderBuf.pData_, 0x0, cheaderBuf.size_);
long bufRead = io_->read(cheaderBuf.pData_, cheaderBuf.size_);
if (io_->error()) throw Error(14);
if (bufRead != cheaderBuf.size_) throw Error(20);
// Decode chunk data length.
uint32_t dataOffset = Exiv2::getULong(cheaderBuf.pData_, Exiv2::bigEndian);
for (int i = 4; i < 8; i++) {
chType[i-4]=cheaderBuf.pData_[i];
}
// test that we haven't hit EOF, or wanting to read excessive data
long restore = io_->tell();
if( restore == -1
|| dataOffset > uint32_t(0x7FFFFFFF)
|| static_cast<long>(dataOffset) > imgSize - restore
){
throw Exiv2::Error(14);
}
// format output
uint32_t blen = dataOffset > 32 ? 32 : dataOffset ;
std::string dataString ;
DataBuf buff(blen);
io_->read(buff.pData_,blen);
io_->seek(restore, BasicIo::beg);
dataString = Internal::binaryToString(buff, blen);
if ( option == kpsBasic || option == kpsRecursive )
out << Internal::stringFormat("%8d | %5d | %10s |%8d | "
,(uint32_t)address, index++,chType,dataOffset)
<< dataString << std::endl;
// chunk type
bool tEXt = std::strcmp(chType,"tEXt")== 0;
bool zTXt = std::strcmp(chType,"zTXt")== 0;
bool iCCP = std::strcmp(chType,"iCCP")== 0;
bool iTXt = std::strcmp(chType,"iTXt")== 0;
// for XMP, ICC etc: read and format data
bool bXMP = option == kpsXMP && findi(dataString,xmpKey)==0;
bool bICC = option == kpsIccProfile && findi(dataString,iccKey)==0;
bool bExif = option == kpsRecursive && findi(dataString,exifKey)==0;
bool bIptc = option == kpsRecursive && findi(dataString,iptcKey)==0;
bool bSoft = option == kpsRecursive && findi(dataString,softKey)==0;
bool bDump = bXMP || bICC || bExif || bIptc || bSoft ;
if( bDump ) {
DataBuf dataBuf;
byte* data = new byte[dataOffset+1];
data[dataOffset]=0;
io_->read(data,dataOffset);
io_->seek(restore, BasicIo::beg);
uint32_t name_l = (uint32_t) std::strlen((const char*)data)+1; // leading string length
uint32_t start = name_l;
// decode the chunk
bool bGood = false;
if ( tEXt ) {
bGood = tEXtToDataBuf(data+name_l,dataOffset-name_l,dataBuf);
}
if ( zTXt || iCCP ) {
name_l++ ; // +1 = 'compressed' flag
bGood = zlibToDataBuf(data+name_l,dataOffset-name_l,dataBuf);
}
if ( iTXt ) {
while ( data[start] == 0 && start < dataOffset ) start++; // crawl over the '\0' bytes between XML:....\0\0<xml stuff
data[dataOffset]=0; // ensure the XML is nul terminated
bGood = (start+3) < dataOffset ; // good if not a nul chunk
}
// format is content dependent
if ( bGood ) {
if ( bXMP ) {
out << data+start; // output the xml
}
if ( bExif ) {
const char* bytes = (const char*) dataBuf.pData_;
uint32_t l = (uint32_t) std::strlen(bytes)+2;
// create a copy on write memio object with the data, then print the structure
BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(dataBuf.pData_+l,dataBuf.size_-l));
TiffImage::printTiffStructure(*p,out,option,depth);
}
if ( bSoft ) {
const char* bytes = (const char*) dataBuf.pData_;
uint32_t l = (uint32_t) std::strlen(bytes)+2;
// create a copy on write memio object with the data, then print the structure
BasicIo::AutoPtr p = BasicIo::AutoPtr(new MemIo(dataBuf.pData_+l,dataBuf.size_-l));
out << Internal::indent(depth) << (const char*) buff.pData_ << ": " << (const char*) dataBuf.pData_ << std::endl;
}
if ( bICC ) {
out.write((const char*) dataBuf.pData_,dataBuf.size_);
}
if ( bIptc ) {
IptcData::printStructure(out,dataBuf.pData_,dataBuf.size_,depth);
}
}
delete[] data;
}
io_->seek(dataOffset + 4 , BasicIo::cur);
if (io_->error()) throw Error(14);
}
}
}
RE: Extracting/reading PNG iTXt chunks with Exiv2 - Added by Arnold Wiegert about 5 years ago
Again, many thanks for this clarification.
For some reason I had expected to find this metadata under metadata in the Exiv2 code :-)
I'll give this sample code a try.