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 |