diff options
author | Yujie Qin <yujieqin@google.com> | 2016-01-12 08:23:38 +0100 |
---|---|---|
committer | Yujie Qin <yujieqin@google.com> | 2016-01-12 08:23:38 +0100 |
commit | 77a7b0f3312953d580f19b024d8108858b58e4e2 (patch) | |
tree | 46dcfc6b62432877c3be66e892dd64a203bdbd09 | |
parent | 3cda805d84a285063face5033992d755ab468e10 (diff) | |
download | piex-77a7b0f3312953d580f19b024d8108858b58e4e2.tar.gz |
Update PIEX
-rw-r--r-- | src/piex.cc | 65 | ||||
-rw-r--r-- | src/piex_types.h | 4 | ||||
-rw-r--r-- | src/tiff_parser.cc | 16 |
3 files changed, 52 insertions, 33 deletions
diff --git a/src/piex.cc b/src/piex.cc index 1d7401f..a2f90a7 100644 --- a/src/piex.cc +++ b/src/piex.cc @@ -17,6 +17,7 @@ #include "src/piex.h" #include <cstdint> +#include <limits> #include <set> #include <vector> @@ -85,8 +86,8 @@ void GetThumbnailOffsetAndLength(StreamInterface* stream, PreviewImageData thumbnail_data; if (GetPreviewData(extended_tags, kNumberOfIfds, stream, &thumbnail_data) == kOk) { - preview_image_data->thumbnail_offset = thumbnail_data.jpeg_offset; - preview_image_data->thumbnail_length = thumbnail_data.jpeg_length; + preview_image_data->thumbnail_offset = thumbnail_data.preview_offset; + preview_image_data->thumbnail_length = thumbnail_data.preview_length; } } @@ -228,9 +229,9 @@ Error GetOlympusPreviewImage(StreamInterface* stream, return kUnsupported; } - camera_settings_ifd.Get(kPreviewOffset, &preview_image_data->jpeg_offset); - preview_image_data->jpeg_offset += makernote_offset; - camera_settings_ifd.Get(kPreviewLength, &preview_image_data->jpeg_length); + camera_settings_ifd.Get(kPreviewOffset, &preview_image_data->preview_offset); + preview_image_data->preview_offset += makernote_offset; + camera_settings_ifd.Get(kPreviewLength, &preview_image_data->preview_length); // Get the crop size from the raw processing ifd. TiffDirectory raw_processing_ifd(endian); @@ -333,9 +334,11 @@ Error DngGetPreviewData(StreamInterface* stream, return error; } - // Find the largest jpeg compressed preview image. - std::uint32_t jpeg_length = 0; - std::uint32_t jpeg_offset = 0; + // Find the largest and smallest jpeg compressed preview image. + std::uint32_t preview_length = 0; + std::uint32_t preview_offset = 0; + std::uint32_t thumbnail_length = std::numeric_limits<std::uint32_t>::max(); + std::uint32_t thumbnail_offset = std::numeric_limits<std::uint32_t>::max(); for (const auto& ifd : tiff_content.tiff_directory[0].GetSubDirectories()) { std::uint32_t compression; std::uint32_t photometric_interpretation; @@ -349,15 +352,26 @@ Error DngGetPreviewData(StreamInterface* stream, std::vector<std::uint32_t> byte_counts; if (ifd.Get(kTiffTagStripOffsets, &strip_offsets) && ifd.Get(kTiffTagStripByteCounts, &byte_counts) && - strip_offsets.size() == 1 && byte_counts.size() == 1 && - byte_counts[0] > jpeg_length) { - jpeg_length = byte_counts[0]; - jpeg_offset = strip_offsets[0]; + strip_offsets.size() == 1 && byte_counts.size() == 1) { + if (byte_counts[0] > preview_length) { + preview_length = byte_counts[0]; + preview_offset = strip_offsets[0]; + } + if (byte_counts[0] < thumbnail_length) { + thumbnail_length = byte_counts[0]; + thumbnail_offset = strip_offsets[0]; + } } } } - preview_image_data->jpeg_length = jpeg_length; - preview_image_data->jpeg_offset = jpeg_offset; + preview_image_data->preview_length = preview_length; + preview_image_data->preview_offset = preview_offset; + + // A thumbnail image is supposed to be smaller compared to the preview. + if (thumbnail_length < preview_length) { + preview_image_data->thumbnail_length = thumbnail_length; + preview_image_data->thumbnail_offset = thumbnail_offset; + } return kOk; } @@ -373,19 +387,24 @@ Error NefGetPreviewData(StreamInterface* stream, return error; } + PreviewImageData thumbnail_data; + GetThumbnailOffsetAndLength(stream, &thumbnail_data); + preview_image_data->thumbnail_offset = thumbnail_data.thumbnail_offset; + preview_image_data->thumbnail_length = thumbnail_data.thumbnail_length; + // The Nikon RAW data provides the dimensions of the sensor image, which are // slightly larger than the dimensions of the preview image. In order to // determine the correct full width and height of the image, the preview image // size needs to be taken into account. Based on experiments the preview image // dimensions must be at least 90% of the sensor image dimensions to let it be // a full size preview image. - if (preview_image_data->jpeg_length > 0) { // when preview image exists + if (preview_image_data->preview_length > 0) { // when preview image exists const float kEpsilon = 0.9f; std::uint16_t width; std::uint16_t height; - if (!GetPreviewDimensions(preview_image_data->jpeg_offset, stream, &width, - &height) || + if (!GetPreviewDimensions(preview_image_data->preview_offset, stream, + &width, &height) || preview_image_data->full_width == 0 || preview_image_data->full_height == 0) { return kUnsupported; @@ -442,8 +461,8 @@ Error RafGetPreviewData(StreamInterface* stream, } // Merge the Exif data with the RAW data to form the preview_image_data. - preview_image_data->jpeg_offset = jpeg_offset; - preview_image_data->jpeg_length = jpeg_length; + preview_image_data->preview_offset = jpeg_offset; + preview_image_data->preview_length = jpeg_length; return kOk; } @@ -463,18 +482,18 @@ Error Rw2GetPreviewData(StreamInterface* stream, return error; } - if (preview_data.jpeg_length > 0) { // when preview image exists + if (preview_data.preview_length > 0) { // when preview image exists // Parse the Exif information from the preview image. Omit kUnsupported, // because the exif data does not contain any preview image. - const std::uint32_t exif_offset = preview_data.jpeg_offset + 12; + const std::uint32_t exif_offset = preview_data.preview_offset + 12; if (GetExifData(exif_offset, stream, preview_image_data) == kFail) { return kFail; } } // Merge the Exif data with the RAW data to form the preview_image_data. - preview_image_data->jpeg_offset = preview_data.jpeg_offset; - preview_image_data->jpeg_length = preview_data.jpeg_length; + preview_image_data->preview_offset = preview_data.preview_offset; + preview_image_data->preview_length = preview_data.preview_length; preview_image_data->iso = preview_data.iso; preview_image_data->full_width = preview_data.full_width; preview_image_data->full_height = preview_data.full_height; diff --git a/src/piex_types.h b/src/piex_types.h index ad96b76..a180d87 100644 --- a/src/piex_types.h +++ b/src/piex_types.h @@ -60,8 +60,8 @@ struct PreviewImageData { // correctly. A thumbnail is typically 160x120 pixel small and usually // has black borders at the top and bottom. If length is 0 the image could not // be extracted. - std::uint32_t jpeg_offset = 0; - std::uint32_t jpeg_length = 0; + std::uint32_t preview_offset = 0; + std::uint32_t preview_length = 0; std::uint32_t thumbnail_offset = 0; std::uint32_t thumbnail_length = 0; std::uint32_t exif_orientation = 1; // horizontal as default diff --git a/src/tiff_parser.cc b/src/tiff_parser.cc index c0f1b14..a36d5c8 100644 --- a/src/tiff_parser.cc +++ b/src/tiff_parser.cc @@ -172,20 +172,20 @@ Error FillPreviewImageData(const TiffDirectory& tiff_directory, return kFail; } if (strip_offsets.size() == 1 && strip_byte_counts.size() == 1) { - preview_image_data->jpeg_offset = strip_offsets[0]; - preview_image_data->jpeg_length = strip_byte_counts[0]; + preview_image_data->preview_offset = strip_offsets[0]; + preview_image_data->preview_length = strip_byte_counts[0]; } } else if (tiff_directory.Has(kTiffTagJpegOffset) && tiff_directory.Has(kTiffTagJpegByteCount)) { success &= tiff_directory.Get(kTiffTagJpegOffset, - &preview_image_data->jpeg_offset); + &preview_image_data->preview_offset); success &= tiff_directory.Get(kTiffTagJpegByteCount, - &preview_image_data->jpeg_length); + &preview_image_data->preview_length); } else if (tiff_directory.Has(kPanaTagJpegImage)) { - if (!tiff_directory.GetOffsetAndLength(kPanaTagJpegImage, - TIFF_TYPE_UNDEFINED, - &preview_image_data->jpeg_offset, - &preview_image_data->jpeg_length)) { + if (!tiff_directory.GetOffsetAndLength( + kPanaTagJpegImage, TIFF_TYPE_UNDEFINED, + &preview_image_data->preview_offset, + &preview_image_data->preview_length)) { return kFail; } } |