OLD | NEW |
---|---|
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 "SkCodec_libgif.h" | 8 #include "SkCodec_libgif.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
52 static int32_t read_bytes_callback(GifFileType* fileType, GifByteType* out, | 52 static int32_t read_bytes_callback(GifFileType* fileType, GifByteType* out, |
53 int32_t size) { | 53 int32_t size) { |
54 SkStream* stream = (SkStream*) fileType->UserData; | 54 SkStream* stream = (SkStream*) fileType->UserData; |
55 return (int32_t) stream->read(out, size); | 55 return (int32_t) stream->read(out, size); |
56 } | 56 } |
57 | 57 |
58 /* | 58 /* |
59 * Open the gif file | 59 * Open the gif file |
60 */ | 60 */ |
61 static GifFileType* open_gif(SkStream* stream) { | 61 static GifFileType* open_gif(SkStream* stream) { |
62 #if GIFLIB_MAJOR < 5 | |
63 return DGifOpen(stream, read_bytes_callback); | |
64 #else | |
65 return DGifOpen(stream, read_bytes_callback, NULL); | 62 return DGifOpen(stream, read_bytes_callback, NULL); |
66 #endif | |
67 } | 63 } |
68 | 64 |
69 /* | 65 /* |
70 * This function cleans up the gif object after the decode completes | 66 * This function cleans up the gif object after the decode completes |
71 * It is used in a SkAutoTCallIProc template | 67 * It is used in a SkAutoTCallIProc template |
72 */ | 68 */ |
73 void SkGifCodec::CloseGif(GifFileType* gif) { | 69 void SkGifCodec::CloseGif(GifFileType* gif) { |
74 #if GIFLIB_MAJOR < 5 || (GIFLIB_MAJOR == 5 && GIFLIB_MINOR == 0) | 70 #if GIFLIB_MAJOR < 5 || (GIFLIB_MAJOR == 5 && GIFLIB_MINOR == 0) |
msarett
2015/08/21 13:24:26
This is the only one I haven't removed. I think w
| |
75 DGifCloseFile(gif); | 71 DGifCloseFile(gif); |
76 #else | 72 #else |
77 DGifCloseFile(gif, NULL); | 73 DGifCloseFile(gif, NULL); |
78 #endif | 74 #endif |
79 } | 75 } |
80 | 76 |
81 /* | 77 /* |
82 * This function free extension data that has been saved to assist the image | 78 * This function free extension data that has been saved to assist the image |
83 * decoder | 79 * decoder |
84 */ | 80 */ |
85 void SkGifCodec::FreeExtension(SavedImage* image) { | 81 void SkGifCodec::FreeExtension(SavedImage* image) { |
86 if (NULL != image->ExtensionBlocks) { | 82 if (NULL != image->ExtensionBlocks) { |
87 #if GIFLIB_MAJOR < 5 | |
88 FreeExtension(image); | |
89 #else | |
90 GifFreeExtensions(&image->ExtensionBlockCount, &image->ExtensionBlocks); | 83 GifFreeExtensions(&image->ExtensionBlockCount, &image->ExtensionBlocks); |
91 #endif | |
92 } | 84 } |
93 } | 85 } |
94 | 86 |
95 /* | 87 /* |
96 * Check if a there is an index of the color table for a transparent pixel | 88 * Check if a there is an index of the color table for a transparent pixel |
97 */ | 89 */ |
98 static uint32_t find_trans_index(const SavedImage& image) { | 90 static uint32_t find_trans_index(const SavedImage& image) { |
99 // If there is a transparent index specified, it will be contained in an | 91 // If there is a transparent index specified, it will be contained in an |
100 // extension block. We will loop through extension blocks in reverse order | 92 // extension block. We will loop through extension blocks in reverse order |
101 // to check the most recent extension blocks first. | 93 // to check the most recent extension blocks first. |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 kInvalidConversion); | 239 kInvalidConversion); |
248 } | 240 } |
249 | 241 |
250 // Use this as a container to hold information about any gif extension | 242 // Use this as a container to hold information about any gif extension |
251 // blocks. This generally stores transparency and animation instructions. | 243 // blocks. This generally stores transparency and animation instructions. |
252 SavedImage saveExt; | 244 SavedImage saveExt; |
253 SkAutoTCallVProc<SavedImage, FreeExtension> autoFreeExt(&saveExt); | 245 SkAutoTCallVProc<SavedImage, FreeExtension> autoFreeExt(&saveExt); |
254 saveExt.ExtensionBlocks = NULL; | 246 saveExt.ExtensionBlocks = NULL; |
255 saveExt.ExtensionBlockCount = 0; | 247 saveExt.ExtensionBlockCount = 0; |
256 GifByteType* extData; | 248 GifByteType* extData; |
257 #if GIFLIB_MAJOR >= 5 | |
258 int32_t extFunction; | 249 int32_t extFunction; |
259 #endif | |
260 | 250 |
261 // We will loop over components of gif images until we find an image. Once | 251 // We will loop over components of gif images until we find an image. Once |
262 // we find an image, we will decode and return it. While many gif files | 252 // we find an image, we will decode and return it. While many gif files |
263 // contain more than one image, we will simply decode the first image. | 253 // contain more than one image, we will simply decode the first image. |
264 const int32_t width = dstInfo.width(); | 254 const int32_t width = dstInfo.width(); |
265 const int32_t height = dstInfo.height(); | 255 const int32_t height = dstInfo.height(); |
266 GifRecordType recordType; | 256 GifRecordType recordType; |
267 do { | 257 do { |
268 // Get the current record type | 258 // Get the current record type |
269 if (GIF_ERROR == DGifGetRecordType(fGif, &recordType)) { | 259 if (GIF_ERROR == DGifGetRecordType(fGif, &recordType)) { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
498 // displayed in the same frame together. I will | 488 // displayed in the same frame together. I will |
499 // currently leave this unimplemented until I find a | 489 // currently leave this unimplemented until I find a |
500 // test case that expects this behavior. | 490 // test case that expects this behavior. |
501 return kSuccess; | 491 return kSuccess; |
502 } | 492 } |
503 | 493 |
504 // Extensions are used to specify special properties of the image | 494 // Extensions are used to specify special properties of the image |
505 // such as transparency or animation. | 495 // such as transparency or animation. |
506 case EXTENSION_RECORD_TYPE: | 496 case EXTENSION_RECORD_TYPE: |
507 // Read extension data | 497 // Read extension data |
508 #if GIFLIB_MAJOR < 5 | |
509 if (GIF_ERROR == | |
510 DGifGetExtension(fGif, &saveExt.Function, &extData)) { | |
511 #else | |
512 if (GIF_ERROR == | 498 if (GIF_ERROR == |
513 DGifGetExtension(fGif, &extFunction, &extData)) { | 499 DGifGetExtension(fGif, &extFunction, &extData)) { |
514 #endif | |
515 return gif_error("Could not get extension.\n", | 500 return gif_error("Could not get extension.\n", |
516 kIncompleteInput); | 501 kIncompleteInput); |
517 } | 502 } |
518 | 503 |
519 // Create an extension block with our data | 504 // Create an extension block with our data |
520 while (NULL != extData) { | 505 while (NULL != extData) { |
521 // Add a single block | 506 // Add a single block |
522 #if GIFLIB_MAJOR < 5 | |
523 if (GIF_ERROR == AddExtensionBlock(&saveExt, extData[0], | |
524 &extData[1])) { | |
525 #else | |
526 if (GIF_ERROR == | 507 if (GIF_ERROR == |
527 GifAddExtensionBlock(&saveExt.ExtensionBlockCount, | 508 GifAddExtensionBlock(&saveExt.ExtensionBlockCount, |
528 &saveExt.ExtensionBlocks, extFunction, extData[0], | 509 &saveExt.ExtensionBlocks, extFunction, extData[0], |
529 &extData[1])) { | 510 &extData[1])) { |
530 #endif | |
531 return gif_error("Could not add extension block.\n", | 511 return gif_error("Could not add extension block.\n", |
532 kIncompleteInput); | 512 kIncompleteInput); |
533 } | 513 } |
534 // Move to the next block | 514 // Move to the next block |
535 if (GIF_ERROR == DGifGetExtensionNext(fGif, &extData)) { | 515 if (GIF_ERROR == DGifGetExtensionNext(fGif, &extData)) { |
536 return gif_error("Could not get next extension.\n", | 516 return gif_error("Could not get next extension.\n", |
537 kIncompleteInput); | 517 kIncompleteInput); |
538 } | 518 } |
539 #if GIFLIB_MAJOR < 5 | |
540 saveExt.Function = 0; | |
541 #endif | |
542 } | 519 } |
543 break; | 520 break; |
544 | 521 |
545 // Signals the end of the gif file | 522 // Signals the end of the gif file |
546 case TERMINATE_RECORD_TYPE: | 523 case TERMINATE_RECORD_TYPE: |
547 break; | 524 break; |
548 | 525 |
549 default: | 526 default: |
550 // giflib returns an error code if the record type is not known. | 527 // giflib returns an error code if the record type is not known. |
551 // We should catch this error immediately. | 528 // We should catch this error immediately. |
552 SkASSERT(false); | 529 SkASSERT(false); |
553 break; | 530 break; |
554 } | 531 } |
555 } while (TERMINATE_RECORD_TYPE != recordType); | 532 } while (TERMINATE_RECORD_TYPE != recordType); |
556 | 533 |
557 return gif_error("Could not find any images to decode in gif file.\n", | 534 return gif_error("Could not find any images to decode in gif file.\n", |
558 kInvalidInput); | 535 kInvalidInput); |
559 } | 536 } |
OLD | NEW |