Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef SkCodec_DEFINED | 8 #ifndef SkCodec_DEFINED |
| 9 #define SkCodec_DEFINED | 9 #define SkCodec_DEFINED |
| 10 | 10 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 | 64 |
| 65 // Upscaling is not supported. Return the original size if the client | 65 // Upscaling is not supported. Return the original size if the client |
| 66 // requests an upscale. | 66 // requests an upscale. |
| 67 if (desiredScale >= 1.0f) { | 67 if (desiredScale >= 1.0f) { |
| 68 return this->getInfo().dimensions(); | 68 return this->getInfo().dimensions(); |
| 69 } | 69 } |
| 70 return this->onGetScaledDimensions(desiredScale); | 70 return this->onGetScaledDimensions(desiredScale); |
| 71 } | 71 } |
| 72 | 72 |
| 73 /** | 73 /** |
| 74 * Return (via desiredSubset) a subset which can decoded from this codec, | |
| 75 * or false if this codec cannot decode subsets or anything similar to | |
| 76 * desiredSubset. | |
| 77 * | |
| 78 * @param desiredSubset In/out parameter. As input, a desired subset of | |
| 79 * the original bounds (as specified by getInfo). If true is returned, | |
| 80 * desiredSubset may have been modified to a subset which is | |
| 81 * supported. Although a particular change may have been made to | |
| 82 * desiredSubset to create something supported, it is possible other | |
| 83 * changes could result in a valid subset. | |
| 84 * If false is returned, desiredSubset's value is undefined. | |
| 85 * @return true if this codec supports decoding desiredSubset (as | |
| 86 * returned, potentially modified) | |
| 87 */ | |
| 88 bool getValidSubset(SkIRect* desiredSubset) const { | |
| 89 return this->onGetValidSubset(desiredSubset); | |
| 90 } | |
| 91 | |
| 92 /** | |
| 93 * Format of the encoded data. | 74 * Format of the encoded data. |
| 94 */ | 75 */ |
| 95 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat() ; } | 76 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat() ; } |
| 96 | 77 |
| 97 /** | 78 /** |
| 98 * Used to describe the result of a call to getPixels(). | 79 * Used to describe the result of a call to getPixels(). |
| 99 * | 80 * |
| 100 * Result is the union of possible results from subclasses. | 81 * Result is the union of possible results from subclasses. |
| 101 */ | 82 */ |
| 102 enum Result { | 83 enum Result { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 */ | 136 */ |
| 156 kNo_ZeroInitialized, | 137 kNo_ZeroInitialized, |
| 157 }; | 138 }; |
| 158 | 139 |
| 159 /** | 140 /** |
| 160 * Additional options to pass to getPixels. | 141 * Additional options to pass to getPixels. |
| 161 */ | 142 */ |
| 162 struct Options { | 143 struct Options { |
| 163 Options() | 144 Options() |
| 164 : fZeroInitialized(kNo_ZeroInitialized) | 145 : fZeroInitialized(kNo_ZeroInitialized) |
| 165 , fSubset(NULL) | 146 , fSubset(nullptr) |
| 147 , fScaledDimensions(nullptr) | |
| 148 , fScaledSubset(nullptr) | |
| 166 {} | 149 {} |
| 167 | 150 |
| 168 ZeroInitialized fZeroInitialized; | 151 ZeroInitialized fZeroInitialized; |
| 152 | |
| 169 /** | 153 /** |
| 170 * If not NULL, represents a subset of the original image to decode. | 154 * fSubset represents a subset of the original image to decode. |
| 171 * Must be within the bounds returned by getInfo(). | 155 * It must be within the bounds returned by getInfo(). |
| 172 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which | 156 * If the EncodedFormat is kWEBP_SkEncodedFormat, the top and left |
| 173 * currently supports subsets), the top and left values must be even. | 157 * values must be even. |
| 158 * If fSubset is NULL, we are not performing a subset decode. | |
| 159 * | |
| 160 * fScaledDimensions and fScaledSubset are used together to help | |
| 161 * specify a scaled subset decode. Both should be non-NULL for a | |
| 162 * scaled subset decode, and both should be NULL otherwise. | |
| 163 * | |
| 164 * If fScaledDimensions and fScaledSubset are NULL, we are not | |
| 165 * performing a scaled subset decode: | |
| 166 * (1) If fSubset is non-NULL, we are performing an unscaled | |
| 167 * subset decode, and the subset dimensions must match the | |
| 168 * dstInfo dimensions. | |
| 169 * (2) If fSubset is NULL and the dstInfo dimensions do not | |
| 170 * match the original dimensions, we are performing a | |
| 171 * scaled decode. | |
| 172 * (3) If fSubset is NULL and the dstInfo dimensions match the | |
|
scroggo
2015/10/12 20:47:06
Maybe it is worth noting that (2) and (3) are the
| |
| 173 * original dimensions, we are performing an unscaled, full | |
| 174 * image decode. | |
| 175 * | |
| 176 * If both are non-NULL we are performing a scaled subset decode: | |
|
scroggo
2015/10/12 20:47:06
Which "both"? fScaledDimensions and fScaledSubset?
| |
| 177 * fSubset must be non-NULL. | |
| 178 * fScaledSubset must be within the bounds of fScaledDimensions. | |
| 179 * The dimensions of fScaledSubset must match the dimensions | |
| 180 * specified by dstInfo. | |
| 181 * | |
| 182 * Usage: | |
| 183 * Call getScaledSubsetDimensions() with the desired fSubset of | |
| 184 * the original image and the desired scale. The function will | |
| 185 * populate the options object with valid values of | |
| 186 * fScaledDimensions and fScaledSubset that can be decoded | |
| 187 * efficiently. | |
| 174 * | 188 * |
| 175 * In getPixels, we will attempt to decode the exact rectangular | 189 * In getPixels, we will attempt to decode the exact rectangular |
| 176 * subset specified by fSubset. | 190 * subset specified by fSubset. |
| 177 * | 191 * |
| 178 * In a scanline decode, it does not make sense to specify a subset | 192 * In a scanline decode, it does not make sense to specify a subset |
| 179 * top or subset height, since the client already controls which rows | 193 * top or subset height, since the client already controls which rows |
| 180 * to get and which rows to skip. During scanline decodes, we will | 194 * to get and which rows to skip. During scanline decodes, we will |
| 181 * require that the subset top be zero and the subset height be equal | 195 * require that the subset top be zero and the subset height be equal |
| 182 * to the full height. We will, however, use the values of | 196 * to the full height. We will, however, use the values of |
| 183 * subset left and subset width to decode partial scanlines on calls | 197 * subset left and subset width to decode partial scanlines on calls |
| 184 * to getScanlines(). | 198 * to getScanlines(). |
| 185 */ | 199 */ |
| 186 SkIRect* fSubset; | 200 SkIRect* fSubset; |
| 201 SkISize* fScaledDimensions; | |
| 202 SkIRect* fScaledSubset; | |
| 187 }; | 203 }; |
| 188 | 204 |
| 189 /** | 205 /** |
| 206 * @param desiredScale The requested scale factor. | |
| 207 * @param options In/out parameter. | |
| 208 * options->fSubset (in/out) specifies the | |
|
scroggo
2015/10/12 20:47:06
If we wanted to, we could make options an optional
| |
| 209 * requested subset in terms of the original image | |
| 210 * dimensions. This may be modified to a subset | |
| 211 * that can be decoded more efficiently. | |
| 212 * options->fScaledDimensions is an output and | |
| 213 * specifies the best scaled (full image) output | |
| 214 * dimensions that can be achieved for the | |
| 215 * desiredScale. | |
| 216 * options->fScaledSubset is an output and specifies | |
| 217 * the fSubset in terms of fScaledDimensions. | |
|
scroggo
2015/10/12 20:47:06
"in terms of fScaledDimensions" is not intuitive t
| |
| 218 * | |
| 219 * The codec may not be able to scale and subset efficiently to the exact | |
| 220 * scale and subset requested, so fScaledDimensions and fScaledSubset may | |
| 221 * be approximate. These output values are the codec's suggestion for | |
| 222 * the closest valid scaled subset that it can support. | |
| 223 * | |
| 224 * @return true if fScaledDimensions and fScaledSubset have been | |
|
scroggo
2015/10/12 20:47:06
You've removed getValidSubset, so I assume the int
| |
| 225 * successfully set to values that the codec supports. | |
| 226 * false otherwise. | |
| 227 */ | |
| 228 bool getScaledSubsetDimensions(float desiredScale, const Options& options) c onst; | |
|
reed1
2015/10/12 20:21:00
wow, pretty complicated rules for calling this. Ar
scroggo
2015/10/12 20:47:07
The options object does not appear to be const.
| |
| 229 | |
| 230 /** | |
| 190 * Decode into the given pixels, a block of memory of size at | 231 * Decode into the given pixels, a block of memory of size at |
| 191 * least (info.fHeight - 1) * rowBytes + (info.fWidth * | 232 * least (info.fHeight - 1) * rowBytes + (info.fWidth * |
| 192 * bytesPerPixel) | 233 * bytesPerPixel) |
| 193 * | 234 * |
| 194 * Repeated calls to this function should give the same results, | 235 * Repeated calls to this function should give the same results, |
| 195 * allowing the PixelRef to be immutable. | 236 * allowing the PixelRef to be immutable. |
| 196 * | 237 * |
| 197 * @param info A description of the format (config, size) | 238 * @param info A description of the format (config, size) |
| 198 * expected by the caller. This can simply be identical | 239 * expected by the caller. This can simply be identical |
| 199 * to the info returned by getInfo(). | 240 * to the info returned by getInfo(). |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 400 int outputScanline(int inputScanline) const; | 441 int outputScanline(int inputScanline) const; |
| 401 | 442 |
| 402 protected: | 443 protected: |
| 403 SkCodec(const SkImageInfo&, SkStream*); | 444 SkCodec(const SkImageInfo&, SkStream*); |
| 404 | 445 |
| 405 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { | 446 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { |
| 406 // By default, scaling is not supported. | 447 // By default, scaling is not supported. |
| 407 return this->getInfo().dimensions(); | 448 return this->getInfo().dimensions(); |
| 408 } | 449 } |
| 409 | 450 |
| 410 // FIXME: What to do about subsets?? | 451 virtual bool onGetScaledSubsetDimensions(float desiredScale, const Options& options) const { |
| 452 // By default, scaled subsetting is not supported. | |
| 453 return false; | |
| 454 } | |
| 455 | |
| 411 /** | 456 /** |
| 412 * Subclasses should override if they support dimensions other than the | 457 * Subclasses should override if they support dimensions other than the |
| 413 * srcInfo's. | 458 * srcInfo's. |
| 414 */ | 459 */ |
| 415 virtual bool onDimensionsSupported(const SkISize&) { | 460 virtual bool onDimensionsSupported(const SkISize&) { |
| 416 return false; | 461 return false; |
| 417 } | 462 } |
| 418 | 463 |
| 464 /** | |
| 465 * Subclasses should override depending on how they support subsets. | |
| 466 * | |
| 467 * The default implementation only supports subsetting in the | |
| 468 * x-dimension during a scanline decode. | |
| 469 */ | |
| 470 virtual bool onSubsetSupported(const SkIRect&, bool isScanlineDecode); | |
| 471 | |
| 472 /** | |
| 473 * Subclasses should override depenging on how they support scaled subsetti ng. | |
| 474 * | |
| 475 * If the scale is supported, the default implementation will support subse tting | |
| 476 * in the x-dimension during a scanline decode. | |
| 477 */ | |
| 478 virtual bool onScaledSubsetSupported(const Options&, bool isScanlineDecode); | |
| 479 | |
| 419 virtual SkEncodedFormat onGetEncodedFormat() const = 0; | 480 virtual SkEncodedFormat onGetEncodedFormat() const = 0; |
| 420 | 481 |
| 421 /** | 482 /** |
| 422 * @param rowsDecoded When the encoded image stream is incomplete, this func tion | 483 * @param rowsDecoded When the encoded image stream is incomplete, this func tion |
| 423 * will return kIncompleteInput and rowsDecoded will be s et to | 484 * will return kIncompleteInput and rowsDecoded will be s et to |
| 424 * the number of scanlines that were successfully decoded . | 485 * the number of scanlines that were successfully decoded . |
| 425 * This will allow getPixels() to fill the uninitialized memory. | 486 * This will allow getPixels() to fill the uninitialized memory. |
| 426 */ | 487 */ |
| 427 virtual Result onGetPixels(const SkImageInfo& info, | 488 virtual Result onGetPixels(const SkImageInfo& info, |
| 428 void* pixels, size_t rowBytes, const Options&, | 489 void* pixels, size_t rowBytes, const Options&, |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 529 * The codec may choose to cache the information about scale and subset. | 590 * The codec may choose to cache the information about scale and subset. |
| 530 * Either way, the same information will be passed to onGetPixels/onStart | 591 * Either way, the same information will be passed to onGetPixels/onStart |
| 531 * on success. | 592 * on success. |
| 532 * | 593 * |
| 533 * This must return true for a size returned from getScaledDimensions. | 594 * This must return true for a size returned from getScaledDimensions. |
| 534 */ | 595 */ |
| 535 bool dimensionsSupported(const SkISize& dim) { | 596 bool dimensionsSupported(const SkISize& dim) { |
| 536 return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim); | 597 return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim); |
| 537 } | 598 } |
| 538 | 599 |
| 600 /** | |
| 601 * Return whether decoding this subset is supported. | |
| 602 */ | |
| 603 bool subsetSupported(const SkIRect& subset, bool isScanlineDecode); | |
| 604 | |
| 605 /** | |
| 606 * Return whether a decode with the specified options is supported | |
| 607 */ | |
| 608 bool scaledSubsetSupported(const SkISize& dim, const Options& options, bool isScanlineDecode); | |
| 609 | |
| 539 // Methods for scanline decoding. | 610 // Methods for scanline decoding. |
| 540 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo, | 611 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo, |
| 541 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) { | 612 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) { |
| 542 return kUnimplemented; | 613 return kUnimplemented; |
| 543 } | 614 } |
| 544 | 615 |
| 545 // Naive default version just calls onGetScanlines on temp memory. | 616 // Naive default version just calls onGetScanlines on temp memory. |
| 546 virtual bool onSkipScanlines(int countLines) { | 617 virtual bool onSkipScanlines(int countLines) { |
| 547 // FIXME (msarett): Make this a pure virtual and always override this. | 618 // FIXME (msarett): Make this a pure virtual and always override this. |
| 548 SkAutoMalloc storage(fDstInfo.minRowBytes()); | 619 SkAutoMalloc storage(fDstInfo.minRowBytes()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 580 * May create a sampler, if one is not currently being used. Otherwise, doe s | 651 * May create a sampler, if one is not currently being used. Otherwise, doe s |
| 581 * not affect ownership. | 652 * not affect ownership. |
| 582 * | 653 * |
| 583 * Only valid during scanline decoding. | 654 * Only valid during scanline decoding. |
| 584 */ | 655 */ |
| 585 virtual SkSampler* getSampler(bool createIfNecessary) { return nullptr; } | 656 virtual SkSampler* getSampler(bool createIfNecessary) { return nullptr; } |
| 586 | 657 |
| 587 friend class SkScaledCodec; | 658 friend class SkScaledCodec; |
| 588 }; | 659 }; |
| 589 #endif // SkCodec_DEFINED | 660 #endif // SkCodec_DEFINED |
| OLD | NEW |