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>
This commit is contained in:
Matt Sarett 2017-02-24 14:51:08 -05:00 committed by Skia Commit-Bot
parent 541b1b08a8
commit c5eabe7d22
3 changed files with 35 additions and 10 deletions

View File

@ -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);

View File

@ -61,6 +61,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;
};

View File

@ -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;
}
}