OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkMovie.h" | 10 #include "SkMovie.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 static int Decode(GifFileType* fileType, GifByteType* out, int size) { | 41 static int Decode(GifFileType* fileType, GifByteType* out, int size) { |
42 SkStream* stream = (SkStream*) fileType->UserData; | 42 SkStream* stream = (SkStream*) fileType->UserData; |
43 return (int) stream->read(out, size); | 43 return (int) stream->read(out, size); |
44 } | 44 } |
45 | 45 |
46 SkGIFMovie::SkGIFMovie(SkStream* stream) | 46 SkGIFMovie::SkGIFMovie(SkStream* stream) |
47 { | 47 { |
48 #if GIFLIB_MAJOR < 5 | 48 #if GIFLIB_MAJOR < 5 |
49 fGIF = DGifOpen( stream, Decode ); | 49 fGIF = DGifOpen( stream, Decode ); |
50 #else | 50 #else |
51 fGIF = DGifOpen( stream, Decode, NULL ); | 51 fGIF = DGifOpen( stream, Decode, nullptr ); |
52 #endif | 52 #endif |
53 if (NULL == fGIF) | 53 if (nullptr == fGIF) |
54 return; | 54 return; |
55 | 55 |
56 if (DGifSlurp(fGIF) != GIF_OK) | 56 if (DGifSlurp(fGIF) != GIF_OK) |
57 { | 57 { |
58 DGifCloseFile(fGIF, NULL); | 58 DGifCloseFile(fGIF, nullptr); |
59 fGIF = NULL; | 59 fGIF = nullptr; |
60 } | 60 } |
61 fCurrIndex = -1; | 61 fCurrIndex = -1; |
62 fLastDrawIndex = -1; | 62 fLastDrawIndex = -1; |
63 fPaintingColor = SkPackARGB32(0, 0, 0, 0); | 63 fPaintingColor = SkPackARGB32(0, 0, 0, 0); |
64 } | 64 } |
65 | 65 |
66 SkGIFMovie::~SkGIFMovie() | 66 SkGIFMovie::~SkGIFMovie() |
67 { | 67 { |
68 if (fGIF) | 68 if (fGIF) |
69 DGifCloseFile(fGIF, NULL); | 69 DGifCloseFile(fGIF, nullptr); |
70 } | 70 } |
71 | 71 |
72 static SkMSec savedimage_duration(const SavedImage* image) | 72 static SkMSec savedimage_duration(const SavedImage* image) |
73 { | 73 { |
74 for (int j = 0; j < image->ExtensionBlockCount; j++) | 74 for (int j = 0; j < image->ExtensionBlockCount; j++) |
75 { | 75 { |
76 if (image->ExtensionBlocks[j].Function == GRAPHICS_EXT_FUNC_CODE) | 76 if (image->ExtensionBlocks[j].Function == GRAPHICS_EXT_FUNC_CODE) |
77 { | 77 { |
78 SkASSERT(image->ExtensionBlocks[j].ByteCount >= 4); | 78 SkASSERT(image->ExtensionBlocks[j].ByteCount >= 4); |
79 const uint8_t* b = (const uint8_t*)image->ExtensionBlocks[j].Bytes; | 79 const uint8_t* b = (const uint8_t*)image->ExtensionBlocks[j].Bytes; |
80 return ((b[2] << 8) | b[1]) * 10; | 80 return ((b[2] << 8) | b[1]) * 10; |
81 } | 81 } |
82 } | 82 } |
83 return 0; | 83 return 0; |
84 } | 84 } |
85 | 85 |
86 bool SkGIFMovie::onGetInfo(Info* info) | 86 bool SkGIFMovie::onGetInfo(Info* info) |
87 { | 87 { |
88 if (NULL == fGIF) | 88 if (nullptr == fGIF) |
89 return false; | 89 return false; |
90 | 90 |
91 SkMSec dur = 0; | 91 SkMSec dur = 0; |
92 for (int i = 0; i < fGIF->ImageCount; i++) | 92 for (int i = 0; i < fGIF->ImageCount; i++) |
93 dur += savedimage_duration(&fGIF->SavedImages[i]); | 93 dur += savedimage_duration(&fGIF->SavedImages[i]); |
94 | 94 |
95 info->fDuration = dur; | 95 info->fDuration = dur; |
96 info->fWidth = fGIF->SWidth; | 96 info->fWidth = fGIF->SWidth; |
97 info->fHeight = fGIF->SHeight; | 97 info->fHeight = fGIF->SHeight; |
98 info->fIsOpaque = false; // how to compute? | 98 info->fIsOpaque = false; // how to compute? |
99 return true; | 99 return true; |
100 } | 100 } |
101 | 101 |
102 bool SkGIFMovie::onSetTime(SkMSec time) | 102 bool SkGIFMovie::onSetTime(SkMSec time) |
103 { | 103 { |
104 if (NULL == fGIF) | 104 if (nullptr == fGIF) |
105 return false; | 105 return false; |
106 | 106 |
107 SkMSec dur = 0; | 107 SkMSec dur = 0; |
108 for (int i = 0; i < fGIF->ImageCount; i++) | 108 for (int i = 0; i < fGIF->ImageCount; i++) |
109 { | 109 { |
110 dur += savedimage_duration(&fGIF->SavedImages[i]); | 110 dur += savedimage_duration(&fGIF->SavedImages[i]); |
111 if (dur >= time) | 111 if (dur >= time) |
112 { | 112 { |
113 fCurrIndex = i; | 113 fCurrIndex = i; |
114 return fLastDrawIndex != fCurrIndex; | 114 return fLastDrawIndex != fCurrIndex; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 ExtensionBlock* eb = frame->ExtensionBlocks + i; | 232 ExtensionBlock* eb = frame->ExtensionBlocks + i; |
233 if (eb->Function == GRAPHICS_EXT_FUNC_CODE && | 233 if (eb->Function == GRAPHICS_EXT_FUNC_CODE && |
234 eb->ByteCount == 4) { | 234 eb->ByteCount == 4) { |
235 bool has_transparency = ((eb->Bytes[0] & 1) == 1); | 235 bool has_transparency = ((eb->Bytes[0] & 1) == 1); |
236 if (has_transparency) { | 236 if (has_transparency) { |
237 transparent = (unsigned char)eb->Bytes[3]; | 237 transparent = (unsigned char)eb->Bytes[3]; |
238 } | 238 } |
239 } | 239 } |
240 } | 240 } |
241 | 241 |
242 if (frame->ImageDesc.ColorMap != NULL) { | 242 if (frame->ImageDesc.ColorMap != nullptr) { |
243 // use local color table | 243 // use local color table |
244 cmap = frame->ImageDesc.ColorMap; | 244 cmap = frame->ImageDesc.ColorMap; |
245 } | 245 } |
246 | 246 |
247 if (cmap == NULL || cmap->ColorCount != (1 << cmap->BitsPerPixel)) { | 247 if (cmap == nullptr || cmap->ColorCount != (1 << cmap->BitsPerPixel)) { |
248 SkDEBUGFAIL("bad colortable setup"); | 248 SkDEBUGFAIL("bad colortable setup"); |
249 return; | 249 return; |
250 } | 250 } |
251 | 251 |
252 #if GIFLIB_MAJOR < 5 | 252 #if GIFLIB_MAJOR < 5 |
253 // before GIFLIB 5, de-interlacing wasn't done by library at load time | 253 // before GIFLIB 5, de-interlacing wasn't done by library at load time |
254 if (frame->ImageDesc.Interlace) { | 254 if (frame->ImageDesc.Interlace) { |
255 blitInterlace(bm, frame, cmap, transparent); | 255 blitInterlace(bm, frame, cmap, transparent); |
256 return; | 256 return; |
257 } | 257 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 const uint32_t* src = bm->getAddr32(0, 0); | 338 const uint32_t* src = bm->getAddr32(0, 0); |
339 uint32_t* dst = backup->getAddr32(0, 0); | 339 uint32_t* dst = backup->getAddr32(0, 0); |
340 int cnt = bm->width() * bm->height(); | 340 int cnt = bm->width() * bm->height(); |
341 memcpy(dst, src, cnt*sizeof(uint32_t)); | 341 memcpy(dst, src, cnt*sizeof(uint32_t)); |
342 } | 342 } |
343 } | 343 } |
344 | 344 |
345 bool SkGIFMovie::onGetBitmap(SkBitmap* bm) | 345 bool SkGIFMovie::onGetBitmap(SkBitmap* bm) |
346 { | 346 { |
347 const GifFileType* gif = fGIF; | 347 const GifFileType* gif = fGIF; |
348 if (NULL == gif) | 348 if (nullptr == gif) |
349 return false; | 349 return false; |
350 | 350 |
351 if (gif->ImageCount < 1) { | 351 if (gif->ImageCount < 1) { |
352 return false; | 352 return false; |
353 } | 353 } |
354 | 354 |
355 const int width = gif->SWidth; | 355 const int width = gif->SWidth; |
356 const int height = gif->SHeight; | 356 const int height = gif->SHeight; |
357 if (width <= 0 || height <= 0) { | 357 if (width <= 0 || height <= 0) { |
358 return false; | 358 return false; |
(...skipping 26 matching lines...) Expand all Loading... |
385 int lastIndex = fCurrIndex; | 385 int lastIndex = fCurrIndex; |
386 if (lastIndex < 0) { | 386 if (lastIndex < 0) { |
387 // first time | 387 // first time |
388 lastIndex = 0; | 388 lastIndex = 0; |
389 } else if (lastIndex > fGIF->ImageCount - 1) { | 389 } else if (lastIndex > fGIF->ImageCount - 1) { |
390 // this block must not be reached. | 390 // this block must not be reached. |
391 lastIndex = fGIF->ImageCount - 1; | 391 lastIndex = fGIF->ImageCount - 1; |
392 } | 392 } |
393 | 393 |
394 SkColor bgColor = SkPackARGB32(0, 0, 0, 0); | 394 SkColor bgColor = SkPackARGB32(0, 0, 0, 0); |
395 if (gif->SColorMap != NULL) { | 395 if (gif->SColorMap != nullptr) { |
396 const GifColorType& col = gif->SColorMap->Colors[fGIF->SBackGroundColor]
; | 396 const GifColorType& col = gif->SColorMap->Colors[fGIF->SBackGroundColor]
; |
397 bgColor = SkColorSetARGB(0xFF, col.Red, col.Green, col.Blue); | 397 bgColor = SkColorSetARGB(0xFF, col.Red, col.Green, col.Blue); |
398 } | 398 } |
399 | 399 |
400 // draw each frames - not intelligent way | 400 // draw each frames - not intelligent way |
401 for (int i = startIndex; i <= lastIndex; i++) { | 401 for (int i = startIndex; i <= lastIndex; i++) { |
402 const SavedImage* cur = &fGIF->SavedImages[i]; | 402 const SavedImage* cur = &fGIF->SavedImages[i]; |
403 if (i == 0) { | 403 if (i == 0) { |
404 bool trans; | 404 bool trans; |
405 int disposal; | 405 int disposal; |
406 getTransparencyAndDisposalMethod(cur, &trans, &disposal); | 406 getTransparencyAndDisposalMethod(cur, &trans, &disposal); |
407 if (!trans && gif->SColorMap != NULL) { | 407 if (!trans && gif->SColorMap != nullptr) { |
408 fPaintingColor = bgColor; | 408 fPaintingColor = bgColor; |
409 } else { | 409 } else { |
410 fPaintingColor = SkColorSetARGB(0, 0, 0, 0); | 410 fPaintingColor = SkColorSetARGB(0, 0, 0, 0); |
411 } | 411 } |
412 | 412 |
413 bm->eraseColor(fPaintingColor); | 413 bm->eraseColor(fPaintingColor); |
414 fBackup.eraseColor(fPaintingColor); | 414 fBackup.eraseColor(fPaintingColor); |
415 } else { | 415 } else { |
416 // Dispose previous frame before move to next frame. | 416 // Dispose previous frame before move to next frame. |
417 const SavedImage* prev = &fGIF->SavedImages[i-1]; | 417 const SavedImage* prev = &fGIF->SavedImages[i-1]; |
(...skipping 21 matching lines...) Expand all Loading... |
439 char buf[GIF_STAMP_LEN]; | 439 char buf[GIF_STAMP_LEN]; |
440 if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) { | 440 if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) { |
441 if (memcmp(GIF_STAMP, buf, GIF_STAMP_LEN) == 0 || | 441 if (memcmp(GIF_STAMP, buf, GIF_STAMP_LEN) == 0 || |
442 memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 || | 442 memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 || |
443 memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) { | 443 memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) { |
444 // must rewind here, since our construct wants to re-read the data | 444 // must rewind here, since our construct wants to re-read the data |
445 stream->rewind(); | 445 stream->rewind(); |
446 return new SkGIFMovie(stream); | 446 return new SkGIFMovie(stream); |
447 } | 447 } |
448 } | 448 } |
449 return NULL; | 449 return nullptr; |
450 } | 450 } |
451 | 451 |
452 static SkTRegistry<SkMovie*(*)(SkStreamRewindable*)> gReg(Factory); | 452 static SkTRegistry<SkMovie*(*)(SkStreamRewindable*)> gReg(Factory); |
OLD | NEW |