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 "SkCodec.h" 12 #include "SkColorSpace.h" 13 #include "SkColorSpaceXform.h" 14 #include "SkImageInfo.h" 15 #include "SkSwizzler.h" 16 #include "SkStream.h" 17 #include "SkTemplates.h" 18 19 class JpegDecoderMgr; 20 21 /* 22 * 23 * This class implements the decoding for jpeg images 24 * 25 */ 26 class SkJpegCodec : public SkCodec { 27 public: 28 static bool IsJpeg(const void*, size_t); 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 onQueryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override; 50 51 Result onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) override; 52 onGetEncodedFormat()53 SkEncodedImageFormat onGetEncodedFormat() const override { 54 return SkEncodedImageFormat::kJPEG; 55 } 56 57 bool onRewind() override; 58 59 bool onDimensionsSupported(const SkISize&) override; 60 conversionSupported(const SkImageInfo &,SkColorType,bool,const SkColorSpace *)61 bool conversionSupported(const SkImageInfo&, SkColorType, bool, 62 const SkColorSpace*) const override { 63 // This class checks for conversion after creating colorXform. 64 return true; 65 } 66 67 private: 68 69 /* 70 * Allows SkRawCodec to communicate the color space from the exif data. 71 */ 72 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*, 73 sk_sp<SkColorSpace> defaultColorSpace); 74 75 /* 76 * Read enough of the stream to initialize the SkJpegCodec. 77 * Returns a bool representing success or failure. 78 * 79 * @param codecOut 80 * If this returns true, and codecOut was not nullptr, 81 * codecOut will be set to a new SkJpegCodec. 82 * 83 * @param decoderMgrOut 84 * If this returns true, and codecOut was nullptr, 85 * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new 86 * JpegDecoderMgr pointer. 87 * 88 * @param stream 89 * Deleted on failure. 90 * codecOut will take ownership of it in the case where we created a codec. 91 * Ownership is unchanged when we set decoderMgrOut. 92 * 93 * @param defaultColorSpace 94 * If the jpeg does not have an embedded color space, the image data should 95 * be tagged with this color space. 96 */ 97 static Result ReadHeader(SkStream* stream, SkCodec** codecOut, 98 JpegDecoderMgr** decoderMgrOut, sk_sp<SkColorSpace> defaultColorSpace); 99 100 /* 101 * Creates an instance of the decoder 102 * Called only by NewFromStream 103 * 104 * @param info contains properties of the encoded data 105 * @param stream the encoded image data 106 * @param decoderMgr holds decompress struct, src manager, and error manager 107 * takes ownership 108 */ 109 SkJpegCodec(int width, int height, const SkEncodedInfo& info, std::unique_ptr<SkStream> stream, 110 JpegDecoderMgr* decoderMgr, sk_sp<SkColorSpace> colorSpace, SkEncodedOrigin origin); 111 112 /* 113 * Checks if the conversion between the input image and the requested output 114 * image has been implemented. 115 * 116 * Sets the output color space. 117 */ 118 bool setOutputColorSpace(const SkImageInfo& dst); 119 120 void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options, 121 bool needsCMYKToRGB); 122 void allocateStorage(const SkImageInfo& dstInfo); 123 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&); 124 125 /* 126 * Scanline decoding. 127 */ 128 SkSampler* getSampler(bool createIfNecessary) override; 129 Result onStartScanlineDecode(const SkImageInfo& dstInfo, 130 const Options& options) override; 131 int onGetScanlines(void* dst, int count, size_t rowBytes) override; 132 bool onSkipScanlines(int count) override; 133 134 std::unique_ptr<JpegDecoderMgr> fDecoderMgr; 135 136 // We will save the state of the decompress struct after reading the header. 137 // This allows us to safely call onGetScaledDimensions() at any time. 138 const int fReadyState; 139 140 141 SkAutoTMalloc<uint8_t> fStorage; 142 uint8_t* fSwizzleSrcRow; 143 uint32_t* fColorXformSrcRow; 144 145 // libjpeg-turbo provides some subsetting. In the case that libjpeg-turbo 146 // cannot take the exact the subset that we need, we will use the swizzler 147 // to further subset the output from libjpeg-turbo. 148 SkIRect fSwizzlerSubset; 149 150 std::unique_ptr<SkSwizzler> fSwizzler; 151 152 friend class SkRawCodec; 153 154 typedef SkCodec INHERITED; 155 }; 156 157 #endif 158