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

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

Issue 1365313002: Merge SkCodec with SkScanlineDecoder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Respond to matt's comments in patch set 1 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
« no previous file with comments | « gyp/codec.gyp ('k') | include/codec/SkScaledCodec.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 27 matching lines...) Expand all
38 * 38 *
39 * Will take a ref if it returns a codec, else will not affect the data. 39 * Will take a ref if it returns a codec, else will not affect the data.
40 */ 40 */
41 static SkCodec* NewFromData(SkData*); 41 static SkCodec* NewFromData(SkData*);
42 42
43 virtual ~SkCodec(); 43 virtual ~SkCodec();
44 44
45 /** 45 /**
46 * Return the ImageInfo associated with this codec. 46 * Return the ImageInfo associated with this codec.
47 */ 47 */
48 const SkImageInfo& getInfo() const { return fInfo; } 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. 58 // Negative and zero scales are errors.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 /** 124 /**
125 * The input did not contain a valid image. 125 * The input did not contain a valid image.
126 */ 126 */
127 kInvalidInput, 127 kInvalidInput,
128 /** 128 /**
129 * Fulfilling this request requires rewinding the input, which is not 129 * Fulfilling this request requires rewinding the input, which is not
130 * supported for this input. 130 * supported for this input.
131 */ 131 */
132 kCouldNotRewind, 132 kCouldNotRewind,
133 /** 133 /**
134 * This method is not implemented by this generator. 134 * This method is not implemented by this codec.
135 * FIXME: Perhaps this should be kUnsupported?
135 */ 136 */
136 kUnimplemented, 137 kUnimplemented,
138 /**
139 * start() was not called before calling getScanlines.
140 */
141 kScanlineDecodingNotStarted,
djsollen 2015/09/29 20:22:17 move this above unimplemented.
scroggo 2015/09/30 13:32:20 Done.
137 }; 142 };
138 143
139 /** 144 /**
140 * Whether or not the memory passed to getPixels is zero initialized. 145 * Whether or not the memory passed to getPixels is zero initialized.
141 */ 146 */
142 enum ZeroInitialized { 147 enum ZeroInitialized {
143 /** 148 /**
144 * The memory passed to getPixels is zero initialized. The SkCodec 149 * The memory passed to getPixels is zero initialized. The SkCodec
145 * may take advantage of this by skipping writing zeroes. 150 * may take advantage of this by skipping writing zeroes.
146 */ 151 */
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 * to scale. If the generator cannot perform this scale, 200 * to scale. If the generator cannot perform this scale,
196 * it will return kInvalidScale. 201 * it will return kInvalidScale.
197 * 202 *
198 * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256 203 * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
199 * SkPMColor values in ctable. On success the generator must copy N colors into that storage, 204 * SkPMColor values in ctable. On success the generator must copy N colors into that storage,
200 * (where N is the logical number of table entries) and set ctableCount to N. 205 * (where N is the logical number of table entries) and set ctableCount to N.
201 * 206 *
202 * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount 207 * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
203 * is not null, it will be set to 0. 208 * is not null, it will be set to 0.
204 * 209 *
210 * If a scanline decode is in progress, scanline mode will end, requiring t he client to call
211 * start() in order to return to decoding scanlines.
212 *
205 * @return Result kSuccess, or another value explaining the type of failure . 213 * @return Result kSuccess, or another value explaining the type of failure .
206 */ 214 */
207 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, con st Options*, 215 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, con st Options*,
208 SkPMColor ctable[], int* ctableCount); 216 SkPMColor ctable[], int* ctableCount);
209 217
210 /** 218 /**
211 * Simplified version of getPixels() that asserts that info is NOT kIndex8_ SkColorType and 219 * Simplified version of getPixels() that asserts that info is NOT kIndex8_ SkColorType and
212 * uses the default Options. 220 * uses the default Options.
213 */ 221 */
214 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); 222 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
215 223
216 /** 224 /**
217 * Some images may initially report that they have alpha due to the format 225 * Some images may initially report that they have alpha due to the format
218 * of the encoded data, but then never use any colors which have alpha 226 * of the encoded data, but then never use any colors which have alpha
219 * less than 100%. This function can be called *after* decoding to 227 * less than 100%. This function can be called *after* decoding to
220 * determine if such an image truly had alpha. Calling it before decoding 228 * determine if such an image truly had alpha. Calling it before decoding
221 * is undefined. 229 * is undefined.
222 * FIXME: see skbug.com/3582. 230 * FIXME: see skbug.com/3582.
223 */ 231 */
224 bool reallyHasAlpha() const { 232 bool reallyHasAlpha() const {
225 return this->onReallyHasAlpha(); 233 return this->onReallyHasAlpha();
226 } 234 }
227 235
236 /**
237 * The remaining functions revolve around decoding scanlines.
238 */
239
240 /**
241 * Prepare for a scanline decode with the specified options.
242 *
243 * After this call, this class will be ready to decode the first scanline.
244 *
245 * This must be called in order to call getScanlines or skipScanlines.
246 *
247 * This may require rewinding the stream.
248 *
249 * Not all SkCodecs support this.
250 *
251 * @param dstInfo Info of the destination. If the dimensions do not match
252 * those of getInfo, this implies a scale.
253 * @param options Contains decoding options, including if memory is zero
254 * initialized.
255 * @param ctable A pointer to a color table. When dstInfo.colorType() is
256 * kIndex8, this should be non-NULL and have enough storage for 256
257 * colors. The color table will be populated after decoding the palett e.
258 * @param ctableCount A pointer to the size of the color table. When
259 * dstInfo.colorType() is kIndex8, this should be non-NULL. It will
260 * be modified to the true size of the color table (<= 256) after
261 * decoding the palette.
262 * @return Enum representing success or reason for failure.
263 */
264 Result start(const SkImageInfo& dstInfo, const SkCodec::Options* options,
djsollen 2015/09/29 20:22:17 now that this is no longer part of a scanline clas
scroggo 2015/09/30 13:32:20 Matt included the same name in his suggestions. Do
265 SkPMColor ctable[], int* ctableCount);
266
267 /**
268 * Simplified version of start() that asserts that info is NOT
269 * kIndex8_SkColorType and uses the default Options.
270 */
271 Result start(const SkImageInfo& dstInfo);
272
273 /**
274 * Write the next countLines scanlines into dst.
275 *
276 * Not valid to call before calling start().
277 *
278 * @param dst Must be non-null, and large enough to hold countLines
279 * scanlines of size rowBytes.
280 * @param countLines Number of lines to write.
281 * @param rowBytes Number of bytes per row. Must be large enough to hold
282 * a scanline based on the SkImageInfo used to create this object.
283 */
284 Result getScanlines(void* dst, int countLines, size_t rowBytes) {
djsollen 2015/09/29 20:22:17 any reason not to move this to the cpp file since
scroggo 2015/09/30 13:32:20 Done. I also moved skipScanlines into cpp
285 if (fCurrScanline < 0) {
286 return kScanlineDecodingNotStarted;
287 }
288
289 SkASSERT(!fDstInfo.isEmpty());
290 if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0
291 || fCurrScanline + countLines > fDstInfo.height()) {
292 return kInvalidParameters;
293 }
294 const Result result = this->onGetScanlines(dst, countLines, rowBytes);
295 fCurrScanline += countLines;
296 return result;
297 }
298
299 /**
300 * Skip count scanlines.
301 *
302 * Not valid to call before calling start().
303 *
304 * The default version just calls onGetScanlines and discards the dst.
305 * NOTE: If skipped lines are the only lines with alpha, this default
306 * will make reallyHasAlpha return true, when it could have returned
307 * false.
308 */
309 Result skipScanlines(int countLines) {
310 if (fCurrScanline < 0) {
311 return kScanlineDecodingNotStarted;
312 }
313 SkASSERT(!fDstInfo.isEmpty());
314 if (fCurrScanline + countLines > fDstInfo.height()) {
315 // Arguably, we could just skip the scanlines which are remaining,
316 // and return kSuccess. We choose to return invalid so the client
317 // can catch their bug.
318 return SkCodec::kInvalidParameters;
319 }
320 const Result result = this->onSkipScanlines(countLines);
321 fCurrScanline += countLines;
322 return result;
323 }
324
325 /**
326 * The order in which rows are output from the scanline decoder is not the
327 * same for all variations of all image types. This explains the possible
328 * output row orderings.
329 */
330 enum SkScanlineOrder {
331 /*
332 * By far the most common, this indicates that the image can be decoded
333 * reliably using the scanline decoder, and that rows will be output in
334 * the logical order.
335 */
336 kTopDown_SkScanlineOrder,
337
338 /*
339 * This indicates that the scanline decoder reliably outputs rows, but
340 * they will be returned in reverse order. If the scanline format is
341 * kBottomUp, the getY() API can be used to determine the actual
342 * y-coordinate of the next output row, but the client is not forced
343 * to take advantage of this, given that it's not too tough to keep
344 * track independently.
345 *
346 * For full image decodes, it is safe to get all of the scanlines at
347 * once, since the decoder will handle inverting the rows as it
348 * decodes.
349 *
350 * For subset decodes and sampling, it is simplest to get and skip
351 * scanlines one at a time, using the getY() API. It is possible to
352 * ask for larger chunks at a time, but this should be used with
353 * caution. As with full image decodes, the decoder will handle
354 * inverting the requested rows, but rows will still be delivered
355 * starting from the bottom of the image.
356 *
357 * Upside down bmps are an example.
358 */
359 kBottomUp_SkScanlineOrder,
360
361 /*
362 * This indicates that the scanline decoder reliably outputs rows, but
363 * they will not be in logical order. If the scanline format is
364 * kOutOfOrder, the getY() API should be used to determine the actual
365 * y-coordinate of the next output row.
366 *
367 * For this scanline ordering, it is advisable to get and skip
368 * scanlines one at a time.
369 *
370 * Interlaced gifs are an example.
371 */
372 kOutOfOrder_SkScanlineOrder,
373
374 /*
375 * Indicates that the entire image must be decoded in order to output
376 * any amount of scanlines. In this case, it is a REALLY BAD IDEA to
377 * request scanlines 1-by-1 or in small chunks. The client should
378 * determine which scanlines are needed and ask for all of them in
379 * a single call to getScanlines().
380 *
381 * Interlaced pngs are an example.
382 */
383 kNone_SkScanlineOrder,
384 };
385
386 /**
387 * An enum representing the order in which scanlines will be returned by
388 * the scanline decoder.
389 */
390 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; }
391
392 /**
393 * Returns the y-coordinate of the next row to be returned by the scanline
394 * decoder. This will be overridden in the case of
395 * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of
396 * kNone_SkScanlineOrder.
397 *
398 * Results are undefined when not in scanline decoding mode.
399 *
400 * FIXME: Rename to nextScanline()?
djsollen 2015/09/29 20:22:17 I agree that this should be renamed
scroggo 2015/09/30 13:32:20 Renamed to nextScanline(). I also renamed updateY
401 */
402 int getY() const {
403 return this->onGetY();
404 }
405
228 protected: 406 protected:
229 SkCodec(const SkImageInfo&, SkStream*); 407 SkCodec(const SkImageInfo&, SkStream*);
230 408
231 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { 409 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const {
232 // By default, scaling is not supported. 410 // By default, scaling is not supported.
233 return this->getInfo().dimensions(); 411 return this->getInfo().dimensions();
234 } 412 }
235 413
236 virtual SkEncodedFormat onGetEncodedFormat() const = 0; 414 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
237 415
(...skipping 30 matching lines...) Expand all
268 return true; 446 return true;
269 } 447 }
270 448
271 /** 449 /**
272 * Get method for the input stream 450 * Get method for the input stream
273 */ 451 */
274 SkStream* stream() { 452 SkStream* stream() {
275 return fStream.get(); 453 return fStream.get();
276 } 454 }
277 455
456 /**
457 * The remaining functions revolve around decoding scanlines.
458 */
459
460 /**
461 * Most images types will be kTopDown and will not need to override this fu nction.
462 */
463 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; }
464
465 /**
466 * Most images will be kTopDown and will not need to override this function .
467 */
468 virtual int onGetY() const { return fCurrScanline; }
469
470 /**
471 * Update the next scanline. Used by interlaced png.
472 */
473 void updateY(int newY) { fCurrScanline = newY; }
474
475 const SkImageInfo& dstInfo() const { return fDstInfo; }
476
477 const SkCodec::Options& options() const { return fOptions; }
478
278 private: 479 private:
279 const SkImageInfo fInfo; 480 const SkImageInfo fSrcInfo;
280 SkAutoTDelete<SkStream> fStream; 481 SkAutoTDelete<SkStream> fStream;
281 bool fNeedsRewind; 482 bool fNeedsRewind;
483 // These fields are only meaningful during scanline decodes.
484 SkImageInfo fDstInfo;
485 SkCodec::Options fOptions;
486 int fCurrScanline;
487
488 // Methods for scanline decoding.
489 virtual SkCodec::Result onStart(const SkImageInfo& dstInfo,
490 const SkCodec::Options& options,
491 SkPMColor ctable[], int* ctableCount) {
492 return kUnimplemented;
493 }
494
495 // Naive default version just calls onGetScanlines on temp memory.
496 virtual SkCodec::Result onSkipScanlines(int countLines) {
497 SkAutoMalloc storage(fDstInfo.minRowBytes());
498 // Note that we pass 0 to rowBytes so we continue to use the same memory .
499 // Also note that while getScanlines checks that rowBytes is big enough,
500 // onGetScanlines bypasses that check.
501 // Calling the virtual method also means we do not double count
502 // countLines.
503 return this->onGetScanlines(storage.get(), countLines, 0);
504 }
505
506 virtual SkCodec::Result onGetScanlines(void* dst, int countLines,
507 size_t rowBytes) {
508 return kUnimplemented;
509 }
510
282 }; 511 };
283 #endif // SkCodec_DEFINED 512 #endif // SkCodec_DEFINED
OLDNEW
« no previous file with comments | « gyp/codec.gyp ('k') | include/codec/SkScaledCodec.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698