73
73
#define TAG_cmt2 0x434D5432 /* *< "CMD2" exifID */
74
74
#define TAG_cmt3 0x434D5433 /* *< "CMT3" canonID */
75
75
#define TAG_cmt4 0x434D5434 /* *< "CMT4" gpsID */
76
- #define TAG_colr 0x636f6c72 /* *< "colr" */
76
+ #define TAG_colr 0x636f6c72 /* *< "colr" Colour information */
77
77
#define TAG_exif 0x45786966 /* *< "Exif" Used by JXL*/
78
- #define TAG_xml 0x786d6c20 /* *< "xml" Used by JXL*/
78
+ #define TAG_xml 0x786d6c20 /* *< "xml " Used by JXL*/
79
+ #define TAG_thmb 0x54484d42 /* *< "THMB" Canon thumbnail */
80
+ #define TAG_prvw 0x50525657 /* *< "PRVW" Canon preview image */
79
81
80
82
// *****************************************************************************
81
83
// class member definitions
@@ -124,7 +126,7 @@ namespace Exiv2
124
126
125
127
bool BmffImage::fullBox (uint32_t box)
126
128
{
127
- return box == TAG_meta || box == TAG_iinf || box == TAG_iloc;
129
+ return box == TAG_meta || box == TAG_iinf || box == TAG_iloc || box == TAG_thmb || box == TAG_prvw ;
128
130
}
129
131
130
132
static bool skipBox (uint32_t box)
@@ -264,7 +266,7 @@ namespace Exiv2
264
266
enforce (data.size_ - skip >= 4 , Exiv2::kerCorruptedMetadata);
265
267
flags = getLong (data.pData_ + skip, endian_); // version/flags
266
268
version = static_cast <uint8_t >(flags >> 24 );
267
- version &= 0x00ffffff ;
269
+ flags &= 0x00ffffff ;
268
270
skip += 4 ;
269
271
}
270
272
@@ -453,7 +455,12 @@ namespace Exiv2
453
455
out << " uuidName " << name << std::endl;
454
456
bLF = false ;
455
457
}
456
- if (name == " cano" ) {
458
+ if (name == " cano" || name == " canp" ) {
459
+ if (name == " canp" ) {
460
+ // based on
461
+ // https://github.com/lclevy/canon_cr3/blob/7be75d6/parse_cr3.py#L271
462
+ io_->seek (8 , BasicIo::cur);
463
+ }
457
464
while (io_->tell () < box_end) {
458
465
io_->seek (boxHandler (out,option,box_end,depth + 1 ), BasicIo::beg);
459
466
}
@@ -480,10 +487,20 @@ namespace Exiv2
480
487
case TAG_xml:
481
488
parseXmp (box_length,io_->tell ());
482
489
break ;
490
+ case TAG_thmb:
491
+ if (version == 0 ) {
492
+ parseCr3Preview (data, out, bTrace, skip, skip+2 , skip+4 , skip+12 );
493
+ }
494
+ break ;
495
+ case TAG_prvw:
496
+ if (version == 0 ) {
497
+ parseCr3Preview (data, out, bTrace, skip+2 , skip+4 , skip+8 , skip+12 );
498
+ }
499
+ break ;
483
500
484
501
default : break ; /* do nothing */
485
502
}
486
- if ( bLF&& bTrace) out << std::endl;
503
+ if (bLF && bTrace) out << std::endl;
487
504
488
505
// return address of next box
489
506
return box_end;
@@ -564,6 +581,42 @@ namespace Exiv2
564
581
}
565
582
}
566
583
584
+ void BmffImage::parseCr3Preview (DataBuf &data,
585
+ std::ostream& out,
586
+ bool bTrace,
587
+ uint32_t width_offset,
588
+ uint32_t height_offset,
589
+ uint32_t size_offset,
590
+ uint32_t relative_position)
591
+ {
592
+ // Derived from https://github.com/lclevy/canon_cr3
593
+ // Only JPEG (version 0) is currently supported
594
+ // (relative_position is identical between versions)
595
+ long here = io_->tell ();
596
+ enforce (here >= 0 &&
597
+ here <= std::numeric_limits<long >::max () - static_cast <long >(relative_position),
598
+ kerCorruptedMetadata);
599
+ NativePreview nativePreview;
600
+ nativePreview.position_ = here + relative_position;
601
+ enforce (4 <= data.size_ , kerCorruptedMetadata);
602
+ enforce (width_offset <= static_cast <size_t >(data.size_ - 2 ), kerCorruptedMetadata);
603
+ nativePreview.width_ = getShort (data.pData_ + width_offset, endian_);
604
+ enforce (height_offset <= static_cast <size_t >(data.size_ - 2 ), kerCorruptedMetadata);
605
+ nativePreview.height_ = getShort (data.pData_ + height_offset, endian_);
606
+ enforce (size_offset <= static_cast <size_t >(data.size_ - 4 ), kerCorruptedMetadata);
607
+ nativePreview.size_ = getLong (data.pData_ + size_offset, endian_);
608
+ nativePreview.filter_ = " " ;
609
+ nativePreview.mimeType_ = " image/jpeg" ;
610
+ nativePreviews_.push_back (nativePreview);
611
+
612
+ if (bTrace) {
613
+ out << Internal::stringFormat (" width,height,size = %u,%u,%u" ,
614
+ nativePreview.width_ ,
615
+ nativePreview.height_ ,
616
+ nativePreview.size_ );
617
+ }
618
+ }
619
+
567
620
void BmffImage::setComment (const std::string& /* comment*/ )
568
621
{
569
622
// bmff files are read-only
0 commit comments