diff options
Diffstat (limited to 'src/pdf')
-rw-r--r-- | src/pdf/SkJpegInfo.cpp | 35 | ||||
-rw-r--r-- | src/pdf/SkJpegInfo.h | 26 | ||||
-rw-r--r-- | src/pdf/SkPDFBitmap.cpp | 44 |
3 files changed, 58 insertions, 47 deletions
diff --git a/src/pdf/SkJpegInfo.cpp b/src/pdf/SkJpegInfo.cpp index 5e5ec792ea..df99de4e93 100644 --- a/src/pdf/SkJpegInfo.cpp +++ b/src/pdf/SkJpegInfo.cpp @@ -5,15 +5,16 @@ * found in the LICENSE file. */ -#include "SkData.h" #include "SkJpegInfo.h" +#ifndef SK_HAS_JPEG_LIBRARY + namespace { class JpegSegment { public: - JpegSegment(const SkData* skdata) - : fData(static_cast<const char*>(skdata->data())) - , fSize(skdata->size()) + JpegSegment(const void* data, size_t size) + : fData(static_cast<const char*>(data)) + , fSize(size) , fOffset(0) , fLength(0) {} bool read() { @@ -75,10 +76,13 @@ private: }; } // namespace -bool SkIsJFIF(const SkData* skdata, SkJFIFInfo* info) { +bool SkGetJpegInfo(const void* data, size_t len, + SkISize* size, + SkEncodedInfo::Color* colorType, + SkEncodedOrigin* orientation) { static const uint16_t kSOI = 0xFFD8; static const uint16_t kAPP0 = 0xFFE0; - JpegSegment segment(skdata); + JpegSegment segment(data, len); if (!segment.read() || segment.marker() != kSOI) { return false; // not a JPEG } @@ -106,14 +110,17 @@ bool SkIsJFIF(const SkData* skdata, SkJFIFInfo* info) { if (numberOfComponents != 1 && numberOfComponents != 3) { return false; // Invalid JFIF } - if (info) { - info->fSize.set(JpegSegment::GetBigendianUint16(&segment.data()[3]), - JpegSegment::GetBigendianUint16(&segment.data()[1])); - if (numberOfComponents == 3) { - info->fType = SkJFIFInfo::kYCbCr; - } else { - info->fType = SkJFIFInfo::kGrayscale; - } + if (size) { + *size = {JpegSegment::GetBigendianUint16(&segment.data()[3]), + JpegSegment::GetBigendianUint16(&segment.data()[1])}; + } + if (colorType) { + *colorType = numberOfComponents == 3 ? SkEncodedInfo::kYUV_Color + : SkEncodedInfo::kGray_Color; + } + if (orientation) { + *orientation = kTopLeft_SkEncodedOrigin; } return true; } +#endif // SK_HAS_JPEG_LIBRARY diff --git a/src/pdf/SkJpegInfo.h b/src/pdf/SkJpegInfo.h index 39de99455a..2f0eb6f54a 100644 --- a/src/pdf/SkJpegInfo.h +++ b/src/pdf/SkJpegInfo.h @@ -7,25 +7,19 @@ #ifndef SkJpegInfo_DEFINED #define SkJpegInfo_DEFINED +#include "SkEncodedInfo.h" +#include "SkEncodedOrigin.h" #include "SkSize.h" -class SkData; +/** Returns true if the data seems to be a valid JPEG image with a known colorType. -struct SkJFIFInfo { - SkISize fSize; - enum Type { - kGrayscale, - kYCbCr, - } fType; -}; - -/** Returns true iff the data seems to be a valid JFIF JPEG image. - If so and if info is not nullptr, populate info. - - JPEG/JFIF References: - http://www.w3.org/Graphics/JPEG/itu-t81.pdf - http://www.w3.org/Graphics/JPEG/jfif3.pdf + @param [out] size Image size in pixels + @param [out] colorType Encoded color type (kGray_Color, kYUV_Color, several others). + @param [out] orientation EXIF Orientation of the image. */ -bool SkIsJFIF(const SkData* skdata, SkJFIFInfo* info); +bool SkGetJpegInfo(const void* data, size_t len, + SkISize* size, + SkEncodedInfo::Color* colorType, + SkEncodedOrigin* orientation); #endif // SkJpegInfo_DEFINED diff --git a/src/pdf/SkPDFBitmap.cpp b/src/pdf/SkPDFBitmap.cpp index faae47ef63..b575d16430 100644 --- a/src/pdf/SkPDFBitmap.cpp +++ b/src/pdf/SkPDFBitmap.cpp @@ -376,8 +376,8 @@ public: SkISize fSize; sk_sp<SkData> fData; bool fIsYUV; - PDFJpegBitmap(SkISize size, SkData* data, bool isYUV) - : fSize(size), fData(SkRef(data)), fIsYUV(isYUV) { SkASSERT(data); } + PDFJpegBitmap(SkISize size, sk_sp<SkData> data, bool isYUV) + : fSize(size), fData(std::move(data)), fIsYUV(isYUV) { SkASSERT(fData); } void emitObject(SkWStream*, const SkPDFObjNumMap&) const override; void drop() override { fData = nullptr; } }; @@ -406,32 +406,42 @@ void PDFJpegBitmap::emitObject(SkWStream* stream, } // namespace //////////////////////////////////////////////////////////////////////////////// - -sk_sp<SkPDFObject> SkPDFCreateBitmapObject(sk_sp<SkImage> image, int encodingQuality) { - SkASSERT(image); - SkASSERT(encodingQuality >= 0); - sk_sp<SkData> data = image->refEncodedData(); - SkJFIFInfo info; - if (data && SkIsJFIF(data.get(), &info)) { - bool yuv = info.fType == SkJFIFInfo::kYCbCr; - if (info.fSize == image->dimensions()) { // Sanity check. +sk_sp<PDFJpegBitmap> make_jpeg_bitmap(sk_sp<SkData> data, SkISize size) { + SkISize jpegSize; + SkEncodedInfo::Color jpegColorType; + SkEncodedOrigin exifOrientation; + if (data && SkGetJpegInfo(data->data(), data->size(), &jpegSize, + &jpegColorType, &exifOrientation)) { + bool yuv = jpegColorType == SkEncodedInfo::kYUV_Color; + bool goodColorType = yuv || jpegColorType == SkEncodedInfo::kGray_Color; + if (jpegSize == size // Sanity check. + && goodColorType + && kTopLeft_SkEncodedOrigin == exifOrientation) { // hold on to data, not image. #ifdef SK_PDF_IMAGE_STATS gJpegImageObjects.fetch_add(1); #endif - return sk_make_sp<PDFJpegBitmap>(info.fSize, data.get(), yuv); + return sk_make_sp<PDFJpegBitmap>(jpegSize, std::move(data), yuv); } } + return nullptr; +} + +sk_sp<SkPDFObject> SkPDFCreateBitmapObject(sk_sp<SkImage> image, int encodingQuality) { + SkASSERT(image); + SkASSERT(encodingQuality >= 0); + SkISize dimensions = image->dimensions(); + sk_sp<SkData> data = image->refEncodedData(); + if (auto jpeg = make_jpeg_bitmap(std::move(data), dimensions)) { + return jpeg; + } const bool isOpaque = image_compute_is_opaque(image.get()); if (encodingQuality <= 100 && isOpaque) { data = image->encodeToData(SkEncodedImageFormat::kJPEG, encodingQuality); - if (data && SkIsJFIF(data.get(), &info)) { - bool yuv = info.fType == SkJFIFInfo::kYCbCr; - if (info.fSize == image->dimensions()) { // Sanity check. - return sk_make_sp<PDFJpegBitmap>(info.fSize, data.get(), yuv); - } + if (auto jpeg = make_jpeg_bitmap(std::move(data), dimensions)) { + return jpeg; } } |