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

Side by Side Diff: src/codec/SkGifCodec.cpp

Issue 2045293002: Add support for multiple frames in SkCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Return metadata in a vector Created 4 years, 3 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 #include "SkBitmap.h" 8 #include "SkBitmap.h"
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkCodecAnimation.h" 10 #include "SkCodecAnimation.h"
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 // A lot of users (including Chromium!) ignore the background color, but we (currently) 259 // A lot of users (including Chromium!) ignore the background color, but we (currently)
260 // use it to fill in the color table if it's less than 256 colors. 260 // use it to fill in the color table if it's less than 256 colors.
261 fColorTable.reset(create_color_table(*desc.ColorMap, transIndex, SK_ MaxU32)); 261 fColorTable.reset(create_color_table(*desc.ColorMap, transIndex, SK_ MaxU32));
262 } 262 }
263 } 263 }
264 264
265 for (int i = 0; i < gif->ImageCount; i++) { 265 for (int i = 0; i < gif->ImageCount; i++) {
266 const SavedImage* image = &gif->SavedImages[i]; 266 const SavedImage* image = &gif->SavedImages[i];
267 const GifImageDesc& desc = image->ImageDesc; 267 const GifImageDesc& desc = image->ImageDesc;
268 268
269 auto& frame = fFrameInfos.push_back(); 269 auto& frame = fFrameInfos[i];
270 // FIXME: Probably want to intersect this with the bounds, just in case. 270 // FIXME: Probably want to intersect this with the bounds, just in case.
271 // But then we'll need to make sure we draw the right thing... 271 // But then we'll need to make sure we draw the right thing...
272 // i.e. if the top is cut off (desc.Top < 0), we want to start off drawi ng line -desc.Top 272 // i.e. if the top is cut off (desc.Top < 0), we want to start off drawi ng line -desc.Top
273 // (probably?) 273 // (probably?)
274 // Or if we're cut off width-wise, we need to ensure we use the original row bytes 274 // Or if we're cut off width-wise, we need to ensure we use the original row bytes
275 // (desc.Width) but the corrected width. 275 // (desc.Width) but the corrected width.
276 frame.fFrameRect = SkIRect::MakeXYWH(desc.Left, desc.Top, desc.Width, de sc.Height); 276 frame.fFrameRect = SkIRect::MakeXYWH(desc.Left, desc.Top, desc.Width, de sc.Height);
277 if (!read_graphics_extension(*image, &frame.fTransIndex, &frame.fDuratio n, 277 if (!read_graphics_extension(*image, &frame.fTransIndex, &frame.fDuratio n,
278 &frame.fDisposalMethod)) { 278 &frame.fDisposalMethod)) {
279 frame.fDisposalMethod = SkCodecAnimation::Keep_DisposalMethod; 279 frame.fDisposalMethod = SkCodecAnimation::Keep_DisposalMethod;
(...skipping 20 matching lines...) Expand all
300 frame.fRequiredFrame = kIndependentFrame; 300 frame.fRequiredFrame = kIndependentFrame;
301 } else { 301 } else {
302 frame.fRequiredFrame = i - 1; 302 frame.fRequiredFrame = i - 1;
303 } 303 }
304 break; 304 break;
305 } 305 }
306 } 306 }
307 } 307 }
308 } 308 }
309 309
310 size_t SkGifCodec::onGetRequiredFrame(size_t index) { 310 std::vector<SkCodec::FrameInfo> SkGifCodec::onGetFrameInfo() {
311 if ((int) index >= fFrameInfos.count()) { 311 const size_t size = fFrameInfos.size();
312 return kIndependentFrame; 312 if (1 == size) {
313 // As with other formats, return empty set for non-animated
314 // FIXME: But it might be animated, we just haven't received the second frame?
315 // I suppose we could check the duration? But even that might not be per fect...
316 return {};
313 } 317 }
314 318 std::vector<FrameInfo> result(size);
315 return fFrameInfos[index].fRequiredFrame; 319 for (size_t i = 0; i < size; i++) {
316 } 320 result[i] = (FrameInfo) fFrameInfos[i];
317
318 size_t SkGifCodec::onGetFrameDuration(size_t index) {
319 if ((int) index >= fFrameInfos.count()) {
320 return 0;
321 } 321 }
322 322 return result;
323 return fFrameInfos[index].fDuration;
324 } 323 }
325 324
326 bool SkGifCodec::GetDimensions(GifFileType* gif, SkISize* size) { 325 bool SkGifCodec::GetDimensions(GifFileType* gif, SkISize* size) {
327 // Get the encoded dimension values for the first frame. Some GIFs have fram es that are bigger 326 // Get the encoded dimension values for the first frame. Some GIFs have fram es that are bigger
328 // than the screen width and height. For the first frame only, we will expan d in that case. 327 // than the screen width and height. For the first frame only, we will expan d in that case.
329 SavedImage* image = &gif->SavedImages[0]; 328 SavedImage* image = &gif->SavedImages[0];
330 const GifImageDesc& desc = image->ImageDesc; 329 const GifImageDesc& desc = image->ImageDesc;
331 int frameLeft = desc.Left; 330 int frameLeft = desc.Left;
332 int frameTop = desc.Top; 331 int frameTop = desc.Top;
333 int frameWidth = desc.Width; 332 int frameWidth = desc.Width;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 && dstInfo.colorType() == kIndex_8_SkColorType) { 420 && dstInfo.colorType() == kIndex_8_SkColorType) {
422 // FIXME: It is possible that a later frame can be decoded to index8, if it does one of the 421 // FIXME: It is possible that a later frame can be decoded to index8, if it does one of the
423 // following: 422 // following:
424 // - Covers the entire previous frame 423 // - Covers the entire previous frame
425 // - Shares a color table (and transparent index) with any prior frames that are showing. 424 // - Shares a color table (and transparent index) with any prior frames that are showing.
426 // We must support index8 for the first frame to be backwards compatible on Android. 425 // We must support index8 for the first frame to be backwards compatible on Android.
427 return gif_error("Cannot decode multiframe gif (except frame 0) as index 8.\n", 426 return gif_error("Cannot decode multiframe gif (except frame 0) as index 8.\n",
428 kInvalidConversion); 427 kInvalidConversion);
429 } 428 }
430 429
431 if (opts.fFrameOptions && (int) opts.fFrameOptions->fIndex > fFrameInfos.cou nt()) { 430 if (opts.fFrameOptions && opts.fFrameOptions->fIndex > fFrameInfos.size()) {
432 return gif_error("frame index out of range!\n", kInvalidParameters); 431 return gif_error("frame index out of range!\n", kInvalidParameters);
433 } 432 }
434 433
435 // Initialize color table and copy to the client if necessary 434 // Initialize color table and copy to the client if necessary
436 this->initializeColorTable(dstInfo, inputColorPtr, inputColorCount); 435 this->initializeColorTable(dstInfo, inputColorPtr, inputColorCount);
437 return kSuccess; 436 return kSuccess;
438 } 437 }
439 438
440 /* 439 /*
441 * Initiates the gif decode 440 * Initiates the gif decode
(...skipping 17 matching lines...) Expand all
459 return kSuccess; 458 return kSuccess;
460 } 459 }
461 460
462 // FIXME: This should be SkCodec::Result, probably? 461 // FIXME: This should be SkCodec::Result, probably?
463 void SkGifCodec::decodeFrame(const SkImageInfo& dstInfo, void* pixels, size_t ds tRowBytes, 462 void SkGifCodec::decodeFrame(const SkImageInfo& dstInfo, void* pixels, size_t ds tRowBytes,
464 const Options& opts) { 463 const Options& opts) {
465 SkBitmap tmpBm; 464 SkBitmap tmpBm;
466 void* dst = pixels; 465 void* dst = pixels;
467 466
468 const size_t frameIndex = opts.fFrameOptions ? opts.fFrameOptions->fIndex : 0; 467 const size_t frameIndex = opts.fFrameOptions ? opts.fFrameOptions->fIndex : 0;
469 SkASSERT((int) frameIndex < fFrameInfos.count()); 468 SkASSERT(frameIndex < fFrameInfos.size());
470 const auto& frameInfo = fFrameInfos[frameIndex]; 469 const auto& frameInfo = fFrameInfos[frameIndex];
471 const SkIRect& frameRect = frameInfo.fFrameRect; 470 const SkIRect& frameRect = frameInfo.fFrameRect;
472 const bool independent = frameInfo.fRequiredFrame == kIndependentFrame; 471 const bool independent = frameInfo.fRequiredFrame == kIndependentFrame;
473 if (!independent) { 472 if (!independent) {
474 if (opts.fFrameOptions && !opts.fFrameOptions->fHasPriorFrame) { 473 if (opts.fFrameOptions && !opts.fFrameOptions->fHasPriorFrame) {
475 // Decode that frame into pixels. 474 // Decode that frame into pixels.
476 Options prevFrameOpts(opts); 475 Options prevFrameOpts(opts);
477 MultiFrameOptions prevFrameMultiOpts; 476 MultiFrameOptions prevFrameMultiOpts;
478 prevFrameMultiOpts.fIndex = frameInfo.fRequiredFrame; 477 prevFrameMultiOpts.fIndex = frameInfo.fRequiredFrame;
479 prevFrameMultiOpts.fHasPriorFrame = false; 478 prevFrameMultiOpts.fHasPriorFrame = false;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 } 549 }
551 } 550 }
552 551
553 // FIXME: This is similar to the implementation for bmp and png. Can we share m ore code or 552 // FIXME: This is similar to the implementation for bmp and png. Can we share m ore code or
554 // possibly make this non-virtual? 553 // possibly make this non-virtual?
555 uint64_t SkGifCodec::onGetFillValue(const SkImageInfo& dstInfo) const { 554 uint64_t SkGifCodec::onGetFillValue(const SkImageInfo& dstInfo) const {
556 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); 555 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
557 return get_color_table_fill_value(dstInfo.colorType(), dstInfo.alphaType(), colorPtr, 556 return get_color_table_fill_value(dstInfo.colorType(), dstInfo.alphaType(), colorPtr,
558 fFillIndex, nullptr); 557 fFillIndex, nullptr);
559 } 558 }
OLDNEW
« include/codec/SkCodec.h ('K') | « src/codec/SkGifCodec.h ('k') | tests/CodecAnimTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698