ecere/gui/Window: Prevent uninitialized values if base Window methods not overridden...
[sdk] / extras / fli.ec
1 /****************************************************************************
2    FLC/FLI Player
3
4    Copyright (c) 2001 Jerome Jacovella-St-Louis
5    All Rights Reserved.
6
7 ****************************************************************************/
8 import "ecere"
9
10 #pragma pack(push,1)
11
12 struct FLIheader
13 {
14    uint size              __attribute__((packed));
15    uint16 magic           __attribute__((packed));
16    uint16 frame           __attribute__((packed));
17    uint16 width           __attribute__((packed));
18    uint16 height          __attribute__((packed));
19    uint16 depth           __attribute__((packed));
20    uint16 flags           __attribute__((packed));
21    uint16 speed           __attribute__((packed));
22    uint next              __attribute__((packed));
23    uint frit              __attribute__((packed));
24    byte expand[102];
25 };
26
27 struct FLIFrame
28 {
29    uint size              __attribute__((packed));
30    uint16 magic           __attribute__((packed));
31    uint16 chunknum        __attribute__((packed));
32    byte nothing[8];
33 };
34
35 struct FLIchunk
36 {
37    uint size              __attribute__((packed));
38    uint16 type            __attribute__((packed));
39 };
40
41 #pragma pack(pop)
42
43 #define FLI_COLOR       11  //RGB ranging from 0-63
44 #define FLI_BLACK       13  //When creating a new frame
45 #define FLI_COPY        16  //Raw
46
47 #define FLI_LC          12  //Line compression (common)
48 #define FLI_BRUN        15  //First frame only
49 #define FLI_DELTA       7   //Delta (common)
50 #define FLI_256_COLOR   4   //RGB ranging from 0-255
51 #define FLI_MINI        18  //That's shit
52
53 class Fli
54 {
55    // Private
56    FLIheader header;
57    FLIFrame fliFrame;
58    FLIchunk chunk;
59    File f;
60
61    void FliColor(Bitmap bitmap)
62    {
63       uint16 skip=0, put;
64       uint16 num;
65       uint16 c;
66       byte palette[768];
67       f.Read(&num,sizeof(uint16),1);
68       for(; num>0; num--)
69       {
70          byte ch;
71
72          f.Getc((char *)&ch);
73          skip+=ch;
74          f.Getc((char *)&ch);
75          put=ch;
76
77          if(!put)
78             put=256;
79          f.Read(palette+skip*3,1,3*put);
80
81          if(chunk.type!=FLI_256_COLOR)
82             for(c=0; c<put*3; c++)
83                palette[c+skip*3]*=4;
84          for(c=skip; c<skip+put; c++)
85             this.palette[c] = ColorAlpha {255, Color{palette[c*3],palette[c*3+1],palette[c*3+2]}};
86          CopyBytesBy4(bitmap.palette+skip,this.palette+skip,put);
87          skip+=put;
88       }
89       palUpdate=true;
90    }
91
92    void Lc(Bitmap bitmap)
93    {
94       uint offset;
95       short skipline, putline;
96       byte value;
97       short num;
98       signed char put;
99
100       f.Read(&skipline,sizeof(uint16),1);
101       f.Read(&putline,sizeof(uint16),1);
102       for(; putline>0; putline--, skipline++)
103       {
104          byte ch;
105          offset=skipline*bitmap.width;
106          f.Getc((char *)&ch);
107          num = ch;
108          for(; num>0; num--)
109          {
110             f.Getc((char *)&ch);
111             offset += ch;
112             f.Getc((char *)&ch);
113             put = ch;
114             if(put>0)
115             {
116                f.Read(bitmap.picture+offset,1,put);
117                offset+=put;
118             }
119             else if(put<0)
120             {
121                f.Getc((char *)&value);
122                FillBytes(bitmap.picture+offset,value,-put);
123                offset-=put;
124             }
125          }
126       }
127    }
128
129    void Delta(Bitmap bitmap)
130    {
131       byte ch;
132       short putline;
133       int y;
134       int offset;
135
136       short num;
137       signed char put;
138       uint16 value;
139
140       f.Read(&putline,sizeof(uint16),1);
141
142       for(y=0; putline>0; )
143       {
144          f.Read(&num,sizeof(uint16),1);
145          if(!num)break;
146          if(num>0)
147          {
148             offset=y*bitmap.width;
149             for(; num>0; num--)
150             {
151                f.Getc((char *)&ch);
152                offset += ch;
153                f.Getc((char *)&ch);
154                put = ch;
155
156                if(put>0)
157                {
158                   f.Read(bitmap.picture+offset,1,put*2);
159                   offset+=put*2;
160                }
161                else if(put<0)
162                {
163                   f.Read(&value,sizeof(uint16),1);
164                   FillBytesBy2(bitmap.picture+offset,value,-put);
165                   offset-=put*2;
166                }
167             }
168             y++;
169             putline--;
170          }
171          else if(num<0)
172             y-=num;
173       }
174    }
175
176    void Brun(Bitmap bitmap)
177    {
178       uint offset;
179       int y;
180       //short num;
181       signed char put;
182       byte value;
183       for(y=0; y<bitmap.height; y++)
184       {
185          byte ch;
186          int x = 0;
187          f.Getc((char *)&ch);
188          //num = ch;
189          /*if(!num)
190          {
191             f.Getc((char *)&ch);
192             f.Getc((char *)&ch);
193             FillBytes(bitmap.picture,ch,bitmap.size);
194             return;
195          }*/
196          offset=bitmap.width*y;
197          // for(; num>0 && x < bitmap.width; num--)
198          for(; x < bitmap.width; )
199          {
200             f.Getc((char *)&ch);
201             put = ch;
202             if(put<0)
203             {
204                f.Read(bitmap.picture+offset,1,-put);
205                offset-=put;
206                x-=put;
207             }
208             else if(put>0)
209             {
210                f.Getc((char *)&value);
211                if(offset > bitmap.width * bitmap.height)
212                   printf("bug");
213                FillBytes(bitmap.picture+offset,value,put);
214                offset += put;
215                x+=put;
216             }
217          }
218       }
219    }
220
221    // Public
222    int width, height;
223    double speed;
224    ColorAlpha palette[256];
225    int numFrames;
226    int frame;
227    bool palUpdate;
228
229    property int width { get { return width; } }
230    property int height { get { return height; } }
231    property double speed { get { return speed; } }
232    property ColorAlpha * palette { get { return palette; } }
233    property int numFrames { get { return numFrames; } }
234    property int frame { get { return frame; } set { frame = value; } }
235    property bool palUpdate { get { return palUpdate; } set { palUpdate = value; }}
236
237    bool Load(const char *fileName)
238    {
239       bool result = false;
240       //f=FileOpen(fileName, read);
241       f = FileOpenBuffered(fileName, read);
242       if(f)
243       {
244          f.Read(&header,sizeof(FLIheader),1);
245          if(header.magic<0xAF12)
246             header.speed = header.speed * 100 / 7;
247          speed = header.speed / 1000.0;
248          palUpdate=false;
249          frame=0;
250          width = header.width;
251          height = header.height;
252          FillBytesBy4(palette,0,256);
253          numFrames = header.frame;
254
255          result = true;
256       }
257       return result;
258    }
259
260    void PlayFrame(Bitmap bitmap)
261    {
262       int nextf,nextc;
263
264       if(!f) return;
265       if(frame==header.frame)
266         frame=0;
267       if(!frame)
268          f.Seek(128L, start);
269
270       f.Read(&fliFrame,sizeof(FLIFrame),1);
271       nextf=f.Tell()+fliFrame.size-sizeof(FLIFrame);
272       for(; fliFrame.chunknum>0; fliFrame.chunknum--)
273       {
274          f.Read(&chunk,sizeof(FLIchunk),1);
275          nextc=f.Tell()+chunk.size-sizeof(FLIchunk);
276          switch(chunk.type)
277          {
278             case FLI_COLOR:      FliColor(bitmap); break;
279             case FLI_256_COLOR:  FliColor(bitmap); break;
280             case FLI_BRUN:       Brun(bitmap); break;
281             case FLI_LC:         Lc(bitmap); break;
282             case FLI_DELTA:      Delta(bitmap); break;
283             case FLI_BLACK:      FillBytes(bitmap.picture,0,bitmap.size); break;
284             case FLI_COPY:       f.Read(bitmap.picture,1,bitmap.size);  break;
285          }
286          f.Seek(nextc, start);
287       }
288       f.Seek(nextf, start);
289       frame++;
290    }
291
292    bool Save(char *fileName, Bitmap bitmap, int frames, int speed)
293    {
294       f=FileOpen(fileName, write);
295       if(!f)
296          return false;
297       header.size=sizeof(FLIheader)+
298                        sizeof(FLIchunk)+768+
299                        (sizeof(FLIFrame)+sizeof(FLIchunk)+bitmap.size)*frames;
300
301       header.magic=0xAF12;
302       header.frame=(uint16)frames;
303       header.width=(uint16)bitmap.width;
304       header.height=(uint16)bitmap.height;
305       header.depth=8;
306       header.flags=0;
307       header.speed=(uint16)speed;
308       header.next=0;
309       header.frit=0;
310       FillBytes(header.expand,0,102);
311       f.Write(&header,sizeof(FLIheader),1);
312       frame=0;
313       FillBytesBy4(palette,0,256);
314       return true;
315    }
316
317    void SaveFrame(Bitmap bitmap, ColorAlpha * palette)
318    {
319       uint16 num;
320       int c;
321       fliFrame.magic=0xF1FA;
322       fliFrame.chunknum=1;
323       fliFrame.size=sizeof(FLIFrame)+sizeof(FLIchunk)+bitmap.size;
324       if(!frame)
325       {
326          fliFrame.chunknum++;
327          fliFrame.size+=sizeof(FLIchunk)+772;
328       }
329       FillBytes(fliFrame.nothing,0,8);
330       f.Write(&fliFrame,sizeof(FLIFrame),1);
331
332       if(!frame)
333       {
334          //Color chunk
335          CopyBytesBy4(palette,palette,256);
336          chunk.size=sizeof(FLIchunk)+772;
337          chunk.type=FLI_COLOR;
338          f.Write(&chunk,sizeof(FLIchunk),1);
339          num=1;
340          f.Write(&num,sizeof(uint16),1);
341          num=0;
342          f.Write(&num,sizeof(uint16),1);
343          for(c=0; c<256; c++)
344          {
345             f.Putc(palette[c].color.r);
346             f.Putc(palette[c].color.g);
347             f.Putc(palette[c].color.b);
348          }
349       }
350       //Copy chunk
351       chunk.size=sizeof(FLIchunk)+bitmap.size;
352       chunk.type=FLI_COPY;
353       f.Write(&chunk,sizeof(FLIchunk),1);
354       f.Write(bitmap.picture,1,bitmap.size);
355    }
356
357    /*
358    ~Fli()
359    {
360       delete f;
361    }
362    */
363 }