Skip to content

Commit

Permalink
Fix pixelwidth and pixelheight for raf files (#810)
Browse files Browse the repository at this point in the history
Fix pixelwidth and pixelheight for raf files
  • Loading branch information
D4N authored Jul 28, 2019
2 parents dd3fcfa + 982a8a7 commit 98e63e4
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 10 deletions.
70 changes: 61 additions & 9 deletions src/rafimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -313,8 +309,64 @@ namespace Exiv2 {

enforce(jpg_img_len >= 12, kerCorruptedMetadata);

/* 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];
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<long>(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);

Expand Down
2 changes: 1 addition & 1 deletion tests/bugfixes/github/test_issue_857.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]

0 comments on commit 98e63e4

Please sign in to comment.