Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /*
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 }