Magellan Linux

Annotation of /trunk/linterm_tools/fw_builder/bootsplash/mng.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 658 - (hide annotations) (download)
Mon Jan 14 16:57:24 2008 UTC (16 years, 4 months ago) by niro
File MIME type: text/plain
File size: 9395 byte(s)
initial import

1 niro 658 /*
2     * fbmngplay - fb console MNG player.
3     * (c) 2001-2002 by Stefan Reinauer, <stepan@suse.de>
4     *
5     * This program is based on mngplay, part of libmng, written and (C) by
6     * Ralph Giles <giles@ashlu.bc.ca>
7     *
8     * This program my be redistributed under the terms of the
9     * GNU General Public Licence, version 2, or at your preference,
10     * any later version.
11     */
12    
13     #include <unistd.h>
14     #include <sys/time.h>
15    
16     #include "fbmngplay.h"
17     #include "console.h"
18     #include "mng.h"
19    
20     mngstuff *mng;
21     unsigned char *bufferstream;
22     unsigned long bufferpos = 0, buffersize = 0;
23    
24     /*
25     * callbacks for the mng decoder
26     */
27    
28     /* memory allocation; data must be zeroed */
29     mng_ptr mngalloc(mng_uint32 size)
30     {
31     return (mng_ptr) calloc(1, size);
32     }
33    
34     /* memory deallocation */
35     void mngfree(mng_ptr p, mng_uint32 size)
36     {
37     free(p);
38     return;
39     }
40    
41     mng_bool mngopenstream(mng_handle mng)
42     {
43     mngstuff *mymng;
44    
45     /* look up our stream struct */
46     mymng = (mngstuff *) mng_get_userdata(mng);
47    
48     /* open the file */
49     mymng->file = fopen(mymng->filename, "rb");
50     if (mymng->file == NULL) {
51     fprintf(stderr, "unable to open '%s'\n", mymng->filename);
52     run = 0;
53     return MNG_FALSE;
54     }
55    
56     if (buffered) {
57     unsigned long len;
58     fseek(mymng->file, 0, SEEK_END);
59     len = ftell(mymng->file);
60     rewind(mymng->file);
61     bufferstream = malloc(len);
62     if (!bufferstream) {
63     /* Not enough memory for buffers
64     * -> we go back to unbuffered mode
65     */
66     printf("Reverted to non buffered mode.\n");
67     buffered = 0;
68     return MNG_TRUE;
69     }
70     buffersize = len;
71     fread(bufferstream, 1, len, mymng->file);
72     bufferpos = 0;
73     fclose(mymng->file);
74     mymng->file = NULL;
75     }
76    
77     return MNG_TRUE;
78     }
79    
80     mng_bool mngclosestream(mng_handle mng)
81     {
82     mngstuff *mymng;
83    
84     /* look up our stream struct */
85     mymng = (mngstuff *) mng_get_userdata(mng);
86    
87     /* close the file */
88     if (mymng->file)
89     fclose(mymng->file);
90     mymng->file = NULL; /* for safety */
91    
92     if (bufferstream) {
93     free(bufferstream);
94     bufferstream = 0;
95     buffersize = 0;
96     bufferpos = 0;
97     }
98     return MNG_TRUE;
99     }
100    
101     /* feed data to the decoder */
102     mng_bool mngreadstream(mng_handle mng, mng_ptr buffer,
103     mng_uint32 size, mng_uint32 * bytesread)
104     {
105     mngstuff *mymng;
106    
107     /* look up our stream struct */
108     mymng = (mngstuff *) mng_get_userdata(mng);
109     if (!buffered) {
110     /* read the requested amount of data from the file */
111     *bytesread = fread(buffer, 1, size, mymng->file);
112     } else {
113     *bytesread = (buffersize - bufferpos) <
114     size ? (buffersize - bufferpos) : size;
115     memcpy(buffer, bufferstream + bufferpos, *bytesread);
116     bufferpos += (*bytesread);
117     }
118     return MNG_TRUE;
119     }
120    
121     mng_bool mnggetbackgroundbuffer(mng_handle mng)
122     {
123     unsigned char *background, *src;
124     mngstuff *mymng = mng_get_userdata(mng);
125     mng_uint32 width = mymng->width, height = mymng->height;
126     int bytes = (mymng->fbbpp >> 3);
127    
128     if (mymng->background)
129     return MNG_TRUE;
130    
131     /* If we're not on the right terminal, don't
132     * initialize background yet.
133     */
134     if (sconly && current_console() != start_console)
135     return MNG_FALSE;
136    
137     background = (unsigned char *) malloc(width * height * bytes);
138     if (background == NULL) {
139     fprintf(stderr, "could not allocate background buffer.\n");
140     exit(0);
141     }
142    
143     mymng->background = background;
144     src =
145     mymng->display + (mymng->fbwidth * mymng->fby +
146     mymng->fbx) * bytes;
147    
148     while (height--) {
149     memcpy(background, src, width * bytes);
150     background += width * bytes;
151     src += mymng->fbrow;
152     }
153    
154     return MNG_TRUE;
155     }
156    
157     /* the header's been read. set up the display stuff */
158     mng_bool mngprocessheader(mng_handle mng,
159     mng_uint32 width, mng_uint32 height)
160     {
161     mngstuff *mymng;
162     unsigned char *copybuffer;
163    
164     mymng = (mngstuff *) mng_get_userdata(mng);
165     mymng->width = width;
166     mymng->height = height;
167    
168     copybuffer = (unsigned char *) malloc(width * height * 4);
169     if (copybuffer == NULL) {
170     fprintf(stderr, "could not allocate copy buffer.\n");
171     exit(0);
172     }
173     mymng->copybuffer = copybuffer;
174    
175     /* Try to get background buffer */
176     mnggetbackgroundbuffer(mng);
177    
178     /* tell the mng decoder about our bit-depth choice */
179     /* FIXME: this works on intel. is it correct in general? */
180     mng_set_canvasstyle(mng, MNG_CANVAS_BGRA8);
181    
182     return MNG_TRUE;
183     }
184    
185     /* return a row pointer for the decoder to fill */
186     mng_ptr mnggetcanvasline(mng_handle mng, mng_uint32 line)
187     {
188     mngstuff *mymng;
189     mng_ptr row;
190    
191     /* dereference our structure */
192     mymng = (mngstuff *) mng_get_userdata(mng);
193    
194     /* we assume any necessary locking has happened
195     outside, in the frame level code */
196     row = mymng->copybuffer + mymng->width * 4 * line;
197    
198     return (row);
199     }
200    
201     /* timer */
202     mng_uint32 mnggetticks(mng_handle mng)
203     {
204     mng_uint32 ticks;
205     struct timeval tv;
206     struct timezone tz;
207    
208     gettimeofday(&tv, &tz);
209     ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
210    
211     return (ticks);
212     }
213    
214     static inline void copyline(unsigned char *dest, unsigned char *src,
215     unsigned char *background, mngstuff * mymng)
216     {
217     // BGRA8
218     unsigned int i = mymng->width;
219     unsigned int fr, fg, fb, br, bg, bb, r, g, b, a;
220     unsigned short output, input;
221    
222     while (i--) {
223     fb = *src++;
224     fg = *src++;
225     fr = *src++;
226    
227     a = *src++;
228     a = a * mymng->alpha / 100;
229     switch (mymng->fbbpp) {
230     case 16:
231     input = *((unsigned short *) background)++;
232    
233     br = (input >> mng->fbredo) << (8 - mng->fbredl);
234     bg = (input >> mng->fbgreeno) << (8 -
235     mng->fbgreenl);
236     bb = (input >> mng->fbblueo) << (8 - mng->fbbluel);
237     br &= 0xf8;
238     bg &= 0xfc;
239     bb &= 0xff;
240     #if 0
241     br = (input >> 8) & 0xf8;
242     bg = (input >> 3) & 0xfc;
243     bb = input << 3 & 0xff;
244     #endif
245     break;
246     case 24:
247     bb = *background++;
248     bg = *background++;
249     br = *background++;
250     break;
251     case 32:
252     bb = *background++;
253     bg = *background++;
254     br = *background++;
255     background++;
256     break;
257     default:
258     br = 0;
259     bg = 0;
260     bb = 0;
261     printf("depth not supported.\n");
262     run = 0;
263     break;
264     }
265    
266     r = ((fr * a) + (br * (0x100 - a))) >> 8;
267     g = ((fg * a) + (bg * (0x100 - a))) >> 8;
268     b = ((fb * a) + (bb * (0x100 - a))) >> 8;
269    
270     switch (mymng->fbbpp) {
271     case 16:
272     // dumb 24->16 bit conversion.
273     r >>= (8 - mng->fbredl);
274     g >>= (8 - mng->fbgreenl);
275     b >>= (8 - mng->fbbluel);
276    
277     output =
278     (r << mng->fbredo) | (g << mng->
279     fbgreeno) | (b << mng->
280     fbblueo);
281    
282     *((unsigned short *) dest)++ = output;
283     break;
284     case 24:
285     *dest++ = b;
286     *dest++ = g;
287     *dest++ = r;
288     break;
289     case 32:
290     *dest++ = b;
291     *dest++ = g;
292     *dest++ = r;
293     dest++;
294     break;
295     default:
296     break;
297     }
298     }
299     }
300    
301     mng_bool mngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y,
302     mng_uint32 w, mng_uint32 h)
303     {
304     mngstuff *mymng = mng_get_userdata(mng);
305     unsigned char *background;
306     unsigned char *dest, *src;
307     int bytes = (mymng->fbbpp >> 3);
308    
309     if (sconly && current_console() != start_console)
310     return MNG_TRUE;
311    
312     /* When we read the header, we might still
313     * have been on a different console
314     */
315    
316     if (!(mymng->background))
317     mnggetbackgroundbuffer(mng);
318    
319     background = mymng->background;
320    
321     dest =
322     mymng->display + (mymng->fby * mymng->fbwidth +
323     mymng->fbx) * bytes;
324     src = mymng->copybuffer;
325    
326     /* refresh the screen with the new frame */
327     while (h-- > 0) {
328     copyline(dest, src, background, mymng);
329    
330     dest += mymng->fbrow;
331     background += mymng->width * bytes;
332     /* 4 bytes per pixel due to RGBA */
333     src += 4 * mymng->width;
334     }
335    
336     /* remove traces in alpha transparent pictures. */
337     memset(mymng->copybuffer, 0, 4 * mymng->width * mymng->height);
338    
339     return MNG_TRUE;
340     }
341    
342     /* interframe delay callback */
343     mng_bool mngsettimer(mng_handle mng, mng_uint32 msecs)
344     {
345     mngstuff *mymng;
346    
347     /* look up our stream struct */
348     mymng = (mngstuff *) mng_get_userdata(mng);
349    
350     /* set the timer for when the decoder wants to be woken */
351     mymng->delay = msecs;
352    
353     return MNG_TRUE;
354     }
355    
356     mng_bool mngerror(mng_handle mng, mng_int32 code, mng_int8 severity,
357     mng_chunkid chunktype, mng_uint32 chunkseq,
358     mng_int32 extra1, mng_int32 extra2, mng_pchar text)
359     {
360     mngstuff *mymng;
361     char chunk[5];
362    
363     /* dereference our data so we can get the filename */
364     mymng = (mngstuff *) mng_get_userdata(mng);
365     /* pull out the chuck type as a string */
366     // FIXME: does this assume unsigned char?
367     chunk[0] = (char) ((chunktype >> 24) & 0xFF);
368     chunk[1] = (char) ((chunktype >> 16) & 0xFF);
369     chunk[2] = (char) ((chunktype >> 8) & 0xFF);
370     chunk[3] = (char) ((chunktype) & 0xFF);
371     chunk[4] = '\0';
372    
373     /* output the error */
374     fprintf(stderr, "error playing '%s' chunk %s (%d):\n",
375     mymng->filename, chunk, chunkseq);
376     fprintf(stderr, "%s\n", text);
377    
378     return 0;
379     }
380    
381     int mngquit(mng_handle mng)
382     {
383     mngstuff *mymng;
384    
385     /* dereference our data so we can free it */
386     mymng = (mngstuff *) mng_get_userdata(mng);
387    
388     /* cleanup. this will call mymngclosestream */
389     mng_cleanup(&mng);
390    
391     /* free our data */
392     free(mymng);
393    
394     exit(0);
395     }
396    
397     void cleanup(void)
398     {
399     mngquit(mng->mng);
400     exit(0);
401     }
402    
403     void restore_area(void)
404     {
405     int height, width;
406     unsigned char *dest, *background;
407    
408     if (sconly && current_console() != start_console)
409     return;
410    
411     /* when we didn't manage to get a background until
412     * now, we don't have anything to restore anyways.
413     */
414    
415     if (!(mng->background))
416     return;
417    
418     background = mng->background;
419     height = mng->height;
420     width = mng->width;
421     dest = mng->display + ((mng->fbwidth * mng->fby + mng->fbx) *
422     (mng->fbbpp >> 3));
423    
424     while (height--) {
425     memcpy(dest, background, width * (mng->fbbpp >> 3));
426     background += width * (mng->fbbpp >> 3);
427     dest += mng->fbrow;
428     }
429     }