blob: ed94b613f9fcbd2374cc6b171738d45b01fac6b0 [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"
13#include "SkJpegDecoderMgr.h"
mtklein525e90a2015-06-18 09:58:57 -070014#include "SkJpegUtility_codec.h"
msarette16b04a2015-04-15 07:32:19 -070015#include "SkStream.h"
16
17extern "C" {
18 #include "jpeglib.h"
19}
20
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
50 SkEncodedFormat onGetEncodedFormat() const override {
51 return kJPEG_SkEncodedFormat;
52 }
53
scroggob427db12015-08-12 07:24:13 -070054 bool onRewind() override;
55
scroggoe7fc14b2015-10-02 13:14:46 -070056 bool onDimensionsSupported(const SkISize&) override;
57
msarette16b04a2015-04-15 07:32:19 -070058private:
59
60 /*
61 * Read enough of the stream to initialize the SkJpegCodec.
62 * Returns a bool representing success or failure.
63 *
64 * @param codecOut
halcanary96fcdcc2015-08-27 07:41:13 -070065 * If this returns true, and codecOut was not nullptr,
msarette16b04a2015-04-15 07:32:19 -070066 * codecOut will be set to a new SkJpegCodec.
67 *
68 * @param decoderMgrOut
halcanary96fcdcc2015-08-27 07:41:13 -070069 * If this returns true, and codecOut was nullptr,
70 * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new
msarette16b04a2015-04-15 07:32:19 -070071 * JpegDecoderMgr pointer.
72 *
73 * @param stream
74 * Deleted on failure.
75 * codecOut will take ownership of it in the case where we created a codec.
76 * Ownership is unchanged when we set decoderMgrOut.
77 *
78 */
79 static bool ReadHeader(SkStream* stream, SkCodec** codecOut,
80 JpegDecoderMgr** decoderMgrOut);
81
82 /*
83 * Creates an instance of the decoder
84 * Called only by NewFromStream
85 *
86 * @param srcInfo contains the source width and height
87 * @param stream the encoded image data
88 * @param decoderMgr holds decompress struct, src manager, and error manager
89 * takes ownership
90 */
91 SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream, JpegDecoderMgr* decoderMgr);
92
msarett97fdea62015-04-29 08:17:15 -070093 /*
msarett1c8a5872015-07-07 08:50:01 -070094 * Checks if the conversion between the input image and the requested output
95 * image has been implemented
96 * Sets the output color space
97 */
98 bool setOutputColorSpace(const SkImageInfo& dst);
99
scroggo46c57472015-09-30 08:57:13 -0700100 // scanline decoding
msarettfdb47572015-10-13 12:50:14 -0700101 void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
msarette6dd0042015-10-09 11:07:34 -0700102 SkSampler* getSampler(bool createIfNecessary) override;
scroggo46c57472015-09-30 08:57:13 -0700103 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
msarettfdb47572015-10-13 12:50:14 -0700104 SkPMColor ctable[], int* ctableCount) override;
msarette6dd0042015-10-09 11:07:34 -0700105 int onGetScanlines(void* dst, int count, size_t rowBytes) override;
106 bool onSkipScanlines(int count) override;
scroggo46c57472015-09-30 08:57:13 -0700107
msarette16b04a2015-04-15 07:32:19 -0700108 SkAutoTDelete<JpegDecoderMgr> fDecoderMgr;
msarettfbccb592015-09-01 06:43:41 -0700109 // We will save the state of the decompress struct after reading the header.
110 // This allows us to safely call onGetScaledDimensions() at any time.
111 const int fReadyState;
msarette16b04a2015-04-15 07:32:19 -0700112
scroggo46c57472015-09-30 08:57:13 -0700113 // scanline decoding
114 SkAutoMalloc fStorage; // Only used if sampling is needed
115 uint8_t* fSrcRow; // Only used if sampling is needed
116 SkAutoTDelete<SkSwizzler> fSwizzler;
117
msarette16b04a2015-04-15 07:32:19 -0700118 typedef SkCodec INHERITED;
119};
120
121#endif