Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: include/codec/SkCodec.h

Issue 1321433002: Add subsetting to SkScaledCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@gif-scan
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 */ 47 */
48 const SkImageInfo& getInfo() const { return fSrcInfo; } 48 const SkImageInfo& getInfo() const { return fSrcInfo; }
49 49
50 /** 50 /**
51 * Return a size that approximately supports the desired scale factor. 51 * Return a size that approximately supports the desired scale factor.
52 * The codec may not be able to scale efficiently to the exact scale 52 * The codec may not be able to scale efficiently to the exact scale
53 * factor requested, so return a size that approximates that scale. 53 * factor requested, so return a size that approximates that scale.
54 * The returned value is the codec's suggestion for the closest valid 54 * The returned value is the codec's suggestion for the closest valid
55 * scale that it can natively support 55 * scale that it can natively support
56 */ 56 */
57 SkISize getScaledDimensions(float desiredScale) const { 57 SkISize getScaledDimensions(float desiredScale) const;
58 // Negative and zero scales are errors.
59 SkASSERT(desiredScale > 0.0f);
60 if (desiredScale <= 0.0f) {
61 return SkISize::Make(0, 0);
62 }
63
64 // Upscaling is not supported. Return the original size if the client
65 // requests an upscale.
66 if (desiredScale >= 1.0f) {
67 return this->getInfo().dimensions();
68 }
69 return this->onGetScaledDimensions(desiredScale);
70 }
71 58
72 /** 59 /**
73 * Return (via desiredSubset) a subset which can decoded from this codec, 60 * Return (via desiredSubset) a subset which can decoded from this codec,
74 * or false if this codec cannot decode subsets or anything similar to 61 * or false if this codec cannot decode subsets or anything similar to
75 * desiredSubset. 62 * desiredSubset.
76 * 63 *
77 * @param desiredSubset In/out parameter. As input, a desired subset of 64 * @param desiredSubset In/out parameter. As input, a desired subset of
78 * the original bounds (as specified by getInfo). If true is returned, 65 * the original bounds (as specified by getInfo). If true is returned,
79 * desiredSubset may have been modified to a subset which is 66 * desiredSubset may have been modified to a subset which is
80 * supported. Although a particular change may have been made to 67 * supported. Although a particular change may have been made to
81 * desiredSubset to create something supported, it is possible other 68 * desiredSubset to create something supported, it is possible other
82 * changes could result in a valid subset. 69 * changes could result in a valid subset.
83 * If false is returned, desiredSubset's value is undefined. 70 * If false is returned, desiredSubset's value is undefined.
84 * @return true if this codec supports decoding desiredSubset (as 71 * @return true if this codec supports decoding desiredSubset (as
85 * returned, potentially modified) 72 * returned, potentially modified)
86 */ 73 */
87 bool getValidSubset(SkIRect* desiredSubset) const { 74 bool getValidSubset(SkIRect* desiredSubset) const;
88 return this->onGetValidSubset(desiredSubset);
89 }
90 75
91 /** 76 /**
92 * Format of the encoded data. 77 * Format of the encoded data.
93 */ 78 */
94 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat() ; } 79 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat() ; }
95 80
96 /** 81 /**
97 * Used to describe the result of a call to getPixels(). 82 * Used to describe the result of a call to getPixels().
98 * 83 *
99 * Result is the union of possible results from subclasses. 84 * Result is the union of possible results from subclasses.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 kNo_ZeroInitialized, 140 kNo_ZeroInitialized,
156 }; 141 };
157 142
158 /** 143 /**
159 * Additional options to pass to getPixels. 144 * Additional options to pass to getPixels.
160 */ 145 */
161 struct Options { 146 struct Options {
162 Options() 147 Options()
163 : fZeroInitialized(kNo_ZeroInitialized) 148 : fZeroInitialized(kNo_ZeroInitialized)
164 , fSubset(NULL) 149 , fSubset(NULL)
150 , fScaledDimensions(SkISize::Make(0, 0))
151 , fScaledSubset(SkIRect::MakeEmpty())
165 {} 152 {}
166 153
167 ZeroInitialized fZeroInitialized; 154 ZeroInitialized fZeroInitialized;
155
168 /** 156 /**
169 * If not NULL, represents a subset of the original image to decode. 157 * fSubset represents a subset of the original image to decode.
158 * It must be within the bounds returned by getInfo().
159 * If the EncodedFormat is kWEBP_SkEncodedFormat, the top and left
160 * values must be even.
161 * If fSubset is NULL, we are not performing a subset decode.
170 * 162 *
171 * Must be within the bounds returned by getInfo(). 163 * fScaledDimensions and fScaledSubset are used together to help
164 * specify a scaled subset decode. Both should be specified for a
165 * scaled subset decode, and both should be zeroed otherwise.
172 * 166 *
173 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which 167 * If fScaledDimensions and fScaledSubset are zeroed, we are not
174 * currently supports subsets), the top and left values must be even. 168 * performing a scaled subset decode:
169 * (1) If fSubset is non-NULL, we are performing an unscaled
170 * subset decode, and the subset dimensions must match the
171 * dstInfo dimensions.
172 * (2) If fSubset is NULL and the dstInfo dimensions do not
173 * match the original dimensions, we are performing a
174 * scaled decode.
175 * (3) If fSubset is NULL and the dstInfo dimensions match the
176 * original dimensions, we are performing an unscaled, full
177 * image decode.
178 *
179 * If both are non-NULL we are performing a scaled subset decode:
180 * fSubset must be non-NULL.
181 * fScaledSubset must be within the bounds of fScaledDimensions.
182 * The dimensions of fScaledSubset must match the dimensions
183 * specified by dstInfo.
184 *
185 * Usage:
186 * Call getScaledSubsetDimensions() with the desired fSubset of
187 * the original image and the desired scale. The function will
188 * populate the options object with valid values of
189 * fScaledDimensions and fScaledSubset that can be decoded
190 * efficiently.
175 */ 191 */
176 SkIRect* fSubset; 192 SkIRect* fSubset;
193 SkISize fScaledDimensions;
scroggo 2015/10/02 18:27:03 For fSubset, we decided to make it an unowned poin
msarett 2015/10/06 23:01:27 I'll change to be consistent. My concern is that
scroggo 2015/10/07 17:49:39 I don't think it's so bad. In this case it will ju
194 SkIRect fScaledSubset;
177 }; 195 };
178 196
179 /** 197 /**
198 * @param desiredScale The requested scale factor.
199 * @param options In/out parameter.
200 * options->fSubset (in/out) specifies the
201 * requested subset in terms of the original image
202 * dimensions. This may be modified to a subset
scroggo 2015/10/02 18:27:03 So if I understand correctly, this is analogous to
msarett 2015/10/06 23:01:27 I'm in favor of combining. I had considered that
203 * that can be decoded more efficiently.
204 * options->fScaledDimensions is an output and
205 * specifies the best scaled (full image) output
206 * dimensions that can be achieved for the
207 * desiredScale.
208 * options->fScaledSubset is an output and specifies
209 * the fSubset in terms of fScaledDimensions.
210 *
211 * The codec may not be able to scale and subset efficiently to the exact
212 * scale and subset requested, so fScaledDimensions and fScaledSubset may
213 * be approximate. These output values are the codec's suggestion for
214 * the closest valid scaled subset that it can support.
215 *
216 * @return true if fScaledDimensions and fScaledSubset have been
217 * successfully set to values that the codec supports.
218 * false otherwise.
219 */
220 bool getScaledSubsetDimensions(float desiredScale, Options* options) const;
221
222 /**
180 * Decode into the given pixels, a block of memory of size at 223 * Decode into the given pixels, a block of memory of size at
181 * least (info.fHeight - 1) * rowBytes + (info.fWidth * 224 * least (info.fHeight - 1) * rowBytes + (info.fWidth *
182 * bytesPerPixel) 225 * bytesPerPixel)
183 * 226 *
184 * Repeated calls to this function should give the same results, 227 * Repeated calls to this function should give the same results,
185 * allowing the PixelRef to be immutable. 228 * allowing the PixelRef to be immutable.
186 * 229 *
187 * @param info A description of the format (config, size) 230 * @param info A description of the format (config, size)
188 * expected by the caller. This can simply be identical 231 * expected by the caller. This can simply be identical
189 * to the info returned by getInfo(). 232 * to the info returned by getInfo().
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 * those of getInfo, this implies a scale. 291 * those of getInfo, this implies a scale.
249 * @param options Contains decoding options, including if memory is zero 292 * @param options Contains decoding options, including if memory is zero
250 * initialized. 293 * initialized.
251 * @param ctable A pointer to a color table. When dstInfo.colorType() is 294 * @param ctable A pointer to a color table. When dstInfo.colorType() is
252 * kIndex8, this should be non-NULL and have enough storage for 256 295 * kIndex8, this should be non-NULL and have enough storage for 256
253 * colors. The color table will be populated after decoding the palett e. 296 * colors. The color table will be populated after decoding the palett e.
254 * @param ctableCount A pointer to the size of the color table. When 297 * @param ctableCount A pointer to the size of the color table. When
255 * dstInfo.colorType() is kIndex8, this should be non-NULL. It will 298 * dstInfo.colorType() is kIndex8, this should be non-NULL. It will
256 * be modified to the true size of the color table (<= 256) after 299 * be modified to the true size of the color table (<= 256) after
257 * decoding the palette. 300 * decoding the palette.
301 * @param subsetLeft The left offset at which to begin decoding each
302 * scanline. This enables partial scanline decodes.
303 * @param subsetWidth The number of pixels to decode in each scanline row.
scroggo 2015/10/02 18:27:03 My first thought was that this could be represente
msarett 2015/10/06 23:01:27 I'm in favor of putting all of this on the Options
258 * @return Enum representing success or reason for failure. 304 * @return Enum representing success or reason for failure.
259 */ 305 */
260 Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Option s* options, 306 Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Option s* options,
261 SkPMColor ctable[], int* ctableCount); 307 SkPMColor ctable[], int* ctableCount, int subsetLeft, int subse tWidth);
308
309 /**
310 * Simplified version of startScanlineDecode() that does not enable partial
311 * scanline decoding.
312 */
313 Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Option s* options,
314 SkPMColor ctable[], int* ctableCount);
262 315
263 /** 316 /**
264 * Simplified version of startScanlineDecode() that asserts that info is NO T 317 * Simplified version of startScanlineDecode() that asserts that info is NO T
265 * kIndex8_SkColorType and uses the default Options. 318 * kIndex8_SkColorType, uses the default Options, and does not enable
319 * partial scanline decoding.
266 */ 320 */
267 Result startScanlineDecode(const SkImageInfo& dstInfo); 321 Result startScanlineDecode(const SkImageInfo& dstInfo);
268 322
269 /** 323 /**
270 * Write the next countLines scanlines into dst. 324 * Write the next countLines scanlines into dst.
271 * 325 *
272 * Not valid to call before calling startScanlineDecode(). 326 * Not valid to call before calling startScanlineDecode().
273 * 327 *
274 * @param dst Must be non-null, and large enough to hold countLines 328 * @param dst Must be non-null, and large enough to hold countLines
275 * scanlines of size rowBytes. 329 * scanlines of size rowBytes.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 int outputScanline(int inputScanline) const; 444 int outputScanline(int inputScanline) const;
391 445
392 protected: 446 protected:
393 SkCodec(const SkImageInfo&, SkStream*); 447 SkCodec(const SkImageInfo&, SkStream*);
394 448
395 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { 449 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
396 // By default, scaling is not supported. 450 // By default, scaling is not supported.
397 return this->getInfo().dimensions(); 451 return this->getInfo().dimensions();
398 } 452 }
399 453
454 virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const {
455 // By default, subsets are not supported.
456 return false;
457 }
458
459 virtual bool onGetScaledSubsetDimensions(float desiredScale, Options* option s) const {
460 // By default, scaled subsetting is not supported.
461 return false;
462 }
463
400 virtual SkEncodedFormat onGetEncodedFormat() const = 0; 464 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
401 465
402 /** 466 /**
403 * @param rowsDecoded When the encoded image stream is incomplete, this func tion 467 * @param rowsDecoded When the encoded image stream is incomplete, this func tion
404 * will return kIncompleteInput and rowsDecoded will be s et to 468 * will return kIncompleteInput and rowsDecoded will be s et to
405 * the number of scanlines that were successfully decoded . 469 * the number of scanlines that were successfully decoded .
406 * This will allow getPixels() to fill the uninitialized memory. 470 * This will allow getPixels() to fill the uninitialized memory.
407 */ 471 */
408 virtual Result onGetPixels(const SkImageInfo& info, 472 virtual Result onGetPixels(const SkImageInfo& info,
409 void* pixels, size_t rowBytes, const Options&, 473 void* pixels, size_t rowBytes, const Options&,
410 SkPMColor ctable[], int* ctableCount, 474 SkPMColor ctable[], int* ctableCount,
411 int* rowsDecoded) = 0; 475 int* rowsDecoded) = 0;
412 476
413 virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const {
414 // By default, subsets are not supported.
415 return false;
416 }
417
418 virtual bool onReallyHasAlpha() const { return false; } 477 virtual bool onReallyHasAlpha() const { return false; }
419 478
420 /** 479 /**
421 * If the stream was previously read, attempt to rewind. 480 * If the stream was previously read, attempt to rewind.
422 * 481 *
423 * If the stream needed to be rewound, call onRewind. 482 * If the stream needed to be rewound, call onRewind.
424 * @returns true if the codec is at the right position and can be used. 483 * @returns true if the codec is at the right position and can be used.
425 * false if there was a failure to rewind. 484 * false if there was a failure to rewind.
426 * 485 *
427 * This is called by getPixels() and start(). Subclasses may call if they 486 * This is called by getPixels() and start(). Subclasses may call if they
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 545
487 /** 546 /**
488 * Update the next scanline. Used by interlaced png. 547 * Update the next scanline. Used by interlaced png.
489 */ 548 */
490 void updateNextScanline(int newY) { fCurrScanline = newY; } 549 void updateNextScanline(int newY) { fCurrScanline = newY; }
491 550
492 const SkImageInfo& dstInfo() const { return fDstInfo; } 551 const SkImageInfo& dstInfo() const { return fDstInfo; }
493 552
494 const SkCodec::Options& options() const { return fOptions; } 553 const SkCodec::Options& options() const { return fOptions; }
495 554
555 int subsetWidth() const { return fSubsetWidth; }
556
496 private: 557 private:
497 const SkImageInfo fSrcInfo; 558 const SkImageInfo fSrcInfo;
498 SkAutoTDelete<SkStream> fStream; 559 SkAutoTDelete<SkStream> fStream;
499 bool fNeedsRewind; 560 bool fNeedsRewind;
500 // These fields are only meaningful during scanline decodes. 561 // These fields are only meaningful during scanline decodes.
501 SkImageInfo fDstInfo; 562 SkImageInfo fDstInfo;
502 SkCodec::Options fOptions; 563 SkCodec::Options fOptions;
503 int fCurrScanline; 564 int fCurrScanline;
565 int fSubsetWidth;
504 566
505 // Methods for scanline decoding. 567 // Methods for scanline decoding.
506 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo, 568 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo,
507 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) { 569 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t, int subsetLeft,
570 int subsetWidth) {
508 return kUnimplemented; 571 return kUnimplemented;
509 } 572 }
510 573
511 // Naive default version just calls onGetScanlines on temp memory. 574 // Naive default version just calls onGetScanlines on temp memory.
512 virtual bool onSkipScanlines(int countLines) { 575 virtual bool onSkipScanlines(int countLines) {
513 // FIXME (msarett): Make this a pure virtual and always override this. 576 // FIXME (msarett): Make this a pure virtual and always override this.
514 SkAutoMalloc storage(fDstInfo.minRowBytes()); 577 SkAutoMalloc storage(fDstInfo.minRowBytes());
515 578
516 // Note that we pass 0 to rowBytes so we continue to use the same memory . 579 // Note that we pass 0 to rowBytes so we continue to use the same memory .
517 // Also note that while getScanlines checks that rowBytes is big enough, 580 // Also note that while getScanlines checks that rowBytes is big enough,
(...skipping 16 matching lines...) Expand all
534 * @param linesRequested Number of lines that the client requested 597 * @param linesRequested Number of lines that the client requested
535 * @param linesDecoded Number of lines that were successfully decoded 598 * @param linesDecoded Number of lines that were successfully decoded
536 */ 599 */
537 void fillIncompleteImage(const SkImageInfo& info, void* dst, size_t rowBytes , 600 void fillIncompleteImage(const SkImageInfo& info, void* dst, size_t rowBytes ,
538 ZeroInitialized zeroInit, int linesRequested, int linesDecoded); 601 ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
539 602
540 // Needed to call getFillColor() 603 // Needed to call getFillColor()
541 friend class SkScaledCodec; 604 friend class SkScaledCodec;
542 }; 605 };
543 #endif // SkCodec_DEFINED 606 #endif // SkCodec_DEFINED
OLDNEW
« no previous file with comments | « gyp/tools.gyp ('k') | include/codec/SkScaledCodec.h » ('j') | src/codec/SkBmpCodec.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698