• 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 "SkImageInfo.h"
13 #include "SkSwizzler.h"
14 #include "SkStream.h"
15 #include "SkTemplates.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 onQueryYUV8(SkYUVASizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override;
48 
49     Result onGetYUV8Planes(const SkYUVASizeInfo& sizeInfo,
50                            void* planes[SkYUVASizeInfo::kMaxCount]) 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     void 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     typedef SkCodec INHERITED;
142 };
143 
144 #endif
145