1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkCodec_DEFINED 9 #define SkCodec_DEFINED 10 11 #include "include/codec/SkEncodedOrigin.h" 12 #include "include/core/SkImageInfo.h" 13 #include "include/core/SkPixmap.h" 14 #include "include/core/SkRect.h" 15 #include "include/core/SkRefCnt.h" 16 #include "include/core/SkSize.h" 17 #include "include/core/SkTypes.h" 18 #include "include/core/SkYUVAPixmaps.h" 19 #include "include/private/SkEncodedInfo.h" 20 #include "include/private/base/SkNoncopyable.h" 21 #include "modules/skcms/skcms.h" 22 23 #include <cstddef> 24 #include <memory> 25 #include <tuple> 26 #include <vector> 27 28 class SkAndroidCodec; 29 class SkData; 30 class SkFrameHolder; 31 class SkImage; 32 class SkPngChunkReader; 33 class SkSampler; 34 class SkStream; 35 struct SkGainmapInfo; 36 enum SkAlphaType : int; 37 enum class SkEncodedImageFormat; 38 39 namespace SkCodecAnimation { 40 enum class Blend; 41 enum class DisposalMethod; 42 } 43 44 45 namespace DM { 46 class CodecSrc; 47 } // namespace DM 48 49 /** 50 * Abstraction layer directly on top of an image codec. 51 */ 52 class SK_API SkCodec : SkNoncopyable { 53 public: 54 /** 55 * Minimum number of bytes that must be buffered in SkStream input. 56 * 57 * An SkStream passed to NewFromStream must be able to use this many 58 * bytes to determine the image type. Then the same SkStream must be 59 * passed to the correct decoder to read from the beginning. 60 * 61 * This can be accomplished by implementing peek() to support peeking 62 * this many bytes, or by implementing rewind() to be able to rewind() 63 * after reading this many bytes. 64 */ MinBufferedBytesNeeded()65 static constexpr size_t MinBufferedBytesNeeded() { return 32; } 66 67 /** 68 * Error codes for various SkCodec methods. 69 */ 70 enum Result { 71 /** 72 * General return value for success. 73 */ 74 kSuccess, 75 /** 76 * The input is incomplete. A partial image was generated. 77 */ 78 kIncompleteInput, 79 /** 80 * Like kIncompleteInput, except the input had an error. 81 * 82 * If returned from an incremental decode, decoding cannot continue, 83 * even with more data. 84 */ 85 kErrorInInput, 86 /** 87 * The generator cannot convert to match the request, ignoring 88 * dimensions. 89 */ 90 kInvalidConversion, 91 /** 92 * The generator cannot scale to requested size. 93 */ 94 kInvalidScale, 95 /** 96 * Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes 97 * too small, etc. 98 */ 99 kInvalidParameters, 100 /** 101 * The input did not contain a valid image. 102 */ 103 kInvalidInput, 104 /** 105 * Fulfilling this request requires rewinding the input, which is not 106 * supported for this input. 107 */ 108 kCouldNotRewind, 109 /** 110 * An internal error, such as OOM. 111 */ 112 kInternalError, 113 /** 114 * This method is not implemented by this codec. 115 * FIXME: Perhaps this should be kUnsupported? 116 */ 117 kUnimplemented, 118 }; 119 120 /** 121 * Readable string representing the error code. 122 */ 123 static const char* ResultToString(Result); 124 125 /** 126 * For container formats that contain both still images and image sequences, 127 * instruct the decoder how the output should be selected. (Refer to comments 128 * for each value for more details.) 129 */ 130 enum class SelectionPolicy { 131 /** 132 * If the container format contains both still images and image sequences, 133 * SkCodec should choose one of the still images. This is the default. 134 */ 135 kPreferStillImage, 136 /** 137 * If the container format contains both still images and image sequences, 138 * SkCodec should choose one of the image sequences for animation. 139 */ 140 kPreferAnimation, 141 }; 142 143 /** 144 * If this stream represents an encoded image that we know how to decode, 145 * return an SkCodec that can decode it. Otherwise return NULL. 146 * 147 * As stated above, this call must be able to peek or read 148 * MinBufferedBytesNeeded to determine the correct format, and then start 149 * reading from the beginning. First it will attempt to peek, and it 150 * assumes that if less than MinBufferedBytesNeeded bytes (but more than 151 * zero) are returned, this is because the stream is shorter than this, 152 * so falling back to reading would not provide more data. If peek() 153 * returns zero bytes, this call will instead attempt to read(). This 154 * will require that the stream can be rewind()ed. 155 * 156 * If Result is not NULL, it will be set to either kSuccess if an SkCodec 157 * is returned or a reason for the failure if NULL is returned. 158 * 159 * If SkPngChunkReader is not NULL, take a ref and pass it to libpng if 160 * the image is a png. 161 * 162 * If the SkPngChunkReader is not NULL then: 163 * If the image is not a PNG, the SkPngChunkReader will be ignored. 164 * If the image is a PNG, the SkPngChunkReader will be reffed. 165 * If the PNG has unknown chunks, the SkPngChunkReader will be used 166 * to handle these chunks. SkPngChunkReader will be called to read 167 * any unknown chunk at any point during the creation of the codec 168 * or the decode. Note that if SkPngChunkReader fails to read a 169 * chunk, this could result in a failure to create the codec or a 170 * failure to decode the image. 171 * If the PNG does not contain unknown chunks, the SkPngChunkReader 172 * will not be used or modified. 173 * 174 * If NULL is returned, the stream is deleted immediately. Otherwise, the 175 * SkCodec takes ownership of it, and will delete it when done with it. 176 */ 177 static std::unique_ptr<SkCodec> MakeFromStream( 178 std::unique_ptr<SkStream>, Result* = nullptr, 179 SkPngChunkReader* = nullptr, 180 SelectionPolicy selectionPolicy = SelectionPolicy::kPreferStillImage); 181 182 /** 183 * If this data represents an encoded image that we know how to decode, 184 * return an SkCodec that can decode it. Otherwise return NULL. 185 * 186 * If the SkPngChunkReader is not NULL then: 187 * If the image is not a PNG, the SkPngChunkReader will be ignored. 188 * If the image is a PNG, the SkPngChunkReader will be reffed. 189 * If the PNG has unknown chunks, the SkPngChunkReader will be used 190 * to handle these chunks. SkPngChunkReader will be called to read 191 * any unknown chunk at any point during the creation of the codec 192 * or the decode. Note that if SkPngChunkReader fails to read a 193 * chunk, this could result in a failure to create the codec or a 194 * failure to decode the image. 195 * If the PNG does not contain unknown chunks, the SkPngChunkReader 196 * will not be used or modified. 197 */ 198 static std::unique_ptr<SkCodec> MakeFromData(sk_sp<SkData>, SkPngChunkReader* = nullptr); 199 200 virtual ~SkCodec(); 201 202 /** 203 * Return a reasonable SkImageInfo to decode into. 204 * 205 * If the image has an ICC profile that does not map to an SkColorSpace, 206 * the returned SkImageInfo will use SRGB. 207 */ getInfo()208 SkImageInfo getInfo() const { return fEncodedInfo.makeImageInfo(); } 209 dimensions()210 SkISize dimensions() const { return {fEncodedInfo.width(), fEncodedInfo.height()}; } bounds()211 SkIRect bounds() const { 212 return SkIRect::MakeWH(fEncodedInfo.width(), fEncodedInfo.height()); 213 } 214 215 /** 216 * Return the ICC profile of the encoded data. 217 */ getICCProfile()218 const skcms_ICCProfile* getICCProfile() const { 219 return this->getEncodedInfo().profile(); 220 } 221 222 /** 223 * Returns the image orientation stored in the EXIF data. 224 * If there is no EXIF data, or if we cannot read the EXIF data, returns kTopLeft. 225 */ getOrigin()226 SkEncodedOrigin getOrigin() const { return fOrigin; } 227 228 /** 229 * Return a size that approximately supports the desired scale factor. 230 * The codec may not be able to scale efficiently to the exact scale 231 * factor requested, so return a size that approximates that scale. 232 * The returned value is the codec's suggestion for the closest valid 233 * scale that it can natively support 234 */ getScaledDimensions(float desiredScale)235 SkISize getScaledDimensions(float desiredScale) const { 236 // Negative and zero scales are errors. 237 SkASSERT(desiredScale > 0.0f); 238 if (desiredScale <= 0.0f) { 239 return SkISize::Make(0, 0); 240 } 241 242 // Upscaling is not supported. Return the original size if the client 243 // requests an upscale. 244 if (desiredScale >= 1.0f) { 245 return this->dimensions(); 246 } 247 return this->onGetScaledDimensions(desiredScale); 248 } 249 250 /** 251 * Return (via desiredSubset) a subset which can decoded from this codec, 252 * or false if this codec cannot decode subsets or anything similar to 253 * desiredSubset. 254 * 255 * @param desiredSubset In/out parameter. As input, a desired subset of 256 * the original bounds (as specified by getInfo). If true is returned, 257 * desiredSubset may have been modified to a subset which is 258 * supported. Although a particular change may have been made to 259 * desiredSubset to create something supported, it is possible other 260 * changes could result in a valid subset. 261 * If false is returned, desiredSubset's value is undefined. 262 * @return true if this codec supports decoding desiredSubset (as 263 * returned, potentially modified) 264 */ getValidSubset(SkIRect * desiredSubset)265 bool getValidSubset(SkIRect* desiredSubset) const { 266 return this->onGetValidSubset(desiredSubset); 267 } 268 269 /** 270 * Format of the encoded data. 271 */ getEncodedFormat()272 SkEncodedImageFormat getEncodedFormat() const { return this->onGetEncodedFormat(); } 273 274 /** 275 * Whether or not the memory passed to getPixels is zero initialized. 276 */ 277 enum ZeroInitialized { 278 /** 279 * The memory passed to getPixels is zero initialized. The SkCodec 280 * may take advantage of this by skipping writing zeroes. 281 */ 282 kYes_ZeroInitialized, 283 /** 284 * The memory passed to getPixels has not been initialized to zero, 285 * so the SkCodec must write all zeroes to memory. 286 * 287 * This is the default. It will be used if no Options struct is used. 288 */ 289 kNo_ZeroInitialized, 290 }; 291 292 /** 293 * Additional options to pass to getPixels. 294 */ 295 struct Options { OptionsOptions296 Options() 297 : fZeroInitialized(kNo_ZeroInitialized) 298 , fSubset(nullptr) 299 , fFrameIndex(0) 300 , fPriorFrame(kNoFrame) 301 {} 302 303 ZeroInitialized fZeroInitialized; 304 /** 305 * If not NULL, represents a subset of the original image to decode. 306 * Must be within the bounds returned by getInfo(). 307 * If the EncodedFormat is SkEncodedImageFormat::kWEBP (the only one which 308 * currently supports subsets), the top and left values must be even. 309 * 310 * In getPixels and incremental decode, we will attempt to decode the 311 * exact rectangular subset specified by fSubset. 312 * 313 * In a scanline decode, it does not make sense to specify a subset 314 * top or subset height, since the client already controls which rows 315 * to get and which rows to skip. During scanline decodes, we will 316 * require that the subset top be zero and the subset height be equal 317 * to the full height. We will, however, use the values of 318 * subset left and subset width to decode partial scanlines on calls 319 * to getScanlines(). 320 */ 321 const SkIRect* fSubset; 322 323 /** 324 * The frame to decode. 325 * 326 * Only meaningful for multi-frame images. 327 */ 328 int fFrameIndex; 329 330 /** 331 * If not kNoFrame, the dst already contains the prior frame at this index. 332 * 333 * Only meaningful for multi-frame images. 334 * 335 * If fFrameIndex needs to be blended with a prior frame (as reported by 336 * getFrameInfo[fFrameIndex].fRequiredFrame), the client can set this to 337 * any non-kRestorePrevious frame in [fRequiredFrame, fFrameIndex) to 338 * indicate that that frame is already in the dst. Options.fZeroInitialized 339 * is ignored in this case. 340 * 341 * If set to kNoFrame, the codec will decode any necessary required frame(s) first. 342 */ 343 int fPriorFrame; 344 }; 345 346 /** 347 * Decode into the given pixels, a block of memory of size at 348 * least (info.fHeight - 1) * rowBytes + (info.fWidth * 349 * bytesPerPixel) 350 * 351 * Repeated calls to this function should give the same results, 352 * allowing the PixelRef to be immutable. 353 * 354 * @param info A description of the format (config, size) 355 * expected by the caller. This can simply be identical 356 * to the info returned by getInfo(). 357 * 358 * This contract also allows the caller to specify 359 * different output-configs, which the implementation can 360 * decide to support or not. 361 * 362 * A size that does not match getInfo() implies a request 363 * to scale. If the generator cannot perform this scale, 364 * it will return kInvalidScale. 365 * 366 * If the info contains a non-null SkColorSpace, the codec 367 * will perform the appropriate color space transformation. 368 * 369 * If the caller passes in the SkColorSpace that maps to the 370 * ICC profile reported by getICCProfile(), the color space 371 * transformation is a no-op. 372 * 373 * If the caller passes a null SkColorSpace, no color space 374 * transformation will be done. 375 * 376 * If a scanline decode is in progress, scanline mode will end, requiring the client to call 377 * startScanlineDecode() in order to return to decoding scanlines. 378 * 379 * @return Result kSuccess, or another value explaining the type of failure. 380 */ 381 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*); 382 383 /** 384 * Simplified version of getPixels() that uses the default Options. 385 */ getPixels(const SkImageInfo & info,void * pixels,size_t rowBytes)386 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) { 387 return this->getPixels(info, pixels, rowBytes, nullptr); 388 } 389 390 Result getPixels(const SkPixmap& pm, const Options* opts = nullptr) { 391 return this->getPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), opts); 392 } 393 394 /** 395 * Return an image containing the pixels. 396 */ 397 std::tuple<sk_sp<SkImage>, SkCodec::Result> getImage(const SkImageInfo& info, 398 const Options* opts = nullptr); 399 std::tuple<sk_sp<SkImage>, SkCodec::Result> getImage(); 400 401 /** 402 * If decoding to YUV is supported, this returns true. Otherwise, this 403 * returns false and the caller will ignore output parameter yuvaPixmapInfo. 404 * 405 * @param supportedDataTypes Indicates the data type/planar config combinations that are 406 * supported by the caller. If the generator supports decoding to 407 * YUV(A), but not as a type in supportedDataTypes, this method 408 * returns false. 409 * @param yuvaPixmapInfo Output parameter that specifies the planar configuration, subsampling, 410 * orientation, chroma siting, plane color types, and row bytes. 411 */ 412 bool queryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes, 413 SkYUVAPixmapInfo* yuvaPixmapInfo) const; 414 415 /** 416 * Returns kSuccess, or another value explaining the type of failure. 417 * This always attempts to perform a full decode. To get the planar 418 * configuration without decoding use queryYUVAInfo(). 419 * 420 * @param yuvaPixmaps Contains preallocated pixmaps configured according to a successful call 421 * to queryYUVAInfo(). 422 */ 423 Result getYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps); 424 425 /** 426 * Prepare for an incremental decode with the specified options. 427 * 428 * This may require a rewind. 429 * 430 * If kIncompleteInput is returned, may be called again after more data has 431 * been provided to the source SkStream. 432 * 433 * @param dstInfo Info of the destination. If the dimensions do not match 434 * those of getInfo, this implies a scale. 435 * @param dst Memory to write to. Needs to be large enough to hold the subset, 436 * if present, or the full image as described in dstInfo. 437 * @param options Contains decoding options, including if memory is zero 438 * initialized and whether to decode a subset. 439 * @return Enum representing success or reason for failure. 440 */ 441 Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, 442 const Options*); 443 startIncrementalDecode(const SkImageInfo & dstInfo,void * dst,size_t rowBytes)444 Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes) { 445 return this->startIncrementalDecode(dstInfo, dst, rowBytes, nullptr); 446 } 447 448 /** 449 * Start/continue the incremental decode. 450 * 451 * Not valid to call before a call to startIncrementalDecode() returns 452 * kSuccess. 453 * 454 * If kIncompleteInput is returned, may be called again after more data has 455 * been provided to the source SkStream. 456 * 457 * Unlike getPixels and getScanlines, this does not do any filling. This is 458 * left up to the caller, since they may be skipping lines or continuing the 459 * decode later. In the latter case, they may choose to initialize all lines 460 * first, or only initialize the remaining lines after the first call. 461 * 462 * @param rowsDecoded Optional output variable returning the total number of 463 * lines initialized. Only meaningful if this method returns kIncompleteInput. 464 * Otherwise the implementation may not set it. 465 * Note that some implementations may have initialized this many rows, but 466 * not necessarily finished those rows (e.g. interlaced PNG). This may be 467 * useful for determining what rows the client needs to initialize. 468 * @return kSuccess if all lines requested in startIncrementalDecode have 469 * been completely decoded. kIncompleteInput otherwise. 470 */ 471 Result incrementalDecode(int* rowsDecoded = nullptr) { 472 if (!fStartedIncrementalDecode) { 473 return kInvalidParameters; 474 } 475 return this->onIncrementalDecode(rowsDecoded); 476 } 477 478 /** 479 * The remaining functions revolve around decoding scanlines. 480 */ 481 482 /** 483 * Prepare for a scanline decode with the specified options. 484 * 485 * After this call, this class will be ready to decode the first scanline. 486 * 487 * This must be called in order to call getScanlines or skipScanlines. 488 * 489 * This may require rewinding the stream. 490 * 491 * Not all SkCodecs support this. 492 * 493 * @param dstInfo Info of the destination. If the dimensions do not match 494 * those of getInfo, this implies a scale. 495 * @param options Contains decoding options, including if memory is zero 496 * initialized. 497 * @return Enum representing success or reason for failure. 498 */ 499 Result startScanlineDecode(const SkImageInfo& dstInfo, const Options* options); 500 501 /** 502 * Simplified version of startScanlineDecode() that uses the default Options. 503 */ startScanlineDecode(const SkImageInfo & dstInfo)504 Result startScanlineDecode(const SkImageInfo& dstInfo) { 505 return this->startScanlineDecode(dstInfo, nullptr); 506 } 507 508 /** 509 * Write the next countLines scanlines into dst. 510 * 511 * Not valid to call before calling startScanlineDecode(). 512 * 513 * @param dst Must be non-null, and large enough to hold countLines 514 * scanlines of size rowBytes. 515 * @param countLines Number of lines to write. 516 * @param rowBytes Number of bytes per row. Must be large enough to hold 517 * a scanline based on the SkImageInfo used to create this object. 518 * @return the number of lines successfully decoded. If this value is 519 * less than countLines, this will fill the remaining lines with a 520 * default value. 521 */ 522 int getScanlines(void* dst, int countLines, size_t rowBytes); 523 524 /** 525 * Skip count scanlines. 526 * 527 * Not valid to call before calling startScanlineDecode(). 528 * 529 * The default version just calls onGetScanlines and discards the dst. 530 * NOTE: If skipped lines are the only lines with alpha, this default 531 * will make reallyHasAlpha return true, when it could have returned 532 * false. 533 * 534 * @return true if the scanlines were successfully skipped 535 * false on failure, possible reasons for failure include: 536 * An incomplete input image stream. 537 * Calling this function before calling startScanlineDecode(). 538 * If countLines is less than zero or so large that it moves 539 * the current scanline past the end of the image. 540 */ 541 bool skipScanlines(int countLines); 542 543 /** 544 * The order in which rows are output from the scanline decoder is not the 545 * same for all variations of all image types. This explains the possible 546 * output row orderings. 547 */ 548 enum SkScanlineOrder { 549 /* 550 * By far the most common, this indicates that the image can be decoded 551 * reliably using the scanline decoder, and that rows will be output in 552 * the logical order. 553 */ 554 kTopDown_SkScanlineOrder, 555 556 /* 557 * This indicates that the scanline decoder reliably outputs rows, but 558 * they will be returned in reverse order. If the scanline format is 559 * kBottomUp, the nextScanline() API can be used to determine the actual 560 * y-coordinate of the next output row, but the client is not forced 561 * to take advantage of this, given that it's not too tough to keep 562 * track independently. 563 * 564 * For full image decodes, it is safe to get all of the scanlines at 565 * once, since the decoder will handle inverting the rows as it 566 * decodes. 567 * 568 * For subset decodes and sampling, it is simplest to get and skip 569 * scanlines one at a time, using the nextScanline() API. It is 570 * possible to ask for larger chunks at a time, but this should be used 571 * with caution. As with full image decodes, the decoder will handle 572 * inverting the requested rows, but rows will still be delivered 573 * starting from the bottom of the image. 574 * 575 * Upside down bmps are an example. 576 */ 577 kBottomUp_SkScanlineOrder, 578 }; 579 580 /** 581 * An enum representing the order in which scanlines will be returned by 582 * the scanline decoder. 583 * 584 * This is undefined before startScanlineDecode() is called. 585 */ getScanlineOrder()586 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); } 587 588 /** 589 * Returns the y-coordinate of the next row to be returned by the scanline 590 * decoder. 591 * 592 * This will equal fCurrScanline, except in the case of strangely 593 * encoded image types (bottom-up bmps). 594 * 595 * Results are undefined when not in scanline decoding mode. 596 */ nextScanline()597 int nextScanline() const { return this->outputScanline(fCurrScanline); } 598 599 /** 600 * Returns the output y-coordinate of the row that corresponds to an input 601 * y-coordinate. The input y-coordinate represents where the scanline 602 * is located in the encoded data. 603 * 604 * This will equal inputScanline, except in the case of strangely 605 * encoded image types (bottom-up bmps, interlaced gifs). 606 */ 607 int outputScanline(int inputScanline) const; 608 609 /** 610 * Return the number of frames in the image. 611 * 612 * May require reading through the stream. 613 */ getFrameCount()614 int getFrameCount() { 615 return this->onGetFrameCount(); 616 } 617 618 // Sentinel value used when a frame index implies "no frame": 619 // - FrameInfo::fRequiredFrame set to this value means the frame 620 // is independent. 621 // - Options::fPriorFrame set to this value means no (relevant) prior frame 622 // is residing in dst's memory. 623 static constexpr int kNoFrame = -1; 624 625 // This transitional definition was added in August 2018, and will eventually be removed. 626 #ifdef SK_LEGACY_SKCODEC_NONE_ENUM 627 static constexpr int kNone = kNoFrame; 628 #endif 629 630 /** 631 * Information about individual frames in a multi-framed image. 632 */ 633 struct FrameInfo { 634 /** 635 * The frame that this frame needs to be blended with, or 636 * kNoFrame if this frame is independent (so it can be 637 * drawn over an uninitialized buffer). 638 * 639 * Note that this is the *earliest* frame that can be used 640 * for blending. Any frame from [fRequiredFrame, i) can be 641 * used, unless its fDisposalMethod is kRestorePrevious. 642 */ 643 int fRequiredFrame; 644 645 /** 646 * Number of milliseconds to show this frame. 647 */ 648 int fDuration; 649 650 /** 651 * Whether the end marker for this frame is contained in the stream. 652 * 653 * Note: this does not guarantee that an attempt to decode will be complete. 654 * There could be an error in the stream. 655 */ 656 bool fFullyReceived; 657 658 /** 659 * This is conservative; it will still return non-opaque if e.g. a 660 * color index-based frame has a color with alpha but does not use it. 661 */ 662 SkAlphaType fAlphaType; 663 664 /** 665 * Whether the updated rectangle contains alpha. 666 * 667 * This is conservative; it will still be set to true if e.g. a color 668 * index-based frame has a color with alpha but does not use it. In 669 * addition, it may be set to true, even if the final frame, after 670 * blending, is opaque. 671 */ 672 bool fHasAlphaWithinBounds; 673 674 /** 675 * How this frame should be modified before decoding the next one. 676 */ 677 SkCodecAnimation::DisposalMethod fDisposalMethod; 678 679 /** 680 * How this frame should blend with the prior frame. 681 */ 682 SkCodecAnimation::Blend fBlend; 683 684 /** 685 * The rectangle updated by this frame. 686 * 687 * It may be empty, if the frame does not change the image. It will 688 * always be contained by SkCodec::dimensions(). 689 */ 690 SkIRect fFrameRect; 691 }; 692 693 /** 694 * Return info about a single frame. 695 * 696 * Does not read through the stream, so it should be called after 697 * getFrameCount() to parse any frames that have not already been parsed. 698 * 699 * Only supported by animated (multi-frame) codecs. Note that this is a 700 * property of the codec (the SkCodec subclass), not the image. 701 * 702 * To elaborate, some codecs support animation (e.g. GIF). Others do not 703 * (e.g. BMP). Animated codecs can still represent single frame images. 704 * Calling getFrameInfo(0, etc) will return true for a single frame GIF 705 * even if the overall image is not animated (in that the pixels on screen 706 * do not change over time). When incrementally decoding a GIF image, we 707 * might only know that there's a single frame *so far*. 708 * 709 * For non-animated SkCodec subclasses, it's sufficient but not necessary 710 * for this method to always return false. 711 */ getFrameInfo(int index,FrameInfo * info)712 bool getFrameInfo(int index, FrameInfo* info) const { 713 if (index < 0) { 714 return false; 715 } 716 return this->onGetFrameInfo(index, info); 717 } 718 719 /** 720 * Return info about all the frames in the image. 721 * 722 * May require reading through the stream to determine info about the 723 * frames (including the count). 724 * 725 * As such, future decoding calls may require a rewind. 726 * 727 * This may return an empty vector for non-animated codecs. See the 728 * getFrameInfo(int, FrameInfo*) comment. 729 */ 730 std::vector<FrameInfo> getFrameInfo(); 731 732 static constexpr int kRepetitionCountInfinite = -1; 733 734 /** 735 * Return the number of times to repeat, if this image is animated. This number does not 736 * include the first play through of each frame. For example, a repetition count of 4 means 737 * that each frame is played 5 times and then the animation stops. 738 * 739 * It can return kRepetitionCountInfinite, a negative number, meaning that the animation 740 * should loop forever. 741 * 742 * May require reading the stream to find the repetition count. 743 * 744 * As such, future decoding calls may require a rewind. 745 * 746 * For still (non-animated) image codecs, this will return 0. 747 */ getRepetitionCount()748 int getRepetitionCount() { 749 return this->onGetRepetitionCount(); 750 } 751 752 // Register a decoder at runtime by passing two function pointers: 753 // - peek() to return true if the span of bytes appears to be your encoded format; 754 // - make() to attempt to create an SkCodec from the given stream. 755 // Not thread safe. 756 static void Register( 757 bool (*peek)(const void*, size_t), 758 std::unique_ptr<SkCodec> (*make)(std::unique_ptr<SkStream>, SkCodec::Result*)); 759 760 protected: getEncodedInfo()761 const SkEncodedInfo& getEncodedInfo() const { return fEncodedInfo; } 762 763 using XformFormat = skcms_PixelFormat; 764 765 SkCodec(SkEncodedInfo&&, 766 XformFormat srcFormat, 767 std::unique_ptr<SkStream>, 768 SkEncodedOrigin = kTopLeft_SkEncodedOrigin); 769 770 void setSrcXformFormat(XformFormat pixelFormat); 771 getSrcXformFormat()772 XformFormat getSrcXformFormat() const { 773 return fSrcXformFormat; 774 } 775 onGetGainmapInfo(SkGainmapInfo *,std::unique_ptr<SkStream> *)776 virtual bool onGetGainmapInfo(SkGainmapInfo*, std::unique_ptr<SkStream>*) { return false; } 777 onGetScaledDimensions(float)778 virtual SkISize onGetScaledDimensions(float /*desiredScale*/) const { 779 // By default, scaling is not supported. 780 return this->dimensions(); 781 } 782 783 // FIXME: What to do about subsets?? 784 /** 785 * Subclasses should override if they support dimensions other than the 786 * srcInfo's. 787 */ onDimensionsSupported(const SkISize &)788 virtual bool onDimensionsSupported(const SkISize&) { 789 return false; 790 } 791 792 virtual SkEncodedImageFormat onGetEncodedFormat() const = 0; 793 794 /** 795 * @param rowsDecoded When the encoded image stream is incomplete, this function 796 * will return kIncompleteInput and rowsDecoded will be set to 797 * the number of scanlines that were successfully decoded. 798 * This will allow getPixels() to fill the uninitialized memory. 799 */ 800 virtual Result onGetPixels(const SkImageInfo& info, 801 void* pixels, size_t rowBytes, const Options&, 802 int* rowsDecoded) = 0; 803 onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes &,SkYUVAPixmapInfo *)804 virtual bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&, 805 SkYUVAPixmapInfo*) const { return false; } 806 onGetYUVAPlanes(const SkYUVAPixmaps &)807 virtual Result onGetYUVAPlanes(const SkYUVAPixmaps&) { return kUnimplemented; } 808 onGetValidSubset(SkIRect *)809 virtual bool onGetValidSubset(SkIRect* /*desiredSubset*/) const { 810 // By default, subsets are not supported. 811 return false; 812 } 813 814 /** 815 * If the stream was previously read, attempt to rewind. 816 * 817 * If the stream needed to be rewound, call onRewind. 818 * @returns true if the codec is at the right position and can be used. 819 * false if there was a failure to rewind. 820 * 821 * This is called by getPixels(), getYUV8Planes(), startIncrementalDecode() and 822 * startScanlineDecode(). Subclasses may call if they need to rewind at another time. 823 */ 824 bool SK_WARN_UNUSED_RESULT rewindIfNeeded(); 825 826 /** 827 * Called by rewindIfNeeded, if the stream needed to be rewound. 828 * 829 * Subclasses should do any set up needed after a rewind. 830 */ onRewind()831 virtual bool onRewind() { 832 return true; 833 } 834 835 /** 836 * Get method for the input stream 837 */ stream()838 SkStream* stream() { 839 return fStream.get(); 840 } 841 842 /** 843 * The remaining functions revolve around decoding scanlines. 844 */ 845 846 /** 847 * Most images types will be kTopDown and will not need to override this function. 848 */ onGetScanlineOrder()849 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; } 850 dstInfo()851 const SkImageInfo& dstInfo() const { return fDstInfo; } 852 options()853 const Options& options() const { return fOptions; } 854 855 /** 856 * Returns the number of scanlines that have been decoded so far. 857 * This is unaffected by the SkScanlineOrder. 858 * 859 * Returns -1 if we have not started a scanline decode. 860 */ currScanline()861 int currScanline() const { return fCurrScanline; } 862 863 virtual int onOutputScanline(int inputScanline) const; 864 865 /** 866 * Return whether we can convert to dst. 867 * 868 * Will be called for the appropriate frame, prior to initializing the colorXform. 869 */ 870 virtual bool conversionSupported(const SkImageInfo& dst, bool srcIsOpaque, 871 bool needsColorXform); 872 873 // Some classes never need a colorXform e.g. 874 // - ICO uses its embedded codec's colorXform 875 // - WBMP is just Black/White usesColorXform()876 virtual bool usesColorXform() const { return true; } 877 void applyColorXform(void* dst, const void* src, int count) const; 878 colorXform()879 bool colorXform() const { return fXformTime != kNo_XformTime; } xformOnDecode()880 bool xformOnDecode() const { return fXformTime == kDecodeRow_XformTime; } 881 onGetFrameCount()882 virtual int onGetFrameCount() { 883 return 1; 884 } 885 onGetFrameInfo(int,FrameInfo *)886 virtual bool onGetFrameInfo(int, FrameInfo*) const { 887 return false; 888 } 889 onGetRepetitionCount()890 virtual int onGetRepetitionCount() { 891 return 0; 892 } 893 894 private: 895 const SkEncodedInfo fEncodedInfo; 896 XformFormat fSrcXformFormat; 897 std::unique_ptr<SkStream> fStream; 898 bool fNeedsRewind = false; 899 const SkEncodedOrigin fOrigin; 900 901 SkImageInfo fDstInfo; 902 Options fOptions; 903 904 enum XformTime { 905 kNo_XformTime, 906 kPalette_XformTime, 907 kDecodeRow_XformTime, 908 }; 909 XformTime fXformTime; 910 XformFormat fDstXformFormat; // Based on fDstInfo. 911 skcms_ICCProfile fDstProfile; 912 skcms_AlphaFormat fDstXformAlphaFormat; 913 914 // Only meaningful during scanline decodes. 915 int fCurrScanline = -1; 916 917 bool fStartedIncrementalDecode = false; 918 919 // Allows SkAndroidCodec to call handleFrameIndex (potentially decoding a prior frame and 920 // clearing to transparent) without SkCodec calling it, too. 921 bool fAndroidCodecHandlesFrameIndex = false; 922 923 bool initializeColorXform(const SkImageInfo& dstInfo, SkEncodedInfo::Alpha, bool srcIsOpaque); 924 925 /** 926 * Return whether these dimensions are supported as a scale. 927 * 928 * The codec may choose to cache the information about scale and subset. 929 * Either way, the same information will be passed to onGetPixels/onStart 930 * on success. 931 * 932 * This must return true for a size returned from getScaledDimensions. 933 */ dimensionsSupported(const SkISize & dim)934 bool dimensionsSupported(const SkISize& dim) { 935 return dim == this->dimensions() || this->onDimensionsSupported(dim); 936 } 937 938 /** 939 * For multi-framed images, return the object with information about the frames. 940 */ getFrameHolder()941 virtual const SkFrameHolder* getFrameHolder() const { 942 return nullptr; 943 } 944 945 /** 946 * Check for a valid Options.fFrameIndex, and decode prior frames if necessary. 947 * 948 * If androidCodec is not null, that means this SkCodec is owned by an SkAndroidCodec. In that 949 * case, the Options will be treated as an AndroidOptions, and SkAndroidCodec will be used to 950 * decode a prior frame, if a prior frame is needed. When such an owned SkCodec calls 951 * handleFrameIndex, it will immediately return kSuccess, since SkAndroidCodec already handled 952 * it. 953 */ 954 Result handleFrameIndex(const SkImageInfo&, void* pixels, size_t rowBytes, const Options&, 955 SkAndroidCodec* androidCodec = nullptr); 956 957 // Methods for scanline decoding. onStartScanlineDecode(const SkImageInfo &,const Options &)958 virtual Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/, 959 const Options& /*options*/) { 960 return kUnimplemented; 961 } 962 onStartIncrementalDecode(const SkImageInfo &,void *,size_t,const Options &)963 virtual Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t, 964 const Options&) { 965 return kUnimplemented; 966 } 967 onIncrementalDecode(int *)968 virtual Result onIncrementalDecode(int*) { 969 return kUnimplemented; 970 } 971 972 onSkipScanlines(int)973 virtual bool onSkipScanlines(int /*countLines*/) { return false; } 974 onGetScanlines(void *,int,size_t)975 virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; } 976 977 /** 978 * On an incomplete decode, getPixels() and getScanlines() will call this function 979 * to fill any uinitialized memory. 980 * 981 * @param dstInfo Contains the destination color type 982 * Contains the destination alpha type 983 * Contains the destination width 984 * The height stored in this info is unused 985 * @param dst Pointer to the start of destination pixel memory 986 * @param rowBytes Stride length in destination pixel memory 987 * @param zeroInit Indicates if memory is zero initialized 988 * @param linesRequested Number of lines that the client requested 989 * @param linesDecoded Number of lines that were successfully decoded 990 */ 991 void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, 992 ZeroInitialized zeroInit, int linesRequested, int linesDecoded); 993 994 /** 995 * Return an object which will allow forcing scanline decodes to sample in X. 996 * 997 * May create a sampler, if one is not currently being used. Otherwise, does 998 * not affect ownership. 999 * 1000 * Only valid during scanline decoding or incremental decoding. 1001 */ getSampler(bool)1002 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; } 1003 1004 friend class DM::CodecSrc; // for fillIncompleteImage 1005 friend class SkSampledCodec; 1006 friend class SkIcoCodec; 1007 friend class SkAndroidCodec; // for fEncodedInfo 1008 }; 1009 #endif // SkCodec_DEFINED 1010