forked from pixelmatix/AnimatedGIFs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
GifDecoder.h
152 lines (128 loc) · 4.44 KB
/
GifDecoder.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#ifndef _GIFDECODER_H_
#define _GIFDECODER_H_
#include <stdint.h>
typedef void (*callback)(void);
typedef void (*pixel_callback)(int16_t x, int16_t y, uint8_t red, uint8_t green, uint8_t blue);
typedef void* (*get_buffer_callback)(void);
typedef bool (*file_seek_callback)(unsigned long position);
typedef unsigned long (*file_position_callback)(void);
typedef int (*file_read_callback)(void);
typedef int (*file_read_block_callback)(void * buffer, int numberOfBytes);
typedef struct rgb_24 {
uint8_t red;
uint8_t green;
uint8_t blue;
} rgb_24;
// LZW constants
// NOTE: LZW_MAXBITS should be set to 10 or 11 for small displays, 12 for large displays
// all 32x32-pixel GIFs tested work with 11, most work with 10
// LZW_MAXBITS = 12 will support all GIFs, but takes 16kB RAM
#define LZW_SIZTABLE (1 << lzwMaxBits)
template <int maxGifWidth, int maxGifHeight, int lzwMaxBits>
class GifDecoder {
public:
int startDecoding(void);
int decodeFrame(void);
void setScreenClearCallback(callback f);
void setUpdateScreenCallback(callback f);
void setDrawPixelCallback(pixel_callback f);
void setStartDrawingCallback(callback f);
void setFileSeekCallback(file_seek_callback f);
void setFilePositionCallback(file_position_callback f);
void setFileReadCallback(file_read_callback f);
void setFileReadBlockCallback(file_read_block_callback f);
private:
void parseTableBasedImage(void);
void decompressAndDisplayFrame(unsigned long filePositionAfter);
int parseData(void);
int parseGIFFileTerminator(void);
void parseCommentExtension(void);
void parseApplicationExtension(void);
void parseGraphicControlExtension(void);
void parsePlainTextExtension(void);
void parseGlobalColorTable(void);
void parseLogicalScreenDescriptor(void);
bool parseGifHeader(void);
void copyImageDataRect(uint8_t *dst, uint8_t *src, int x, int y, int width, int height);
void fillImageData(uint8_t colorIndex);
void fillImageDataRect(uint8_t colorIndex, int x, int y, int width, int height);
int readIntoBuffer(void *buffer, int numberOfBytes);
int readWord(void);
void backUpStream(int n);
int readByte(void);
void lzw_decode_init(int csize);
int lzw_decode(uint8_t *buf, int len, uint8_t *bufend);
void lzw_setTempBuffer(uint8_t * tempBuffer);
int lzw_get_code(void);
// Logical screen descriptor attributes
int lsdWidth;
int lsdHeight;
int lsdPackedField;
int lsdAspectRatio;
int lsdBackgroundIndex;
// Table based image attributes
int tbiImageX;
int tbiImageY;
int tbiWidth;
int tbiHeight;
int tbiPackedBits;
bool tbiInterlaced;
int frameDelay;
int transparentColorIndex;
int prevBackgroundIndex;
int prevDisposalMethod;
int disposalMethod;
int lzwCodeSize;
bool keyFrame;
int rectX;
int rectY;
int rectWidth;
int rectHeight;
unsigned long nextFrameTime_ms;
int colorCount;
rgb_24 palette[256];
char tempBuffer[260];
// Buffer image data is decoded into
uint8_t imageData[maxGifWidth * maxGifHeight];
// Backup image data buffer for saving portions of image disposal method == 3
uint8_t imageDataBU[maxGifWidth * maxGifHeight];
callback screenClearCallback;
callback updateScreenCallback;
pixel_callback drawPixelCallback;
callback startDrawingCallback;
file_seek_callback fileSeekCallback;
file_position_callback filePositionCallback;
file_read_callback fileReadCallback;
file_read_block_callback fileReadBlockCallback;
// LZW variables
int bbits;
int bbuf;
int cursize; // The current code size
int curmask;
int codesize;
int clear_code;
int end_code;
int newcodes; // First available code
int top_slot; // Highest code for current size
int extra_slot;
int slot; // Last read code
int fc, oc;
int bs; // Current buffer size for GIF
int bcnt;
uint8_t *sp;
uint8_t * temp_buffer;
uint8_t stack [LZW_SIZTABLE];
uint8_t suffix [LZW_SIZTABLE];
uint16_t prefix [LZW_SIZTABLE];
// Masks for 0 .. 16 bits
unsigned int mask[17] = {
0x0000, 0x0001, 0x0003, 0x0007,
0x000F, 0x001F, 0x003F, 0x007F,
0x00FF, 0x01FF, 0x03FF, 0x07FF,
0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
0xFFFF
};
};
#include "GifDecoder_Impl.h"
#include "LzwDecoder_Impl.h"
#endif