blob: fd8ee63d6c619a48f003bd550b5ed1a766d4be0b [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"
msarettad8bcfe2016-03-07 07:09:03 -080012#include "SkColorSpace.h"
msarett50ce1f22016-07-29 06:23:33 -070013#include "SkColorSpaceXform.h"
msarette16b04a2015-04-15 07:32:19 -070014#include "SkImageInfo.h"
msarett39b2d5a2016-02-17 08:26:31 -080015#include "SkSwizzler.h"
msarette16b04a2015-04-15 07:32:19 -070016#include "SkStream.h"
scroggo565901d2015-12-10 10:44:13 -080017#include "SkTemplates.h"
msarette16b04a2015-04-15 07:32:19 -070018
msarett39b2d5a2016-02-17 08:26:31 -080019class JpegDecoderMgr;
msarette16b04a2015-04-15 07:32:19 -070020
21/*
22 *
23 * This class implements the decoding for jpeg images
24 *
25 */
26class SkJpegCodec : public SkCodec {
27public:
scroggodb30be22015-12-08 18:54:13 -080028 static bool IsJpeg(const void*, size_t);
msarette16b04a2015-04-15 07:32:19 -070029
30 /*
31 * Assumes IsJpeg was called and returned true
msarette16b04a2015-04-15 07:32:19 -070032 * Takes ownership of the stream
33 */
Mike Reedede7bac2017-07-23 15:30:02 -040034 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
msarette16b04a2015-04-15 07:32:19 -070035
36protected:
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&,
Leon Scroggins571b30f2017-07-11 17:35:31 +000047 int*) override;
msarette16b04a2015-04-15 07:32:19 -070048
msarett4984c3c2016-03-10 05:44:43 -080049 bool onQueryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override;
msarettb714fb02016-01-22 14:46:42 -080050
msarett4984c3c2016-03-10 05:44:43 -080051 Result onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) override;
msarettb714fb02016-01-22 14:46:42 -080052
Hal Canarydb683012016-11-23 08:55:18 -070053 SkEncodedImageFormat onGetEncodedFormat() const override {
54 return SkEncodedImageFormat::kJPEG;
msarette16b04a2015-04-15 07:32:19 -070055 }
56
scroggob427db12015-08-12 07:24:13 -070057 bool onRewind() override;
58
scroggoe7fc14b2015-10-02 13:14:46 -070059 bool onDimensionsSupported(const SkISize&) override;
60
Leon Scroggins III07418182017-08-15 12:24:02 -040061 bool conversionSupported(const SkImageInfo&, SkEncodedInfo::Color, bool,
62 const SkColorSpace*) const override {
63 // This class checks for conversion after creating colorXform.
64 return true;
65 }
66
msarette16b04a2015-04-15 07:32:19 -070067private:
68
69 /*
Matt Sarettc5eabe72017-02-24 14:51:08 -050070 * Allows SkRawCodec to communicate the color space from the exif data.
71 */
Mike Reedede7bac2017-07-23 15:30:02 -040072 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*,
73 sk_sp<SkColorSpace> defaultColorSpace);
Matt Sarettc5eabe72017-02-24 14:51:08 -050074
75 /*
msarette16b04a2015-04-15 07:32:19 -070076 * Read enough of the stream to initialize the SkJpegCodec.
77 * Returns a bool representing success or failure.
78 *
79 * @param codecOut
halcanary96fcdcc2015-08-27 07:41:13 -070080 * If this returns true, and codecOut was not nullptr,
msarette16b04a2015-04-15 07:32:19 -070081 * codecOut will be set to a new SkJpegCodec.
82 *
83 * @param decoderMgrOut
halcanary96fcdcc2015-08-27 07:41:13 -070084 * If this returns true, and codecOut was nullptr,
85 * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new
msarette16b04a2015-04-15 07:32:19 -070086 * JpegDecoderMgr pointer.
87 *
88 * @param stream
89 * Deleted on failure.
90 * codecOut will take ownership of it in the case where we created a codec.
91 * Ownership is unchanged when we set decoderMgrOut.
92 *
Matt Sarettc5eabe72017-02-24 14:51:08 -050093 * @param defaultColorSpace
94 * If the jpeg does not have an embedded color space, the image data should
95 * be tagged with this color space.
msarette16b04a2015-04-15 07:32:19 -070096 */
Leon Scroggins III588fb042017-07-14 16:32:31 -040097 static Result ReadHeader(SkStream* stream, SkCodec** codecOut,
Matt Sarettc5eabe72017-02-24 14:51:08 -050098 JpegDecoderMgr** decoderMgrOut, sk_sp<SkColorSpace> defaultColorSpace);
msarette16b04a2015-04-15 07:32:19 -070099
100 /*
101 * Creates an instance of the decoder
102 * Called only by NewFromStream
103 *
msarettc30c4182016-04-20 11:53:35 -0700104 * @param info contains properties of the encoded data
msarette16b04a2015-04-15 07:32:19 -0700105 * @param stream the encoded image data
106 * @param decoderMgr holds decompress struct, src manager, and error manager
107 * takes ownership
108 */
Mike Reedede7bac2017-07-23 15:30:02 -0400109 SkJpegCodec(int width, int height, const SkEncodedInfo& info, std::unique_ptr<SkStream> stream,
Matt Saretta9e9bfc2016-11-01 12:19:50 -0400110 JpegDecoderMgr* decoderMgr, sk_sp<SkColorSpace> colorSpace, Origin origin);
msarette16b04a2015-04-15 07:32:19 -0700111
msarett97fdea62015-04-29 08:17:15 -0700112 /*
msarett1c8a5872015-07-07 08:50:01 -0700113 * Checks if the conversion between the input image and the requested output
msarett50ce1f22016-07-29 06:23:33 -0700114 * image has been implemented.
115 *
116 * Sets the output color space.
msarett1c8a5872015-07-07 08:50:01 -0700117 */
msarett2ecc35f2016-09-08 11:55:16 -0700118 bool setOutputColorSpace(const SkImageInfo& dst);
msarett1c8a5872015-07-07 08:50:01 -0700119
Matt Sarett7f15b682017-02-24 17:22:09 -0500120 void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options,
121 bool needsCMYKToRGB);
msarett50ce1f22016-07-29 06:23:33 -0700122 void allocateStorage(const SkImageInfo& dstInfo);
Matt Sarettc8c901f2017-01-24 16:16:33 -0500123 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&);
msarett50ce1f22016-07-29 06:23:33 -0700124
125 /*
126 * Scanline decoding.
127 */
msarette6dd0042015-10-09 11:07:34 -0700128 SkSampler* getSampler(bool createIfNecessary) override;
Leon Scroggins571b30f2017-07-11 17:35:31 +0000129 Result onStartScanlineDecode(const SkImageInfo& dstInfo,
130 const Options& options) override;
msarette6dd0042015-10-09 11:07:34 -0700131 int onGetScanlines(void* dst, int count, size_t rowBytes) override;
132 bool onSkipScanlines(int count) override;
scroggo46c57472015-09-30 08:57:13 -0700133
Ben Wagner145dbcd2016-11-03 14:40:50 -0400134 std::unique_ptr<JpegDecoderMgr> fDecoderMgr;
msarett50ce1f22016-07-29 06:23:33 -0700135
msarettfbccb592015-09-01 06:43:41 -0700136 // We will save the state of the decompress struct after reading the header.
137 // This allows us to safely call onGetScaledDimensions() at any time.
msarett50ce1f22016-07-29 06:23:33 -0700138 const int fReadyState;
msarette16b04a2015-04-15 07:32:19 -0700139
msarett50ce1f22016-07-29 06:23:33 -0700140
141 SkAutoTMalloc<uint8_t> fStorage;
142 uint8_t* fSwizzleSrcRow;
143 uint32_t* fColorXformSrcRow;
144
msarett91c22b22016-02-22 12:27:46 -0800145 // libjpeg-turbo provides some subsetting. In the case that libjpeg-turbo
146 // cannot take the exact the subset that we need, we will use the swizzler
147 // to further subset the output from libjpeg-turbo.
msarett50ce1f22016-07-29 06:23:33 -0700148 SkIRect fSwizzlerSubset;
149
Ben Wagner145dbcd2016-11-03 14:40:50 -0400150 std::unique_ptr<SkSwizzler> fSwizzler;
msarett9876ac52016-06-01 14:47:18 -0700151
Matt Sarettc5eabe72017-02-24 14:51:08 -0500152 friend class SkRawCodec;
153
msarette16b04a2015-04-15 07:32:19 -0700154 typedef SkCodec INHERITED;
155};
156
157#endif