3737#include " enforce.hpp"
3838#include " safe_op.hpp"
3939
40- // + standard includes
40+ // +standard includes
4141#include < string>
4242#include < cstring>
4343#include < iostream>
@@ -92,7 +92,7 @@ namespace Exiv2 {
9292 // not supported
9393 throw (Error (kerInvalidSettingForImage, " Image comment" , " RAF" ));
9494 }
95-
95+
9696 void RafImage::printStructure (std::ostream& out, PrintStructureOption option, int depth) {
9797 if (io_->open () != 0 ) {
9898 throw Error (kerDataSourceOpenFailed, io_->path (), strError ());
@@ -102,17 +102,21 @@ namespace Exiv2 {
102102 if (io_->error () || io_->eof ()) throw Error (kerFailedToReadImageData);
103103 throw Error (kerNotAnImage, " RAF" );
104104 }
105+ size_t address = 0 ;
106+ size_t address2 = 0 ;
105107 const bool bPrint = option==kpsBasic || option==kpsRecursive;
106108 if ( bPrint ) {
107109 io_->seek (0 ,BasicIo::beg); // rewind
110+ address = io_->tell ();
111+ const char * format = " %8d | %8d | " ;
108112
109113 {
110114 out << Internal::indent (depth)
111115 << " STRUCTURE OF RAF FILE: "
112116 << io ().path ()
113117 << std::endl;
114118 out << Internal::indent (depth)
115- << Internal::stringFormat (" Length | Offset | Payload" )
119+ << Internal::stringFormat (" Address | Length | Payload" )
116120 << std::endl;
117121 }
118122
@@ -121,63 +125,79 @@ namespace Exiv2 {
121125 magicdata[16 ] = 0 ;
122126 {
123127 out << Internal::indent (depth)
124- << Internal::stringFormat (" %8u | %8u | " , 16 , 0 )
125- << " Magic number : "
126- << std::string (( char *)& magicdata)
128+ << Internal::stringFormat (format,address , 16 , 0 )
129+ << " magic : "
130+ << ( char *) magicdata
127131 << std::endl;
128132 }
129133
134+ address = io_->tell ();
130135 byte data1 [5 ];
131136 io_->read (data1, 4 );
132137 data1[4 ] = 0 ;
133138 {
134139 out << Internal::indent (depth)
135- << Internal::stringFormat (" %8u | %8u | " , 4 , 16 )
136- << " data 1 : "
140+ << Internal::stringFormat (format,address , 4 , 16 )
141+ << " data1 : "
137142 << std::string ((char *)&data1)
138143 << std::endl;
139144 }
140145
146+ address = io_->tell ();
141147 byte data2 [9 ];
142148 io_->read (data2, 8 );
143149 data2[8 ] = 0 ;
144150 {
145151 out << Internal::indent (depth)
146- << Internal::stringFormat (" %8u | %8u | " , 8 , 20 )
147- << " data 2 : "
152+ << Internal::stringFormat (format,address , 8 , 20 )
153+ << " data2 : "
148154 << std::string ((char *)&data2)
149155 << std::endl;
150156 }
151157
158+ address = io_->tell ();
152159 byte camdata [33 ];
153160 io_->read (camdata, 32 );
154161 camdata[32 ] = 0 ;
155162 {
156163 out << Internal::indent (depth)
157- << Internal::stringFormat (" %8u | %8u | " , 32 , 28 )
158- << " camera : "
164+ << Internal::stringFormat (format,address , 32 , 28 )
165+ << " camera : "
159166 << std::string ((char *)&camdata)
160167 << std::endl;
161168 }
162169
170+ address = io_->tell ();
163171 byte dir_version [5 ];
164172 io_->read (dir_version, 4 );
165173 dir_version[4 ] = 0 ;
166174 {
167175 out << Internal::indent (depth)
168- << Internal::stringFormat (" %8u | %8u | " , 4 , 60 )
169- << " dir version : "
176+ << Internal::stringFormat (format,address , 4 , 60 )
177+ << " version : "
170178 << std::string ((char *)&dir_version)
171179 << std::endl;
172180 }
173181
174- byte unknown [20 ];
175- io_->read (unknown, 20 );
182+ address = io_->tell ();
183+ DataBuf unknown (20 );
184+ io_->read (unknown.pData_ ,unknown.size_ );
185+ {
186+ out << Internal::indent (depth)
187+ << Internal::stringFormat (format,address, 20 )
188+ << " unknown : "
189+ << Internal::binaryToString (makeSlice (unknown, 0 ,unknown.size_ ))
190+ << std::endl;
191+ }
176192
193+
194+ address = io_->tell ();
177195 byte jpg_img_offset [4 ];
178196 io_->read (jpg_img_offset, 4 );
179197 byte jpg_img_length [4 ];
198+ address2 = io_->tell ();
180199 io_->read (jpg_img_length, 4 );
200+
181201 long jpg_img_off = Exiv2::getULong ((const byte *) jpg_img_offset, bigEndian);
182202 long jpg_img_len = Exiv2::getULong ((const byte *) jpg_img_length, bigEndian);
183203 std::stringstream j_off;
@@ -186,20 +206,22 @@ namespace Exiv2 {
186206 j_len << jpg_img_len;
187207 {
188208 out << Internal::indent (depth)
189- << Internal::stringFormat (" %8u | %8u | " , 4 , 84 )
190- << " JPEG Image Offset : "
209+ << Internal::stringFormat (format,address, 4 )
210+ << " JPEG Offset : "
191211 << j_off.str ()
192212 << std::endl;
193213 out << Internal::indent (depth)
194- << Internal::stringFormat (" %8u | %8u | " , 4 , 88 )
195- << " JPEG Image Length : "
214+ << Internal::stringFormat (format,address2, 4 )
215+ << " JPEG Length : "
196216 << j_len.str ()
197217 << std::endl;
198218 }
199219
220+ address = io_->tell ();
200221 byte cfa_header_offset [4 ];
201222 io_->read (cfa_header_offset, 4 );
202223 byte cfa_header_length [4 ];
224+ address2 = io_->tell ();
203225 io_->read (cfa_header_length, 4 );
204226 long cfa_hdr_off = Exiv2::getULong ((const byte *) cfa_header_offset, bigEndian);
205227 long cfa_hdr_len = Exiv2::getULong ((const byte *) cfa_header_length, bigEndian);
@@ -209,20 +231,22 @@ namespace Exiv2 {
209231 ch_len << cfa_hdr_len;
210232 {
211233 out << Internal::indent (depth)
212- << Internal::stringFormat (" %8u | %8u | " , 4 , 92 )
213- << " CFA Header Offset : "
234+ << Internal::stringFormat (format,address, 4 )
235+ << " CFA Offset : "
214236 << ch_off.str ()
215237 << std::endl;
216238 out << Internal::indent (depth)
217- << Internal::stringFormat (" %8u | %8u | " , 4 , 96 )
218- << " CFA Header Length : "
239+ << Internal::stringFormat (format,address2, 4 )
240+ << " CFA Length : "
219241 << ch_len.str ()
220242 << std::endl;
221243 }
222244
223245 byte cfa_offset [4 ];
246+ address = io_->tell ();
224247 io_->read (cfa_offset, 4 );
225248 byte cfa_length [4 ];
249+ address2 = io_->tell ();
226250 io_->read (cfa_length, 4 );
227251 long cfa_off = Exiv2::getULong ((const byte *) cfa_offset, bigEndian);
228252 long cfa_len = Exiv2::getULong ((const byte *) cfa_length, bigEndian);
@@ -232,44 +256,47 @@ namespace Exiv2 {
232256 c_len << cfa_len;
233257 {
234258 out << Internal::indent (depth)
235- << Internal::stringFormat (" %8u | %8u | " , 4 , 100 )
236- << " CFA Offset : "
259+ << Internal::stringFormat (format,address, 4 )
260+ << " TIFF Offset : "
237261 << c_off.str ()
238262 << std::endl;
239263 out << Internal::indent (depth)
240- << Internal::stringFormat (" %8u | %8u | " , 4 , 104 )
241- << " CFA Length : "
264+ << Internal::stringFormat (format,address2, 4 )
265+ << " TIFF Length : "
242266 << c_len.str ()
243267 << std::endl;
244268 }
245269
246270 io_->seek (jpg_img_off, BasicIo::beg); // rewind
271+ address = io_->tell ();
247272 DataBuf payload (16 ); // header is different from chunks
248273 io_->read (payload.pData_ , payload.size_ );
249274 {
250275 out << Internal::indent (depth)
251- << Internal::stringFormat (" %8u | %8u | " , jpg_img_len, jpg_img_off)
252- << " jpg image / exif : "
276+ << Internal::stringFormat (format,address, jpg_img_len) // , jpg_img_off)
277+ << " JPEG : "
253278 << Internal::binaryToString (makeSlice (payload, 0 , payload.size_ ))
254279 << std::endl;
255280 }
256281
257282 io_->seek (cfa_hdr_off, BasicIo::beg); // rewind
283+ address = io_->tell ();
258284 io_->read (payload.pData_ , payload.size_ );
259285 {
260286 out << Internal::indent (depth)
261- << Internal::stringFormat (" %8u | %8u | " , cfa_hdr_len, cfa_hdr_off)
262- << " CFA Header : "
287+ << Internal::stringFormat (format,address , cfa_hdr_len, cfa_hdr_off)
288+ << " CFA : "
263289 << Internal::binaryToString (makeSlice (payload, 0 , payload.size_ ))
264290 << std::endl;
265291 }
266292
267293 io_->seek (cfa_off, BasicIo::beg); // rewind
294+ address = io_->tell ();
268295 io_->read (payload.pData_ , payload.size_ );
269296 {
270297 out << Internal::indent (depth)
271- << Internal::stringFormat (" %8u | %8u | " , cfa_len, cfa_off)
272- << " CFA : "
298+ << Internal::stringFormat (format,address , cfa_len, cfa_off)
299+ << " TIFF : "
273300 << Internal::binaryToString (makeSlice (payload, 0 , payload.size_ ))
274301 << std::endl;
275302 }
@@ -330,6 +357,31 @@ namespace Exiv2 {
330357 exifData_[" Exif.Image2.JPEGInterchangeFormatLength" ] = getULong (jpg_img_length, bigEndian);
331358
332359 setByteOrder (bo);
360+
361+ // parse the tiff
362+ byte readBuff[4 ];
363+ if (io_->seek (100 , BasicIo::beg) != 0 ) throw Error (kerFailedToReadImageData);
364+ if (io_->read (readBuff, 4 ) != 4 ) throw Error (kerFailedToReadImageData);
365+ uint32_t tiffOffset = Exiv2::getULong (readBuff, bigEndian);
366+
367+ if (io_->read (readBuff, 4 ) != 4 ) throw Error (kerFailedToReadImageData);
368+ uint32_t tiffLength = Exiv2::getULong (readBuff, bigEndian);
369+
370+ // sanity check. Does tiff lie inside the file?
371+ enforce (Safe::add (tiffOffset, tiffLength) <= io_->size (), kerCorruptedMetadata);
372+
373+ DataBuf tiff (tiffLength);
374+ if (io_->seek (tiffOffset, BasicIo::beg) != 0 ) throw Error (kerFailedToReadImageData);
375+ io_->read (tiff.pData_ , tiff.size_ );
376+
377+ if (!io_->error () && !io_->eof ())
378+ {
379+ TiffParser::decode (exifData_,
380+ iptcData_,
381+ xmpData_,
382+ tiff.pData_ ,
383+ tiff.size_ );
384+ }
333385 } // RafImage::readMetadata
334386
335387 void RafImage::writeMetadata ()
0 commit comments