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