From 738b630587ea9665015671731be0f45422f40794 Mon Sep 17 00:00:00 2001 From: Alexander Stippich Date: Thu, 20 Jun 2019 16:30:17 +0200 Subject: [PATCH 1/3] read image width and height from RAF metadata --- src/rafimage.cpp | 64 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/src/rafimage.cpp b/src/rafimage.cpp index be34fa7cbc..1129a83dcf 100644 --- a/src/rafimage.cpp +++ b/src/rafimage.cpp @@ -59,19 +59,15 @@ namespace Exiv2 { int RafImage::pixelWidth() const { - Exiv2::ExifData::const_iterator widthIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension")); - if (widthIter != exifData_.end() && widthIter->count() > 0) { - return widthIter->toLong(); - } + if (pixelWidth_ != 0) return pixelWidth_; + return 0; } int RafImage::pixelHeight() const { - Exiv2::ExifData::const_iterator heightIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension")); - if (heightIter != exifData_.end() && heightIter->count() > 0) { - return heightIter->toLong(); - } + if (pixelHeight_ != 0) return pixelHeight_; + return 0; } @@ -313,8 +309,58 @@ namespace Exiv2 { enforce(jpg_img_len >= 12, kerCorruptedMetadata); + // look for the height and width of the raw image in the raf metadata header + byte cfa_header_offset [4]; + if (io_->read(cfa_header_offset, 4) != 4) throw Error(kerFailedToReadImageData); + byte cfa_header_length [4]; + if (io_->read(cfa_header_length, 4) != 4) throw Error(kerFailedToReadImageData); + uint32_t cfa_hdr_off_u32 = Exiv2::getULong((const byte *) cfa_header_offset, bigEndian); + uint32_t cfa_hdr_len_u32 = Exiv2::getULong((const byte *) cfa_header_length, bigEndian); + + enforce(Safe::add(cfa_hdr_off_u32, cfa_hdr_len_u32) <= io_->size(), kerCorruptedMetadata); + + long cfa_hdr_off = static_cast(cfa_hdr_off_u32); + + if (io_->seek(cfa_hdr_off, BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); + + byte tag_count[4]; + if (io_->read(tag_count, 4) != 4) throw Error(kerFailedToReadImageData); + uint32_t count = getULong(tag_count, bigEndian); + // check that the count value is in a sane range + // assume a size of 4 bytes, but raf tags may also be larger + enforce(count < cfa_hdr_len_u32 / 4, kerCorruptedMetadata); + + byte byte_tag[2]; + byte byte_size[2]; + uint16_t tag; + uint16_t tag_size; + + for (uint32_t i = 0; i < count; ++i ) { + if (io_->read(byte_tag, 2) != 2 || io_->read(byte_size, 2) != 2) { + break; + } else { + tag = getUShort(byte_tag, bigEndian); + tag_size = getUShort(byte_size, bigEndian); + } + if (tag == 0x0100) { + byte image_height [2]; + byte image_width [2]; + if (io_->read(image_height, 2) == 2) { + pixelHeight_ = getUShort(image_height, bigEndian); + } + if (io_->read(image_width, 2) == 2) { + pixelWidth_ = getUShort(image_width, bigEndian); + } + break; + } else { + if (io_->seek(tag_size, BasicIo::cur) != 0 || io_->eof()) { + break; + }; + } + } // raf metadata header + DataBuf buf(jpg_img_len - 12); - if (io_->seek(jpg_img_off + 12,BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); + if (io_->seek(jpg_img_off + 12, BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); io_->read(buf.pData_, buf.size_); if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); From 1e869f605c35753029e9b5d28063278878063596 Mon Sep 17 00:00:00 2001 From: Alexander Stippich Date: Thu, 20 Jun 2019 16:56:23 +0200 Subject: [PATCH 2/3] fix test for issue 857 --- tests/bugfixes/github/test_issue_857.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bugfixes/github/test_issue_857.py b/tests/bugfixes/github/test_issue_857.py index 266bebcd3d..d0472df688 100644 --- a/tests/bugfixes/github/test_issue_857.py +++ b/tests/bugfixes/github/test_issue_857.py @@ -22,7 +22,7 @@ class OutOfMemoryInRafImageReadMetadata(metaclass=CaseMeta): $kerCorruptedMetadata """, """Exiv2 exception in print action for file $filename2: -This does not look like a TIFF image +$kerCorruptedMetadata """ ] retval = [1,1] From 982a8a739c030e852dfe22855fa3ad7501ae3bb4 Mon Sep 17 00:00:00 2001 From: Alexander Stippich Date: Tue, 9 Jul 2019 19:42:37 +0200 Subject: [PATCH 3/3] document raf metadata structure --- src/rafimage.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/rafimage.cpp b/src/rafimage.cpp index 1129a83dcf..e59ef2242c 100644 --- a/src/rafimage.cpp +++ b/src/rafimage.cpp @@ -309,7 +309,13 @@ namespace Exiv2 { enforce(jpg_img_len >= 12, kerCorruptedMetadata); - // look for the height and width of the raw image in the raf metadata header + /* Look for the height and width of the raw image in the raf metadata header. + * Raf metadata starts with 4 bytes giving the number of available tags, + * followed by the tags. Each tag starts with two bytes with the tag id and + * two bytes with the tag size, followed by the actual tag data. + * The image width and height have the tag id of 0x0100. + * For more tag ids have a look at e.g. exiftool. + */ byte cfa_header_offset [4]; if (io_->read(cfa_header_offset, 4) != 4) throw Error(kerFailedToReadImageData); byte cfa_header_length [4];