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