C++11 override should now be supported by all of {bots,Chrome,Android,Mozilla}
[platform/upstream/libSkiaSharp.git] / include / codec / SkCodec.h
1 /*
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
11 #include "SkEncodedFormat.h"
12 #include "SkImageGenerator.h"
13 #include "SkImageInfo.h"
14 #include "SkScanlineDecoder.h"
15 #include "SkSize.h"
16 #include "SkStream.h"
17 #include "SkTemplates.h"
18 #include "SkTypes.h"
19
20 class SkData;
21
22 /**
23  *  Abstraction layer directly on top of an image codec.
24  */
25 class SkCodec : public SkImageGenerator {
26 public:
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      */
51     SkISize getScaledDimensions(float desiredScale) const {
52         return this->onGetScaledDimensions(desiredScale);
53     }
54
55     /**
56      *  Format of the encoded data.
57      */
58     SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
59
60     /**
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
95 protected:
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      */
103 #ifdef SK_SUPPORT_LEGACY_BOOL_ONGETINFO
104     bool onGetInfo(SkImageInfo* info) override {
105         *info = fInfo;
106         return true;
107     }
108 #endif
109
110     virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
111         // By default, scaling is not supported.
112         return fInfo.dimensions();
113     }
114
115     virtual SkEncodedFormat onGetEncodedFormat() const = 0;
116
117     /**
118      *  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     /**
135      *  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
149     /*
150      *
151      * Get method for the input stream
152      *
153      */
154     SkStream* stream() {
155         return fStream.get();
156     }
157
158 private:
159     const SkImageInfo                   fInfo;
160     SkAutoTDelete<SkStream>             fStream;
161     bool                                fNeedsRewind;
162     SkAutoTDelete<SkScanlineDecoder>    fScanlineDecoder;
163
164     typedef SkImageGenerator INHERITED;
165 };
166 #endif // SkCodec_DEFINED