Skip to content

Commit

Permalink
Add support for CR3s with embedded heif thumbnails
Browse files Browse the repository at this point in the history
  • Loading branch information
nchusid committed Nov 6, 2020
1 parent 256bd10 commit a1b85d5
Show file tree
Hide file tree
Showing 17 changed files with 672 additions and 23 deletions.
Empty file modified LICENSE
100644 → 100755
Empty file.
Empty file modified README
100644 → 100755
Empty file.
Empty file modified src/binary_parse/cached_paged_byte_array.cc
100644 → 100755
Empty file.
Empty file modified src/binary_parse/cached_paged_byte_array.h
100644 → 100755
Empty file.
Empty file modified src/binary_parse/range_checked_byte_ptr.cc
100644 → 100755
Empty file.
Empty file modified src/binary_parse/range_checked_byte_ptr.h
100644 → 100755
Empty file.
21 changes: 21 additions & 0 deletions src/image_type_recognition/image_type_recognition_lite.cc
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,25 @@ class ArwTypeChecker : public TypeChecker {
}
};

// Canon RAW (CR3 extension).
class Cr3TypeChecker : public TypeChecker {
public:
static constexpr size_t kSignatureOffset = 4;
static constexpr const char* kSignature = "ftypcrx ";

virtual RawImageTypes Type() const { return kCr3Image; }

virtual size_t RequestedSize() const {
return kSignatureOffset + strlen(kSignature);
}

// Checks for the ftyp box w/ brand 'crx '.
virtual bool IsMyType(const RangeCheckedBytePtr& source) const {
RangeCheckedBytePtr limited_source = LimitSource(source);
return IsSignatureMatched(limited_source, kSignatureOffset, kSignature);
}
};

// Canon RAW (CR2 extension).
class Cr2TypeChecker : public TypeChecker {
public:
Expand Down Expand Up @@ -749,6 +768,7 @@ class TypeCheckerList {
TypeCheckerList() {
// Add all supported RAW type checkers here.
checkers_.push_back(new ArwTypeChecker());
checkers_.push_back(new Cr3TypeChecker());
checkers_.push_back(new Cr2TypeChecker());
checkers_.push_back(new CrwTypeChecker());
checkers_.push_back(new DcrTypeChecker());
Expand Down Expand Up @@ -841,6 +861,7 @@ bool IsRaw(const RawImageTypes type) {

// Raw image types
case kArwImage:
case kCr3Image:
case kCr2Image:
case kCrwImage:
case kDcrImage:
Expand Down
1 change: 1 addition & 0 deletions src/image_type_recognition/image_type_recognition_lite.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ enum RawImageTypes {
// raw image types
kArwImage,
kCr2Image,
kCr3Image,
kCrwImage,
kDcrImage,
kDngImage,
Expand Down
28 changes: 21 additions & 7 deletions src/piex.cc
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "src/binary_parse/range_checked_byte_ptr.h"
#include "src/image_type_recognition/image_type_recognition_lite.h"
#include "src/piex_cr3.h"
#include "src/tiff_parser.h"

namespace piex {
Expand Down Expand Up @@ -649,7 +650,8 @@ bool IsRaw(StreamInterface* data) {
}

Error GetPreviewImageData(StreamInterface* data,
PreviewImageData* preview_image_data) {
PreviewImageData* preview_image_data,
RawImageTypes* output_type) {
const size_t bytes = BytesRequiredForIsRaw();
if (data == nullptr || bytes == 0) {
return kFail;
Expand All @@ -662,11 +664,15 @@ Error GetPreviewImageData(StreamInterface* data,
}
RangeCheckedBytePtr header_buffer(file_header.data(), file_header.size());

switch (RecognizeRawImageTypeLite(header_buffer)) {
RawImageTypes type = RecognizeRawImageTypeLite(header_buffer);
if (output_type != nullptr) *output_type = type;
switch (type) {
case image_type_recognition::kArwImage:
return ArwGetPreviewData(data, preview_image_data);
case image_type_recognition::kCr2Image:
return Cr2GetPreviewData(data, preview_image_data);
case image_type_recognition::kCr3Image:
return Cr3GetPreviewData(data, preview_image_data);
case image_type_recognition::kDngImage:
return DngGetPreviewData(data, preview_image_data);
case image_type_recognition::kNefImage:
Expand Down Expand Up @@ -703,24 +709,32 @@ bool GetOrientation(StreamInterface* data, std::uint32_t* orientation) {
using image_type_recognition::GetNumberOfBytesForIsOfType;
using image_type_recognition::IsOfType;

std::vector<std::uint8_t> file_header(
GetNumberOfBytesForIsOfType(image_type_recognition::kRafImage));
size_t min_header_bytes =
std::max(GetNumberOfBytesForIsOfType(image_type_recognition::kRafImage),
GetNumberOfBytesForIsOfType(image_type_recognition::kCr3Image));

std::vector<std::uint8_t> file_header(min_header_bytes);
if (data->GetData(0, file_header.size(), file_header.data()) != kOk) {
return false;
}

// For RAF files a special routine is necessary to get orientation. For others
// the general approach is sufficient.
// For RAF and CR# files a special routine is necessary to get orientation.
// For others the general approach is sufficient.
if (IsOfType(RangeCheckedBytePtr(file_header.data(), file_header.size()),
image_type_recognition::kRafImage)) {
return RafGetOrientation(data, orientation);
} else if (IsOfType(
RangeCheckedBytePtr(file_header.data(), file_header.size()),
image_type_recognition::kCr3Image)) {
return Cr3GetOrientation(data, orientation);
} else {
return GetExifOrientation(data, 0 /* offset */, orientation);
}
}

std::vector<std::string> SupportedExtensions() {
return {"ARW", "CR2", "DNG", "NEF", "NRW", "ORF", "PEF", "RAF", "RW2", "SRW"};
return {"ARW", "CR2", "CR3", "DNG", "NEF", "NRW",
"ORF", "PEF", "RAF", "RW2", "SRW"};
}

} // namespace piex
8 changes: 6 additions & 2 deletions src/piex.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <string>
#include <vector>

#include "src/image_type_recognition/image_type_recognition_lite.h"
#include "src/piex_types.h"

namespace piex {
Expand All @@ -70,8 +71,11 @@ bool IsRaw(StreamInterface* data);
//
// One could check the "preview_image_data->preview_length != 0" for the
// existance of a preview image.
Error GetPreviewImageData(StreamInterface* data,
PreviewImageData* preview_image_data);
//
// Updates output_type based on data, if output_type is non-null.
Error GetPreviewImageData(
StreamInterface* data, PreviewImageData* preview_image_data,
image_type_recognition::RawImageTypes* output_type = nullptr);

// Returns true if the full width and height and the mosaic pattern dimension of
// a DNG image could be obtained. False otherwise.
Expand Down
Loading

0 comments on commit a1b85d5

Please sign in to comment.