| 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 |
| 11 #include "../private/SkTemplates.h" | 11 #include "../private/SkTemplates.h" |
| 12 #include "SkColor.h" | 12 #include "SkColor.h" |
| 13 #include "SkEncodedFormat.h" | 13 #include "SkEncodedFormat.h" |
| 14 #include "SkEncodedInfo.h" | 14 #include "SkEncodedInfo.h" |
| 15 #include "SkImageInfo.h" | 15 #include "SkImageInfo.h" |
| 16 #include "SkSize.h" | 16 #include "SkSize.h" |
| 17 #include "SkStream.h" | 17 #include "SkStream.h" |
| 18 #include "SkTypes.h" | 18 #include "SkTypes.h" |
| 19 #include "SkYUVSizeInfo.h" | 19 #include "SkYUVSizeInfo.h" |
| 20 | 20 |
| 21 #include <vector> |
| 22 |
| 21 class SkColorSpace; | 23 class SkColorSpace; |
| 22 class SkData; | 24 class SkData; |
| 23 class SkPngChunkReader; | 25 class SkPngChunkReader; |
| 24 class SkSampler; | 26 class SkSampler; |
| 25 | 27 |
| 26 namespace DM { | 28 namespace DM { |
| 27 class CodecSrc; | 29 class CodecSrc; |
| 28 class ColorCodecSrc; | 30 class ColorCodecSrc; |
| 29 } | 31 } |
| 30 class ColorCodecBench; | 32 class ColorCodecBench; |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 */ | 215 */ |
| 214 kCouldNotRewind, | 216 kCouldNotRewind, |
| 215 /** | 217 /** |
| 216 * This method is not implemented by this codec. | 218 * This method is not implemented by this codec. |
| 217 * FIXME: Perhaps this should be kUnsupported? | 219 * FIXME: Perhaps this should be kUnsupported? |
| 218 */ | 220 */ |
| 219 kUnimplemented, | 221 kUnimplemented, |
| 220 }; | 222 }; |
| 221 | 223 |
| 222 /** | 224 /** |
| 225 * Additional options that only apply to multiframe images. |
| 226 */ |
| 227 struct MultiFrameOptions { |
| 228 MultiFrameOptions() |
| 229 : fIndex(0) |
| 230 , fHasPriorFrame(false) |
| 231 {} |
| 232 |
| 233 /** |
| 234 * The frame to decode. |
| 235 */ |
| 236 size_t fIndex; |
| 237 |
| 238 /** |
| 239 * If true, the dst already contains the prior frame. |
| 240 * |
| 241 * If fIndex needs to be blended with a prior frame (as reported by |
| 242 * getFrameInfo[fIndex].fRequiredFrame), the client can set this to |
| 243 * either true or false: |
| 244 * |
| 245 * true means that the prior frame is already in the dst, and this |
| 246 * codec only needs to decode fIndex and blend it with the dst. |
| 247 * Options.fZeroInitialized is ignored in this case. |
| 248 * |
| 249 * false means that the dst does not contain the prior frame, so this |
| 250 * codec needs to first decode the prior frame (which in turn may need |
| 251 * to decode its prior frame). |
| 252 */ |
| 253 bool fHasPriorFrame; |
| 254 }; |
| 255 |
| 256 /** |
| 223 * Whether or not the memory passed to getPixels is zero initialized. | 257 * Whether or not the memory passed to getPixels is zero initialized. |
| 224 */ | 258 */ |
| 225 enum ZeroInitialized { | 259 enum ZeroInitialized { |
| 226 /** | 260 /** |
| 227 * The memory passed to getPixels is zero initialized. The SkCodec | 261 * The memory passed to getPixels is zero initialized. The SkCodec |
| 228 * may take advantage of this by skipping writing zeroes. | 262 * may take advantage of this by skipping writing zeroes. |
| 229 */ | 263 */ |
| 230 kYes_ZeroInitialized, | 264 kYes_ZeroInitialized, |
| 231 /** | 265 /** |
| 232 * The memory passed to getPixels has not been initialized to zero, | 266 * The memory passed to getPixels has not been initialized to zero, |
| 233 * so the SkCodec must write all zeroes to memory. | 267 * so the SkCodec must write all zeroes to memory. |
| 234 * | 268 * |
| 235 * This is the default. It will be used if no Options struct is used. | 269 * This is the default. It will be used if no Options struct is used. |
| 236 */ | 270 */ |
| 237 kNo_ZeroInitialized, | 271 kNo_ZeroInitialized, |
| 238 }; | 272 }; |
| 239 | 273 |
| 240 /** | 274 /** |
| 241 * Additional options to pass to getPixels. | 275 * Additional options to pass to getPixels. |
| 242 */ | 276 */ |
| 243 struct Options { | 277 struct Options { |
| 244 Options() | 278 Options() |
| 245 : fZeroInitialized(kNo_ZeroInitialized) | 279 : fZeroInitialized(kNo_ZeroInitialized) |
| 246 , fSubset(NULL) | 280 , fSubset(nullptr) |
| 281 , fFrameOptions(nullptr) |
| 247 {} | 282 {} |
| 248 | 283 |
| 249 ZeroInitialized fZeroInitialized; | 284 ZeroInitialized fZeroInitialized; |
| 250 /** | 285 /** |
| 251 * If not NULL, represents a subset of the original image to decode. | 286 * If not NULL, represents a subset of the original image to decode. |
| 252 * Must be within the bounds returned by getInfo(). | 287 * Must be within the bounds returned by getInfo(). |
| 253 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which | 288 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which |
| 254 * currently supports subsets), the top and left values must be even. | 289 * currently supports subsets), the top and left values must be even. |
| 255 * | 290 * |
| 256 * In getPixels and incremental decode, we will attempt to decode the | 291 * In getPixels and incremental decode, we will attempt to decode the |
| 257 * exact rectangular subset specified by fSubset. | 292 * exact rectangular subset specified by fSubset. |
| 258 * | 293 * |
| 259 * In a scanline decode, it does not make sense to specify a subset | 294 * In a scanline decode, it does not make sense to specify a subset |
| 260 * top or subset height, since the client already controls which rows | 295 * top or subset height, since the client already controls which rows |
| 261 * to get and which rows to skip. During scanline decodes, we will | 296 * to get and which rows to skip. During scanline decodes, we will |
| 262 * require that the subset top be zero and the subset height be equal | 297 * require that the subset top be zero and the subset height be equal |
| 263 * to the full height. We will, however, use the values of | 298 * to the full height. We will, however, use the values of |
| 264 * subset left and subset width to decode partial scanlines on calls | 299 * subset left and subset width to decode partial scanlines on calls |
| 265 * to getScanlines(). | 300 * to getScanlines(). |
| 266 */ | 301 */ |
| 267 SkIRect* fSubset; | 302 const SkIRect* fSubset; |
| 303 |
| 304 /** |
| 305 * Options that are only relevant for multi-frame images. |
| 306 * |
| 307 * Unowned pointer. |
| 308 */ |
| 309 const MultiFrameOptions* fFrameOptions; |
| 268 }; | 310 }; |
| 269 | 311 |
| 270 /** | 312 /** |
| 271 * Decode into the given pixels, a block of memory of size at | 313 * Decode into the given pixels, a block of memory of size at |
| 272 * least (info.fHeight - 1) * rowBytes + (info.fWidth * | 314 * least (info.fHeight - 1) * rowBytes + (info.fWidth * |
| 273 * bytesPerPixel) | 315 * bytesPerPixel) |
| 274 * | 316 * |
| 275 * Repeated calls to this function should give the same results, | 317 * Repeated calls to this function should give the same results, |
| 276 * allowing the PixelRef to be immutable. | 318 * allowing the PixelRef to be immutable. |
| 277 * | 319 * |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 * For subset decodes and sampling, it is simplest to get and skip | 557 * For subset decodes and sampling, it is simplest to get and skip |
| 516 * scanlines one at a time, using the nextScanline() API. It is | 558 * scanlines one at a time, using the nextScanline() API. It is |
| 517 * possible to ask for larger chunks at a time, but this should be used | 559 * possible to ask for larger chunks at a time, but this should be used |
| 518 * with caution. As with full image decodes, the decoder will handle | 560 * with caution. As with full image decodes, the decoder will handle |
| 519 * inverting the requested rows, but rows will still be delivered | 561 * inverting the requested rows, but rows will still be delivered |
| 520 * starting from the bottom of the image. | 562 * starting from the bottom of the image. |
| 521 * | 563 * |
| 522 * Upside down bmps are an example. | 564 * Upside down bmps are an example. |
| 523 */ | 565 */ |
| 524 kBottomUp_SkScanlineOrder, | 566 kBottomUp_SkScanlineOrder, |
| 525 | |
| 526 /* | |
| 527 * This indicates that the scanline decoder reliably outputs rows, but | |
| 528 * they will not be in logical order. If the scanline format is | |
| 529 * kOutOfOrder, the nextScanline() API should be used to determine the | |
| 530 * actual y-coordinate of the next output row. | |
| 531 * | |
| 532 * For this scanline ordering, it is advisable to get and skip | |
| 533 * scanlines one at a time. | |
| 534 * | |
| 535 * Interlaced gifs are an example. | |
| 536 */ | |
| 537 kOutOfOrder_SkScanlineOrder, | |
| 538 }; | 567 }; |
| 539 | 568 |
| 540 /** | 569 /** |
| 541 * An enum representing the order in which scanlines will be returned by | 570 * An enum representing the order in which scanlines will be returned by |
| 542 * the scanline decoder. | 571 * the scanline decoder. |
| 543 * | 572 * |
| 544 * This is undefined before startScanlineDecode() is called. | 573 * This is undefined before startScanlineDecode() is called. |
| 545 */ | 574 */ |
| 546 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder()
; } | 575 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder()
; } |
| 547 | 576 |
| 548 /** | 577 /** |
| 549 * Returns the y-coordinate of the next row to be returned by the scanline | 578 * Returns the y-coordinate of the next row to be returned by the scanline |
| 550 * decoder. | 579 * decoder. |
| 551 * | 580 * |
| 552 * This will equal fCurrScanline, except in the case of strangely | 581 * This will equal fCurrScanline, except in the case of strangely |
| 553 * encoded image types (bottom-up bmps, interlaced gifs). | 582 * encoded image types (bottom-up bmps). |
| 554 * | 583 * |
| 555 * Results are undefined when not in scanline decoding mode. | 584 * Results are undefined when not in scanline decoding mode. |
| 556 */ | 585 */ |
| 557 int nextScanline() const { return this->outputScanline(fCurrScanline); } | 586 int nextScanline() const { return this->outputScanline(fCurrScanline); } |
| 558 | 587 |
| 559 /** | 588 /** |
| 560 * Returns the output y-coordinate of the row that corresponds to an input | 589 * Returns the output y-coordinate of the row that corresponds to an input |
| 561 * y-coordinate. The input y-coordinate represents where the scanline | 590 * y-coordinate. The input y-coordinate represents where the scanline |
| 562 * is located in the encoded data. | 591 * is located in the encoded data. |
| 563 * | 592 * |
| 564 * This will equal inputScanline, except in the case of strangely | 593 * This will equal inputScanline, except in the case of strangely |
| 565 * encoded image types (bottom-up bmps, interlaced gifs). | 594 * encoded image types (bottom-up bmps, interlaced gifs). |
| 566 */ | 595 */ |
| 567 int outputScanline(int inputScanline) const; | 596 int outputScanline(int inputScanline) const; |
| 568 | 597 |
| 598 // The required frame for an independent frame is marked as |
| 599 // kIndependentFrame. |
| 600 static constexpr size_t kIndependentFrame = static_cast<size_t>(-1); |
| 601 |
| 602 /** |
| 603 * Information about individual frames in a multi-framed image. |
| 604 */ |
| 605 struct FrameInfo { |
| 606 /** |
| 607 * The frame that this frame needs to be blended with, or |
| 608 * kIndependentFrame. |
| 609 */ |
| 610 size_t fRequiredFrame; |
| 611 |
| 612 /** |
| 613 * Number of milliseconds to show this frame. |
| 614 */ |
| 615 size_t fDuration; |
| 616 }; |
| 617 |
| 618 /** |
| 619 * Return info about the frames in the image. |
| 620 * |
| 621 * May require reading through the stream to determine the number of |
| 622 * frames. |
| 623 * |
| 624 * As such, future decoding calls may require a rewind. |
| 625 * |
| 626 * For single-frame images, this will return an empty vector. |
| 627 */ |
| 628 std::vector<FrameInfo> getFrameInfo() { |
| 629 return this->onGetFrameInfo(); |
| 630 } |
| 631 |
| 569 protected: | 632 protected: |
| 570 /** | 633 /** |
| 571 * Takes ownership of SkStream* | 634 * Takes ownership of SkStream* |
| 572 */ | 635 */ |
| 573 SkCodec(int width, | 636 SkCodec(int width, |
| 574 int height, | 637 int height, |
| 575 const SkEncodedInfo&, | 638 const SkEncodedInfo&, |
| 576 SkStream*, | 639 SkStream*, |
| 577 sk_sp<SkColorSpace> = nullptr, | 640 sk_sp<SkColorSpace> = nullptr, |
| 578 Origin = kTopLeft_Origin); | 641 Origin = kTopLeft_Origin); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 /** | 762 /** |
| 700 * Returns the number of scanlines that have been decoded so far. | 763 * Returns the number of scanlines that have been decoded so far. |
| 701 * This is unaffected by the SkScanlineOrder. | 764 * This is unaffected by the SkScanlineOrder. |
| 702 * | 765 * |
| 703 * Returns -1 if we have not started a scanline decode. | 766 * Returns -1 if we have not started a scanline decode. |
| 704 */ | 767 */ |
| 705 int currScanline() const { return fCurrScanline; } | 768 int currScanline() const { return fCurrScanline; } |
| 706 | 769 |
| 707 virtual int onOutputScanline(int inputScanline) const; | 770 virtual int onOutputScanline(int inputScanline) const; |
| 708 | 771 |
| 772 virtual std::vector<FrameInfo> onGetFrameInfo() { |
| 773 // empty vector - this is not animated. |
| 774 return {}; |
| 775 } |
| 776 |
| 709 /** | 777 /** |
| 710 * Used for testing with qcms. | 778 * Used for testing with qcms. |
| 711 * FIXME: Remove this when we are done comparing with qcms. | 779 * FIXME: Remove this when we are done comparing with qcms. |
| 712 */ | 780 */ |
| 713 virtual sk_sp<SkData> getICCData() const { return nullptr; } | 781 virtual sk_sp<SkData> getICCData() const { return nullptr; } |
| 714 private: | 782 private: |
| 715 const SkEncodedInfo fEncodedInfo; | 783 const SkEncodedInfo fEncodedInfo; |
| 716 const SkImageInfo fSrcInfo; | 784 const SkImageInfo fSrcInfo; |
| 717 SkAutoTDelete<SkStream> fStream; | 785 SkAutoTDelete<SkStream> fStream; |
| 718 bool fNeedsRewind; | 786 bool fNeedsRewind; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 */ | 843 */ |
| 776 void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBy
tes, | 844 void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBy
tes, |
| 777 ZeroInitialized zeroInit, int linesRequested, int linesDecoded); | 845 ZeroInitialized zeroInit, int linesRequested, int linesDecoded); |
| 778 | 846 |
| 779 /** | 847 /** |
| 780 * Return an object which will allow forcing scanline decodes to sample in
X. | 848 * Return an object which will allow forcing scanline decodes to sample in
X. |
| 781 * | 849 * |
| 782 * May create a sampler, if one is not currently being used. Otherwise, doe
s | 850 * May create a sampler, if one is not currently being used. Otherwise, doe
s |
| 783 * not affect ownership. | 851 * not affect ownership. |
| 784 * | 852 * |
| 785 * Only valid during scanline decoding. | 853 * Only valid during scanline decoding or incremental decoding. |
| 786 */ | 854 */ |
| 787 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr;
} | 855 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr;
} |
| 788 | 856 |
| 789 // For testing with qcms | 857 // For testing with qcms |
| 790 // FIXME: Remove these when we are done comparing with qcms. | 858 // FIXME: Remove these when we are done comparing with qcms. |
| 791 friend class DM::ColorCodecSrc; | 859 friend class DM::ColorCodecSrc; |
| 792 friend class ColorCodecBench; | 860 friend class ColorCodecBench; |
| 793 | 861 |
| 794 friend class DM::CodecSrc; // for fillIncompleteImage | 862 friend class DM::CodecSrc; // for fillIncompleteImage |
| 795 friend class SkSampledCodec; | 863 friend class SkSampledCodec; |
| 796 friend class SkIcoCodec; | 864 friend class SkIcoCodec; |
| 797 }; | 865 }; |
| 798 #endif // SkCodec_DEFINED | 866 #endif // SkCodec_DEFINED |
| OLD | NEW |