Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1220)

Side by Side Diff: include/codec/SkCodec.h

Issue 1365313002: Merge SkCodec with SkScanlineDecoder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef SkCodec_DEFINED 8 #ifndef SkCodec_DEFINED
9 #define SkCodec_DEFINED 9 #define SkCodec_DEFINED
10 10
(...skipping 27 matching lines...) Expand all
38 * 38 *
39 * Will take a ref if it returns a codec, else will not affect the data. 39 * Will take a ref if it returns a codec, else will not affect the data.
40 */ 40 */
41 static SkCodec* NewFromData(SkData*); 41 static SkCodec* NewFromData(SkData*);
42 42
43 virtual ~SkCodec(); 43 virtual ~SkCodec();
44 44
45 /** 45 /**
46 * Return the ImageInfo associated with this codec. 46 * Return the ImageInfo associated with this codec.
47 */ 47 */
48 const SkImageInfo& getInfo() const { return fInfo; } 48 const SkImageInfo& getInfo() const { return fSrcInfo; }
49 49
50 /** 50 /**
51 * Return a size that approximately supports the desired scale factor. 51 * Return a size that approximately supports the desired scale factor.
52 * The codec may not be able to scale efficiently to the exact scale 52 * The codec may not be able to scale efficiently to the exact scale
53 * factor requested, so return a size that approximates that scale. 53 * factor requested, so return a size that approximates that scale.
54 * The returned value is the codec's suggestion for the closest valid 54 * The returned value is the codec's suggestion for the closest valid
55 * scale that it can natively support 55 * scale that it can natively support
56 */ 56 */
57 SkISize getScaledDimensions(float desiredScale) const { 57 SkISize getScaledDimensions(float desiredScale) const {
58 // Negative and zero scales are errors. 58 // Negative and zero scales are errors.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 /** 124 /**
125 * The input did not contain a valid image. 125 * The input did not contain a valid image.
126 */ 126 */
127 kInvalidInput, 127 kInvalidInput,
128 /** 128 /**
129 * Fulfilling this request requires rewinding the input, which is not 129 * Fulfilling this request requires rewinding the input, which is not
130 * supported for this input. 130 * supported for this input.
131 */ 131 */
132 kCouldNotRewind, 132 kCouldNotRewind,
133 /** 133 /**
134 * This method is not implemented by this generator. 134 * This method is not implemented by this codec.
135 * FIXME: Perhaps this should be kUnsupported?
135 */ 136 */
136 kUnimplemented, 137 kUnimplemented,
138 /**
139 * start() was not called before calling getScanlines.
140 */
141 kScanlineDecodingNotStarted,
137 }; 142 };
138 143
139 /** 144 /**
140 * Whether or not the memory passed to getPixels is zero initialized. 145 * Whether or not the memory passed to getPixels is zero initialized.
141 */ 146 */
142 enum ZeroInitialized { 147 enum ZeroInitialized {
143 /** 148 /**
144 * The memory passed to getPixels is zero initialized. The SkCodec 149 * The memory passed to getPixels is zero initialized. The SkCodec
145 * may take advantage of this by skipping writing zeroes. 150 * may take advantage of this by skipping writing zeroes.
146 */ 151 */
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 * to scale. If the generator cannot perform this scale, 200 * to scale. If the generator cannot perform this scale,
196 * it will return kInvalidScale. 201 * it will return kInvalidScale.
197 * 202 *
198 * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256 203 * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
199 * SkPMColor values in ctable. On success the generator must copy N colors into that storage, 204 * SkPMColor values in ctable. On success the generator must copy N colors into that storage,
200 * (where N is the logical number of table entries) and set ctableCount to N. 205 * (where N is the logical number of table entries) and set ctableCount to N.
201 * 206 *
202 * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount 207 * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
203 * is not null, it will be set to 0. 208 * is not null, it will be set to 0.
204 * 209 *
210 * If a scanline decode is in progress, scanline mode will end, requiring t he client to call
211 * start() in order to return to decoding scanlines.
212 *
205 * @return Result kSuccess, or another value explaining the type of failure . 213 * @return Result kSuccess, or another value explaining the type of failure .
206 */ 214 */
207 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, con st Options*, 215 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, con st Options*,
208 SkPMColor ctable[], int* ctableCount); 216 SkPMColor ctable[], int* ctableCount);
209 217
210 /** 218 /**
211 * Simplified version of getPixels() that asserts that info is NOT kIndex8_ SkColorType and 219 * Simplified version of getPixels() that asserts that info is NOT kIndex8_ SkColorType and
212 * uses the default Options. 220 * uses the default Options.
213 */ 221 */
214 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); 222 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
215 223
216 /** 224 /**
217 * Some images may initially report that they have alpha due to the format 225 * Some images may initially report that they have alpha due to the format
218 * of the encoded data, but then never use any colors which have alpha 226 * of the encoded data, but then never use any colors which have alpha
219 * less than 100%. This function can be called *after* decoding to 227 * less than 100%. This function can be called *after* decoding to
220 * determine if such an image truly had alpha. Calling it before decoding 228 * determine if such an image truly had alpha. Calling it before decoding
221 * is undefined. 229 * is undefined.
222 * FIXME: see skbug.com/3582. 230 * FIXME: see skbug.com/3582.
223 */ 231 */
224 bool reallyHasAlpha() const { 232 bool reallyHasAlpha() const {
225 return this->onReallyHasAlpha(); 233 return this->onReallyHasAlpha();
226 } 234 }
227 235
236 /**
237 * The remaining functions revolve around decoding scanlines.
238 */
239
240 /**
241 * Initialize on the first scanline, with the specified options.
msarett 2015/09/28 14:48:50 "Initialize on the first scanline" is a little unc
scroggo 2015/09/28 16:01:52 Sgtm. I think it made a little more sense back whe
242 *
243 * This must be called in order to call getScanlines or skipScanlines.
244 *
245 * This may require rewinding the stream.
246 *
247 * Not all SkCodecs support this.
248 *
249 * @param dstInfo Info of the destination. If the dimensions do not match
250 * those of getInfo, this implies a scale.
251 * @param options Contains decoding options, including if memory is zero
252 * initialized.
253 * @param ctable A pointer to a color table. When dstInfo.colorType() is
254 * kIndex8, this should be non-NULL and have enough storage for 256
255 * colors. The color table will be populated after decoding the palett e.
256 * @param ctableCount A pointer to the size of the color table. When
257 * dstInfo.colorType() is kIndex8, this should be non-NULL. It will
258 * be modified to the true size of the color table (<= 256) after
259 * decoding the palette.
260 * @return Enum representing success or reason for failure.
261 */
262 Result start(const SkImageInfo& dstInfo, const SkCodec::Options* options,
scroggo 2015/09/25 16:07:49 I left the name "start" to make the changeover sim
msarett 2015/09/28 14:48:50 I like a shorter name but that's because I know wh
scroggo 2015/09/28 16:01:52 These sound fine with me. I'll wait for API review
263 SkPMColor ctable[], int* ctableCount);
264
265 /**
266 * Simplified version of start() that asserts that info is NOT
267 * kIndex8_SkColorType and uses the default Options.
268 */
269 Result start(const SkImageInfo& dstInfo);
270
271 /**
272 * Write the next countLines scanlines into dst.
273 *
274 * Not valid to call before calling start().
275 *
276 * @param dst Must be non-null, and large enough to hold countLines
277 * scanlines of size rowBytes.
278 * @param countLines Number of lines to write.
279 * @param rowBytes Number of bytes per row. Must be large enough to hold
280 * a scanline based on the SkImageInfo used to create this object.
281 */
282 Result getScanlines(void* dst, int countLines, size_t rowBytes) {
283 if (fCurrScanline < 0) {
scroggo 2015/09/25 16:07:49 Alternatively, I could have checked fDstInfo, whic
msarett 2015/09/28 14:48:50 I like what you've chosen to do.
284 return kScanlineDecodingNotStarted;
scroggo 2015/09/25 16:07:49 I know (msarett@) you have a CL out for review whi
msarett 2015/09/28 14:48:50 Yeah I think that's ok. Maybe we can provide more
scroggo 2015/09/28 16:01:52 I think returning kScanlineDecodingNoStarted is pr
285 }
286
287 SkASSERT(!fDstInfo.isEmpty());
288 if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0
289 || fCurrScanline + countLines > fDstInfo.height()) {
290 return kInvalidParameters;
291 }
292 const Result result = this->onGetScanlines(dst, countLines, rowBytes);
293 fCurrScanline += countLines;
294 return result;
295 }
296
297 /**
298 * Skip count scanlines.
299 *
300 * Not valid to call before calling start().
301 *
302 * The default version just calls onGetScanlines and discards the dst.
303 * NOTE: If skipped lines are the only lines with alpha, this default
304 * will make reallyHasAlpha return true, when it could have returned
305 * false.
306 */
307 Result skipScanlines(int countLines) {
308 if (fCurrScanline < 0) {
309 return kScanlineDecodingNotStarted;
310 }
311 SkASSERT(!fDstInfo.isEmpty());
312 if (fCurrScanline + countLines > fDstInfo.height()) {
313 // Arguably, we could just skip the scanlines which are remaining,
314 // and return kSuccess. We choose to return invalid so the client
315 // can catch their bug.
316 return SkCodec::kInvalidParameters;
317 }
318 const Result result = this->onSkipScanlines(countLines);
319 fCurrScanline += countLines;
320 return result;
321 }
322
323 /**
324 * The order in which rows are output from the scanline decoder is not the
325 * same for all variations of all image types. This explains the possible
326 * output row orderings.
327 */
328 enum SkScanlineOrder {
329 /*
330 * By far the most common, this indicates that the image can be decoded
331 * reliably using the scanline decoder, and that rows will be output in
332 * the logical order.
333 */
334 kTopDown_SkScanlineOrder,
335
336 /*
337 * This indicates that the scanline decoder reliably outputs rows, but
338 * they will be returned in reverse order. If the scanline format is
339 * kBottomUp, the getY() API can be used to determine the actual
340 * y-coordinate of the next output row, but the client is not forced
341 * to take advantage of this, given that it's not too tough to keep
342 * track independently.
343 *
344 * For full image decodes, it is safe to get all of the scanlines at
345 * once, since the decoder will handle inverting the rows as it
346 * decodes.
347 *
348 * For subset decodes and sampling, it is simplest to get and skip
349 * scanlines one at a time, using the getY() API. It is possible to
350 * ask for larger chunks at a time, but this should be used with
351 * caution. As with full image decodes, the decoder will handle
352 * inverting the requested rows, but rows will still be delivered
353 * starting from the bottom of the image.
354 *
355 * Upside down bmps are an example.
356 */
357 kBottomUp_SkScanlineOrder,
358
359 /*
360 * This indicates that the scanline decoder reliably outputs rows, but
361 * they will not be in logical order. If the scanline format is
362 * kOutOfOrder, the getY() API should be used to determine the actual
363 * y-coordinate of the next output row.
364 *
365 * For this scanline ordering, it is advisable to get and skip
366 * scanlines one at a time.
367 *
368 * Interlaced gifs are an example.
369 */
370 kOutOfOrder_SkScanlineOrder,
371
372 /*
373 * Indicates that the entire image must be decoded in order to output
374 * any amount of scanlines. In this case, it is a REALLY BAD IDEA to
375 * request scanlines 1-by-1 or in small chunks. The client should
376 * determine which scanlines are needed and ask for all of them in
377 * a single call to getScanlines().
378 *
379 * Interlaced pngs are an example.
380 */
381 kNone_SkScanlineOrder,
382 };
383
384 /**
385 * An enum representing the order in which scanlines will be returned by
386 * the scanline decoder.
387 */
388 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; }
389
390 /**
391 * Returns the y-coordinate of the next row to be returned by the scanline
392 * decoder. This will be overridden in the case of
393 * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of
394 * kNone_SkScanlineOrder.
395 *
396 * Results are undefined when not in scanline decoding mode.
397 */
398 int getY() const {
399 SkASSERT(kNone_SkScanlineOrder != this->getScanlineOrder());
msarett 2015/09/28 14:48:50 Given that the interlaced png scanline decoder now
scroggo 2015/09/28 16:01:52 I've removed the assert. FWIW, interlaced png call
400 return this->onGetY();
401 }
402
228 protected: 403 protected:
229 SkCodec(const SkImageInfo&, SkStream*); 404 SkCodec(const SkImageInfo&, SkStream*);
230 405
231 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { 406 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
232 // By default, scaling is not supported. 407 // By default, scaling is not supported.
233 return this->getInfo().dimensions(); 408 return this->getInfo().dimensions();
234 } 409 }
235 410
236 virtual SkEncodedFormat onGetEncodedFormat() const = 0; 411 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
237 412
(...skipping 30 matching lines...) Expand all
268 return true; 443 return true;
269 } 444 }
270 445
271 /** 446 /**
272 * Get method for the input stream 447 * Get method for the input stream
273 */ 448 */
274 SkStream* stream() { 449 SkStream* stream() {
275 return fStream.get(); 450 return fStream.get();
276 } 451 }
277 452
453 /**
454 * The remaining functions revolve around decoding scanlines.
455 */
456
457 /**
458 * Most images types will be kTopDown and will not need to override this fu nction.
459 */
460 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; }
461
462 /**
463 * Most images will be kTopDown and will not need to override this function .
464 */
465 virtual int onGetY() const { return fCurrScanline; }
466
467 /**
468 * Update the next scanline. Used by interlaced png.
469 */
470 void updateY(int newY) { fCurrScanline = newY; }
scroggo 2015/09/25 16:07:49 I named this updateY to mirror getY, but I might p
msarett 2015/09/28 14:48:50 I'm in favor of renaming these. I think my origin
scroggo 2015/09/28 16:01:52 I'll add a FIXME to discuss for API review. I woul
471
472 const SkImageInfo& dstInfo() const { return fDstInfo; }
473
474 const SkCodec::Options& options() const { return fOptions; }
475
278 private: 476 private:
279 const SkImageInfo fInfo; 477 const SkImageInfo fSrcInfo;
280 SkAutoTDelete<SkStream> fStream; 478 SkAutoTDelete<SkStream> fStream;
281 bool fNeedsRewind; 479 bool fNeedsRewind;
480 // These fields are only meaningful during scanline decodes.
481 SkImageInfo fDstInfo;
482 SkCodec::Options fOptions;
483 int fCurrScanline;
484
485 // Methods for scanline decoding.
486 virtual SkCodec::Result onStart(const SkImageInfo& dstInfo,
487 const SkCodec::Options& options,
488 SkPMColor ctable[], int* ctableCount) {
489 return kUnimplemented;
490 }
491
492 // Naive default version just calls onGetScanlines on temp memory.
493 virtual SkCodec::Result onSkipScanlines(int countLines) {
494 SkAutoMalloc storage(fDstInfo.minRowBytes());
495 // Note that we pass 0 to rowBytes so we continue to use the same memory .
496 // Also note that while getScanlines checks that rowBytes is big enough,
497 // onGetScanlines bypasses that check.
498 // Calling the virtual method also means we do not double count
499 // countLines.
500 return this->onGetScanlines(storage.get(), countLines, 0);
501 }
502
503 virtual SkCodec::Result onGetScanlines(void* dst, int countLines,
504 size_t rowBytes) {
505 return kUnimplemented;
506 }
507
282 }; 508 };
283 #endif // SkCodec_DEFINED 509 #endif // SkCodec_DEFINED
OLDNEW
« no previous file with comments | « gyp/codec.gyp ('k') | include/codec/SkScaledCodec.h » ('j') | src/codec/SkCodec_libgif.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698