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