FastLED 3.10.8
Loading...
Searching...
No Matches
gif.cpp.hpp
Go to the documentation of this file.
1#include "fl/codec/gif.h"
2// IWYU pragma: begin_keep
4// IWYU pragma: end_keep
6#include "fl/stl/noexcept.h"
7
8namespace fl {
9
10IDecoderPtr Gif::createDecoder(const GifConfig& config, fl::string* error_message) FL_NO_EXCEPT {
11 // Create the software GIF decoder
12 auto decoder = fl::make_shared<fl::third_party::SoftwareGifDecoder>(config.format);
13
14 if (!decoder) {
15 if (error_message) {
16 *error_message = "Failed to allocate GIF decoder";
17 }
18 return nullptr;
19 }
20
21 return decoder;
22}
23
25 // libnsgif is always available since it's included directly
26 return true;
27}
28
30 GifInfo info;
31
32 // Validate input data
33 if (data.empty()) {
34 if (error_message) {
35 *error_message = "Empty GIF data";
36 }
37 return info; // returns invalid info
38 }
39
40 // Minimum size check - GIF must have at least the header (6 bytes) + some content
41 if (data.size() < 13) { // GIF header (6) + screen descriptor (7)
42 if (error_message) {
43 *error_message = "GIF data too small";
44 }
45 return info;
46 }
47
48 // Check GIF signature
49 if (data[0] != 'G' || data[1] != 'I' || data[2] != 'F') {
50 if (error_message) {
51 *error_message = "Invalid GIF signature";
52 }
53 return info;
54 }
55
56 // Check version (87a or 89a)
57 if (!((data[3] == '8' && data[4] == '7' && data[5] == 'a') ||
58 (data[3] == '8' && data[4] == '9' && data[5] == 'a'))) {
59 if (error_message) {
60 *error_message = "Unsupported GIF version";
61 }
62 return info;
63 }
64
65 // Parse logical screen descriptor (starts at byte 6)
66 // Width (2 bytes, little endian) at offset 6-7
67 // Height (2 bytes, little endian) at offset 8-9
68 fl::u16 width = data[6] | (data[7] << 8);
69 fl::u16 height = data[8] | (data[9] << 8);
70
71 if (width == 0 || height == 0) {
72 if (error_message) {
73 *error_message = "Invalid GIF dimensions";
74 }
75 return info;
76 }
77
78 // For a more complete parsing, we would need to create a temporary decoder
79 // and let libnsgif parse the structure. Let's use the existing decoder briefly.
81 auto stream = fl::make_shared<fl::memorybuf>(data.size());
82 stream->write(data);
83
84 if (decoder->begin(stream)) {
85 // Now we can extract more detailed info using the decoder's methods
86 info.width = decoder->getWidth();
87 info.height = decoder->getHeight();
88 info.frameCount = decoder->getFrameCount();
89 info.loopCount = decoder->getLoopCount();
90 info.isAnimated = decoder->isAnimated();
91 info.bitsPerPixel = 8; // GIF is always 8 bits per pixel
92 info.isValid = true;
93
94 decoder->end();
95 } else {
96 // Fallback to basic header parsing if decoder fails
97 info.width = width;
98 info.height = height;
99 info.frameCount = 1; // Assume static image
100 info.loopCount = 0;
101 info.isAnimated = false;
102 info.bitsPerPixel = 8;
103 info.isValid = true;
104
105 if (error_message) {
106 *error_message = ""; // Clear any error message for fallback case
107 }
108 }
109
110 return info;
111}
112
113} // namespace fl
static GifInfo parseGifInfo(fl::span< const fl::u8 > data, fl::string *error_message=nullptr) FL_NO_EXCEPT
Definition gif.cpp.hpp:29
static IDecoderPtr createDecoder(const GifConfig &config, fl::string *error_message=nullptr) FL_NO_EXCEPT
Definition gif.cpp.hpp:10
static bool isSupported() FL_NO_EXCEPT
Definition gif.cpp.hpp:24
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
Definition shared_ptr.h:423
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
u8 u8 height
Definition blur.h:186
u8 width
Definition blur.h:186
Base definition for an LED controller.
Definition crgb.hpp:179
fl::u16 height
Definition gif.h:13
fl::u32 loopCount
Definition gif.h:15
bool isValid
Definition gif.h:18
bool isAnimated
Definition gif.h:17
fl::u8 bitsPerPixel
Definition gif.h:16
fl::u32 frameCount
Definition gif.h:14
fl::u16 width
Definition gif.h:12