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

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

Issue 1332053002: Fill incomplete images in SkCodec parent class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Response to comments in Patch Set 5 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 113 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 * startScanlineDecode() was not called before calling getScanlines.
135 */
136 kScanlineDecodingNotStarted,
137 /**
138 * This method is not implemented by this codec. 134 * This method is not implemented by this codec.
139 * FIXME: Perhaps this should be kUnsupported? 135 * FIXME: Perhaps this should be kUnsupported?
140 */ 136 */
141 kUnimplemented, 137 kUnimplemented,
142 }; 138 };
143 139
144 /** 140 /**
145 * Whether or not the memory passed to getPixels is zero initialized. 141 * Whether or not the memory passed to getPixels is zero initialized.
146 */ 142 */
147 enum ZeroInitialized { 143 enum ZeroInitialized {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 * less than 100%. This function can be called *after* decoding to 223 * less than 100%. This function can be called *after* decoding to
228 * determine if such an image truly had alpha. Calling it before decoding 224 * determine if such an image truly had alpha. Calling it before decoding
229 * is undefined. 225 * is undefined.
230 * FIXME: see skbug.com/3582. 226 * FIXME: see skbug.com/3582.
231 */ 227 */
232 bool reallyHasAlpha() const { 228 bool reallyHasAlpha() const {
233 return this->onReallyHasAlpha(); 229 return this->onReallyHasAlpha();
234 } 230 }
235 231
236 /** 232 /**
233 * On a kIncompleteInput, getPixels() and getScanlines() will fill any unini tialized
scroggo 2015/10/01 20:48:58 Maybe change "kIncompleteInput" to "incomplete inp
msarett 2015/10/01 22:34:51 Done.
234 * scanlines. This allows the subclass to indicate what value to fill with.
235 *
236 * @param colorType Destination color type.
237 * @param alphaType Destination alpha type.
238 * @return The value with which to fill uninitialized pixels.
239 *
240 * Note that we can interpret the return value as an SkPMColor, a 16-bit 565 color,
241 * an 8-bit gray color, or an 8-bit index into a color table, depending on t he color
242 * type specified in dstInfo.
243 */
244 uint32_t getFillValue(SkColorType colorType, SkAlphaType alphaType) const {
245 return this->onGetFillValue(colorType, alphaType);
246 }
247
248 /**
237 * The remaining functions revolve around decoding scanlines. 249 * The remaining functions revolve around decoding scanlines.
238 */ 250 */
239 251
240 /** 252 /**
241 * Prepare for a scanline decode with the specified options. 253 * Prepare for a scanline decode with the specified options.
242 * 254 *
243 * After this call, this class will be ready to decode the first scanline. 255 * After this call, this class will be ready to decode the first scanline.
244 * 256 *
245 * This must be called in order to call getScanlines or skipScanlines. 257 * This must be called in order to call getScanlines or skipScanlines.
246 * 258 *
(...skipping 26 matching lines...) Expand all
273 /** 285 /**
274 * Write the next countLines scanlines into dst. 286 * Write the next countLines scanlines into dst.
275 * 287 *
276 * Not valid to call before calling startScanlineDecode(). 288 * Not valid to call before calling startScanlineDecode().
277 * 289 *
278 * @param dst Must be non-null, and large enough to hold countLines 290 * @param dst Must be non-null, and large enough to hold countLines
279 * scanlines of size rowBytes. 291 * scanlines of size rowBytes.
280 * @param countLines Number of lines to write. 292 * @param countLines Number of lines to write.
281 * @param rowBytes Number of bytes per row. Must be large enough to hold 293 * @param rowBytes Number of bytes per row. Must be large enough to hold
282 * a scanline based on the SkImageInfo used to create this object. 294 * a scanline based on the SkImageInfo used to create this object.
295 * @return the number of lines successfully decoded. If this value is
296 * less than countLines, this will fill the remaining lines with a
297 * default value.
283 */ 298 */
284 Result getScanlines(void* dst, int countLines, size_t rowBytes); 299 int getScanlines(void* dst, int countLines, size_t rowBytes);
285 300
286 /** 301 /**
287 * Skip count scanlines. 302 * Skip count scanlines.
288 * 303 *
289 * Not valid to call before calling startScanlineDecode(). 304 * Not valid to call before calling startScanlineDecode().
290 * 305 *
291 * The default version just calls onGetScanlines and discards the dst. 306 * The default version just calls onGetScanlines and discards the dst.
292 * NOTE: If skipped lines are the only lines with alpha, this default 307 * NOTE: If skipped lines are the only lines with alpha, this default
293 * will make reallyHasAlpha return true, when it could have returned 308 * will make reallyHasAlpha return true, when it could have returned
294 * false. 309 * false.
310 *
311 * @return true if the scanlines were successfully skipped
312 * false on failure, possible reasons for failure include:
313 * An incomplete input image stream.
314 * Calling this function before calling startScanlineDecode().
315 * If countLines is less than zero or so large that it moves
316 * the current scanline past the end of the image.
295 */ 317 */
296 Result skipScanlines(int countLines); 318 bool skipScanlines(int countLines);
297 319
298 /** 320 /**
299 * The order in which rows are output from the scanline decoder is not the 321 * The order in which rows are output from the scanline decoder is not the
300 * same for all variations of all image types. This explains the possible 322 * same for all variations of all image types. This explains the possible
301 * output row orderings. 323 * output row orderings.
302 */ 324 */
303 enum SkScanlineOrder { 325 enum SkScanlineOrder {
304 /* 326 /*
305 * By far the most common, this indicates that the image can be decoded 327 * By far the most common, this indicates that the image can be decoded
306 * reliably using the scanline decoder, and that rows will be output in 328 * reliably using the scanline decoder, and that rows will be output in
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 }; 379 };
358 380
359 /** 381 /**
360 * An enum representing the order in which scanlines will be returned by 382 * An enum representing the order in which scanlines will be returned by
361 * the scanline decoder. 383 * the scanline decoder.
362 */ 384 */
363 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; } 385 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; }
364 386
365 /** 387 /**
366 * Returns the y-coordinate of the next row to be returned by the scanline 388 * Returns the y-coordinate of the next row to be returned by the scanline
367 * decoder. This will be overridden in the case of 389 * decoder.
368 * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of 390 *
369 * kNone_SkScanlineOrder. 391 * This will often equal fCurrScanline, but may not in the case of strangel y
scroggo 2015/10/01 20:48:58 I find "often" a little confusing here. You really
msarett 2015/10/01 22:34:52 Done.
392 * encoded image types (bottom-up bmps, interlaced gifs).
370 * 393 *
371 * Results are undefined when not in scanline decoding mode. 394 * Results are undefined when not in scanline decoding mode.
372 */ 395 */
373 int nextScanline() const { 396 int nextScanline() const { return this->outputScanline(fCurrScanline); }
374 return this->onNextScanline(); 397
375 } 398 /**
399 * Returns the output y-coordinate of the row that corresponds to an input
400 * y-coordinate. The input y-coordinate represents where the scanline
401 * is located in the encoded data.
402 *
403 * This will often equal inputScanline, but may not in the case of strangel y
scroggo 2015/10/01 20:48:58 I again, I think often is the wrong word to use he
msarett 2015/10/01 22:34:52 Done.
404 * encoded image types (bottom-up bmps, interlaced gifs).
405 */
406 int outputScanline(int inputScanline) const;
376 407
377 protected: 408 protected:
378 SkCodec(const SkImageInfo&, SkStream*); 409 SkCodec(const SkImageInfo&, SkStream*);
379 410
380 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { 411 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
381 // By default, scaling is not supported. 412 // By default, scaling is not supported.
382 return this->getInfo().dimensions(); 413 return this->getInfo().dimensions();
383 } 414 }
384 415
385 virtual SkEncodedFormat onGetEncodedFormat() const = 0; 416 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
386 417
418 /**
419 * @param rowsDecoded When the encoded image stream is incomplete, this func tion
420 * will return kIncompleteInput and rowsDecoded will be s et to
421 * the number of scanlines that were successfully decoded .
422 * This will allow getPixels() to fill the uninitialized memory.
423 */
387 virtual Result onGetPixels(const SkImageInfo& info, 424 virtual Result onGetPixels(const SkImageInfo& info,
388 void* pixels, size_t rowBytes, const Options&, 425 void* pixels, size_t rowBytes, const Options&,
389 SkPMColor ctable[], int* ctableCount) = 0; 426 SkPMColor ctable[], int* ctableCount,
427 int* rowsDecoded) = 0;
390 428
391 virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const { 429 virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const {
392 // By default, subsets are not supported. 430 // By default, subsets are not supported.
393 return false; 431 return false;
394 } 432 }
395 433
396 virtual bool onReallyHasAlpha() const { return false; } 434 virtual bool onReallyHasAlpha() const { return false; }
397 435
398 /** 436 /**
399 * If the stream was previously read, attempt to rewind. 437 * If the stream was previously read, attempt to rewind.
(...skipping 10 matching lines...) Expand all
410 /** 448 /**
411 * Called by rewindIfNeeded, if the stream needed to be rewound. 449 * Called by rewindIfNeeded, if the stream needed to be rewound.
412 * 450 *
413 * Subclasses should do any set up needed after a rewind. 451 * Subclasses should do any set up needed after a rewind.
414 */ 452 */
415 virtual bool onRewind() { 453 virtual bool onRewind() {
416 return true; 454 return true;
417 } 455 }
418 456
419 /** 457 /**
458 * Some subclasses will override this function, but this is a useful default for the color
459 * types that we support. Note that for color types that do not use the ful l 32-bits,
460 * we will simply take the low bits of the fill value.
461 *
462 * kN32_SkColorType: Transparent or Black
463 * kRGB_565_SkColorType: Black
464 * kGray_8_SkColorType: Black
465 * kIndex_8_SkColorType: First color in color table
466 */
467 virtual uint32_t onGetFillValue(SkColorType colorType, SkAlphaType alphaType ) const {
468 return kOpaque_SkAlphaType == alphaType ? SK_ColorBLACK : SK_ColorTRANSP ARENT;
469 }
470
471 /**
420 * Get method for the input stream 472 * Get method for the input stream
421 */ 473 */
422 SkStream* stream() { 474 SkStream* stream() {
423 return fStream.get(); 475 return fStream.get();
424 } 476 }
425 477
426 /** 478 /**
427 * The remaining functions revolve around decoding scanlines. 479 * The remaining functions revolve around decoding scanlines.
428 */ 480 */
429 481
430 /** 482 /**
431 * Most images types will be kTopDown and will not need to override this fu nction. 483 * Most images types will be kTopDown and will not need to override this fu nction.
432 */ 484 */
433 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; } 485 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; }
434 486
435 /** 487 /**
436 * Most images will be kTopDown and will not need to override this function .
437 */
438 virtual int onNextScanline() const { return fCurrScanline; }
439
440 /**
441 * Update the next scanline. Used by interlaced png. 488 * Update the next scanline. Used by interlaced png.
442 */ 489 */
443 void updateNextScanline(int newY) { fCurrScanline = newY; } 490 void updateNextScanline(int newY) { fCurrScanline = newY; }
444 491
445 const SkImageInfo& dstInfo() const { return fDstInfo; } 492 const SkImageInfo& dstInfo() const { return fDstInfo; }
446 493
447 const SkCodec::Options& options() const { return fOptions; } 494 const SkCodec::Options& options() const { return fOptions; }
448 495
449 private: 496 private:
450 const SkImageInfo fSrcInfo; 497 const SkImageInfo fSrcInfo;
451 SkAutoTDelete<SkStream> fStream; 498 SkAutoTDelete<SkStream> fStream;
452 bool fNeedsRewind; 499 bool fNeedsRewind;
453 // These fields are only meaningful during scanline decodes. 500 // These fields are only meaningful during scanline decodes.
454 SkImageInfo fDstInfo; 501 SkImageInfo fDstInfo;
455 SkCodec::Options fOptions; 502 SkCodec::Options fOptions;
456 int fCurrScanline; 503 int fCurrScanline;
457 504
458 // Methods for scanline decoding. 505 // Methods for scanline decoding.
459 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo, 506 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo,
460 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) { 507 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) {
461 return kUnimplemented; 508 return kUnimplemented;
462 } 509 }
463 510
464 // Naive default version just calls onGetScanlines on temp memory. 511 // Naive default version just calls onGetScanlines on temp memory.
465 virtual SkCodec::Result onSkipScanlines(int countLines) { 512 virtual bool onSkipScanlines(int countLines) {
513 // FIXME (msarett): Make this a pure virtual and always override this.
466 SkAutoMalloc storage(fDstInfo.minRowBytes()); 514 SkAutoMalloc storage(fDstInfo.minRowBytes());
515
467 // Note that we pass 0 to rowBytes so we continue to use the same memory . 516 // Note that we pass 0 to rowBytes so we continue to use the same memory .
468 // Also note that while getScanlines checks that rowBytes is big enough, 517 // Also note that while getScanlines checks that rowBytes is big enough,
469 // onGetScanlines bypasses that check. 518 // onGetScanlines bypasses that check.
470 // Calling the virtual method also means we do not double count 519 // Calling the virtual method also means we do not double count
471 // countLines. 520 // countLines.
472 return this->onGetScanlines(storage.get(), countLines, 0); 521 return (uint32_t) countLines == this->onGetScanlines(storage.get(), coun tLines, 0);
473 } 522 }
474 523
475 virtual SkCodec::Result onGetScanlines(void* dst, int countLines, 524 virtual uint32_t onGetScanlines(void* dst, int countLines, size_t rowBytes) { return 0; }
476 size_t rowBytes) { 525
477 return kUnimplemented; 526 /**
478 } 527 * On an incomplete decode, getPixels() and getScanlines() will call this fu nction
528 * to fill any uinitialized memory.
529 *
530 * @param info Destination image info
531 * @param dst Pointer to the start of destination pixel memory
532 * @param rowBytes Stride length in destination pixel memory
533 * @param zeroInit Indicates if memory is zero initialized
534 * @param linesRequested Number of lines that the client requested
535 * @param linesDecoded Number of lines that were successfully decoded
536 */
537 void fillIncompleteImage(const SkImageInfo& info, void* dst, size_t rowBytes ,
538 ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
479 539
480 }; 540 };
481 #endif // SkCodec_DEFINED 541 #endif // SkCodec_DEFINED
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698