From c5eabe7d22834189c77fe95ebaf72fed0ef2bb8e Mon Sep 17 00:00:00 2001 From: Matt Sarett Date: Fri, 24 Feb 2017 14:51:08 -0500 Subject: Read color space info from raw exif data b/35516531 Change-Id: I86ad40b059f300375b0293bd96ecb967811f3a07 Reviewed-on: https://skia-review.googlesource.com/8951 Reviewed-by: Leon Scroggins Commit-Queue: Matt Sarett --- src/codec/SkJpegCodec.cpp | 15 +++++++++------ src/codec/SkJpegCodec.h | 12 +++++++++++- src/codec/SkRawCodec.cpp | 18 +++++++++++++++--- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index 995aaa6b96..1ed76a7c4d 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -189,8 +189,8 @@ static sk_sp get_icc_profile(jpeg_decompress_struct* dinfo) { return iccData; } -bool SkJpegCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, - JpegDecoderMgr** decoderMgrOut) { +bool SkJpegCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, JpegDecoderMgr** decoderMgrOut, + sk_sp defaultColorSpace) { // Create a JpegDecoderMgr to own all of the decompress information std::unique_ptr decoderMgr(new JpegDecoderMgr(stream)); @@ -251,8 +251,7 @@ bool SkJpegCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, } } if (!colorSpace) { - // Treat unmarked jpegs as sRGB. - colorSpace = SkColorSpace::MakeSRGB(); + colorSpace = defaultColorSpace; } const int width = decoderMgr->dinfo()->image_width; @@ -269,9 +268,13 @@ bool SkJpegCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, } SkCodec* SkJpegCodec::NewFromStream(SkStream* stream) { + return SkJpegCodec::NewFromStream(stream, SkColorSpace::MakeSRGB()); +} + +SkCodec* SkJpegCodec::NewFromStream(SkStream* stream, sk_sp defaultColorSpace) { std::unique_ptr streamDeleter(stream); SkCodec* codec = nullptr; - if (ReadHeader(stream, &codec, nullptr)) { + if (ReadHeader(stream, &codec, nullptr, std::move(defaultColorSpace))) { // Codec has taken ownership of the stream, we do not need to delete it SkASSERT(codec); streamDeleter.release(); @@ -353,7 +356,7 @@ SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const { bool SkJpegCodec::onRewind() { JpegDecoderMgr* decoderMgr = nullptr; - if (!ReadHeader(this->stream(), nullptr, &decoderMgr)) { + if (!ReadHeader(this->stream(), nullptr, &decoderMgr, nullptr)) { return fDecoderMgr->returnFalse("onRewind"); } SkASSERT(nullptr != decoderMgr); diff --git a/src/codec/SkJpegCodec.h b/src/codec/SkJpegCodec.h index af795ceefc..b6d75289e6 100644 --- a/src/codec/SkJpegCodec.h +++ b/src/codec/SkJpegCodec.h @@ -61,6 +61,11 @@ protected: private: + /* + * Allows SkRawCodec to communicate the color space from the exif data. + */ + static SkCodec* NewFromStream(SkStream*, sk_sp defaultColorSpace); + /* * Read enough of the stream to initialize the SkJpegCodec. * Returns a bool representing success or failure. @@ -79,9 +84,12 @@ private: * codecOut will take ownership of it in the case where we created a codec. * Ownership is unchanged when we set decoderMgrOut. * + * @param defaultColorSpace + * If the jpeg does not have an embedded color space, the image data should + * be tagged with this color space. */ static bool ReadHeader(SkStream* stream, SkCodec** codecOut, - JpegDecoderMgr** decoderMgrOut); + JpegDecoderMgr** decoderMgrOut, sk_sp defaultColorSpace); /* * Creates an instance of the decoder @@ -134,6 +142,8 @@ private: std::unique_ptr fSwizzler; + friend class SkRawCodec; + typedef SkCodec INHERITED; }; diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp index 1684a16884..0a1cea1688 100644 --- a/src/codec/SkRawCodec.cpp +++ b/src/codec/SkRawCodec.cpp @@ -648,6 +648,19 @@ SkCodec* SkRawCodec::NewFromStream(SkStream* stream) { ::piex::PreviewImageData imageData; if (::piex::IsRaw(&piexStream)) { ::piex::Error error = ::piex::GetPreviewImageData(&piexStream, &imageData); + if (error == ::piex::Error::kFail) { + return nullptr; + } + + sk_sp colorSpace; + switch (imageData.color_space) { + case ::piex::PreviewImageData::kSrgb: + colorSpace = SkColorSpace::MakeSRGB(); + break; + case ::piex::PreviewImageData::kAdobeRgb: + colorSpace = SkColorSpace_Base::MakeNamed(SkColorSpace_Base::kAdobeRGB_Named); + break; + } // Theoretically PIEX can return JPEG compressed image or uncompressed RGB image. We only // handle the JPEG compressed preview image here. @@ -659,9 +672,8 @@ SkCodec* SkRawCodec::NewFromStream(SkStream* stream) { // FIXME: one may avoid the copy of memoryStream and use the buffered rawStream. SkMemoryStream* memoryStream = rawStream->transferBuffer(imageData.preview.offset, imageData.preview.length); - return memoryStream ? SkJpegCodec::NewFromStream(memoryStream) : nullptr; - } else if (error == ::piex::Error::kFail) { - return nullptr; + return memoryStream ? SkJpegCodec::NewFromStream(memoryStream, std::move(colorSpace)) + : nullptr; } } -- cgit v1.2.3