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

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: Use aligned memory in swizzler test 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
« no previous file with comments | « gyp/tools.gyp ('k') | include/codec/SkScaledCodec.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 /** 125 /**
126 * The input did not contain a valid image. 126 * The input did not contain a valid image.
127 */ 127 */
128 kInvalidInput, 128 kInvalidInput,
129 /** 129 /**
130 * Fulfilling this request requires rewinding the input, which is not 130 * Fulfilling this request requires rewinding the input, which is not
131 * supported for this input. 131 * supported for this input.
132 */ 132 */
133 kCouldNotRewind, 133 kCouldNotRewind,
134 /** 134 /**
135 * startScanlineDecode() was not called before calling getScanlines.
136 */
137 kScanlineDecodingNotStarted,
138 /**
139 * This method is not implemented by this codec. 135 * This method is not implemented by this codec.
140 * FIXME: Perhaps this should be kUnsupported? 136 * FIXME: Perhaps this should be kUnsupported?
141 */ 137 */
142 kUnimplemented, 138 kUnimplemented,
143 }; 139 };
144 140
145 /** 141 /**
146 * Whether or not the memory passed to getPixels is zero initialized. 142 * Whether or not the memory passed to getPixels is zero initialized.
147 */ 143 */
148 enum ZeroInitialized { 144 enum ZeroInitialized {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 /** 270 /**
275 * Write the next countLines scanlines into dst. 271 * Write the next countLines scanlines into dst.
276 * 272 *
277 * Not valid to call before calling startScanlineDecode(). 273 * Not valid to call before calling startScanlineDecode().
278 * 274 *
279 * @param dst Must be non-null, and large enough to hold countLines 275 * @param dst Must be non-null, and large enough to hold countLines
280 * scanlines of size rowBytes. 276 * scanlines of size rowBytes.
281 * @param countLines Number of lines to write. 277 * @param countLines Number of lines to write.
282 * @param rowBytes Number of bytes per row. Must be large enough to hold 278 * @param rowBytes Number of bytes per row. Must be large enough to hold
283 * a scanline based on the SkImageInfo used to create this object. 279 * a scanline based on the SkImageInfo used to create this object.
280 * @return the number of lines successfully decoded. If this value is
281 * less than countLines, this will fill the remaining lines with a
282 * default value.
284 */ 283 */
285 Result getScanlines(void* dst, int countLines, size_t rowBytes); 284 int getScanlines(void* dst, int countLines, size_t rowBytes);
286 285
287 /** 286 /**
288 * Skip count scanlines. 287 * Skip count scanlines.
289 * 288 *
290 * Not valid to call before calling startScanlineDecode(). 289 * Not valid to call before calling startScanlineDecode().
291 * 290 *
292 * The default version just calls onGetScanlines and discards the dst. 291 * The default version just calls onGetScanlines and discards the dst.
293 * NOTE: If skipped lines are the only lines with alpha, this default 292 * NOTE: If skipped lines are the only lines with alpha, this default
294 * will make reallyHasAlpha return true, when it could have returned 293 * will make reallyHasAlpha return true, when it could have returned
295 * false. 294 * false.
295 *
296 * @return true if the scanlines were successfully skipped
297 * false on failure, possible reasons for failure include:
298 * An incomplete input image stream.
299 * Calling this function before calling startScanlineDecode().
300 * If countLines is less than zero or so large that it moves
301 * the current scanline past the end of the image.
296 */ 302 */
297 Result skipScanlines(int countLines); 303 bool skipScanlines(int countLines);
298 304
299 /** 305 /**
300 * The order in which rows are output from the scanline decoder is not the 306 * The order in which rows are output from the scanline decoder is not the
301 * same for all variations of all image types. This explains the possible 307 * same for all variations of all image types. This explains the possible
302 * output row orderings. 308 * output row orderings.
303 */ 309 */
304 enum SkScanlineOrder { 310 enum SkScanlineOrder {
305 /* 311 /*
306 * By far the most common, this indicates that the image can be decoded 312 * By far the most common, this indicates that the image can be decoded
307 * reliably using the scanline decoder, and that rows will be output in 313 * reliably using the scanline decoder, and that rows will be output in
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 }; 364 };
359 365
360 /** 366 /**
361 * An enum representing the order in which scanlines will be returned by 367 * An enum representing the order in which scanlines will be returned by
362 * the scanline decoder. 368 * the scanline decoder.
363 */ 369 */
364 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; } 370 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; }
365 371
366 /** 372 /**
367 * Returns the y-coordinate of the next row to be returned by the scanline 373 * Returns the y-coordinate of the next row to be returned by the scanline
368 * decoder. This will be overridden in the case of 374 * decoder.
369 * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of 375 *
370 * kNone_SkScanlineOrder. 376 * This will equal fCurrScanline, except in the case of strangely
377 * encoded image types (bottom-up bmps, interlaced gifs).
371 * 378 *
372 * Results are undefined when not in scanline decoding mode. 379 * Results are undefined when not in scanline decoding mode.
373 */ 380 */
374 int nextScanline() const { 381 int nextScanline() const { return this->outputScanline(fCurrScanline); }
375 return this->onNextScanline(); 382
376 } 383 /**
384 * Returns the output y-coordinate of the row that corresponds to an input
385 * y-coordinate. The input y-coordinate represents where the scanline
386 * is located in the encoded data.
387 *
388 * This will equal inputScanline, except in the case of strangely
389 * encoded image types (bottom-up bmps, interlaced gifs).
390 */
391 int outputScanline(int inputScanline) const;
377 392
378 protected: 393 protected:
379 SkCodec(const SkImageInfo&, SkStream*); 394 SkCodec(const SkImageInfo&, SkStream*);
380 395
381 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { 396 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
382 // By default, scaling is not supported. 397 // By default, scaling is not supported.
383 return this->getInfo().dimensions(); 398 return this->getInfo().dimensions();
384 } 399 }
385 400
386 // FIXME: What to do about subsets?? 401 // FIXME: What to do about subsets??
387 /** 402 /**
388 * Subclasses should override if they support dimensions other than the 403 * Subclasses should override if they support dimensions other than the
389 * srcInfo's. 404 * srcInfo's.
390 */ 405 */
391 virtual bool onDimensionsSupported(const SkISize&) { 406 virtual bool onDimensionsSupported(const SkISize&) {
392 return false; 407 return false;
393 } 408 }
394 409
395 virtual SkEncodedFormat onGetEncodedFormat() const = 0; 410 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
396 411
412 /**
413 * @param rowsDecoded When the encoded image stream is incomplete, this func tion
414 * will return kIncompleteInput and rowsDecoded will be s et to
415 * the number of scanlines that were successfully decoded .
416 * This will allow getPixels() to fill the uninitialized memory.
417 */
397 virtual Result onGetPixels(const SkImageInfo& info, 418 virtual Result onGetPixels(const SkImageInfo& info,
398 void* pixels, size_t rowBytes, const Options&, 419 void* pixels, size_t rowBytes, const Options&,
399 SkPMColor ctable[], int* ctableCount) = 0; 420 SkPMColor ctable[], int* ctableCount,
421 int* rowsDecoded) = 0;
400 422
401 virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const { 423 virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const {
402 // By default, subsets are not supported. 424 // By default, subsets are not supported.
403 return false; 425 return false;
404 } 426 }
405 427
406 virtual bool onReallyHasAlpha() const { return false; } 428 virtual bool onReallyHasAlpha() const { return false; }
407 429
408 /** 430 /**
409 * If the stream was previously read, attempt to rewind. 431 * If the stream was previously read, attempt to rewind.
(...skipping 10 matching lines...) Expand all
420 /** 442 /**
421 * Called by rewindIfNeeded, if the stream needed to be rewound. 443 * Called by rewindIfNeeded, if the stream needed to be rewound.
422 * 444 *
423 * Subclasses should do any set up needed after a rewind. 445 * Subclasses should do any set up needed after a rewind.
424 */ 446 */
425 virtual bool onRewind() { 447 virtual bool onRewind() {
426 return true; 448 return true;
427 } 449 }
428 450
429 /** 451 /**
452 * On an incomplete input, getPixels() and getScanlines() will fill any unin itialized
453 * scanlines. This allows the subclass to indicate what value to fill with.
454 *
455 * @param colorType Destination color type.
456 * @param alphaType Destination alpha type.
457 * @return The value with which to fill uninitialized pixels.
458 *
459 * Note that we can interpret the return value as an SkPMColor, a 16-bit 565 color,
460 * an 8-bit gray color, or an 8-bit index into a color table, depending on t he color
461 * type.
462 */
463 uint32_t getFillValue(SkColorType colorType, SkAlphaType alphaType) const {
464 return this->onGetFillValue(colorType, alphaType);
465 }
466
467 /**
468 * Some subclasses will override this function, but this is a useful default for the color
469 * types that we support. Note that for color types that do not use the ful l 32-bits,
470 * we will simply take the low bits of the fill value.
471 *
472 * kN32_SkColorType: Transparent or Black
473 * kRGB_565_SkColorType: Black
474 * kGray_8_SkColorType: Black
475 * kIndex_8_SkColorType: First color in color table
476 */
477 virtual uint32_t onGetFillValue(SkColorType colorType, SkAlphaType alphaType ) const {
478 return kOpaque_SkAlphaType == alphaType ? SK_ColorBLACK : SK_ColorTRANSP ARENT;
479 }
480
481 /**
430 * Get method for the input stream 482 * Get method for the input stream
431 */ 483 */
432 SkStream* stream() { 484 SkStream* stream() {
433 return fStream.get(); 485 return fStream.get();
434 } 486 }
435 487
436 /** 488 /**
437 * The remaining functions revolve around decoding scanlines. 489 * The remaining functions revolve around decoding scanlines.
438 */ 490 */
439 491
440 /** 492 /**
441 * Most images types will be kTopDown and will not need to override this fu nction. 493 * Most images types will be kTopDown and will not need to override this fu nction.
442 */ 494 */
443 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; } 495 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; }
444 496
445 /** 497 /**
446 * Most images will be kTopDown and will not need to override this function .
447 */
448 virtual int onNextScanline() const { return fCurrScanline; }
449
450 /**
451 * Update the next scanline. Used by interlaced png. 498 * Update the next scanline. Used by interlaced png.
452 */ 499 */
453 void updateNextScanline(int newY) { fCurrScanline = newY; } 500 void updateNextScanline(int newY) { fCurrScanline = newY; }
454 501
455 const SkImageInfo& dstInfo() const { return fDstInfo; } 502 const SkImageInfo& dstInfo() const { return fDstInfo; }
456 503
457 const SkCodec::Options& options() const { return fOptions; } 504 const SkCodec::Options& options() const { return fOptions; }
458 505
506 virtual int onOutputScanline(int inputScanline) const;
507
459 private: 508 private:
460 const SkImageInfo fSrcInfo; 509 const SkImageInfo fSrcInfo;
461 SkAutoTDelete<SkStream> fStream; 510 SkAutoTDelete<SkStream> fStream;
462 bool fNeedsRewind; 511 bool fNeedsRewind;
463 // These fields are only meaningful during scanline decodes. 512 // These fields are only meaningful during scanline decodes.
464 SkImageInfo fDstInfo; 513 SkImageInfo fDstInfo;
465 SkCodec::Options fOptions; 514 SkCodec::Options fOptions;
466 int fCurrScanline; 515 int fCurrScanline;
467 516
468 /** 517 /**
469 * Return whether these dimensions are supported as a scale. 518 * Return whether these dimensions are supported as a scale.
470 * 519 *
471 * The codec may choose to cache the information about scale and subset. 520 * The codec may choose to cache the information about scale and subset.
472 * Either way, the same information will be passed to onGetPixels/onStart 521 * Either way, the same information will be passed to onGetPixels/onStart
473 * on success. 522 * on success.
474 * 523 *
475 * This must return true for a size returned from getScaledDimensions. 524 * This must return true for a size returned from getScaledDimensions.
476 */ 525 */
477 bool dimensionsSupported(const SkISize& dim) { 526 bool dimensionsSupported(const SkISize& dim) {
478 return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim); 527 return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim);
479 } 528 }
480 529
481 // Methods for scanline decoding. 530 // Methods for scanline decoding.
482 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo, 531 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo,
483 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) { 532 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) {
484 return kUnimplemented; 533 return kUnimplemented;
485 } 534 }
486 535
487 // Naive default version just calls onGetScanlines on temp memory. 536 // Naive default version just calls onGetScanlines on temp memory.
488 virtual SkCodec::Result onSkipScanlines(int countLines) { 537 virtual bool onSkipScanlines(int countLines) {
538 // FIXME (msarett): Make this a pure virtual and always override this.
489 SkAutoMalloc storage(fDstInfo.minRowBytes()); 539 SkAutoMalloc storage(fDstInfo.minRowBytes());
540
490 // Note that we pass 0 to rowBytes so we continue to use the same memory . 541 // Note that we pass 0 to rowBytes so we continue to use the same memory .
491 // Also note that while getScanlines checks that rowBytes is big enough, 542 // Also note that while getScanlines checks that rowBytes is big enough,
492 // onGetScanlines bypasses that check. 543 // onGetScanlines bypasses that check.
493 // Calling the virtual method also means we do not double count 544 // Calling the virtual method also means we do not double count
494 // countLines. 545 // countLines.
495 return this->onGetScanlines(storage.get(), countLines, 0); 546 return countLines == this->onGetScanlines(storage.get(), countLines, 0);
496 } 547 }
497 548
498 virtual SkCodec::Result onGetScanlines(void* dst, int countLines, 549 virtual int onGetScanlines(void* dst, int countLines, size_t rowBytes) { ret urn 0; }
499 size_t rowBytes) { 550
500 return kUnimplemented; 551 /**
501 } 552 * On an incomplete decode, getPixels() and getScanlines() will call this fu nction
553 * to fill any uinitialized memory.
554 *
555 * @param dstInfo Contains the destination color type
556 * Contains the destination alpha type
557 * Contains the destination width
558 * The height stored in this info is unused
559 * @param dst Pointer to the start of destination pixel memory
560 * @param rowBytes Stride length in destination pixel memory
561 * @param zeroInit Indicates if memory is zero initialized
562 * @param linesRequested Number of lines that the client requested
563 * @param linesDecoded Number of lines that were successfully decoded
564 */
565 void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBy tes,
566 ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
502 567
503 /** 568 /**
504 * Return an object which will allow forcing scanline decodes to sample in X. 569 * Return an object which will allow forcing scanline decodes to sample in X.
505 * 570 *
506 * May create a sampler, if one is not currently being used. Otherwise, doe s 571 * May create a sampler, if one is not currently being used. Otherwise, doe s
507 * not affect ownership. 572 * not affect ownership.
508 * 573 *
509 * Only valid during scanline decoding. 574 * Only valid during scanline decoding.
510 */ 575 */
511 virtual SkSampler* getSampler() { return nullptr; } 576 virtual SkSampler* getSampler(bool createIfNecessary) { return nullptr; }
512 577
513 // Needed to call getSampler and dimensionsSupported.
514 friend class SkScaledCodec; 578 friend class SkScaledCodec;
515 }; 579 };
516 #endif // SkCodec_DEFINED 580 #endif // SkCodec_DEFINED
OLDNEW
« no previous file with comments | « gyp/tools.gyp ('k') | include/codec/SkScaledCodec.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698