blob: 7eb5100a8fadcfbd811aad5386c13426b56f20cf [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
32 * Creates a jpeg decoder
33 * Takes ownership of the stream
34 */
35 static SkCodec* NewFromStream(SkStream*);
36
37protected:
38
39 /*
40 * Recommend a set of destination dimensions given a requested scale
41 */
42 SkISize onGetScaledDimensions(float desiredScale) const override;
43
44 /*
45 * Initiates the jpeg decode
46 */
47 Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&,
msarette6dd0042015-10-09 11:07:34 -070048 SkPMColor*, int*, int*) override;
msarette16b04a2015-04-15 07:32:19 -070049
msarett4984c3c2016-03-10 05:44:43 -080050 bool onQueryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override;
msarettb714fb02016-01-22 14:46:42 -080051
msarett4984c3c2016-03-10 05:44:43 -080052 Result onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) override;
msarettb714fb02016-01-22 14:46:42 -080053
msarette16b04a2015-04-15 07:32:19 -070054 SkEncodedFormat onGetEncodedFormat() const override {
55 return kJPEG_SkEncodedFormat;
56 }
57
scroggob427db12015-08-12 07:24:13 -070058 bool onRewind() override;
59
scroggoe7fc14b2015-10-02 13:14:46 -070060 bool onDimensionsSupported(const SkISize&) override;
61
msarett9876ac52016-06-01 14:47:18 -070062 sk_sp<SkData> getICCData() const override { return fICCData; }
63
msarette16b04a2015-04-15 07:32:19 -070064private:
65
66 /*
67 * Read enough of the stream to initialize the SkJpegCodec.
68 * Returns a bool representing success or failure.
69 *
70 * @param codecOut
halcanary96fcdcc2015-08-27 07:41:13 -070071 * If this returns true, and codecOut was not nullptr,
msarette16b04a2015-04-15 07:32:19 -070072 * codecOut will be set to a new SkJpegCodec.
73 *
74 * @param decoderMgrOut
halcanary96fcdcc2015-08-27 07:41:13 -070075 * If this returns true, and codecOut was nullptr,
76 * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new
msarette16b04a2015-04-15 07:32:19 -070077 * JpegDecoderMgr pointer.
78 *
79 * @param stream
80 * Deleted on failure.
81 * codecOut will take ownership of it in the case where we created a codec.
82 * Ownership is unchanged when we set decoderMgrOut.
83 *
84 */
85 static bool ReadHeader(SkStream* stream, SkCodec** codecOut,
86 JpegDecoderMgr** decoderMgrOut);
87
88 /*
89 * Creates an instance of the decoder
90 * Called only by NewFromStream
91 *
msarettc30c4182016-04-20 11:53:35 -070092 * @param info contains properties of the encoded data
msarette16b04a2015-04-15 07:32:19 -070093 * @param stream the encoded image data
94 * @param decoderMgr holds decompress struct, src manager, and error manager
95 * takes ownership
96 */
msarettc30c4182016-04-20 11:53:35 -070097 SkJpegCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
msarett9876ac52016-06-01 14:47:18 -070098 JpegDecoderMgr* decoderMgr, sk_sp<SkColorSpace> colorSpace, Origin origin,
99 sk_sp<SkData> iccData);
msarette16b04a2015-04-15 07:32:19 -0700100
msarett97fdea62015-04-29 08:17:15 -0700101 /*
msarett1c8a5872015-07-07 08:50:01 -0700102 * Checks if the conversion between the input image and the requested output
msarett50ce1f22016-07-29 06:23:33 -0700103 * image has been implemented.
104 *
105 * Sets the output color space.
msarett1c8a5872015-07-07 08:50:01 -0700106 */
msarett50ce1f22016-07-29 06:23:33 -0700107 bool setOutputColorSpace(const SkImageInfo& dst, bool needsColorXform);
msarett1c8a5872015-07-07 08:50:01 -0700108
msarettfdb47572015-10-13 12:50:14 -0700109 void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
msarett50ce1f22016-07-29 06:23:33 -0700110 bool initializeColorXform(const SkImageInfo& dstInfo, bool needsColorXform);
111 void allocateStorage(const SkImageInfo& dstInfo);
112 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count);
113
114 /*
115 * Scanline decoding.
116 */
msarette6dd0042015-10-09 11:07:34 -0700117 SkSampler* getSampler(bool createIfNecessary) override;
scroggo46c57472015-09-30 08:57:13 -0700118 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
msarettfdb47572015-10-13 12:50:14 -0700119 SkPMColor ctable[], int* ctableCount) override;
msarette6dd0042015-10-09 11:07:34 -0700120 int onGetScanlines(void* dst, int count, size_t rowBytes) override;
121 bool onSkipScanlines(int count) override;
scroggo46c57472015-09-30 08:57:13 -0700122
msarett50ce1f22016-07-29 06:23:33 -0700123 SkAutoTDelete<JpegDecoderMgr> fDecoderMgr;
124
msarettfbccb592015-09-01 06:43:41 -0700125 // We will save the state of the decompress struct after reading the header.
126 // This allows us to safely call onGetScaledDimensions() at any time.
msarett50ce1f22016-07-29 06:23:33 -0700127 const int fReadyState;
msarette16b04a2015-04-15 07:32:19 -0700128
msarett50ce1f22016-07-29 06:23:33 -0700129
130 SkAutoTMalloc<uint8_t> fStorage;
131 uint8_t* fSwizzleSrcRow;
132 uint32_t* fColorXformSrcRow;
133
msarett91c22b22016-02-22 12:27:46 -0800134 // 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.
msarett50ce1f22016-07-29 06:23:33 -0700137 SkIRect fSwizzlerSubset;
138
139 SkAutoTDelete<SkSwizzler> fSwizzler;
140 std::unique_ptr<SkColorSpaceXform> fColorXform;
scroggo46c57472015-09-30 08:57:13 -0700141
msarett50ce1f22016-07-29 06:23:33 -0700142 sk_sp<SkData> fICCData;
msarett9876ac52016-06-01 14:47:18 -0700143
msarette16b04a2015-04-15 07:32:19 -0700144 typedef SkCodec INHERITED;
145};
146
147#endif