Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |