aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2017-02-24 14:51:08 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-24 20:52:08 +0000
commitc5eabe7d22834189c77fe95ebaf72fed0ef2bb8e (patch)
treef8189ac49d98adfced02e1fa4174a26bb97c8ad4
parent541b1b08a82c8deec09b2bd258e1841660bd862a (diff)
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 <scroggo@google.com> Commit-Queue: Matt Sarett <msarett@google.com>
-rw-r--r--src/codec/SkJpegCodec.cpp15
-rw-r--r--src/codec/SkJpegCodec.h12
-rw-r--r--src/codec/SkRawCodec.cpp18
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<SkData> 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<SkColorSpace> defaultColorSpace) {
// Create a JpegDecoderMgr to own all of the decompress information
std::unique_ptr<JpegDecoderMgr> 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<SkColorSpace> defaultColorSpace) {
std::unique_ptr<SkStream> 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
@@ -62,6 +62,11 @@ protected:
private:
/*
+ * Allows SkRawCodec to communicate the color space from the exif data.
+ */
+ static SkCodec* NewFromStream(SkStream*, sk_sp<SkColorSpace> 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<SkColorSpace> defaultColorSpace);
/*
* Creates an instance of the decoder
@@ -134,6 +142,8 @@ private:
std::unique_ptr<SkSwizzler> 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<SkColorSpace> 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;
}
}