• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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