| 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 |