blob: 049c3c956a4d52a574105bfa2ed6f8247f4cc313 [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"
msarette16b04a2015-04-15 07:32:19 -070013#include "SkImageInfo.h"
msarett39b2d5a2016-02-17 08:26:31 -080014#include "SkSwizzler.h"
msarette16b04a2015-04-15 07:32:19 -070015#include "SkStream.h"
scroggo565901d2015-12-10 10:44:13 -080016#include "SkTemplates.h"
msarette16b04a2015-04-15 07:32:19 -070017
msarett39b2d5a2016-02-17 08:26:31 -080018class JpegDecoderMgr;
msarette16b04a2015-04-15 07:32:19 -070019
20/*
21 *
22 * This class implements the decoding for jpeg images
23 *
24 */
25class SkJpegCodec : public SkCodec {
26public:
scroggodb30be22015-12-08 18:54:13 -080027 static bool IsJpeg(const void*, size_t);
msarette16b04a2015-04-15 07:32:19 -070028
29 /*
30 * Assumes IsJpeg was called and returned true
31 * Creates a jpeg decoder
32 * Takes ownership of the stream
33 */
34 static SkCodec* NewFromStream(SkStream*);
35
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&,
msarette6dd0042015-10-09 11:07:34 -070047 SkPMColor*, int*, 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
msarette16b04a2015-04-15 07:32:19 -070053 SkEncodedFormat onGetEncodedFormat() const override {
54 return kJPEG_SkEncodedFormat;
55 }
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
msarette16b04a2015-04-15 07:32:19 -070061private:
62
63 /*
64 * Read enough of the stream to initialize the SkJpegCodec.
65 * Returns a bool representing success or failure.
66 *
67 * @param codecOut
halcanary96fcdcc2015-08-27 07:41:13 -070068 * If this returns true, and codecOut was not nullptr,
msarette16b04a2015-04-15 07:32:19 -070069 * codecOut will be set to a new SkJpegCodec.
70 *
71 * @param decoderMgrOut
halcanary96fcdcc2015-08-27 07:41:13 -070072 * If this returns true, and codecOut was nullptr,
73 * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new
msarette16b04a2015-04-15 07:32:19 -070074 * JpegDecoderMgr pointer.
75 *
76 * @param stream
77 * Deleted on failure.
78 * codecOut will take ownership of it in the case where we created a codec.
79 * Ownership is unchanged when we set decoderMgrOut.
80 *
81 */
82 static bool ReadHeader(SkStream* stream, SkCodec** codecOut,
83 JpegDecoderMgr** decoderMgrOut);
84
85 /*
86 * Creates an instance of the decoder
87 * Called only by NewFromStream
88 *
89 * @param srcInfo contains the source width and height
90 * @param stream the encoded image data
91 * @param decoderMgr holds decompress struct, src manager, and error manager
92 * takes ownership
93 */
94 SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream, JpegDecoderMgr* decoderMgr);
95
msarett97fdea62015-04-29 08:17:15 -070096 /*
msarett1c8a5872015-07-07 08:50:01 -070097 * Checks if the conversion between the input image and the requested output
98 * image has been implemented
99 * Sets the output color space
100 */
101 bool setOutputColorSpace(const SkImageInfo& dst);
102
scroggo46c57472015-09-30 08:57:13 -0700103 // scanline decoding
msarettfdb47572015-10-13 12:50:14 -0700104 void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
msarette6dd0042015-10-09 11:07:34 -0700105 SkSampler* getSampler(bool createIfNecessary) override;
scroggo46c57472015-09-30 08:57:13 -0700106 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
msarettfdb47572015-10-13 12:50:14 -0700107 SkPMColor ctable[], int* ctableCount) override;
msarette6dd0042015-10-09 11:07:34 -0700108 int onGetScanlines(void* dst, int count, size_t rowBytes) override;
109 bool onSkipScanlines(int count) override;
scroggo46c57472015-09-30 08:57:13 -0700110
msarette16b04a2015-04-15 07:32:19 -0700111 SkAutoTDelete<JpegDecoderMgr> fDecoderMgr;
msarettfbccb592015-09-01 06:43:41 -0700112 // We will save the state of the decompress struct after reading the header.
113 // This allows us to safely call onGetScaledDimensions() at any time.
114 const int fReadyState;
msarette16b04a2015-04-15 07:32:19 -0700115
scroggo46c57472015-09-30 08:57:13 -0700116 // scanline decoding
scroggo565901d2015-12-10 10:44:13 -0800117 SkAutoTMalloc<uint8_t> fStorage; // Only used if sampling is needed
scroggo46c57472015-09-30 08:57:13 -0700118 uint8_t* fSrcRow; // Only used if sampling is needed
msarett91c22b22016-02-22 12:27:46 -0800119 // libjpeg-turbo provides some subsetting. In the case that libjpeg-turbo
120 // cannot take the exact the subset that we need, we will use the swizzler
121 // to further subset the output from libjpeg-turbo.
122 SkIRect fSwizzlerSubset;
scroggo46c57472015-09-30 08:57:13 -0700123 SkAutoTDelete<SkSwizzler> fSwizzler;
124
msarette16b04a2015-04-15 07:32:19 -0700125 typedef SkCodec INHERITED;
126};
127
128#endif