• 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 SkCodec* NewFromStream(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 
61 private:
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