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