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

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: Rebase on merged SkCodec and SkScanlineDecoder 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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 * less than 100%. This function can be called *after* decoding to 227 * less than 100%. This function can be called *after* decoding to
228 * 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
229 * is undefined. 229 * is undefined.
230 * FIXME: see skbug.com/3582. 230 * FIXME: see skbug.com/3582.
231 */ 231 */
232 bool reallyHasAlpha() const { 232 bool reallyHasAlpha() const {
233 return this->onReallyHasAlpha(); 233 return this->onReallyHasAlpha();
234 } 234 }
235 235
236 /** 236 /**
237 * On a kIncompleteInput, we will fill any uninitialized scanlines. We allo w the subclass
scroggo 2015/10/01 14:48:31 I think "we" is a little vague here. I think you m
msarett 2015/10/01 18:14:13 The current implementation will always fill for ge
238 * to indicate what value to fill with.
239 *
240 * @param colorType Destination color type.
241 * @param alphaType Destination alpha type.
242 * @return The value with which to fill uninitialized pixels.
243 *
244 * Note that we can interpret the return value as an SkPMColor, a 16-bit 565 color,
245 * an 8-bit gray color, or an 8-bit index into a color table, depending on t he color
246 * type specified in dstInfo.
247 */
248 uint32_t getFillValue(SkColorType colorType, SkAlphaType alphaType) const {
scroggo 2015/10/01 14:48:31 Does this method need to be public?
msarett 2015/10/01 18:14:13 Yes, SkScaledCodec needs to call fCodec->getFillVa
scroggo 2015/10/01 20:48:57 FWIW, crrev.com/1372973002 makes SkScaledCodec a f
msarett 2015/10/01 22:34:51 That seems like a better solution. I am adding Sk
249 return this->onGetFillValue(colorType, alphaType);
250 }
251
252 /**
237 * The remaining functions revolve around decoding scanlines. 253 * The remaining functions revolve around decoding scanlines.
238 */ 254 */
239 255
240 /** 256 /**
241 * Prepare for a scanline decode with the specified options. 257 * Prepare for a scanline decode with the specified options.
242 * 258 *
243 * After this call, this class will be ready to decode the first scanline. 259 * After this call, this class will be ready to decode the first scanline.
244 * 260 *
245 * This must be called in order to call getScanlines or skipScanlines. 261 * This must be called in order to call getScanlines or skipScanlines.
246 * 262 *
(...skipping 26 matching lines...) Expand all
273 /** 289 /**
274 * Write the next countLines scanlines into dst. 290 * Write the next countLines scanlines into dst.
275 * 291 *
276 * Not valid to call before calling startScanlineDecode(). 292 * Not valid to call before calling startScanlineDecode().
277 * 293 *
278 * @param dst Must be non-null, and large enough to hold countLines 294 * @param dst Must be non-null, and large enough to hold countLines
279 * scanlines of size rowBytes. 295 * scanlines of size rowBytes.
280 * @param countLines Number of lines to write. 296 * @param countLines Number of lines to write.
281 * @param rowBytes Number of bytes per row. Must be large enough to hold 297 * @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. 298 * a scanline based on the SkImageInfo used to create this object.
299 * @return the number of lines successfully decoded
scroggo 2015/10/01 14:48:31 Does this fill if some were decoded? What does it
msarett 2015/10/01 18:14:13 Yes it does. Adding the comment.
283 */ 300 */
284 Result getScanlines(void* dst, int countLines, size_t rowBytes); 301 uint32_t getScanlines(void* dst, int countLines, size_t rowBytes);
285 302
286 /** 303 /**
287 * Skip count scanlines. 304 * Skip count scanlines.
288 * 305 *
289 * Not valid to call before calling startScanlineDecode(). 306 * Not valid to call before calling startScanlineDecode().
290 * 307 *
291 * The default version just calls onGetScanlines and discards the dst. 308 * The default version just calls onGetScanlines and discards the dst.
292 * NOTE: If skipped lines are the only lines with alpha, this default 309 * NOTE: If skipped lines are the only lines with alpha, this default
293 * will make reallyHasAlpha return true, when it could have returned 310 * will make reallyHasAlpha return true, when it could have returned
294 * false. 311 * false.
312 *
313 * @return true if the scanlines were successfully skipped
314 * false on failure, possible reasons for failure include:
315 * An incomplete input image stream
316 * Invalid parameters passed to skipScanlines()
scroggo 2015/10/01 14:48:31 What are invalid parameters?
msarett 2015/10/01 18:14:13 Adding more detail to the comment.
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
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. This will be overridden in the case of
368 * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of 390 * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of
369 * kNone_SkScanlineOrder. 391 * kNone_SkScanlineOrder.
370 * 392 *
371 * Results are undefined when not in scanline decoding mode. 393 * Results are undefined when not in scanline decoding mode.
372 */ 394 */
373 int nextScanline() const { 395 int nextScanline() const { return this->nextScanline(fCurrScanline); }
374 return this->onNextScanline(); 396 /**
scroggo 2015/10/01 14:48:31 nit: newline between these methods
msarett 2015/10/01 18:14:13 Done.
375 } 397 * Alternate version that allows the client to specify the srcY value.
398 * The corresponding dstY will be returned, regardless of the value of
399 * fCurrScanline.
400 */
401 int nextScanline(int srcY) const;
scroggo 2015/10/01 14:48:31 I don't think this name is right. My first thought
msarett 2015/10/01 18:14:13 Hmmm yeah, it made more sense for these to have th
376 402
377 protected: 403 protected:
378 SkCodec(const SkImageInfo&, SkStream*); 404 SkCodec(const SkImageInfo&, SkStream*);
379 405
380 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { 406 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
381 // By default, scaling is not supported. 407 // By default, scaling is not supported.
382 return this->getInfo().dimensions(); 408 return this->getInfo().dimensions();
383 } 409 }
384 410
385 virtual SkEncodedFormat onGetEncodedFormat() const = 0; 411 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
386 412
413 /**
414 * @param rowsDecoded When the encoded image stream is incomplete, this func tion
415 * will return kIncompleteInput and rowsDecoded will be s et to
416 * the number of scanlines that were successfully decoded .
417 * This will allow getPixels() to fill the uninitialized memory.
418 */
387 virtual Result onGetPixels(const SkImageInfo& info, 419 virtual Result onGetPixels(const SkImageInfo& info,
388 void* pixels, size_t rowBytes, const Options&, 420 void* pixels, size_t rowBytes, const Options&,
389 SkPMColor ctable[], int* ctableCount) = 0; 421 SkPMColor ctable[], int* ctableCount,
422 int* rowsDecoded) = 0;
390 423
391 virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const { 424 virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const {
392 // By default, subsets are not supported. 425 // By default, subsets are not supported.
393 return false; 426 return false;
394 } 427 }
395 428
396 virtual bool onReallyHasAlpha() const { return false; } 429 virtual bool onReallyHasAlpha() const { return false; }
397 430
398 /** 431 /**
399 * If the stream was previously read, attempt to rewind. 432 * If the stream was previously read, attempt to rewind.
(...skipping 10 matching lines...) Expand all
410 /** 443 /**
411 * Called by rewindIfNeeded, if the stream needed to be rewound. 444 * Called by rewindIfNeeded, if the stream needed to be rewound.
412 * 445 *
413 * Subclasses should do any set up needed after a rewind. 446 * Subclasses should do any set up needed after a rewind.
414 */ 447 */
415 virtual bool onRewind() { 448 virtual bool onRewind() {
416 return true; 449 return true;
417 } 450 }
418 451
419 /** 452 /**
453 * Some subclasses will override this function, but this is a useful default for the color
454 * types that we support. Note that for color types that do not use the ful l 32-bits,
455 * we will simply take the low bits of the fill value.
456 *
457 * kN32_SkColorType: Transparent or Black
458 * kRGB_565_SkColorType: Black
459 * kGray_8_SkColorType: Black
460 * kIndex_8_SkColorType: First color in color table
461 */
462 virtual uint32_t onGetFillValue(SkColorType colorType, SkAlphaType alphaType ) const {
463 return kOpaque_SkAlphaType == alphaType ? SK_ColorBLACK : SK_ColorTRANSP ARENT;
464 }
465
466 /**
420 * Get method for the input stream 467 * Get method for the input stream
421 */ 468 */
422 SkStream* stream() { 469 SkStream* stream() {
423 return fStream.get(); 470 return fStream.get();
424 } 471 }
425 472
426 /** 473 /**
427 * The remaining functions revolve around decoding scanlines. 474 * The remaining functions revolve around decoding scanlines.
428 */ 475 */
429 476
430 /** 477 /**
431 * Most images types will be kTopDown and will not need to override this fu nction. 478 * Most images types will be kTopDown and will not need to override this fu nction.
432 */ 479 */
433 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; } 480 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; }
434 481
435 /** 482 /**
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. 483 * Update the next scanline. Used by interlaced png.
442 */ 484 */
443 void updateNextScanline(int newY) { fCurrScanline = newY; } 485 void updateNextScanline(int newY) { fCurrScanline = newY; }
444 486
445 const SkImageInfo& dstInfo() const { return fDstInfo; } 487 const SkImageInfo& dstInfo() const { return fDstInfo; }
446 488
447 const SkCodec::Options& options() const { return fOptions; } 489 const SkCodec::Options& options() const { return fOptions; }
448 490
449 private: 491 private:
450 const SkImageInfo fSrcInfo; 492 const SkImageInfo fSrcInfo;
451 SkAutoTDelete<SkStream> fStream; 493 SkAutoTDelete<SkStream> fStream;
452 bool fNeedsRewind; 494 bool fNeedsRewind;
453 // These fields are only meaningful during scanline decodes. 495 // These fields are only meaningful during scanline decodes.
454 SkImageInfo fDstInfo; 496 SkImageInfo fDstInfo;
455 SkCodec::Options fOptions; 497 SkCodec::Options fOptions;
456 int fCurrScanline; 498 int fCurrScanline;
457 499
458 // Methods for scanline decoding. 500 // Methods for scanline decoding.
459 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo, 501 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo,
460 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) { 502 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) {
461 return kUnimplemented; 503 return kUnimplemented;
462 } 504 }
463 505
464 // Naive default version just calls onGetScanlines on temp memory. 506 // Naive default version just calls onGetScanlines on temp memory.
465 virtual SkCodec::Result onSkipScanlines(int countLines) { 507 virtual bool onSkipScanlines(int countLines) {
508 // FIXME (msarett): We should not reallocate this memory on every call.
scroggo 2015/10/01 14:48:31 Is the real fix to always override onSkipScanlines
msarett 2015/10/01 18:14:13 Yes I agree that the solution is to always overrid
466 SkAutoMalloc storage(fDstInfo.minRowBytes()); 509 SkAutoMalloc storage(fDstInfo.minRowBytes());
510
467 // Note that we pass 0 to rowBytes so we continue to use the same memory . 511 // 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, 512 // Also note that while getScanlines checks that rowBytes is big enough,
469 // onGetScanlines bypasses that check. 513 // onGetScanlines bypasses that check.
470 // Calling the virtual method also means we do not double count 514 // Calling the virtual method also means we do not double count
471 // countLines. 515 // countLines.
472 return this->onGetScanlines(storage.get(), countLines, 0); 516 return (uint32_t) countLines == this->onGetScanlines(storage.get(), coun tLines, 0);
473 } 517 }
474 518
475 virtual SkCodec::Result onGetScanlines(void* dst, int countLines, 519 virtual uint32_t onGetScanlines(void* dst, int countLines, size_t rowBytes) { return 0; }
476 size_t rowBytes) { 520
477 return kUnimplemented; 521 /**
478 } 522 * On an incomplete decode, getPixels() and getScanlines() will call this fu nction
523 * to fill any uinitialized memory.
524 *
525 * @param info Destination image info
526 * @param dst Destination pixel memory
scroggo 2015/10/01 14:48:31 I think this is different depending on the scanlin
msarett 2015/10/01 18:14:13 In the redesign, this is always a pointer to the s
527 * @param rowBytes Stride length in destination pixel memory
528 * @param zeroInit Indicates if memory is zero initialized
529 * @param linesRequested Number of lines that the client requested
530 * @param linesDecoded Number of lines that were successfully decoded
531 */
532 void fillIncompleteImage(const SkImageInfo& info, void* dst, size_t rowBytes ,
533 ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
479 534
480 }; 535 };
481 #endif // SkCodec_DEFINED 536 #endif // SkCodec_DEFINED
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698