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