blob: 5617c6bf3461c6c32ab4a1007068242c74f3c9d3 [file] [log] [blame]
msarette16b04a2015-04-15 07:32:19 -07001/*
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"
msarett39b2d5a2016-02-17 08:26:31 -080013#include "SkSwizzler.h"
msarette16b04a2015-04-15 07:32:19 -070014#include "SkStream.h"
scroggo565901d2015-12-10 10:44:13 -080015#include "SkTemplates.h"
msarette16b04a2015-04-15 07:32:19 -070016
msarett39b2d5a2016-02-17 08:26:31 -080017class JpegDecoderMgr;
msarette16b04a2015-04-15 07:32:19 -070018
19/*
20 *
21 * This class implements the decoding for jpeg images
22 *
23 */
24class SkJpegCodec : public SkCodec {
25public:
scroggodb30be22015-12-08 18:54:13 -080026 static bool IsJpeg(const void*, size_t);
msarette16b04a2015-04-15 07:32:19 -070027
28 /*
29 * Assumes IsJpeg was called and returned true
msarette16b04a2015-04-15 07:32:19 -070030 * Takes ownership of the stream
31 */
Mike Reedede7bac2017-07-23 15:30:02 -040032 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
msarette16b04a2015-04-15 07:32:19 -070033
34protected:
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&,
Leon Scroggins571b30f2017-07-11 17:35:31 +000045 int*) override;
msarette16b04a2015-04-15 07:32:19 -070046
Jim Van Verthe24b5872018-10-29 16:26:02 -040047 bool onQueryYUV8(SkYUVASizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override;
msarettb714fb02016-01-22 14:46:42 -080048
Jim Van Verthe24b5872018-10-29 16:26:02 -040049 Result onGetYUV8Planes(const SkYUVASizeInfo& sizeInfo,
50 void* planes[SkYUVASizeInfo::kMaxCount]) override;
msarettb714fb02016-01-22 14:46:42 -080051
Hal Canarydb683012016-11-23 08:55:18 -070052 SkEncodedImageFormat onGetEncodedFormat() const override {
53 return SkEncodedImageFormat::kJPEG;
msarette16b04a2015-04-15 07:32:19 -070054 }
55
scroggob427db12015-08-12 07:24:13 -070056 bool onRewind() override;
57
scroggoe7fc14b2015-10-02 13:14:46 -070058 bool onDimensionsSupported(const SkISize&) override;
59
Leon Scroggins III712476e2018-10-03 15:47:00 -040060 bool conversionSupported(const SkImageInfo&, bool, bool) override;
Leon Scroggins III07418182017-08-15 12:24:02 -040061
msarette16b04a2015-04-15 07:32:19 -070062private:
msarette16b04a2015-04-15 07:32:19 -070063 /*
Leon Scroggins III36f7e322018-08-27 11:55:46 -040064 * Allows SkRawCodec to communicate the color profile from the exif data.
Matt Sarettc5eabe72017-02-24 14:51:08 -050065 */
Mike Reedede7bac2017-07-23 15:30:02 -040066 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*,
Leon Scroggins III36f7e322018-08-27 11:55:46 -040067 std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile);
Matt Sarettc5eabe72017-02-24 14:51:08 -050068
69 /*
msarette16b04a2015-04-15 07:32:19 -070070 * Read enough of the stream to initialize the SkJpegCodec.
71 * Returns a bool representing success or failure.
72 *
73 * @param codecOut
halcanary96fcdcc2015-08-27 07:41:13 -070074 * If this returns true, and codecOut was not nullptr,
msarette16b04a2015-04-15 07:32:19 -070075 * codecOut will be set to a new SkJpegCodec.
76 *
77 * @param decoderMgrOut
halcanary96fcdcc2015-08-27 07:41:13 -070078 * If this returns true, and codecOut was nullptr,
79 * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new
msarette16b04a2015-04-15 07:32:19 -070080 * 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 *
Leon Scroggins III36f7e322018-08-27 11:55:46 -040087 * @param defaultColorProfile
88 * If the jpeg does not have an embedded color profile, the image data should
89 * be tagged with this color profile.
msarette16b04a2015-04-15 07:32:19 -070090 */
Leon Scroggins III588fb042017-07-14 16:32:31 -040091 static Result ReadHeader(SkStream* stream, SkCodec** codecOut,
Leon Scroggins III36f7e322018-08-27 11:55:46 -040092 JpegDecoderMgr** decoderMgrOut,
93 std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile);
msarette16b04a2015-04-15 07:32:19 -070094
95 /*
96 * Creates an instance of the decoder
97 * Called only by NewFromStream
98 *
msarettc30c4182016-04-20 11:53:35 -070099 * @param info contains properties of the encoded data
msarette16b04a2015-04-15 07:32:19 -0700100 * @param stream the encoded image data
101 * @param decoderMgr holds decompress struct, src manager, and error manager
102 * takes ownership
103 */
Leon Scroggins III36f7e322018-08-27 11:55:46 -0400104 SkJpegCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream,
105 JpegDecoderMgr* decoderMgr, SkEncodedOrigin origin);
msarett1c8a5872015-07-07 08:50:01 -0700106
Matt Sarett7f15b682017-02-24 17:22:09 -0500107 void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options,
108 bool needsCMYKToRGB);
msarett50ce1f22016-07-29 06:23:33 -0700109 void allocateStorage(const SkImageInfo& dstInfo);
Matt Sarettc8c901f2017-01-24 16:16:33 -0500110 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&);
msarett50ce1f22016-07-29 06:23:33 -0700111
112 /*
113 * Scanline decoding.
114 */
msarette6dd0042015-10-09 11:07:34 -0700115 SkSampler* getSampler(bool createIfNecessary) override;
Leon Scroggins571b30f2017-07-11 17:35:31 +0000116 Result onStartScanlineDecode(const SkImageInfo& dstInfo,
117 const Options& options) override;
msarette6dd0042015-10-09 11:07:34 -0700118 int onGetScanlines(void* dst, int count, size_t rowBytes) override;
119 bool onSkipScanlines(int count) override;
scroggo46c57472015-09-30 08:57:13 -0700120
Ben Wagner145dbcd2016-11-03 14:40:50 -0400121 std::unique_ptr<JpegDecoderMgr> fDecoderMgr;
msarett50ce1f22016-07-29 06:23:33 -0700122
msarettfbccb592015-09-01 06:43:41 -0700123 // We will save the state of the decompress struct after reading the header.
124 // This allows us to safely call onGetScaledDimensions() at any time.
msarett50ce1f22016-07-29 06:23:33 -0700125 const int fReadyState;
msarette16b04a2015-04-15 07:32:19 -0700126
msarett50ce1f22016-07-29 06:23:33 -0700127
128 SkAutoTMalloc<uint8_t> fStorage;
129 uint8_t* fSwizzleSrcRow;
130 uint32_t* fColorXformSrcRow;
131
msarett91c22b22016-02-22 12:27:46 -0800132 // 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.
msarett50ce1f22016-07-29 06:23:33 -0700135 SkIRect fSwizzlerSubset;
136
Ben Wagner145dbcd2016-11-03 14:40:50 -0400137 std::unique_ptr<SkSwizzler> fSwizzler;
msarett9876ac52016-06-01 14:47:18 -0700138
Matt Sarettc5eabe72017-02-24 14:51:08 -0500139 friend class SkRawCodec;
140
msarette16b04a2015-04-15 07:32:19 -0700141 typedef SkCodec INHERITED;
142};
143
144#endif