blob: 7337006769e13afdb72d77ccc1f8ea77e1d5c7af [file] [log] [blame]
scroggof24f2242015-03-03 08:59:20 -08001/*
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 SkCodec_DEFINED
9#define SkCodec_DEFINED
10
scroggo1dd3ea92015-03-20 11:55:55 -070011#include "SkEncodedFormat.h"
scroggof24f2242015-03-03 08:59:20 -080012#include "SkImageGenerator.h"
13#include "SkImageInfo.h"
scroggo05245902015-03-25 11:11:52 -070014#include "SkScanlineDecoder.h"
scroggof24f2242015-03-03 08:59:20 -080015#include "SkSize.h"
scroggofffeede2015-03-18 10:50:37 -070016#include "SkStream.h"
scroggof24f2242015-03-03 08:59:20 -080017#include "SkTemplates.h"
18#include "SkTypes.h"
19
20class SkData;
scroggof24f2242015-03-03 08:59:20 -080021
22/**
23 * Abstraction layer directly on top of an image codec.
24 */
25class SkCodec : public SkImageGenerator {
26public:
27 /**
28 * If this stream represents an encoded image that we know how to decode,
29 * return an SkCodec that can decode it. Otherwise return NULL.
30 *
31 * If NULL is returned, the stream is deleted immediately. Otherwise, the
32 * SkCodec takes ownership of it, and will delete it when done with it.
33 */
34 static SkCodec* NewFromStream(SkStream*);
35
36 /**
37 * If this data represents an encoded image that we know how to decode,
38 * return an SkCodec that can decode it. Otherwise return NULL.
39 *
40 * Will take a ref if it returns a codec, else will not affect the data.
41 */
42 static SkCodec* NewFromData(SkData*);
43
44 /**
45 * Return a size that approximately supports the desired scale factor.
46 * The codec may not be able to scale efficiently to the exact scale
47 * factor requested, so return a size that approximates that scale.
48 *
49 * FIXME: Move to SkImageGenerator?
50 */
scroggofffeede2015-03-18 10:50:37 -070051 SkISize getScaledDimensions(float desiredScale) const {
52 return this->onGetScaledDimensions(desiredScale);
53 }
scroggof24f2242015-03-03 08:59:20 -080054
scroggo1dd3ea92015-03-20 11:55:55 -070055 /**
56 * Format of the encoded data.
57 */
58 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
59
scroggo05245902015-03-25 11:11:52 -070060 /**
61 * Return an object which can be used to decode individual scanlines.
62 *
63 * This object is owned by the SkCodec, which will handle its lifetime. The
64 * returned object is only valid until the SkCodec is deleted or the next
65 * call to getScanlineDecoder, whichever comes first.
66 *
67 * Calling a second time will rewind and replace the existing one with a
68 * new one. If the stream cannot be rewound, this will delete the existing
69 * one and return NULL.
70 *
71 * @param dstInfo Info of the destination. If the dimensions do not match
72 * those of getInfo, this implies a scale.
73 * @return New SkScanlineDecoder, or NULL on failure.
74 *
75 * NOTE: If any rows were previously decoded, this requires rewinding the
76 * SkStream.
77 *
78 * NOTE: The scanline decoder is owned by the SkCodec and will delete it
79 * when the SkCodec is deleted.
80 */
81 SkScanlineDecoder* getScanlineDecoder(const SkImageInfo& dstInfo);
82
83 /**
84 * Some images may initially report that they have alpha due to the format
85 * of the encoded data, but then never use any colors which have alpha
86 * less than 100%. This function can be called *after* decoding to
87 * determine if such an image truly had alpha. Calling it before decoding
88 * is undefined.
89 * FIXME: see skbug.com/3582.
90 */
91 bool reallyHasAlpha() const {
92 return this->onReallyHasAlpha();
93 }
94
scroggof24f2242015-03-03 08:59:20 -080095protected:
96 SkCodec(const SkImageInfo&, SkStream*);
97
98 /**
99 * The SkAlphaType is a conservative answer. i.e. it is possible that it
100 * initially returns a non-opaque answer, but completing the decode
101 * reveals that the image is actually opaque.
102 */
reed3ef71e32015-03-19 08:31:14 -0700103#ifdef SK_SUPPORT_LEGACY_BOOL_ONGETINFO
scroggof24f2242015-03-03 08:59:20 -0800104 bool onGetInfo(SkImageInfo* info) SK_OVERRIDE {
105 *info = fInfo;
106 return true;
107 }
reed3ef71e32015-03-19 08:31:14 -0700108#endif
scroggof24f2242015-03-03 08:59:20 -0800109
scroggof24f2242015-03-03 08:59:20 -0800110 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
111 // By default, scaling is not supported.
112 return fInfo.dimensions();
113 }
114
scroggo1dd3ea92015-03-20 11:55:55 -0700115 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
116
scroggof24f2242015-03-03 08:59:20 -0800117 /**
scroggo05245902015-03-25 11:11:52 -0700118 * Override if your codec supports scanline decoding.
119 *
120 * No need to call rewindIfNeeded(), which will have already been called
121 * by the base class.
122 *
123 * @param dstInfo Info of the destination. If the dimensions do not match
124 * those of getInfo, this implies a scale.
125 * @return New SkScanlineDecoder on success, NULL otherwise. The SkCodec
126 * will take ownership of the returned scanline decoder.
127 */
128 virtual SkScanlineDecoder* onGetScanlineDecoder(const SkImageInfo& dstInfo) {
129 return NULL;
130 }
131
132 virtual bool onReallyHasAlpha() const { return false; }
133
134 /**
scroggof24f2242015-03-03 08:59:20 -0800135 * If the stream was previously read, attempt to rewind.
136 * @returns:
137 * true
138 * - if the stream needed to be rewound, and the rewind
139 * succeeded.
140 * - if the stream did not need to be rewound.
141 * false
142 * - if the stream needed to be rewound, and rewind failed.
143 * Subclasses MUST call this function before reading the stream (e.g. in
144 * onGetPixels). If it returns false, onGetPixels should return
145 * kCouldNotRewind.
146 */
147 bool SK_WARN_UNUSED_RESULT rewindIfNeeded();
148
msarett74114382015-03-16 11:55:18 -0700149 /*
150 *
151 * Get method for the input stream
152 *
153 */
154 SkStream* stream() {
155 return fStream.get();
156 }
157
scroggof24f2242015-03-03 08:59:20 -0800158private:
scroggo05245902015-03-25 11:11:52 -0700159 const SkImageInfo fInfo;
160 SkAutoTDelete<SkStream> fStream;
161 bool fNeedsRewind;
162 SkAutoTDelete<SkScanlineDecoder> fScanlineDecoder;
reed3ef71e32015-03-19 08:31:14 -0700163
164 typedef SkImageGenerator INHERITED;
scroggof24f2242015-03-03 08:59:20 -0800165};
166#endif // SkCodec_DEFINED