blob: 1b51dbf4890543271f5a435b39f031641cc4d0ff [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
msarett4984c3c2016-03-10 05:44:43 -080047 bool onQueryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override;
msarettb714fb02016-01-22 14:46:42 -080048
msarett4984c3c2016-03-10 05:44:43 -080049 Result onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) override;
msarettb714fb02016-01-22 14:46:42 -080050
Hal Canarydb683012016-11-23 08:55:18 -070051 SkEncodedImageFormat onGetEncodedFormat() const override {
52 return SkEncodedImageFormat::kJPEG;
msarette16b04a2015-04-15 07:32:19 -070053 }
54
scroggob427db12015-08-12 07:24:13 -070055 bool onRewind() override;
56
scroggoe7fc14b2015-10-02 13:14:46 -070057 bool onDimensionsSupported(const SkISize&) override;
58
Leon Scroggins III49894f42018-08-24 11:59:04 -040059 bool conversionSupported(const SkImageInfo&, SkColorType, bool, bool) override;
Leon Scroggins III07418182017-08-15 12:24:02 -040060
msarette16b04a2015-04-15 07:32:19 -070061private:
msarette16b04a2015-04-15 07:32:19 -070062 /*
Leon Scroggins III49894f42018-08-24 11:59:04 -040063 * Allows SkRawCodec to communicate the color profile from the exif data.
Matt Sarettc5eabe72017-02-24 14:51:08 -050064 */
Mike Reedede7bac2017-07-23 15:30:02 -040065 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*,
Leon Scroggins III49894f42018-08-24 11:59:04 -040066 std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile);
Matt Sarettc5eabe72017-02-24 14:51:08 -050067
68 /*
msarette16b04a2015-04-15 07:32:19 -070069 * Read enough of the stream to initialize the SkJpegCodec.
70 * Returns a bool representing success or failure.
71 *
72 * @param codecOut
halcanary96fcdcc2015-08-27 07:41:13 -070073 * If this returns true, and codecOut was not nullptr,
msarette16b04a2015-04-15 07:32:19 -070074 * codecOut will be set to a new SkJpegCodec.
75 *
76 * @param decoderMgrOut
halcanary96fcdcc2015-08-27 07:41:13 -070077 * If this returns true, and codecOut was nullptr,
78 * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new
msarette16b04a2015-04-15 07:32:19 -070079 * 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 *
Leon Scroggins III49894f42018-08-24 11:59:04 -040086 * @param defaultColorProfile
87 * If the jpeg does not have an embedded color profile, the image data should
88 * be tagged with this color profile.
msarette16b04a2015-04-15 07:32:19 -070089 */
Leon Scroggins III588fb042017-07-14 16:32:31 -040090 static Result ReadHeader(SkStream* stream, SkCodec** codecOut,
Leon Scroggins III49894f42018-08-24 11:59:04 -040091 JpegDecoderMgr** decoderMgrOut,
92 std::unique_ptr<SkEncodedInfo::ICCProfile> defaultColorProfile);
msarette16b04a2015-04-15 07:32:19 -070093
94 /*
95 * Creates an instance of the decoder
96 * Called only by NewFromStream
97 *
msarettc30c4182016-04-20 11:53:35 -070098 * @param info contains properties of the encoded data
msarette16b04a2015-04-15 07:32:19 -070099 * @param stream the encoded image data
100 * @param decoderMgr holds decompress struct, src manager, and error manager
101 * takes ownership
102 */
Leon Scroggins III49894f42018-08-24 11:59:04 -0400103 SkJpegCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream,
104 JpegDecoderMgr* decoderMgr, SkEncodedOrigin origin);
msarett1c8a5872015-07-07 08:50:01 -0700105
Matt Sarett7f15b682017-02-24 17:22:09 -0500106 void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options,
107 bool needsCMYKToRGB);
msarett50ce1f22016-07-29 06:23:33 -0700108 void allocateStorage(const SkImageInfo& dstInfo);
Matt Sarettc8c901f2017-01-24 16:16:33 -0500109 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&);
msarett50ce1f22016-07-29 06:23:33 -0700110
111 /*
112 * Scanline decoding.
113 */
msarette6dd0042015-10-09 11:07:34 -0700114 SkSampler* getSampler(bool createIfNecessary) override;
Leon Scroggins571b30f2017-07-11 17:35:31 +0000115 Result onStartScanlineDecode(const SkImageInfo& dstInfo,
116 const Options& options) override;
msarette6dd0042015-10-09 11:07:34 -0700117 int onGetScanlines(void* dst, int count, size_t rowBytes) override;
118 bool onSkipScanlines(int count) override;
scroggo46c57472015-09-30 08:57:13 -0700119
Ben Wagner145dbcd2016-11-03 14:40:50 -0400120 std::unique_ptr<JpegDecoderMgr> fDecoderMgr;
msarett50ce1f22016-07-29 06:23:33 -0700121
msarettfbccb592015-09-01 06:43:41 -0700122 // We will save the state of the decompress struct after reading the header.
123 // This allows us to safely call onGetScaledDimensions() at any time.
msarett50ce1f22016-07-29 06:23:33 -0700124 const int fReadyState;
msarette16b04a2015-04-15 07:32:19 -0700125
msarett50ce1f22016-07-29 06:23:33 -0700126
127 SkAutoTMalloc<uint8_t> fStorage;
128 uint8_t* fSwizzleSrcRow;
129 uint32_t* fColorXformSrcRow;
130
msarett91c22b22016-02-22 12:27:46 -0800131 // libjpeg-turbo provides some subsetting. In the case that libjpeg-turbo
132 // cannot take the exact the subset that we need, we will use the swizzler
133 // to further subset the output from libjpeg-turbo.
msarett50ce1f22016-07-29 06:23:33 -0700134 SkIRect fSwizzlerSubset;
135
Ben Wagner145dbcd2016-11-03 14:40:50 -0400136 std::unique_ptr<SkSwizzler> fSwizzler;
msarett9876ac52016-06-01 14:47:18 -0700137
Matt Sarettc5eabe72017-02-24 14:51:08 -0500138 friend class SkRawCodec;
139
msarette16b04a2015-04-15 07:32:19 -0700140 typedef SkCodec INHERITED;
141};
142
143#endif