1 | // Aseprite FLIC Library |
2 | // Copyright (c) 2015 David Capello |
3 | // |
4 | // This file is released under the terms of the MIT license. |
5 | // Read LICENSE.txt for more information. |
6 | |
7 | #ifndef FLIC_FLIC_H_INCLUDED |
8 | #define FLIC_FLIC_H_INCLUDED |
9 | #pragma once |
10 | |
11 | #include <stdint.h> |
12 | |
13 | #include <cassert> |
14 | #include <cstdio> |
15 | #include <vector> |
16 | |
17 | namespace flic { |
18 | |
19 | struct Color { |
20 | uint8_t r, g, b; |
21 | |
22 | Color() : r(0), g(0), b(0) { |
23 | } |
24 | |
25 | Color(uint8_t r, uint8_t g, uint8_t b) : r(r), g(g), b(b) { |
26 | } |
27 | |
28 | bool operator==(const Color& o) const { |
29 | return r == o.r && g == o.g && b == o.b; |
30 | } |
31 | |
32 | bool operator!=(const Color& o) const { |
33 | return !operator==(o); |
34 | } |
35 | }; |
36 | |
37 | struct { |
38 | int ; |
39 | int ; |
40 | int ; |
41 | int ; |
42 | }; |
43 | |
44 | class Colormap { |
45 | public: |
46 | static const int SIZE = 256; |
47 | |
48 | Colormap() { |
49 | } |
50 | |
51 | int size() const { |
52 | return SIZE; |
53 | } |
54 | |
55 | const Color& operator[](int i) const { |
56 | assert(i >= 0 && i < SIZE); |
57 | return m_color[i]; |
58 | } |
59 | |
60 | Color& operator[](int i) { |
61 | assert(i >= 0 && i < SIZE); |
62 | return m_color[i]; |
63 | } |
64 | |
65 | bool operator==(const Colormap& o) const { |
66 | for (int i=0; i<SIZE; ++i) { |
67 | if (m_color[i] != o[i]) |
68 | return false; |
69 | } |
70 | return true; |
71 | } |
72 | |
73 | bool operator!=(const Colormap& o) const { |
74 | return !operator==(o); |
75 | } |
76 | |
77 | private: |
78 | Color m_color[SIZE]; |
79 | }; |
80 | |
81 | struct Frame { |
82 | uint8_t* pixels; |
83 | uint32_t rowstride; |
84 | Colormap colormap; |
85 | }; |
86 | |
87 | class FileInterface { |
88 | public: |
89 | virtual ~FileInterface() { } |
90 | |
91 | // Returns true if we can read/write bytes from/into the file |
92 | virtual bool ok() const = 0; |
93 | |
94 | // Current position in the file |
95 | virtual size_t tell() = 0; |
96 | |
97 | // Jump to the given position in the file |
98 | virtual void seek(size_t absPos) = 0; |
99 | |
100 | // Returns the next byte in the file or 0 if ok() = false |
101 | virtual uint8_t read8() = 0; |
102 | |
103 | // Writes one byte in the file (or do nothing if ok() = false) |
104 | virtual void write8(uint8_t value) = 0; |
105 | }; |
106 | |
107 | class StdioFileInterface : public flic::FileInterface { |
108 | public: |
109 | StdioFileInterface(FILE* file); |
110 | bool ok() const override; |
111 | size_t tell() override; |
112 | void seek(size_t absPos) override; |
113 | uint8_t read8() override; |
114 | void write8(uint8_t value) override; |
115 | |
116 | private: |
117 | FILE* m_file; |
118 | bool m_ok; |
119 | }; |
120 | |
121 | class Decoder { |
122 | public: |
123 | Decoder(FileInterface* file); |
124 | bool (Header& ); |
125 | bool readFrame(Frame& frame); |
126 | |
127 | private: |
128 | void readChunk(Frame& frame); |
129 | void readBlackChunk(Frame& frame); |
130 | void readCopyChunk(Frame& frame); |
131 | void readColorChunk(Frame& frame, bool oldColorChunk); |
132 | void readBrunChunk(Frame& frame); |
133 | void readLcChunk(Frame& frame); |
134 | void readDeltaChunk(Frame& frame); |
135 | uint16_t read16(); |
136 | uint32_t read32(); |
137 | |
138 | FileInterface* m_file; |
139 | int m_width, m_height; |
140 | int m_frameCount; |
141 | int m_offsetFrame1; |
142 | int m_offsetFrame2; |
143 | }; |
144 | |
145 | class Encoder { |
146 | public: |
147 | Encoder(FileInterface* file); |
148 | ~Encoder(); |
149 | |
150 | void (const Header& ); |
151 | void writeFrame(const Frame& frame); |
152 | |
153 | // Must be called at the end with the first frame. It's required |
154 | // by Animator Pro to loop the animation from the last frame to |
155 | // the first one. |
156 | void writeRingFrame(const Frame& frame); |
157 | |
158 | private: |
159 | void writeColorChunk(const Frame& frame); |
160 | void writeBrunChunk(const Frame& frame); |
161 | void writeBrunLineChunk(const Frame& frame, int y); |
162 | void writeLcChunk(const Frame& frame); |
163 | void writeLcLineChunk(const Frame& frame, int y); |
164 | void write16(uint16_t value); |
165 | void write32(uint32_t value); |
166 | |
167 | FileInterface* m_file; |
168 | int m_width, m_height; |
169 | Colormap m_prevColormap; |
170 | std::vector<uint8_t> m_prevFrameData; |
171 | int m_frameCount; |
172 | int m_offsetFrame1; |
173 | int m_offsetFrame2; |
174 | }; |
175 | |
176 | } // namespace flic |
177 | |
178 | #endif |
179 | |