1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2015 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkJpegCodec_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define SkJpegCodec_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkCodec.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkEncodedImageFormat.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkEncodedOrigin.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkYUVAPixmaps.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkEncodedInfo.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h" 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef> 22*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 23*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 24*c8dee2aaSAndroid Build Coastguard Worker 25*c8dee2aaSAndroid Build Coastguard Worker class JpegDecoderMgr; 26*c8dee2aaSAndroid Build Coastguard Worker class SkSampler; 27*c8dee2aaSAndroid Build Coastguard Worker class SkStream; 28*c8dee2aaSAndroid Build Coastguard Worker class SkSwizzler; 29*c8dee2aaSAndroid Build Coastguard Worker struct SkGainmapInfo; 30*c8dee2aaSAndroid Build Coastguard Worker struct SkImageInfo; 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker /* 33*c8dee2aaSAndroid Build Coastguard Worker * 34*c8dee2aaSAndroid Build Coastguard Worker * This class implements the decoding for jpeg images 35*c8dee2aaSAndroid Build Coastguard Worker * 36*c8dee2aaSAndroid Build Coastguard Worker */ 37*c8dee2aaSAndroid Build Coastguard Worker class SkJpegCodec : public SkCodec { 38*c8dee2aaSAndroid Build Coastguard Worker public: 39*c8dee2aaSAndroid Build Coastguard Worker ~SkJpegCodec() override; 40*c8dee2aaSAndroid Build Coastguard Worker 41*c8dee2aaSAndroid Build Coastguard Worker static bool IsJpeg(const void*, size_t); 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker /* 44*c8dee2aaSAndroid Build Coastguard Worker * Assumes IsJpeg was called and returned true 45*c8dee2aaSAndroid Build Coastguard Worker * Takes ownership of the stream 46*c8dee2aaSAndroid Build Coastguard Worker */ 47*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*); 48*c8dee2aaSAndroid Build Coastguard Worker 49*c8dee2aaSAndroid Build Coastguard Worker protected: 50*c8dee2aaSAndroid Build Coastguard Worker 51*c8dee2aaSAndroid Build Coastguard Worker /* 52*c8dee2aaSAndroid Build Coastguard Worker * Recommend a set of destination dimensions given a requested scale 53*c8dee2aaSAndroid Build Coastguard Worker */ 54*c8dee2aaSAndroid Build Coastguard Worker SkISize onGetScaledDimensions(float desiredScale) const override; 55*c8dee2aaSAndroid Build Coastguard Worker 56*c8dee2aaSAndroid Build Coastguard Worker /* 57*c8dee2aaSAndroid Build Coastguard Worker * Initiates the jpeg decode 58*c8dee2aaSAndroid Build Coastguard Worker */ 59*c8dee2aaSAndroid Build Coastguard Worker Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&, 60*c8dee2aaSAndroid Build Coastguard Worker int*) override; 61*c8dee2aaSAndroid Build Coastguard Worker 62*c8dee2aaSAndroid Build Coastguard Worker bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&, 63*c8dee2aaSAndroid Build Coastguard Worker SkYUVAPixmapInfo*) const override; 64*c8dee2aaSAndroid Build Coastguard Worker 65*c8dee2aaSAndroid Build Coastguard Worker Result onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) override; 66*c8dee2aaSAndroid Build Coastguard Worker onGetEncodedFormat()67*c8dee2aaSAndroid Build Coastguard Worker SkEncodedImageFormat onGetEncodedFormat() const override { 68*c8dee2aaSAndroid Build Coastguard Worker return SkEncodedImageFormat::kJPEG; 69*c8dee2aaSAndroid Build Coastguard Worker } 70*c8dee2aaSAndroid Build Coastguard Worker 71*c8dee2aaSAndroid Build Coastguard Worker bool onRewind() override; 72*c8dee2aaSAndroid Build Coastguard Worker 73*c8dee2aaSAndroid Build Coastguard Worker bool onDimensionsSupported(const SkISize&) override; 74*c8dee2aaSAndroid Build Coastguard Worker 75*c8dee2aaSAndroid Build Coastguard Worker bool conversionSupported(const SkImageInfo&, bool, bool) override; 76*c8dee2aaSAndroid Build Coastguard Worker 77*c8dee2aaSAndroid Build Coastguard Worker bool onGetGainmapCodec(SkGainmapInfo* info, std::unique_ptr<SkCodec>* gainmapCodec) override; 78*c8dee2aaSAndroid Build Coastguard Worker bool onGetGainmapInfo(SkGainmapInfo* info, 79*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStream>* gainmapImageStream) override; 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Worker private: 82*c8dee2aaSAndroid Build Coastguard Worker /* 83*c8dee2aaSAndroid Build Coastguard Worker * Allows SkRawCodec to communicate the color profile from the exif data. 84*c8dee2aaSAndroid Build Coastguard Worker */ 85*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*, 86*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile); 87*c8dee2aaSAndroid Build Coastguard Worker 88*c8dee2aaSAndroid Build Coastguard Worker /* 89*c8dee2aaSAndroid Build Coastguard Worker * Read enough of the stream to initialize the SkJpegCodec. 90*c8dee2aaSAndroid Build Coastguard Worker * Returns a bool representing success or failure. 91*c8dee2aaSAndroid Build Coastguard Worker * 92*c8dee2aaSAndroid Build Coastguard Worker * @param codecOut 93*c8dee2aaSAndroid Build Coastguard Worker * If this returns true, and codecOut was not nullptr, 94*c8dee2aaSAndroid Build Coastguard Worker * codecOut will be set to a new SkJpegCodec. 95*c8dee2aaSAndroid Build Coastguard Worker * 96*c8dee2aaSAndroid Build Coastguard Worker * @param decoderMgrOut 97*c8dee2aaSAndroid Build Coastguard Worker * If this returns true, and codecOut was nullptr, 98*c8dee2aaSAndroid Build Coastguard Worker * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new 99*c8dee2aaSAndroid Build Coastguard Worker * JpegDecoderMgr pointer. 100*c8dee2aaSAndroid Build Coastguard Worker * 101*c8dee2aaSAndroid Build Coastguard Worker * @param stream 102*c8dee2aaSAndroid Build Coastguard Worker * Deleted on failure. 103*c8dee2aaSAndroid Build Coastguard Worker * codecOut will take ownership of it in the case where we created a codec. 104*c8dee2aaSAndroid Build Coastguard Worker * Ownership is unchanged when we set decoderMgrOut. 105*c8dee2aaSAndroid Build Coastguard Worker * 106*c8dee2aaSAndroid Build Coastguard Worker * @param defaultColorProfile 107*c8dee2aaSAndroid Build Coastguard Worker * If the jpeg does not have an embedded color profile, the image data should 108*c8dee2aaSAndroid Build Coastguard Worker * be tagged with this color profile. 109*c8dee2aaSAndroid Build Coastguard Worker */ 110*c8dee2aaSAndroid Build Coastguard Worker static Result ReadHeader(SkStream* stream, SkCodec** codecOut, 111*c8dee2aaSAndroid Build Coastguard Worker JpegDecoderMgr** decoderMgrOut, 112*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile); 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker /* 115*c8dee2aaSAndroid Build Coastguard Worker * Creates an instance of the decoder 116*c8dee2aaSAndroid Build Coastguard Worker * Called only by NewFromStream 117*c8dee2aaSAndroid Build Coastguard Worker * 118*c8dee2aaSAndroid Build Coastguard Worker * @param info contains properties of the encoded data 119*c8dee2aaSAndroid Build Coastguard Worker * @param stream the encoded image data 120*c8dee2aaSAndroid Build Coastguard Worker * @param decoderMgr holds decompress struct, src manager, and error manager 121*c8dee2aaSAndroid Build Coastguard Worker * takes ownership 122*c8dee2aaSAndroid Build Coastguard Worker * @param origin indicates the image orientation as specified in Exif metadata. 123*c8dee2aaSAndroid Build Coastguard Worker * @param xmpMetadata holds the XMP metadata included in the image, if any. 124*c8dee2aaSAndroid Build Coastguard Worker */ 125*c8dee2aaSAndroid Build Coastguard Worker SkJpegCodec(SkEncodedInfo&& info, 126*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStream> stream, 127*c8dee2aaSAndroid Build Coastguard Worker JpegDecoderMgr* decoderMgr, 128*c8dee2aaSAndroid Build Coastguard Worker SkEncodedOrigin origin); 129*c8dee2aaSAndroid Build Coastguard Worker 130*c8dee2aaSAndroid Build Coastguard Worker void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options, 131*c8dee2aaSAndroid Build Coastguard Worker bool needsCMYKToRGB); 132*c8dee2aaSAndroid Build Coastguard Worker [[nodiscard]] bool allocateStorage(const SkImageInfo& dstInfo); 133*c8dee2aaSAndroid Build Coastguard Worker int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&); 134*c8dee2aaSAndroid Build Coastguard Worker 135*c8dee2aaSAndroid Build Coastguard Worker /* 136*c8dee2aaSAndroid Build Coastguard Worker * Scanline decoding. 137*c8dee2aaSAndroid Build Coastguard Worker */ 138*c8dee2aaSAndroid Build Coastguard Worker SkSampler* getSampler(bool createIfNecessary) override; 139*c8dee2aaSAndroid Build Coastguard Worker Result onStartScanlineDecode(const SkImageInfo& dstInfo, 140*c8dee2aaSAndroid Build Coastguard Worker const Options& options) override; 141*c8dee2aaSAndroid Build Coastguard Worker int onGetScanlines(void* dst, int count, size_t rowBytes) override; 142*c8dee2aaSAndroid Build Coastguard Worker bool onSkipScanlines(int count) override; 143*c8dee2aaSAndroid Build Coastguard Worker 144*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<JpegDecoderMgr> fDecoderMgr; 145*c8dee2aaSAndroid Build Coastguard Worker 146*c8dee2aaSAndroid Build Coastguard Worker // We will save the state of the decompress struct after reading the header. 147*c8dee2aaSAndroid Build Coastguard Worker // This allows us to safely call onGetScaledDimensions() at any time. 148*c8dee2aaSAndroid Build Coastguard Worker const int fReadyState; 149*c8dee2aaSAndroid Build Coastguard Worker 150*c8dee2aaSAndroid Build Coastguard Worker 151*c8dee2aaSAndroid Build Coastguard Worker skia_private::AutoTMalloc<uint8_t> fStorage; 152*c8dee2aaSAndroid Build Coastguard Worker uint8_t* fSwizzleSrcRow = nullptr; 153*c8dee2aaSAndroid Build Coastguard Worker uint32_t* fColorXformSrcRow = nullptr; 154*c8dee2aaSAndroid Build Coastguard Worker 155*c8dee2aaSAndroid Build Coastguard Worker // libjpeg-turbo provides some subsetting. In the case that libjpeg-turbo 156*c8dee2aaSAndroid Build Coastguard Worker // cannot take the exact the subset that we need, we will use the swizzler 157*c8dee2aaSAndroid Build Coastguard Worker // to further subset the output from libjpeg-turbo. 158*c8dee2aaSAndroid Build Coastguard Worker SkIRect fSwizzlerSubset = SkIRect::MakeEmpty(); 159*c8dee2aaSAndroid Build Coastguard Worker 160*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSwizzler> fSwizzler; 161*c8dee2aaSAndroid Build Coastguard Worker 162*c8dee2aaSAndroid Build Coastguard Worker friend class SkRawCodec; 163*c8dee2aaSAndroid Build Coastguard Worker 164*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = SkCodec; 165*c8dee2aaSAndroid Build Coastguard Worker }; 166*c8dee2aaSAndroid Build Coastguard Worker 167*c8dee2aaSAndroid Build Coastguard Worker #endif 168