]> git.pld-linux.org Git - packages/kernel.git/blob - bootsplash-3.0.7-2.4.25.patch
- IT82XX seriec RAID support
[packages/kernel.git] / bootsplash-3.0.7-2.4.25.patch
1 diff -urN linux-2.4.24.org/drivers/char/console.c linux-2.4.24/drivers/char/console.c
2 --- linux-2.4.24.org/drivers/char/console.c     2004-01-19 21:00:14.495123806 +0100
3 +++ linux-2.4.24/drivers/char/console.c 2004-01-19 21:03:48.017721428 +0100
4 @@ -3025,6 +3025,31 @@
5         return 0;
6  }
7  
8 +#ifdef CONFIG_FBCON_SPLASHSCREEN
9 +void con_remap_def_color(int currcons, int new_color)
10 +{
11 +       unsigned short *sbuf = screenbuf;
12 +       unsigned c, len = screenbuf_size >> 1;
13 +       int old_color;
14 +
15 +       if (sbuf) {
16 +               old_color = def_color << 8;
17 +               new_color <<= 8;
18 +               while(len--) {
19 +                       c = *sbuf;
20 +                       if (((c ^ old_color) & 0xf000) == 0)
21 +                               *sbuf ^= (old_color ^ new_color) & 0xf000;
22 +                       if (((c ^ old_color) & 0x0f00) == 0)
23 +                               *sbuf ^= (old_color ^ new_color) & 0x0f00;
24 +                       sbuf++;
25 +               }
26 +               new_color >>= 8;
27 +       }
28 +       def_color = color = new_color;
29 +       update_attr(currcons);
30 +}
31 +#endif
32 +
33  /*
34   *     Visible symbols for modules
35   */
36 diff -urN linux-2.4.24.org/drivers/char/keyboard.c linux-2.4.24/drivers/char/keyboard.c
37 --- linux-2.4.24.org/drivers/char/keyboard.c    2004-01-19 21:00:14.168191795 +0100
38 +++ linux-2.4.24/drivers/char/keyboard.c        2004-01-19 21:03:48.066711241 +0100
39 @@ -263,6 +263,15 @@
40         } else
41                 rep = test_and_set_bit(keycode, key_down);
42  
43 +#ifdef CONFIG_FBCON_SPLASHSCREEN
44 +       /* This code has to be redone for some non-x86 platforms */
45 +       if (keycode == 0x3c || keycode == 0x01) {       /* F2 and ESC on a PC keyboard */
46 +               extern int splash_verbose(void);
47 +               if (splash_verbose())
48 +                   goto out;
49 +       }
50 +#endif
51 +
52  #ifdef CONFIG_MAGIC_SYSRQ              /* Handle the SysRq Hack */
53         if (keycode == SYSRQ_KEY) {
54                 sysrq_pressed = !up_flag;
55 diff -urN linux-2.4.24.org/drivers/char/n_tty.c linux-2.4.24/drivers/char/n_tty.c
56 --- linux-2.4.24.org/drivers/char/n_tty.c       2004-01-19 21:00:16.323743526 +0100
57 +++ linux-2.4.24/drivers/char/n_tty.c   2004-01-19 21:03:48.097704796 +0100
58 @@ -45,6 +45,7 @@
59  #include <linux/string.h>
60  #include <linux/slab.h>
61  #include <linux/poll.h>
62 +#include <linux/config.h>
63  
64  #include <asm/uaccess.h>
65  #include <asm/system.h>
66 @@ -971,6 +972,16 @@
67                 return -EIO;
68         }
69  
70 +#ifdef CONFIG_FBCON_SPLASHSCREEN
71 +       if (file->f_dentry->d_inode->i_rdev == CONSOLE_DEV ||
72 +           file->f_dentry->d_inode->i_rdev == SYSCONS_DEV ||
73 +           file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,0) ||
74 +           file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,1)) {
75 +               extern int splash_verbose(void);
76 +               (void)splash_verbose();
77 +       }
78 +#endif
79 +
80         /* Job control check -- must be done at start and after
81            every sleep (POSIX.1 7.1.1.4). */
82         /* NOTE: not yet done after every sleep pending a thorough
83 diff -urN linux-2.4.24.org/drivers/video/Config.in linux-2.4.24/drivers/video/Config.in
84 --- linux-2.4.24.org/drivers/video/Config.in    2004-01-19 21:01:12.428076192 +0100
85 +++ linux-2.4.24/drivers/video/Config.in        2004-01-19 21:05:33.568745824 +0100
86 @@ -243,13 +243,20 @@
87        tristate '  Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL
88     fi
89  
90 +   dep_bool '  Use splash screen instead of boot logo' CONFIG_FBCON_SPLASHSCREEN $CONFIG_BLK_DEV_INITRD
91 +   if [ "$CONFIG_FBCON_SPLASHSCREEN" = "y" ]; then
92 +      define_bool CONFIG_FBCON_CFB16 y
93 +   fi
94 +
95     bool '  Advanced low level driver options' CONFIG_FBCON_ADVANCED
96     if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then
97        tristate '    Monochrome support' CONFIG_FBCON_MFB
98        tristate '    2 bpp packed pixels support' CONFIG_FBCON_CFB2
99        tristate '    4 bpp packed pixels support' CONFIG_FBCON_CFB4
100        tristate '    8 bpp packed pixels support' CONFIG_FBCON_CFB8
101 -      tristate '    16 bpp packed pixels support' CONFIG_FBCON_CFB16
102 +      if [ "$CONFIG_FBCON_SPLASHSCREEN" != "y" ]; then
103 +         tristate '    16 bpp packed pixels support' CONFIG_FBCON_CFB16
104 +      fi
105        tristate '    24 bpp packed pixels support' CONFIG_FBCON_CFB24
106        tristate '    32 bpp packed pixels support' CONFIG_FBCON_CFB32
107        tristate '    Amiga bitplanes support' CONFIG_FBCON_AFB
108 @@ -361,7 +368,9 @@
109            "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
110            "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_INTEL" = "y" -o \
111            "$CONFIG_FB_I810" = "y" ]; then
112 -        define_tristate CONFIG_FBCON_CFB16 y
113 +        if [ "$CONFIG_FBCON_CFB16" != "m" ]; then
114 +                define_tristate CONFIG_FBCON_CFB16 y
115 +        fi
116        else
117          if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
118               "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
119 @@ -380,7 +389,9 @@
120               "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
121               "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_INTEL" = "m" -o \
122               "$CONFIG_FB_I810" = "m" ]; then
123 -           define_tristate CONFIG_FBCON_CFB16 m
124 +           if [ "$CONFIG_FBCON_CFB16" != "y" ]; then
125 +                   define_tristate CONFIG_FBCON_CFB16 m
126 +           fi
127          fi
128        fi
129        if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
130 diff -urN linux-2.4.24.org/drivers/video/fbcon.c linux-2.4.24/drivers/video/fbcon.c
131 --- linux-2.4.24.org/drivers/video/fbcon.c      2004-01-19 21:01:12.383085548 +0100
132 +++ linux-2.4.24/drivers/video/fbcon.c  2004-01-19 21:03:48.196684214 +0100
133 @@ -76,6 +76,7 @@
134  #include <linux/smp.h>
135  #include <linux/init.h>
136  #include <linux/pm.h>
137 +#include <linux/vmalloc.h>
138  
139  #include <asm/irq.h>
140  #include <asm/system.h>
141 @@ -104,6 +105,23 @@
142  #include <video/fbcon-mac.h>   /* for 6x11 font on mac */
143  #include <video/font.h>
144  
145 +#ifdef CONFIG_FBCON_SPLASHSCREEN
146 +#include <video/fbcon-cfb16.h> /* for fbcon_cfb16 */
147 +#include "fbcon-splash.h"
148 +
149 +extern void con_remap_def_color(int currcons, int new_color);
150 +
151 +extern int splash_default;
152 +extern int splash_shown;
153 +
154 +extern struct display_switch fbcon_splash16;
155 +
156 +#ifdef CONFIG_PROC_FS
157 +int splash_proc_register(void);
158 +int splash_proc_unregister(void);
159 +#endif
160 +#endif
161 +
162  #ifdef FBCONDEBUG
163  #  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
164  #else
165 @@ -477,7 +495,9 @@
166      return display_desc;
167  }
168  
169 -
170 +#ifdef CONFIG_FBCON_SPLASHSCREEN
171 +static int splash_registered=0;
172 +#endif
173  static void fbcon_init(struct vc_data *conp, int init)
174  {
175      int unit = conp->vc_num;
176 @@ -501,6 +521,26 @@
177      fb_display[unit].cmap.green = 0;
178      fb_display[unit].cmap.blue = 0;
179      fb_display[unit].cmap.transp = 0;
180 +
181 +#ifdef CONFIG_FBCON_SPLASHSCREEN 
182 +    if (!splash_registered && fb_display[unit].var.bits_per_pixel == 16 ) {
183 +       if (unit == 0 && !fb_display[unit].splash_data) {
184 +           extern unsigned long initrd_start, initrd_end;
185 +
186 +           if (initrd_start && !splash_getraw((unsigned char *)initrd_start, (unsigned char *)initrd_end) && fb_display[unit].splash_data)
187 +               fb_display[unit].splash_data->splash_state = splash_default & 1;
188 +       }
189 +       splash_registered = 1;
190 +#ifdef CONFIG_PROC_FS
191 +       splash_proc_register();
192 +#endif
193 +    }
194 +    if (fb_display[unit].splash_data && fb_display[unit].var.bits_per_pixel != 16 ) {
195 +       vfree(fb_display[unit].splash_data);
196 +       fb_display[unit].splash_data = 0;
197 +    }
198 +#endif
199 +
200      fbcon_setup(unit, init, !init);
201      /* Must be done after fbcon_setup to prevent excess updates */
202      conp->vc_display_fg = &info->display_fg;
203 @@ -517,6 +557,15 @@
204      fbcon_free_font(p);
205      p->dispsw = &fbcon_dummy;
206      p->conp = 0;
207 +#ifdef CONFIG_FBCON_SPLASHSCREEN
208 +    if (splash_registered) {
209 +#ifdef CONFIG_PROC_FS
210 +        splash_proc_unregister();
211 +#endif
212 +       splash_registered = 0;
213 +    }
214 +#endif
215 +
216  }
217  
218  
219 @@ -657,7 +706,14 @@
220      
221      nr_cols = p->var.xres/fontwidth(p);
222      nr_rows = p->var.yres/fontheight(p);
223 -    
224 +#ifdef CONFIG_FBCON_SPLASHSCREEN
225 +    if (p->splash_data && p->splash_data->splash_state) {
226 +       nr_cols = p->splash_data->splash_text_wi / fontwidth(p);
227 +       nr_rows = p->splash_data->splash_text_he / fontheight(p);
228 +       logo = 0;
229 +    }
230 +#endif
231
232      if (logo) {
233         /* Need to make room for the logo */
234         int cnt;
235 @@ -734,6 +790,11 @@
236      p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
237      p->bgcol = 0;
238  
239 +#ifdef CONFIG_FBCON_SPLASHSCREEN
240 +    if(p->splash_data && p->splash_data->splash_state)
241 +       con_remap_def_color(con, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color);
242 +#endif 
243 +
244      if (!init) {
245         if (conp->vc_cols != nr_cols || conp->vc_rows != nr_rows)
246             vc_resize_con(nr_rows, nr_cols, con);
247 @@ -1323,6 +1384,9 @@
248             if (softback_top)
249                 fbcon_softback_note(conp, t, count);
250             if (logo_shown >= 0) goto redraw_up;
251 +#ifdef CONFIG_FBCON_SPLASHSCREEN
252 +           if (splash_shown) goto redraw_up;
253 +#endif
254             switch (p->scrollmode & __SCROLL_YMASK) {
255             case __SCROLL_YMOVE:
256                 p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,
257 @@ -1383,6 +1447,9 @@
258         case SM_DOWN:
259             if (count > conp->vc_rows)  /* Maximum realistic size */
260                 count = conp->vc_rows;
261 +#ifdef CONFIG_FBCON_SPLASHSCREEN
262 +           if (splash_shown) goto redraw_down;
263 +#endif
264             switch (p->scrollmode & __SCROLL_YMASK) {
265             case __SCROLL_YMOVE:
266                 p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count,
267 @@ -1499,6 +1566,13 @@
268         }
269         return;
270      }
271 +#ifdef CONFIG_FBCON_SPLASHSCREEN
272 +    if (splash_shown && sy == dy) {
273 +       /* must use slower redraw bmove to keep background pic intact */
274 +       fbcon_redraw_bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
275 +       return;
276 +    }
277 +#endif
278      p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
279  }
280  
281 @@ -1509,6 +1583,10 @@
282      struct display *p = &fb_display[unit];
283      struct fb_info *info = p->fb_info;
284  
285 +#ifdef CONFIG_FBCON_SPLASHSCREEN
286 +    splash_prepare(p);
287 +#endif
288 +
289      if (softback_top) {
290         int l = fbcon_softback_size / conp->vc_size_row;
291         if (softback_lines)
292 @@ -1568,14 +1646,41 @@
293  {
294      struct display *p = &fb_display[conp->vc_num];
295      struct fb_info *info = p->fb_info;
296 +#ifdef CONFIG_FBCON_SPLASHSCREEN
297 +    struct display_switch *olddispsw=NULL;
298 +    char    *oldscreen_base=NULL;
299 +#endif
300 +   
301  
302      if (blank < 0)     /* Entering graphics mode */
303         return 0;
304  
305 +#ifdef CONFIG_FBCON_SPLASHSCREEN
306 +
307 +    if (p->splash_data && p->splash_data->oldscreen_base) {
308 +       oldscreen_base = p->screen_base;
309 +        p->screen_base = p->splash_data->oldscreen_base;
310 +    }
311 +    if (p->splash_data && p->splash_data->olddispsw) {
312 +        olddispsw = p->dispsw;
313 +        p->dispsw = p->splash_data->olddispsw;
314 +    }
315 +#endif
316 +
317      fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
318  
319      if (!p->can_soft_blank) {
320         if (blank) {
321 +#ifdef CONFIG_FBCON_SPLASHSCREEN
322 +           if (p->splash_data && p->splash_data->oldscreen_base) {
323 +               oldscreen_base = p->screen_base;
324 +               p->screen_base = p->splash_data->oldscreen_base;
325 +           }
326 +           if (p->splash_data && p->splash_data->olddispsw) {
327 +               olddispsw = p->dispsw;
328 +               p->dispsw = p->splash_data->olddispsw;
329 +           }
330 +#endif
331             if (p->visual == FB_VISUAL_MONO01) {
332                 if (p->screen_base)
333                     fb_memset255(p->screen_base,
334 @@ -1583,25 +1688,39 @@
335                                  p->var.bits_per_pixel>>3);
336             } else {
337                 unsigned short oldc;
338 -               u_int height;
339 +               u_int height, width;
340                 u_int y_break;
341  
342                 oldc = conp->vc_video_erase_char;
343                 conp->vc_video_erase_char &= p->charmask;
344                 height = conp->vc_rows;
345 +               width  = conp->vc_cols;
346                 y_break = p->vrows-p->yscroll;
347 +#ifdef CONFIG_FBCON_SPLASHSCREEN
348 +               if (splash_shown) {
349 +                       width=p->var.xres/fontwidth(p);
350 +                       height=p->var.yres/fontheight(p);
351 +               }
352 +#endif
353                 if (height > y_break) {
354 -                       p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, conp->vc_cols);
355 -                       p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, conp->vc_cols);
356 +                       p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, width);
357 +                       p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, width);
358                 } else
359 -                       p->dispsw->clear(conp, p, real_y(p, 0), 0, height, conp->vc_cols);
360 +                       p->dispsw->clear(conp, p, real_y(p, 0), 0, height, width);
361                 conp->vc_video_erase_char = oldc;
362             }
363 +#ifdef CONFIG_FBCON_SPLASHSCREEN
364 +           if(oldscreen_base)
365 +               p->screen_base=oldscreen_base;
366 +           if(olddispsw)
367 +               p->dispsw=olddispsw;
368 +#endif
369             return 0;
370         } else {
371             /* Tell console.c that it has to restore the screen itself */
372             return 1;
373         }
374 +
375      }
376      (*info->blank)(blank, info);
377      return 0;
378 @@ -1762,13 +1881,21 @@
379  
380      if (resize) {
381         struct vc_data *conp = p->conp;
382 +       __u32 xres = p->var.xres, yres = p->var.yres;
383 +
384         /* reset wrap/pan */
385         p->var.xoffset = p->var.yoffset = p->yscroll = 0;
386         p->vrows = p->var.yres_virtual/h;
387 -       if ((p->var.yres % h) && (p->var.yres_virtual % h < p->var.yres % h))
388 +#ifdef CONFIG_FBCON_SPLASHSCREEN
389 +       if (p->splash_data && p->splash_data->splash_state) {
390 +           xres = p->splash_data->splash_text_wi;
391 +           yres = p->splash_data->splash_text_he;
392 +        }
393 +#endif
394 +       if ((yres % h) && (p->var.yres_virtual % h < p->var.yres % h))
395             p->vrows--;
396         updatescrollmode(p);
397 -       vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
398 +       vc_resize_con( yres/h, xres/w, unit );
399          if (CON_IS_VISIBLE(conp) && softback_buf) {
400             int l = fbcon_softback_size / conp->vc_size_row;
401             if (l > 5)
402 @@ -2189,6 +2316,9 @@
403      if (p->fb_info->fbops->fb_rasterimg)
404         p->fb_info->fbops->fb_rasterimg(p->fb_info, 1);
405  
406 +#ifdef CONFIG_FBCON_SPLASHSCREEN
407 +    if (!splash_shown) {
408 +#endif
409      for (x = 0; x < smp_num_cpus * (LOGO_W + 8) &&
410          x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
411          
412 @@ -2450,7 +2580,10 @@
413         }
414  #endif                 
415      }
416 -    
417 +#ifdef CONFIG_FBCON_SPLASHSCREEN
418 +    }
419 +#endif    
420 +
421      if (p->fb_info->fbops->fb_rasterimg)
422         p->fb_info->fbops->fb_rasterimg(p->fb_info, 0);
423  
424 diff -urN linux-2.4.24.org/drivers/video/fbcon-jpegdec.c linux-2.4.24/drivers/video/fbcon-jpegdec.c
425 --- linux-2.4.24.org/drivers/video/fbcon-jpegdec.c      1970-01-01 01:00:00.000000000 +0100
426 +++ linux-2.4.24/drivers/video/fbcon-jpegdec.c  2004-01-19 21:03:48.203682758 +0100
427 @@ -0,0 +1,960 @@
428 +/* 
429 + *    linux/drivers/video/fbcon-jpegdec.c - a tiny jpeg decoder.
430 + *      
431 + *      (w) August 2001 by Michael Schroeder, <mls@suse.de>
432 + *                  
433 + */
434 +
435 +#include <linux/config.h>
436 +#include <linux/string.h>
437 +#include <asm/byteorder.h>
438 +
439 +struct display;
440 +#include "fbcon-splash.h"
441 +#include "fbcon-jpegdec.h"
442 +
443 +#define ISHIFT 11
444 +
445 +#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5))
446 +#define IMULT(a, b) (((a) * (b)) >> ISHIFT)
447 +#define ITOINT(a) ((a) >> ISHIFT)
448 +
449 +#ifndef __P
450 +# define __P(x) x
451 +#endif
452 +
453 +/* special markers */
454 +#define M_BADHUFF      -1
455 +#define M_EOF          0x80
456 +
457 +struct in {
458 +       unsigned char *p;
459 +       unsigned int bits;
460 +       int left;
461 +       int marker;
462 +
463 +       int (*func) __P((void *));
464 +       void *data;
465 +};
466 +
467 +/*********************************/
468 +struct dec_hufftbl;
469 +struct enc_hufftbl;
470 +
471 +union hufftblp {
472 +       struct dec_hufftbl *dhuff;
473 +       struct enc_hufftbl *ehuff;
474 +};
475 +
476 +struct scan {
477 +       int dc;                 /* old dc value */
478 +
479 +       union hufftblp hudc;
480 +       union hufftblp huac;
481 +       int next;               /* when to switch to next scan */
482 +
483 +       int cid;                /* component id */
484 +       int hv;                 /* horiz/vert, copied from comp */
485 +       int tq;                 /* quant tbl, copied from comp */
486 +};
487 +
488 +/*********************************/
489 +
490 +#define DECBITS 10             /* seems to be the optimum */
491 +
492 +struct dec_hufftbl {
493 +       int maxcode[17];
494 +       int valptr[16];
495 +       unsigned char vals[256];
496 +       unsigned int llvals[1 << DECBITS];
497 +};
498 +
499 +static void decode_mcus __P((struct in *, int *, int, struct scan *, int *));
500 +static int dec_readmarker __P((struct in *));
501 +static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *));
502 +
503 +static void setinput __P((struct in *, unsigned char *));
504 +/*********************************/
505 +
506 +#undef PREC
507 +#define PREC int
508 +
509 +static void idctqtab __P((unsigned char *, PREC *));
510 +static void idct __P((int *, int *, PREC *, PREC, int));
511 +static void scaleidctqtab __P((PREC *, PREC));
512 +
513 +/*********************************/
514 +
515 +static void initcol __P((PREC[][64]));
516 +
517 +static void col221111 __P((int *, unsigned char *, int));
518 +static void col221111_16 __P((int *, unsigned char *, int));
519 +
520 +/*********************************/
521 +
522 +#define M_SOI  0xd8
523 +#define M_APP0 0xe0
524 +#define M_DQT  0xdb
525 +#define M_SOF0 0xc0
526 +#define M_DHT   0xc4
527 +#define M_DRI  0xdd
528 +#define M_SOS  0xda
529 +#define M_RST0 0xd0
530 +#define M_EOI  0xd9
531 +#define M_COM  0xfe
532 +
533 +static unsigned char *datap;
534 +
535 +static int getbyte(void)
536 +{
537 +       return *datap++;
538 +}
539 +
540 +static int getword(void)
541 +{
542 +       int c1, c2;
543 +       c1 = *datap++;
544 +       c2 = *datap++;
545 +       return c1 << 8 | c2;
546 +}
547 +
548 +struct comp {
549 +       int cid;
550 +       int hv;
551 +       int tq;
552 +};
553 +
554 +#define MAXCOMP 4
555 +struct jpginfo {
556 +       int nc;                 /* number of components */
557 +       int ns;                 /* number of scans */
558 +       int dri;                /* restart interval */
559 +       int nm;                 /* mcus til next marker */
560 +       int rm;                 /* next restart marker */
561 +};
562 +
563 +static struct jpginfo info;
564 +static struct comp comps[MAXCOMP];
565 +
566 +static struct scan dscans[MAXCOMP];
567 +
568 +static unsigned char quant[4][64];
569 +
570 +static struct dec_hufftbl dhuff[4];
571 +
572 +#define dec_huffdc (dhuff + 0)
573 +#define dec_huffac (dhuff + 2)
574 +
575 +static struct in in;
576 +
577 +static int readtables(int till)
578 +{
579 +       int m, l, i, j, lq, pq, tq;
580 +       int tc, th, tt;
581 +
582 +       for (;;) {
583 +               if (getbyte() != 0xff)
584 +                       return -1;
585 +               if ((m = getbyte()) == till)
586 +                       break;
587 +
588 +               switch (m) {
589 +               case 0xc2:
590 +                       return 0;
591 +
592 +               case M_DQT:
593 +                       lq = getword();
594 +                       while (lq > 2) {
595 +                               pq = getbyte();
596 +                               tq = pq & 15;
597 +                               if (tq > 3)
598 +                                       return -1;
599 +                               pq >>= 4;
600 +                               if (pq != 0)
601 +                                       return -1;
602 +                               for (i = 0; i < 64; i++)
603 +                                       quant[tq][i] = getbyte();
604 +                               lq -= 64 + 1;
605 +                       }
606 +                       break;
607 +
608 +               case M_DHT:
609 +                       l = getword();
610 +                       while (l > 2) {
611 +                               int hufflen[16], k;
612 +                               unsigned char huffvals[256];
613 +
614 +                               tc = getbyte();
615 +                               th = tc & 15;
616 +                               tc >>= 4;
617 +                               tt = tc * 2 + th;
618 +                               if (tc > 1 || th > 1)
619 +                                       return -1;
620 +                               for (i = 0; i < 16; i++)
621 +                                       hufflen[i] = getbyte();
622 +                               l -= 1 + 16;
623 +                               k = 0;
624 +                               for (i = 0; i < 16; i++) {
625 +                                       for (j = 0; j < hufflen[i]; j++)
626 +                                               huffvals[k++] = getbyte();
627 +                                       l -= hufflen[i];
628 +                               }
629 +                               dec_makehuff(dhuff + tt, hufflen,
630 +                                            huffvals);
631 +                       }
632 +                       break;
633 +
634 +               case M_DRI:
635 +                       l = getword();
636 +                       info.dri = getword();
637 +                       break;
638 +
639 +               default:
640 +                       l = getword();
641 +                       while (l-- > 2)
642 +                               getbyte();
643 +                       break;
644 +               }
645 +       }
646 +       return 0;
647 +}
648 +
649 +static void dec_initscans(void)
650 +{
651 +       int i;
652 +
653 +       info.nm = info.dri + 1;
654 +       info.rm = M_RST0;
655 +       for (i = 0; i < info.ns; i++)
656 +               dscans[i].dc = 0;
657 +}
658 +
659 +static int dec_checkmarker(void)
660 +{
661 +       int i;
662 +
663 +       if (dec_readmarker(&in) != info.rm)
664 +               return -1;
665 +       info.nm = info.dri;
666 +       info.rm = (info.rm + 1) & ~0x08;
667 +       for (i = 0; i < info.ns; i++)
668 +               dscans[i].dc = 0;
669 +       return 0;
670 +}
671 +
672 +int jpeg_check_size(unsigned char *buf, int width, int height)
673 +{
674 +       datap = buf;
675 +       getbyte(); 
676 +       getbyte(); 
677 +       readtables(M_SOF0);
678 +       getword();
679 +       getbyte();
680 +        if (height != getword() || width != getword())
681 +               return 0;
682 +        return 1;
683 +}
684 +
685 +int jpeg_decode(buf, pic, width, height, depth, decdata)
686 +unsigned char *buf, *pic;
687 +int width, height, depth;
688 +struct jpeg_decdata *decdata;
689 +{
690 +       int i, j, m, tac, tdc;
691 +       int mcusx, mcusy, mx, my;
692 +       int max[6];
693 +
694 +       if (!decdata)
695 +               return -1;
696 +       datap = buf;
697 +       if (getbyte() != 0xff)
698 +               return ERR_NO_SOI;
699 +       if (getbyte() != M_SOI)
700 +               return ERR_NO_SOI;
701 +       if (readtables(M_SOF0))
702 +               return ERR_BAD_TABLES;
703 +       getword();
704 +       i = getbyte();
705 +       if (i != 8)
706 +               return ERR_NOT_8BIT;
707 +       if (((getword() + 15) & ~15) != height)
708 +               return ERR_HEIGHT_MISMATCH;
709 +       if (((getword() + 15) & ~15) != width)
710 +               return ERR_WIDTH_MISMATCH;
711 +       if ((height & 15) || (width & 15))
712 +               return ERR_BAD_WIDTH_OR_HEIGHT;
713 +       info.nc = getbyte();
714 +       if (info.nc > MAXCOMP)
715 +               return ERR_TOO_MANY_COMPPS;
716 +       for (i = 0; i < info.nc; i++) {
717 +               int h, v;
718 +               comps[i].cid = getbyte();
719 +               comps[i].hv = getbyte();
720 +               v = comps[i].hv & 15;
721 +               h = comps[i].hv >> 4;
722 +               comps[i].tq = getbyte();
723 +               if (h > 3 || v > 3)
724 +                       return ERR_ILLEGAL_HV;
725 +               if (comps[i].tq > 3)
726 +                       return ERR_QUANT_TABLE_SELECTOR;
727 +       }
728 +       if (readtables(M_SOS))
729 +               return ERR_BAD_TABLES;
730 +       getword();
731 +       info.ns = getbyte();
732 +       if (info.ns != 3)
733 +               return ERR_NOT_YCBCR_221111;
734 +       for (i = 0; i < 3; i++) {
735 +               dscans[i].cid = getbyte();
736 +               tdc = getbyte();
737 +               tac = tdc & 15;
738 +               tdc >>= 4;
739 +               if (tdc > 1 || tac > 1)
740 +                       return ERR_QUANT_TABLE_SELECTOR;
741 +               for (j = 0; j < info.nc; j++)
742 +                       if (comps[j].cid == dscans[i].cid)
743 +                               break;
744 +               if (j == info.nc)
745 +                       return ERR_UNKNOWN_CID_IN_SCAN;
746 +               dscans[i].hv = comps[j].hv;
747 +               dscans[i].tq = comps[j].tq;
748 +               dscans[i].hudc.dhuff = dec_huffdc + tdc;
749 +               dscans[i].huac.dhuff = dec_huffac + tac;
750 +       }
751 +       
752 +       i = getbyte();
753 +       j = getbyte();
754 +       m = getbyte();
755 +       
756 +       if (i != 0 || j != 63 || m != 0)
757 +               return ERR_NOT_SEQUENTIAL_DCT;
758 +       
759 +       if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3)
760 +               return ERR_NOT_YCBCR_221111;
761 +
762 +       if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11 || dscans[2].hv != 0x11)
763 +               return ERR_NOT_YCBCR_221111;
764 +
765 +       mcusx = width >> 4;
766 +       mcusy = height >> 4;
767 +
768 +
769 +       idctqtab(quant[dscans[0].tq], decdata->dquant[0]);
770 +       idctqtab(quant[dscans[1].tq], decdata->dquant[1]);
771 +       idctqtab(quant[dscans[2].tq], decdata->dquant[2]);
772 +       initcol(decdata->dquant);
773 +       setinput(&in, datap);
774 +
775 +#if 0
776 +       /* landing zone */
777 +       img[len] = 0;
778 +       img[len + 1] = 0xff;
779 +       img[len + 2] = M_EOF;
780 +#endif
781 +
782 +       dec_initscans();
783 +
784 +       dscans[0].next = 6 - 4;
785 +       dscans[1].next = 6 - 4 - 1;
786 +       dscans[2].next = 6 - 4 - 1 - 1; /* 411 encoding */
787 +       for (my = 0; my < mcusy; my++) {
788 +               for (mx = 0; mx < mcusx; mx++) {
789 +                       if (info.dri && !--info.nm)
790 +                               if (dec_checkmarker())
791 +                                       return ERR_WRONG_MARKER;
792 +                       
793 +                       decode_mcus(&in, decdata->dcts, 6, dscans, max);
794 +                       idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]);
795 +                       idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]);
796 +                       idct(decdata->dcts + 128, decdata->out + 128, decdata->dquant[0], IFIX(128.5), max[2]);
797 +                       idct(decdata->dcts + 192, decdata->out + 192, decdata->dquant[0], IFIX(128.5), max[3]);
798 +                       idct(decdata->dcts + 256, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]);
799 +                       idct(decdata->dcts + 320, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]);
800 +
801 +                       switch (depth) {
802 +                       case 24:
803 +                               col221111(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 3, mcusx * 16 * 3);
804 +                               break;
805 +                       case 16:
806 +                               col221111_16(decdata->out, pic + (my * 16 * mcusx + mx) * (16 * 2), mcusx * (16 * 2));
807 +                               break;
808 +                       default:
809 +                               return ERR_DEPTH_MISMATCH;
810 +                               break;
811 +                       }
812 +               }
813 +       }
814 +       
815 +       m = dec_readmarker(&in);
816 +       if (m != M_EOI)
817 +               return ERR_NO_EOI;
818 +
819 +       return 0;
820 +}
821 +
822 +/****************************************************************/
823 +/**************       huffman decoder             ***************/
824 +/****************************************************************/
825 +
826 +static int fillbits __P((struct in *, int, unsigned int));
827 +static int dec_rec2
828 +__P((struct in *, struct dec_hufftbl *, int *, int, int));
829 +
830 +static void setinput(in, p)
831 +struct in *in;
832 +unsigned char *p;
833 +{
834 +       in->p = p;
835 +       in->left = 0;
836 +       in->bits = 0;
837 +       in->marker = 0;
838 +}
839 +
840 +static int fillbits(in, le, bi)
841 +struct in *in;
842 +int le;
843 +unsigned int bi;
844 +{
845 +       int b, m;
846 +
847 +       if (in->marker) {
848 +               if (le <= 16)
849 +                       in->bits = bi << 16, le += 16;
850 +               return le;
851 +       }
852 +       while (le <= 24) {
853 +               b = *in->p++;
854 +               if (b == 0xff && (m = *in->p++) != 0) {
855 +                       if (m == M_EOF) {
856 +                               if (in->func && (m = in->func(in->data)) == 0)
857 +                                       continue;
858 +                       }
859 +                       in->marker = m;
860 +                       if (le <= 16)
861 +                               bi = bi << 16, le += 16;
862 +                       break;
863 +               }
864 +               bi = bi << 8 | b;
865 +               le += 8;
866 +       }
867 +       in->bits = bi;          /* tmp... 2 return values needed */
868 +       return le;
869 +}
870 +
871 +static int dec_readmarker(in)
872 +struct in *in;
873 +{
874 +       int m;
875 +
876 +       in->left = fillbits(in, in->left, in->bits);
877 +       if ((m = in->marker) == 0)
878 +               return 0;
879 +       in->left = 0;
880 +       in->marker = 0;
881 +       return m;
882 +}
883 +
884 +#define LEBI_DCL       int le, bi
885 +#define LEBI_GET(in)   (le = in->left, bi = in->bits)
886 +#define LEBI_PUT(in)   (in->left = le, in->bits = bi)
887 +
888 +#define GETBITS(in, n) (                                       \
889 +  (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0),   \
890 +  (le -= (n)),                                                 \
891 +  bi >> le & ((1 << (n)) - 1)                                  \
892 +)
893 +
894 +#define UNGETBITS(in, n) (     \
895 +  le += (n)                    \
896 +)
897 +
898 +
899 +static int dec_rec2(in, hu, runp, c, i)
900 +struct in *in;
901 +struct dec_hufftbl *hu;
902 +int *runp;
903 +int c, i;
904 +{
905 +       LEBI_DCL;
906 +
907 +       LEBI_GET(in);
908 +       if (i) {
909 +               UNGETBITS(in, i & 127);
910 +               *runp = i >> 8 & 15;
911 +               i >>= 16;
912 +       } else {
913 +               for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++);
914 +               if (i >= 16) {
915 +                       in->marker = M_BADHUFF;
916 +                       return 0;
917 +               }
918 +               i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
919 +               *runp = i >> 4;
920 +               i &= 15;
921 +       }
922 +       if (i == 0) {           /* sigh, 0xf0 is 11 bit */
923 +               LEBI_PUT(in);
924 +               return 0;
925 +       }
926 +       /* receive part */
927 +       c = GETBITS(in, i);
928 +       if (c < (1 << (i - 1)))
929 +               c += (-1 << i) + 1;
930 +       LEBI_PUT(in);
931 +       return c;
932 +}
933 +
934 +#define DEC_REC(in, hu, r, i)   (      \
935 +  r = GETBITS(in, DECBITS),            \
936 +  i = hu->llvals[r],                   \
937 +  i & 128 ?                            \
938 +    (                                  \
939 +      UNGETBITS(in, i & 127),          \
940 +      r = i >> 8 & 15,                 \
941 +      i >> 16                          \
942 +    )                                  \
943 +  :                                    \
944 +    (                                  \
945 +      LEBI_PUT(in),                    \
946 +      i = dec_rec2(in, hu, &r, r, i),  \
947 +      LEBI_GET(in),                    \
948 +      i                                        \
949 +    )                                  \
950 +)
951 +
952 +static void decode_mcus(in, dct, n, sc, maxp)
953 +struct in *in;
954 +int *dct;
955 +int n;
956 +struct scan *sc;
957 +int *maxp;
958 +{
959 +       struct dec_hufftbl *hu;
960 +       int i, r, t;
961 +       LEBI_DCL;
962 +
963 +       memset(dct, 0, n * 64 * sizeof(*dct));
964 +       LEBI_GET(in);
965 +       while (n-- > 0) {
966 +               hu = sc->hudc.dhuff;
967 +               *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
968 +
969 +               hu = sc->huac.dhuff;
970 +               i = 63;
971 +               while (i > 0) {
972 +                       t = DEC_REC(in, hu, r, t);
973 +                       if (t == 0 && r == 0) {
974 +                               dct += i;
975 +                               break;
976 +                       }
977 +                       dct += r;
978 +                       *dct++ = t;
979 +                       i -= r + 1;
980 +               }
981 +               *maxp++ = 64 - i;
982 +               if (n == sc->next)
983 +                       sc++;
984 +       }
985 +       LEBI_PUT(in);
986 +}
987 +
988 +static void dec_makehuff(hu, hufflen, huffvals)
989 +struct dec_hufftbl *hu;
990 +int *hufflen;
991 +unsigned char *huffvals;
992 +{
993 +       int code, k, i, j, d, x, c, v;
994 +       for (i = 0; i < (1 << DECBITS); i++)
995 +               hu->llvals[i] = 0;
996 +
997 +/*
998 + * llvals layout:
999 + *
1000 + * value v already known, run r, backup u bits:
1001 + *  vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
1002 + * value unknown, size b bits, run r, backup u bits:
1003 + *  000000000000bbbb 0000 rrrr 0 uuuuuuu
1004 + * value and size unknown:
1005 + *  0000000000000000 0000 0000 0 0000000
1006 + */
1007 +       code = 0;
1008 +       k = 0;
1009 +       for (i = 0; i < 16; i++, code <<= 1) {  /* sizes */
1010 +               hu->valptr[i] = k;
1011 +               for (j = 0; j < hufflen[i]; j++) {
1012 +                       hu->vals[k] = *huffvals++;
1013 +                       if (i < DECBITS) {
1014 +                               c = code << (DECBITS - 1 - i);
1015 +                               v = hu->vals[k] & 0x0f; /* size */
1016 +                               for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
1017 +                                       if (v + i < DECBITS) {  /* both fit in table */
1018 +                                               x = d >> (DECBITS - 1 - v -
1019 +                                                         i);
1020 +                                               if (v && x < (1 << (v - 1)))
1021 +                                                       x += (-1 << v) + 1;
1022 +                                               x = x << 16 | (hu-> vals[k] & 0xf0) << 4 |
1023 +                                                       (DECBITS - (i + 1 + v)) | 128;
1024 +                                       } else
1025 +                                               x = v << 16 | (hu-> vals[k] & 0xf0) << 4 |
1026 +                                                       (DECBITS - (i + 1));
1027 +                                       hu->llvals[c | d] = x;
1028 +                               }
1029 +                       }
1030 +                       code++;
1031 +                       k++;
1032 +               }
1033 +               hu->maxcode[i] = code;
1034 +       }
1035 +       hu->maxcode[16] = 0x20000;      /* always terminate decode */
1036 +}
1037 +
1038 +/****************************************************************/
1039 +/**************             idct                  ***************/
1040 +/****************************************************************/
1041 +
1042 +#define ONE ((PREC)IFIX(1.))
1043 +#define S2  ((PREC)IFIX(0.382683432))
1044 +#define C2  ((PREC)IFIX(0.923879532))
1045 +#define C4  ((PREC)IFIX(0.707106781))
1046 +
1047 +#define S22 ((PREC)IFIX(2 * 0.382683432))
1048 +#define C22 ((PREC)IFIX(2 * 0.923879532))
1049 +#define IC4 ((PREC)IFIX(1 / 0.707106781))
1050 +
1051 +#define C3IC1 ((PREC)IFIX(0.847759065))        /* c3/c1 */
1052 +#define C5IC1 ((PREC)IFIX(0.566454497))        /* c5/c1 */
1053 +#define C7IC1 ((PREC)IFIX(0.198912367))        /* c7/c1 */
1054 +
1055 +#define XPP(a,b) (t = a + b, b = a - b, a = t)
1056 +#define XMP(a,b) (t = a - b, b = a + b, a = t)
1057 +#define XPM(a,b) (t = a + b, b = b - a, a = t)
1058 +
1059 +#define ROT(a,b,s,c) ( t = IMULT(a + b, s),    \
1060 +                       a = IMULT(a, c - s) + t,        \
1061 +                       b = IMULT(b, c + s) - t)
1062 +
1063 +#define IDCT           \
1064 +(                      \
1065 +  XPP(t0, t1),         \
1066 +  XMP(t2, t3),         \
1067 +  t2 = IMULT(t2, IC4) - t3,    \
1068 +  XPP(t0, t3),         \
1069 +  XPP(t1, t2),         \
1070 +  XMP(t4, t7),         \
1071 +  XPP(t5, t6),         \
1072 +  XMP(t5, t7),         \
1073 +  t5 = IMULT(t5, IC4), \
1074 +  ROT(t4, t6, S22, C22),\
1075 +  t6 -= t7,            \
1076 +  t5 -= t6,            \
1077 +  t4 -= t5,            \
1078 +  XPP(t0, t7),         \
1079 +  XPP(t1, t6),         \
1080 +  XPP(t2, t5),         \
1081 +  XPP(t3, t4)          \
1082 +)
1083 +
1084 +static unsigned char zig2[64] = {
1085 +       0, 2, 3, 9, 10, 20, 21, 35,
1086 +       14, 16, 25, 31, 39, 46, 50, 57,
1087 +       5, 7, 12, 18, 23, 33, 37, 48,
1088 +       27, 29, 41, 44, 52, 55, 59, 62,
1089 +       15, 26, 30, 40, 45, 51, 56, 58,
1090 +       1, 4, 8, 11, 19, 22, 34, 36,
1091 +       28, 42, 43, 53, 54, 60, 61, 63,
1092 +       6, 13, 17, 24, 32, 38, 47, 49
1093 +};
1094 +
1095 +void idct(in, out, quant, off, max)
1096 +int *in;
1097 +int *out;
1098 +PREC *quant;
1099 +PREC off;
1100 +int max;
1101 +{
1102 +       PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
1103 +       PREC tmp[64], *tmpp;
1104 +       int i, j;
1105 +       unsigned char *zig2p;
1106 +
1107 +       t0 = off;
1108 +       if (max == 1) {
1109 +               t0 += in[0] * quant[0];
1110 +               for (i = 0; i < 64; i++)
1111 +                       out[i] = ITOINT(t0);
1112 +               return;
1113 +       }
1114 +       zig2p = zig2;
1115 +       tmpp = tmp;
1116 +       for (i = 0; i < 8; i++) {
1117 +               j = *zig2p++;
1118 +               t0 += in[j] * quant[j];
1119 +               j = *zig2p++;
1120 +               t5 = in[j] * quant[j];
1121 +               j = *zig2p++;
1122 +               t2 = in[j] * quant[j];
1123 +               j = *zig2p++;
1124 +               t7 = in[j] * quant[j];
1125 +               j = *zig2p++;
1126 +               t1 = in[j] * quant[j];
1127 +               j = *zig2p++;
1128 +               t4 = in[j] * quant[j];
1129 +               j = *zig2p++;
1130 +               t3 = in[j] * quant[j];
1131 +               j = *zig2p++;
1132 +               t6 = in[j] * quant[j];
1133 +               IDCT;
1134 +               tmpp[0 * 8] = t0;
1135 +               tmpp[1 * 8] = t1;
1136 +               tmpp[2 * 8] = t2;
1137 +               tmpp[3 * 8] = t3;
1138 +               tmpp[4 * 8] = t4;
1139 +               tmpp[5 * 8] = t5;
1140 +               tmpp[6 * 8] = t6;
1141 +               tmpp[7 * 8] = t7;
1142 +               tmpp++;
1143 +               t0 = 0;
1144 +       }
1145 +       for (i = 0; i < 8; i++) {
1146 +               t0 = tmp[8 * i + 0];
1147 +               t1 = tmp[8 * i + 1];
1148 +               t2 = tmp[8 * i + 2];
1149 +               t3 = tmp[8 * i + 3];
1150 +               t4 = tmp[8 * i + 4];
1151 +               t5 = tmp[8 * i + 5];
1152 +               t6 = tmp[8 * i + 6];
1153 +               t7 = tmp[8 * i + 7];
1154 +               IDCT;
1155 +               out[8 * i + 0] = ITOINT(t0);
1156 +               out[8 * i + 1] = ITOINT(t1);
1157 +               out[8 * i + 2] = ITOINT(t2);
1158 +               out[8 * i + 3] = ITOINT(t3);
1159 +               out[8 * i + 4] = ITOINT(t4);
1160 +               out[8 * i + 5] = ITOINT(t5);
1161 +               out[8 * i + 6] = ITOINT(t6);
1162 +               out[8 * i + 7] = ITOINT(t7);
1163 +       }
1164 +}
1165 +
1166 +static unsigned char zig[64] = {
1167 +       0, 1, 5, 6, 14, 15, 27, 28,
1168 +       2, 4, 7, 13, 16, 26, 29, 42,
1169 +       3, 8, 12, 17, 25, 30, 41, 43,
1170 +       9, 11, 18, 24, 31, 40, 44, 53,
1171 +       10, 19, 23, 32, 39, 45, 52, 54,
1172 +       20, 22, 33, 38, 46, 51, 55, 60,
1173 +       21, 34, 37, 47, 50, 56, 59, 61,
1174 +       35, 36, 48, 49, 57, 58, 62, 63
1175 +};
1176 +
1177 +static PREC aaidct[8] = {
1178 +       IFIX(0.3535533906), IFIX(0.4903926402),
1179 +       IFIX(0.4619397663), IFIX(0.4157348062),
1180 +       IFIX(0.3535533906), IFIX(0.2777851165),
1181 +       IFIX(0.1913417162), IFIX(0.0975451610)
1182 +};
1183 +
1184 +
1185 +static void idctqtab(qin, qout)
1186 +unsigned char *qin;
1187 +PREC *qout;
1188 +{
1189 +       int i, j;
1190 +
1191 +       for (i = 0; i < 8; i++)
1192 +               for (j = 0; j < 8; j++)
1193 +                       qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] * 
1194 +                                               IMULT(aaidct[i], aaidct[j]);
1195 +}
1196 +
1197 +static void scaleidctqtab(q, sc)
1198 +PREC *q;
1199 +PREC sc;
1200 +{
1201 +       int i;
1202 +
1203 +       for (i = 0; i < 64; i++)
1204 +               q[i] = IMULT(q[i], sc);
1205 +}
1206 +
1207 +/****************************************************************/
1208 +/**************          color decoder            ***************/
1209 +/****************************************************************/
1210 +
1211 +#define ROUND
1212 +
1213 +/*
1214 + * YCbCr Color transformation:
1215 + *
1216 + * y:0..255   Cb:-128..127   Cr:-128..127
1217 + *
1218 + *      R = Y                + 1.40200 * Cr
1219 + *      G = Y - 0.34414 * Cb - 0.71414 * Cr
1220 + *      B = Y + 1.77200 * Cb
1221 + *
1222 + * =>
1223 + *      Cr *= 1.40200;
1224 + *      Cb *= 1.77200;
1225 + *      Cg = 0.19421 * Cb + .50937 * Cr;
1226 + *      R = Y + Cr;
1227 + *      G = Y - Cg;
1228 + *      B = Y + Cb;
1229 + *
1230 + * =>
1231 + *      Cg = (50 * Cb + 130 * Cr + 128) >> 8;
1232 + */
1233 +
1234 +static void initcol(q)
1235 +PREC q[][64];
1236 +{
1237 +       scaleidctqtab(q[1], IFIX(1.77200));
1238 +       scaleidctqtab(q[2], IFIX(1.40200));
1239 +}
1240 +
1241 +/* This is optimized for the stupid sun SUNWspro compiler. */
1242 +#define STORECLAMP(a,x)                                \
1243 +(                                              \
1244 +  (a) = (x),                                   \
1245 +  (unsigned int)(x) >= 256 ?                   \
1246 +    ((a) = (x) < 0 ? 0 : 255)                  \
1247 +  :                                            \
1248 +    0                                          \
1249 +)
1250 +
1251 +#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
1252 +
1253 +#ifdef ROUND
1254 +
1255 +#define CBCRCG(yin, xin)                       \
1256 +(                                              \
1257 +  cb = outc[0 +yin*8+xin],                     \
1258 +  cr = outc[64+yin*8+xin],                     \
1259 +  cg = (50 * cb + 130 * cr + 128) >> 8         \
1260 +)
1261 +
1262 +#else
1263 +
1264 +#define CBCRCG(yin, xin)                       \
1265 +(                                              \
1266 +  cb = outc[0 +yin*8+xin],                     \
1267 +  cr = outc[64+yin*8+xin],                     \
1268 +  cg = (3 * cb + 8 * cr) >> 4                  \
1269 +)
1270 +
1271 +#endif
1272 +
1273 +#define PIC(yin, xin, p, xout)                 \
1274 +(                                              \
1275 +  y = outy[(yin) * 8 + xin],                   \
1276 +  STORECLAMP(p[(xout) * 3 + 0], y + cr),       \
1277 +  STORECLAMP(p[(xout) * 3 + 1], y - cg),       \
1278 +  STORECLAMP(p[(xout) * 3 + 2], y + cb)                \
1279 +)
1280 +
1281 +#ifdef __LITTLE_ENDIAN
1282 +#define PIC_16(yin, xin, p, xout, add)          \
1283 +(                                                \
1284 +  y = outy[(yin) * 8 + xin],                     \
1285 +  y = ((CLAMP(y + cr + add*2+1) & 0xf8) <<  8) | \
1286 +      ((CLAMP(y - cg + add    ) & 0xfc) <<  3) | \
1287 +      ((CLAMP(y + cb + add*2+1)       ) >>  3),  \
1288 +  p[(xout) * 2 + 0] = y & 0xff,                  \
1289 +  p[(xout) * 2 + 1] = y >> 8                     \
1290 +)
1291 +#else
1292 +#ifdef CONFIG_PPC
1293 +#define PIC_16(yin, xin, p, xout, add)          \
1294 +(                                                \
1295 +  y = outy[(yin) * 8 + xin],                     \
1296 +  y = ((CLAMP(y + cr + add*2+1) & 0xf8) <<  7) | \
1297 +      ((CLAMP(y - cg + add*2+1) & 0xf8) <<  2) | \
1298 +      ((CLAMP(y + cb + add*2+1)       ) >>  3),  \
1299 +  p[(xout) * 2 + 0] = y >> 8,                    \
1300 +  p[(xout) * 2 + 1] = y & 0xff                   \
1301 +)
1302 +#else
1303 +#define PIC_16(yin, xin, p, xout, add)          \
1304 +(                                                \
1305 +  y = outy[(yin) * 8 + xin],                     \
1306 +  y = ((CLAMP(y + cr + add*2+1) & 0xf8) <<  8) | \
1307 +      ((CLAMP(y - cg + add    ) & 0xfc) <<  3) | \
1308 +      ((CLAMP(y + cb + add*2+1)       ) >>  3),  \
1309 +  p[(xout) * 2 + 0] = y >> 8,                    \
1310 +  p[(xout) * 2 + 1] = y & 0xff                   \
1311 +)
1312 +#endif
1313 +#endif
1314 +
1315 +#define PIC221111(xin)                                         \
1316 +(                                                              \
1317 +  CBCRCG(0, xin),                                              \
1318 +  PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0),  \
1319 +  PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1),  \
1320 +  PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0),  \
1321 +  PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1)   \
1322 +)
1323 +
1324 +#define PIC221111_16(xin)                                               \
1325 +(                                                                      \
1326 +  CBCRCG(0, xin),                                                      \
1327 +  PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3),     \
1328 +  PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0),     \
1329 +  PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1),     \
1330 +  PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2)      \
1331 +)
1332 +
1333 +static void col221111(out, pic, width)
1334 +int *out;
1335 +unsigned char *pic;
1336 +int width;
1337 +{
1338 +       int i, j, k;
1339 +       unsigned char *pic0, *pic1;
1340 +       int *outy, *outc;
1341 +       int cr, cg, cb, y;
1342 +
1343 +       pic0 = pic;
1344 +       pic1 = pic + width;
1345 +       outy = out;
1346 +       outc = out + 64 * 4;
1347 +       for (i = 2; i > 0; i--) {
1348 +               for (j = 4; j > 0; j--) {
1349 +                       for (k = 0; k < 8; k++) {
1350 +                               PIC221111(k);
1351 +                       }
1352 +                       outc += 8;
1353 +                       outy += 16;
1354 +                       pic0 += 2 * width;
1355 +                       pic1 += 2 * width;
1356 +               }
1357 +               outy += 64 * 2 - 16 * 4;
1358 +       }
1359 +}
1360 +
1361 +static void col221111_16(out, pic, width)
1362 +int *out;
1363 +unsigned char *pic;
1364 +int width;
1365 +{
1366 +       int i, j, k;
1367 +       unsigned char *pic0, *pic1;
1368 +       int *outy, *outc;
1369 +       int cr, cg, cb, y;
1370 +
1371 +       pic0 = pic;
1372 +       pic1 = pic + width;
1373 +       outy = out;
1374 +       outc = out + 64 * 4;
1375 +       for (i = 2; i > 0; i--) {
1376 +               for (j = 4; j > 0; j--) {
1377 +                       for (k = 0; k < 8; k++) {
1378 +                           PIC221111_16(k);
1379 +                       }
1380 +                       outc += 8;
1381 +                       outy += 16;
1382 +                       pic0 += 2 * width;
1383 +                       pic1 += 2 * width;
1384 +               }
1385 +               outy += 64 * 2 - 16 * 4;
1386 +       }
1387 +}
1388 diff -urN linux-2.4.24.org/drivers/video/fbcon-jpegdec.h linux-2.4.24/drivers/video/fbcon-jpegdec.h
1389 --- linux-2.4.24.org/drivers/video/fbcon-jpegdec.h      1970-01-01 01:00:00.000000000 +0100
1390 +++ linux-2.4.24/drivers/video/fbcon-jpegdec.h  2004-01-19 21:03:48.205682343 +0100
1391 @@ -0,0 +1,24 @@
1392 +#define ERR_NO_SOI 1
1393 +#define ERR_NOT_8BIT 2
1394 +#define ERR_HEIGHT_MISMATCH 3
1395 +#define ERR_WIDTH_MISMATCH 4
1396 +#define ERR_BAD_WIDTH_OR_HEIGHT 5
1397 +#define ERR_TOO_MANY_COMPPS 6
1398 +#define ERR_ILLEGAL_HV 7
1399 +#define ERR_QUANT_TABLE_SELECTOR 8
1400 +#define ERR_NOT_YCBCR_221111 9
1401 +#define ERR_UNKNOWN_CID_IN_SCAN 10
1402 +#define ERR_NOT_SEQUENTIAL_DCT 11
1403 +#define ERR_WRONG_MARKER 12
1404 +#define ERR_NO_EOI 13
1405 +#define ERR_BAD_TABLES 14
1406 +#define ERR_DEPTH_MISMATCH 15
1407 +
1408 +struct jpeg_decdata {
1409 +       int dcts[6 * 64 + 16];
1410 +       int out[64 * 6];
1411 +       int dquant[3][64];
1412 +};
1413 +
1414 +extern int jpeg_decode(unsigned char *, unsigned char *, int, int, int, struct jpeg_decdata *);
1415 +extern int jpeg_check_size(unsigned char *, int, int);
1416 diff -urN linux-2.4.24.org/drivers/video/fbcon-splash16.c linux-2.4.24/drivers/video/fbcon-splash16.c
1417 --- linux-2.4.24.org/drivers/video/fbcon-splash16.c     1970-01-01 01:00:00.000000000 +0100
1418 +++ linux-2.4.24/drivers/video/fbcon-splash16.c 2004-01-19 21:03:48.209681511 +0100
1419 @@ -0,0 +1,488 @@
1420 +/*
1421 + *  linux/drivers/video/fbcon-splash16.c -- Low level frame buffer operations for 16 bpp
1422 + *                                          framebuffer operation. Modified to present
1423 + *                                         boot splash screen. 2002/11/7 stepan@suse.de
1424 + * 
1425 + * Based on linux/drivers/video/fbcon-cfb16.c, which is
1426 + *
1427 + *     Created 5 Apr 1997 by Geert Uytterhoeven
1428 + *
1429 + *  This file is subject to the terms and conditions of the GNU General Public
1430 + *  License.  See the file COPYING in the main directory of this archive for
1431 + *  more details.
1432 + */
1433 +
1434 +#include <linux/module.h>
1435 +#include <linux/config.h>
1436 +#include <linux/tty.h>
1437 +#include <linux/console.h>
1438 +#include <linux/string.h>
1439 +#include <linux/fb.h>
1440 +#include <asm/io.h>
1441 +
1442 +#include <video/fbcon.h>
1443 +#include <video/fbcon-cfb16.h>
1444 +
1445 +#include "fbcon-splash.h"
1446 +
1447 +    /*
1448 +     *  16 bpp packed pixels
1449 +     */
1450 +
1451 +static u32 tab_cfb16[] = {
1452 +#if defined(__BIG_ENDIAN)
1453 +    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
1454 +#elif defined(__LITTLE_ENDIAN)
1455 +    0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
1456 +#else
1457 +#error FIXME: No endianness??
1458 +#endif
1459 +};
1460 +
1461 +void fbcon_splash16_bmove(struct display *p, int sy, int sx, int dy, int dx,
1462 +                      int height, int width)
1463 +{
1464 +    int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
1465 +    u8 *src, *dst;
1466 +
1467 +    if (sx == 0 && dx == 0 && width * fontwidth(p) * 2 == bytes) {
1468 +       fb_memmove(p->screen_base + dy * linesize,
1469 +                 p->screen_base + sy * linesize,
1470 +                 height * linesize);
1471 +       return;
1472 +    }
1473 +    if (fontwidthlog(p)) {
1474 +       sx <<= fontwidthlog(p)+1;
1475 +       dx <<= fontwidthlog(p)+1;
1476 +       width <<= fontwidthlog(p)+1;
1477 +    } else {
1478 +       sx *= fontwidth(p)*2;
1479 +       dx *= fontwidth(p)*2;
1480 +       width *= fontwidth(p)*2;
1481 +    }
1482 +    sx += splash_data.splash_text_xo*2 + splash_data.splash_text_yo * bytes;
1483 +    dx += splash_data.splash_text_xo*2 + splash_data.splash_text_yo * bytes;
1484 +    if (dy < sy || (dy == sy && dx < sx)) {
1485 +       src = p->screen_base + sy * linesize + sx;
1486 +       dst = p->screen_base + dy * linesize + dx;
1487 +       for (rows = height * fontheight(p); rows--;) {
1488 +           fb_memmove(dst, src, width);
1489 +           src += bytes;
1490 +           dst += bytes;
1491 +       }
1492 +    } else {
1493 +       src = p->screen_base + (sy+height) * linesize + sx - bytes;
1494 +       dst = p->screen_base + (dy+height) * linesize + dx - bytes;
1495 +       for (rows = height * fontheight(p); rows--;) {
1496 +           fb_memmove(dst, src, width);
1497 +           src -= bytes;
1498 +           dst -= bytes;
1499 +       }
1500 +    }
1501 +}
1502 +
1503 +static inline void rectfill(u8 *dest, int width, int height, u32 data,
1504 +                           int linesize)
1505 +{
1506 +    int i;
1507 +
1508 +    data |= data<<16;
1509 +
1510 +    while (height-- > 0) {
1511 +       u32 *p = (u32 *)dest;
1512 +       for (i = 0; i < width/4; i++) {
1513 +           fb_writel(data, p++);
1514 +           fb_writel(data, p++);
1515 +       }
1516 +       if (width & 2)
1517 +           fb_writel(data, p++);
1518 +       if (width & 1)
1519 +           fb_writew(data, (u16*)p);
1520 +       dest += linesize;
1521 +    }
1522 +}
1523 +
1524 +void splashfill(u8 *dest, u8 *src, int width, int height,
1525 +                       int dest_linesize, int src_linesize)
1526 +{
1527 +
1528 +    int i;
1529 +
1530 +    while (height-- > 0) {
1531 +       u32 *p = (u32 *)dest;
1532 +       u32 *q = (u32 *)src;
1533 +
1534 +       for (i=0; i < width/4; i++) {
1535 +           fb_writel(*q++,p++);
1536 +           fb_writel(*q++,p++);
1537 +       }
1538 +       if (width & 2)
1539 +           fb_writel(*q++,p++);
1540 +       if (width & 1)
1541 +           fb_writew(*(u16*)q,(u16*)p);
1542 +       dest += dest_linesize;
1543 +       src  += src_linesize;
1544 +    }
1545 +}
1546 +
1547 +void fbcon_splash16_clear(struct vc_data *conp, struct display *p, int sy, int sx,
1548 +                      int height, int width)
1549 +{
1550 +    u8 *dest;
1551 +    int bytes = p->next_line, lines = height * fontheight(p);
1552 +    u32 bgx;
1553 +    int offset, transparent=0;
1554 +
1555 +    dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 2;
1556 +
1557 +    bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
1558 +
1559 +    width *= fontwidth(p)/4;
1560 +
1561 +    dest   += splash_data.splash_text_yo * bytes  +
1562 +                 splash_data.splash_text_xo * 2;
1563 +
1564 +    transparent = (splash_data.splash_color == attr_bgcol_ec(p, conp));
1565 +    
1566 +    if (transparent) {
1567 +       offset = (sy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes +
1568 +                (sx * fontwidth(p) + splash_data.splash_text_xo) *  2;
1569 +       
1570 +       if ((width * 8 == bytes && splash_bytes == bytes))
1571 +           splashfill(dest,linux_splash + offset, lines * width * 4, 
1572 +                           1, bytes, splash_bytes);
1573 +       else
1574 +           splashfill(dest,linux_splash + offset, width*4, lines,
1575 +                           bytes, splash_bytes);
1576 +    } else {
1577 +        if (width * 8 == bytes)
1578 +           rectfill(dest, lines * width * 4, 1, bgx, bytes);
1579 +        else
1580 +           rectfill(dest, width * 4, lines, bgx, bytes);
1581 +    }
1582 +}
1583 +
1584 +
1585 +/*
1586 + *  Helper function to read the background from the splashscreen
1587 + */
1588 +# define SPLASH_BGX(off)                       \
1589 +       if (transparent) {                      \
1590 +           bgx = *(u32*)(splashbgx + (off));   \
1591 +           eorx = fgx ^ bgx;                   \
1592 +       }
1593 +
1594 +
1595 +void fbcon_splash16_putc(struct vc_data *conp, struct display *p, int c, int yy,
1596 +                     int xx)
1597 +{
1598 +    u8 *dest, *cdat, bits;
1599 +    int bytes = p->next_line, rows;
1600 +    u32 eorx, fgx, bgx;
1601 +    int transparent = 0;
1602 +    u8 *splashbgx = 0;
1603
1604 +    dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
1605 +
1606 +    fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
1607 +    bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
1608 +
1609 +    transparent = (splash_data.splash_color == attr_bgcol(p, c));
1610 +    
1611 +    dest += splash_data.splash_text_xo * 2 + splash_data.splash_text_yo * bytes;
1612 +    splashbgx = linux_splash +
1613 +           (yy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes + 
1614 +           (xx * fontwidth(p) + splash_data.splash_text_xo) * 2;
1615 +
1616 +    if (transparent && splash_data.splash_color == 0xf) {
1617 +       if (fgx == 0xffea)
1618 +           fgx = 0xfe4a;
1619 +       else if (fgx == 0x57ea)
1620 +           fgx = 0x0540;
1621 +       else if (fgx == 0xffff)
1622 +           fgx = 0x52aa;
1623 +    }
1624 +
1625 +    fgx |= (fgx << 16);
1626 +    bgx |= (bgx << 16);
1627 +    eorx = fgx ^ bgx;
1628 +
1629 +    switch (fontwidth(p)) {
1630 +    case 4:
1631 +    case 8:
1632 +       cdat = p->fontdata + (c & p->charmask) * fontheight(p);
1633 +       for (rows = fontheight(p); rows--; dest += bytes) {
1634 +           bits = *cdat++;
1635 +           SPLASH_BGX(0);
1636 +           fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
1637 +           SPLASH_BGX(4);
1638 +           fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
1639 +           if (fontwidth(p) == 8) {
1640 +               SPLASH_BGX(8);
1641 +               fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
1642 +               SPLASH_BGX(12);
1643 +               fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
1644 +           }
1645 +
1646 +           splashbgx += splash_bytes;
1647 +
1648 +       }
1649 +       break;
1650 +    case 12:
1651 +    case 16:
1652 +       cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
1653 +       for (rows = fontheight(p); rows--; dest += bytes) {
1654 +           bits = *cdat++;
1655 +           SPLASH_BGX(0);
1656 +           fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
1657 +           SPLASH_BGX(4);
1658 +           fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
1659 +           SPLASH_BGX(8);
1660 +           fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
1661 +           SPLASH_BGX(12);
1662 +           fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
1663 +           bits = *cdat++;
1664 +           SPLASH_BGX(16);
1665 +           fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
1666 +           SPLASH_BGX(20);
1667 +           fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
1668 +           if (fontwidth(p) == 16) {
1669 +               SPLASH_BGX(24);
1670 +               fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
1671 +               SPLASH_BGX(28);
1672 +               fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
1673 +           }
1674 +       }
1675 +       break;
1676 +    }
1677 +}
1678 +
1679 +void fbcon_splash16_putcs(struct vc_data *conp, struct display *p,
1680 +                      const unsigned short *s, int count, int yy, int xx)
1681 +{
1682 +    u8 *cdat, *dest, *dest0;
1683 +    u16 c;
1684 +    int rows, bytes = p->next_line;
1685 +    u32 eorx, fgx, bgx;
1686 +    int transparent = 0;
1687 +    u8 *splashbgx0 = 0, *splashbgx;
1688 +
1689 +    dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
1690 +    c = scr_readw(s);
1691 +    fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
1692 +    bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
1693 +
1694 +    transparent = (splash_data.splash_color == attr_bgcol(p, c));
1695 +    
1696 +    dest0 += splash_data.splash_text_xo * 2 + splash_data.splash_text_yo * bytes;
1697 +    splashbgx0 = linux_splash +
1698 +             (yy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes +
1699 +             (xx * fontwidth(p) + splash_data.splash_text_xo) * 2;
1700 +
1701 +    if (transparent && splash_data.splash_color == 0xf) {
1702 +       if (fgx == 0xffea)
1703 +           fgx = 0xfe4a;
1704 +       else if (fgx == 0x57ea)
1705 +           fgx = 0x0540;
1706 +       else if (fgx == 0xffff)
1707 +           fgx = 0x52aa;
1708 +    }
1709 +
1710 +    fgx |= (fgx << 16);
1711 +    bgx |= (bgx << 16);
1712 +    eorx = fgx ^ bgx;
1713 +
1714 +    switch (fontwidth(p)) {
1715 +    case 4:
1716 +    case 8:
1717 +       while (count--) {
1718 +           c = scr_readw(s++) & p->charmask;
1719 +           cdat = p->fontdata + c * fontheight(p);
1720 +
1721 +           splashbgx = splashbgx0;
1722 +
1723 +           for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
1724 +               u8 bits = *cdat++;
1725 +               SPLASH_BGX(0);
1726 +               fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
1727 +               SPLASH_BGX(4);
1728 +               fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
1729 +               if (fontwidth(p) == 8) {
1730 +                   SPLASH_BGX(8);
1731 +                   fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
1732 +                   SPLASH_BGX(12);
1733 +                   fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
1734 +               }
1735 +               splashbgx += splash_bytes;
1736 +           }
1737 +
1738 +           dest0 += fontwidth(p)*2;
1739 +           splashbgx0 += fontwidth(p) * 2;
1740 +       }
1741 +
1742 +       break;
1743 +    case 12:
1744 +    case 16:
1745 +       while (count--) {
1746 +           c = scr_readw(s++) & p->charmask;
1747 +           cdat = p->fontdata + (c * fontheight(p) << 1);
1748 +
1749 +           splashbgx = splashbgx0;
1750 +
1751 +           for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
1752 +               u8 bits = *cdat++;
1753 +               SPLASH_BGX(0);
1754 +               fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
1755 +               SPLASH_BGX(4);
1756 +               fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
1757 +               SPLASH_BGX(8);
1758 +               fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
1759 +               SPLASH_BGX(12);
1760 +               fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
1761 +               bits = *cdat++;
1762 +               SPLASH_BGX(16);
1763 +               fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
1764 +               SPLASH_BGX(20);
1765 +               fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
1766 +               if (fontwidth(p) == 16) {
1767 +                   SPLASH_BGX(24);
1768 +                   fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
1769 +                   SPLASH_BGX(28);
1770 +                   fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
1771 +               }
1772 +               splashbgx += splash_bytes;
1773 +           }
1774 +
1775 +           dest0 += fontwidth(p)*2;
1776 +           splashbgx0 += fontwidth(p) * 2;
1777 +       }
1778 +
1779 +       break;
1780 +    }
1781 +}
1782 +
1783 +void fbcon_splash16_revc(struct display *p, int xx, int yy)
1784 +{
1785 +    u8 *dest;
1786 +    int bytes = p->next_line, rows;
1787 +
1788 +    dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p)*2;
1789 +    dest += splash_data.splash_text_yo * bytes + splash_data.splash_text_xo * 2;
1790 +
1791 +    for (rows = fontheight(p); rows--; dest += bytes) {
1792 +       switch (fontwidth(p)) {
1793 +       case 16:
1794 +           fb_writel(fb_readl(dest+24) ^ 0xffffffff, dest+24);
1795 +           fb_writel(fb_readl(dest+28) ^ 0xffffffff, dest+28);
1796 +           /* FALL THROUGH */
1797 +       case 12:
1798 +           fb_writel(fb_readl(dest+16) ^ 0xffffffff, dest+16);
1799 +           fb_writel(fb_readl(dest+20) ^ 0xffffffff, dest+20);
1800 +           /* FALL THROUGH */
1801 +       case 8:
1802 +           fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8);
1803 +           fb_writel(fb_readl(dest+12) ^ 0xffffffff, dest+12);
1804 +           /* FALL THROUGH */
1805 +       case 4:
1806 +           fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
1807 +           fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4);
1808 +       }
1809 +    }
1810 +}
1811 +
1812 +void fbcon_splash16_clear_margins(struct vc_data *conp, struct display *p,
1813 +                              int bottom_only)
1814 +{
1815 +    int bytes = p->next_line;
1816 +    u32 bgx;
1817 +
1818 +    unsigned int right_start = conp->vc_cols*fontwidth(p);
1819 +    unsigned int bottom_start = conp->vc_rows*fontheight(p);
1820 +    unsigned int right_width, bottom_width;
1821 +
1822 +    int left_margin_width = splash_data.splash_text_xo;
1823 +    int text_width = conp->vc_cols * fontwidth(p);
1824 +    int right_margin_width = p->var.xres - text_width - left_margin_width;
1825 +    int top_margin_height = splash_data.splash_text_yo;
1826 +    int text_height = conp->vc_rows * fontheight(p);
1827 +    int bottom_margin_height = p->var.yres - text_height - top_margin_height;
1828
1829 +    bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
1830 +
1831 +    if (bottom_only == -1) {
1832 +       printk(KERN_DEBUG "Called with bottom-only\n");
1833 +       splashfill(p->screen_base, linux_splash, p->var.xres, p->var.yres, bytes, splash_bytes); 
1834 +       return;
1835 +    }
1836 +
1837 +    if (!bottom_only && (right_width = p->var.xres-right_start)) {
1838 +       /* left margin */
1839 +       splashfill(p->screen_base + top_margin_height * bytes,
1840 +                  linux_splash + top_margin_height * 
1841 +                  splash_bytes, left_margin_width,
1842 +                  text_height, bytes, splash_bytes);
1843 +
1844 +       /* right margin */
1845 +       splashfill(p->screen_base + left_margin_width*2 + text_width*2 +
1846 +                   top_margin_height * bytes, linux_splash +
1847 +                   left_margin_width*2 + text_width*2 + top_margin_height *
1848 +                   splash_bytes, right_margin_width, text_height,
1849 +                   bytes, splash_bytes);
1850 +    }
1851 +
1852 +    if ((bottom_width = p->var.yres-bottom_start))
1853 +       /* bottom margin */
1854 +       splashfill(p->screen_base + (top_margin_height + text_height) *
1855 +                   bytes, linux_splash + (top_margin_height +
1856 +                   text_height) * splash_bytes, p->var.xres, 
1857 +                   bottom_margin_height, bytes, splash_bytes);
1858 +
1859 +    /* top margin */
1860 +    splashfill(p->screen_base, linux_splash,
1861 +           p->var.xres, top_margin_height,
1862 +           bytes, splash_bytes);
1863 +
1864 +    /* leave function if work is done */
1865 +    return;
1866 +}
1867 +
1868 +
1869 +    /*
1870 +     *  `switch' for the low level operations
1871 +     */
1872 +
1873 +struct display_switch fbcon_splash16 = {
1874 +    bmove:             fbcon_splash16_bmove,
1875 +    clear:             fbcon_splash16_clear,
1876 +    putc:              fbcon_splash16_putc,
1877 +    putcs:             fbcon_splash16_putcs,
1878 +    revc:              fbcon_splash16_revc,
1879 +    clear_margins:     fbcon_splash16_clear_margins,
1880 +    fontwidthmask:     FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
1881 +};
1882 +
1883 +
1884 +#ifdef MODULE
1885 +MODULE_LICENSE("GPL");
1886 +
1887 +int init_module(void)
1888 +{
1889 +    return 0;
1890 +}
1891 +
1892 +void cleanup_module(void)
1893 +{}
1894 +#endif /* MODULE */
1895 +
1896 +
1897 +    /*
1898 +     *  Visible symbols for modules
1899 +     */
1900 +
1901 +EXPORT_SYMBOL(fbcon_splash16);
1902 +EXPORT_SYMBOL(fbcon_splash16_bmove);
1903 +EXPORT_SYMBOL(fbcon_splash16_clear);
1904 +EXPORT_SYMBOL(fbcon_splash16_putc);
1905 +EXPORT_SYMBOL(fbcon_splash16_putcs);
1906 +EXPORT_SYMBOL(fbcon_splash16_revc);
1907 +EXPORT_SYMBOL(fbcon_splash16_clear_margins);
1908 diff -urN linux-2.4.24.org/drivers/video/fbcon-splash.c linux-2.4.24/drivers/video/fbcon-splash.c
1909 --- linux-2.4.24.org/drivers/video/fbcon-splash.c       1970-01-01 01:00:00.000000000 +0100
1910 +++ linux-2.4.24/drivers/video/fbcon-splash.c   2004-01-19 21:03:48.216680056 +0100
1911 @@ -0,0 +1,848 @@
1912 +/* 
1913 + *    linux/drivers/video/fbcon-splash.c - splash screen handling functions.
1914 + *     
1915 + *     (w) 2001-2003 by Volker Poplawski, <volker@suse.de>
1916 + *                 Stefan Reinauer, <stepan@suse.de>
1917 + *                 Steffen Winterfeldt, <snwint@suse.de>
1918 + *                 
1919 + *            Ideas & SuSE screen work by Ken Wimer, <wimer@suse.de>
1920 + */
1921 +
1922 +#include <linux/version.h>
1923 +#include <linux/config.h>
1924 +#include <linux/module.h>
1925 +#include <linux/fb.h>
1926 +#include <linux/vt_kern.h>
1927 +#include <linux/vmalloc.h>
1928 +
1929 +#include <asm/irq.h>
1930 +#include <asm/system.h>
1931 +
1932 +#include <video/fbcon.h>
1933 +#include <video/font.h>
1934 +#include <video/fbcon-cfb16.h>  /* for fbcon_cfb16 */
1935 +
1936 +#include "fbcon-splash.h"
1937 +#include "fbcon-jpegdec.h"
1938 +
1939 +#define SPLASH_VERSION "3.0.7-2003/03/10"
1940 +
1941 +#ifdef CONFIG_BLK_DEV_INITRD
1942 +unsigned char signature[] = "BOOTSPL1SPL2SPL3";
1943 +#endif
1944 +
1945 +/* from drivers/char/console.c */
1946 +extern void con_remap_def_color(int currcons, int new_color);
1947 +
1948 +/* from drivers/video/fbcon-splash16.c */
1949 +extern void splashfill(u8 *dest, u8 *src, int width, int height, 
1950 +                       int dest_linesize, int src_linesize);
1951 +
1952 +/* internal control states and data pointers */
1953 +struct splash_data splash_data;
1954 +
1955 +unsigned char *linux_splash;   /* decoded picture */
1956 +int linux_splash_size = 0;
1957 +
1958 +static struct jpeg_decdata *decdata = 0; /* private decoder data */
1959 +
1960 +int splash_bytes;              /* bytes per line in linux_splash */
1961 +int splash_shown = 0;          /* is the splash onscreen? */
1962 +int splash_usesilent = 0;      /* shall we display the silentjpeg */
1963 +int splash_default = 0xf01;
1964 +
1965 +static int splash_status(struct display *p);
1966 +static int splash_recolor(struct display *p);
1967 +static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth);
1968 +
1969 +extern struct display_switch fbcon_splash16;
1970 +
1971 +int __init splash_init(char *options)
1972 +{
1973 +       if(!strncmp("silent",options,6)) {
1974 +               printk(KERN_INFO "bootsplash: silent mode.\n");
1975 +               splash_usesilent = 1;
1976 +               /* skip "silent," */
1977 +               if (strlen(options)==6)
1978 +                       return 0;
1979 +               options+=7;
1980 +       }
1981 +       if(!strncmp("verbose",options,7)) {
1982 +               printk(KERN_INFO "bootsplash: verbose mode.\n");
1983 +               splash_usesilent = 0;
1984 +               return 0;
1985 +       }
1986 +               
1987 +       splash_default = simple_strtoul(options, NULL, 0);
1988 +
1989 +       return 0;
1990 +}
1991 +
1992 +__setup("splash=", splash_init);
1993 +
1994 +
1995 +static int splash_hasinter(unsigned char *buf, int num)
1996 +{
1997 +    unsigned char *bufend = buf + num * 12;
1998 +    while(buf < bufend) {
1999 +       if (buf[1] > 127)               /* inter? */
2000 +           return 1;
2001 +       buf += buf[3] > 127 ? 24 : 12;  /* blend? */
2002 +    }
2003 +    return 0;
2004 +}
2005 +
2006 +static int boxextract(unsigned char *buf, unsigned short *dp, unsigned char *cols, int *blendp)
2007 +{
2008 +    dp[0] = buf[0] | buf[1] << 8;
2009 +    dp[1] = buf[2] | buf[3] << 8;
2010 +    dp[2] = buf[4] | buf[5] << 8;
2011 +    dp[3] = buf[6] | buf[7] << 8;
2012 +    *(unsigned int *)(cols + 0) =
2013 +       *(unsigned int *)(cols + 4) =
2014 +       *(unsigned int *)(cols + 8) =
2015 +       *(unsigned int *)(cols + 12) = *(unsigned int *)(buf + 8);
2016 +    if (dp[1] > 32767) {
2017 +       dp[1] = ~dp[1];
2018 +       *(unsigned int *)(cols + 4) = *(unsigned int *)(buf + 12);
2019 +       *(unsigned int *)(cols + 8) = *(unsigned int *)(buf + 16);
2020 +       *(unsigned int *)(cols + 12) = *(unsigned int *)(buf + 20);
2021 +       *blendp = 1;
2022 +       return 24;
2023 +    }
2024 +    return 12;
2025 +}
2026 +
2027 +static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num, int percent, int overpaint)
2028 +{
2029 +    int x, y, i, p, doblend, r, g, b, a, add;
2030 +    unsigned short data1[4];
2031 +    unsigned char cols1[16];
2032 +    unsigned short data2[4];
2033 +    unsigned char cols2[16];
2034 +    unsigned char *bufend;
2035 +    unsigned short *picp;
2036 +
2037 +    if (num == 0)
2038 +       return;
2039 +    bufend = buf + num * 12;
2040 +    while(buf < bufend) {
2041 +       doblend = 0;
2042 +       buf += boxextract(buf, data1, cols1, &doblend);
2043 +       if (data1[0] > 32767)
2044 +           buf += boxextract(buf, data2, cols2, &doblend);
2045 +       if (data1[2] > 32767) {
2046 +           if (overpaint)
2047 +               continue;
2048 +           data1[2] = ~data1[2];
2049 +       }
2050 +       if (data1[3] > 32767) {
2051 +           if (percent == 65536)
2052 +               continue;
2053 +           data1[3] = ~data1[3];
2054 +       }
2055 +       if (data1[0] > 32767) {
2056 +           data1[0] = ~data1[0];
2057 +           for (i = 0; i < 4; i++)
2058 +               data1[i] = (data1[i] * (65536 - percent) + data2[i] * percent) >> 16;
2059 +           for (i = 0; i < 16; i++)
2060 +               cols1[i] = (cols1[i] * (65536 - percent) + cols2[i] * percent) >> 16;
2061 +       }
2062 +       *(unsigned int *)cols2 = *(unsigned int *)cols1;
2063 +       a = cols2[3];
2064 +       if (a == 0 && !doblend)
2065 +           continue;
2066 +       for (y = data1[1]; y <= data1[3]; y++) {
2067 +           if (doblend) {
2068 +               if ((p = data1[3] - data1[1]) != 0)
2069 +                   p = ((y - data1[1]) << 16) / p;
2070 +               for (i = 0; i < 8; i++)
2071 +                   cols2[i + 8] = (cols1[i] * (65536 - p) + cols1[i + 8] * p) >> 16;
2072 +           }
2073 +           add = (data1[0] & 1);
2074 +           add ^= (add ^ y) & 1 ? 1 : 3;               /* 2x2 ordered dithering */
2075 +           picp = (unsigned short *)(pic + data1[0] * 2 + y * bytes);
2076 +           for (x = data1[0]; x <= data1[2]; x++) {
2077 +               if (doblend) {
2078 +                   if ((p = data1[2] - data1[0]) != 0)
2079 +                       p = ((x - data1[0]) << 16) / p;
2080 +                   for (i = 0; i < 4; i++)
2081 +                       cols2[i] = (cols2[i + 8] * (65536 - p) + cols2[i + 12] * p) >> 16;
2082 +                   a = cols2[3];
2083 +               }
2084 +               r = cols2[0];
2085 +               g = cols2[1];
2086 +               b = cols2[2];
2087 +               if (a != 255) {
2088 +                   i = *picp;
2089 +                   r = ((i >> 8 & 0xf8) * (255 - a) + r * a) / 255;
2090 +                   g = ((i >> 3 & 0xfc) * (255 - a) + g * a) / 255;
2091 +                   b = ((i << 3 & 0xf8) * (255 - a) + b * a) / 255;
2092 +               }
2093 +  #define CLAMP(x) ((x) >= 256 ? 255 : (x))
2094 +               i = ((CLAMP(r + add*2+1) & 0xf8) <<  8) |
2095 +                   ((CLAMP(g + add    ) & 0xfc) <<  3) |
2096 +                   ((CLAMP(b + add*2+1)       ) >>  3);
2097 +               *picp++ = i;
2098 +               add ^= 3;
2099 +           }
2100 +       }
2101 +    }
2102 +}
2103 +
2104 +static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth)
2105 +{
2106 +    int size, err;
2107 +    unsigned char *mem;
2108 +
2109 +    size = ((width + 15) & ~15) * ((height + 15) & ~15) * (depth >> 3);
2110 +    mem = vmalloc(size);
2111 +    if (!mem) {
2112 +       printk(KERN_INFO "No memory for decoded picture!\n");
2113 +       return -1;
2114 +    }
2115 +    if (!decdata)
2116 +       decdata = vmalloc(sizeof(*decdata));
2117 +    if ((err = jpeg_decode(jpeg, mem, ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata)))
2118 +         printk(KERN_INFO "error %d while decompressing picture.\n",err);
2119 +    vfree(mem);
2120 +    return err ? -1 : 0;
2121 +}
2122 +
2123 +static void splash_free(struct display * p)
2124 +{
2125 +    if (!p->splash_data)
2126 +       return;
2127 +    if (p->splash_data->oldscreen_base)
2128 +           p->screen_base = p->splash_data->oldscreen_base;
2129 +    if (p->splash_data->olddispsw)
2130 +           p->dispsw = p->splash_data->olddispsw;
2131 +    if (p->splash_data->splash_silentjpeg)
2132 +           vfree(p->splash_data->splash_sboxes);
2133 +    vfree(p->splash_data);
2134 +    p->splash_data = 0;
2135 +}
2136 +
2137 +static int splash_mkpenguin(struct splash_data *data, int pxo, int pyo, int pwi, int phe, int pr, int pg, int pb)
2138 +{
2139 +    unsigned char *buf;
2140 +    int i;
2141 +
2142 +    if (pwi ==0 || phe == 0)
2143 +       return 0;
2144 +    buf = (unsigned char *)data + sizeof(*data);
2145 +    pwi += pxo - 1;
2146 +    phe += pyo - 1;
2147 +    *buf++ = pxo;
2148 +    *buf++ = pxo >> 8;
2149 +    *buf++ = pyo;
2150 +    *buf++ = pyo >> 8;
2151 +    *buf++ = pwi;
2152 +    *buf++ = pwi >> 8;
2153 +    *buf++ = phe;
2154 +    *buf++ = phe >> 8;
2155 +    *buf++ = pr;
2156 +    *buf++ = pg;
2157 +    *buf++ = pb;
2158 +    *buf++ = 0;
2159 +    for (i = 0; i < 12; i++, buf++)
2160 +       *buf = buf[-12];
2161 +    buf[-24] ^= 0xff;
2162 +    buf[-23] ^= 0xff;
2163 +    buf[-1] = 0xff;
2164 +    return 2;
2165 +}
2166 +
2167 +int splash_getraw(unsigned char *start, unsigned char *end)
2168 +{
2169 +       unsigned char *ndata;
2170 +       int found = 0;
2171 +       int splash_size = 0;
2172 +       void *splash_start = 0;
2173 +        int unit = 0;
2174 +        int width = 0, height = 0;
2175 +       int silentsize;
2176 +       int boxcount = 0;
2177 +       int sboxcount = 0;
2178 +       int palcnt = 0;
2179 +       struct display *p;
2180 +
2181 +       printk(KERN_INFO "Looking for splash picture...");
2182 +
2183 +       p = &fb_display[0];
2184 +        silentsize = 0;
2185 +
2186 +       for (ndata = start; ndata < end; ndata++) {
2187 +               if (*((unsigned int *)ndata) != *((unsigned int *)signature))
2188 +                       continue;
2189 +               if (*((unsigned int *)(ndata+4))==*((unsigned int *)(signature+4))) {
2190 +                       printk(".");
2191 +                       unit = 0;
2192 +                       p = &fb_display[0];
2193 +                       width = p->var.xres;
2194 +                       height = p->var.yres;
2195 +
2196 +                       splash_size = ndata[16] + (ndata[17] << 8) + (ndata[18] << 16) + (ndata[19] << 24);
2197 +                       if (ndata + 20 + splash_size > end) {
2198 +                               printk(" found, but truncated!\n");
2199 +                               return -1;
2200 +                       }
2201 +                       if (!jpeg_check_size(ndata + 20, width, height)) { 
2202 +                               ndata += 20 - 1 + splash_size;
2203 +                               continue;
2204 +                       }
2205 +                       if (splash_check_jpeg(ndata + 20, width, height, p->var.bits_per_pixel))
2206 +                               return -1;
2207 +                       if (p->splash_data)
2208 +                               splash_free(p);
2209 +                       p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size + 24);
2210 +                       if (!p->splash_data)
2211 +                               break;
2212 +
2213 +                       p->splash_data->oldscreen_base = 0;
2214 +                       p->splash_data->olddispsw = 0;
2215 +                       p->splash_data->splash_silentjpeg = 0;
2216 +
2217 +                       p->splash_data->splash_text_xo = ndata[ 8] + (ndata[ 9] << 8);
2218 +                       p->splash_data->splash_text_yo = ndata[10] + (ndata[11] << 8);
2219 +                       p->splash_data->splash_text_wi = ndata[12] + (ndata[13] << 8);
2220 +                       p->splash_data->splash_text_he = ndata[14] + (ndata[15] << 8);
2221 +                       /* use 8x16 font... */
2222 +                       p->splash_data->splash_text_xo *= 8;
2223 +                       p->splash_data->splash_text_wi *= 8;
2224 +                       p->splash_data->splash_text_yo *= 16;
2225 +                       p->splash_data->splash_text_he *= 16;
2226 +                       p->splash_data->splash_color = (splash_default >> 8) & 0x0f;
2227 +                       p->splash_data->splash_fg_color = (splash_default >> 4) & 0x0f;
2228 +                       p->splash_data->splash_state = splash_default & 1;
2229 +                       p->splash_data->splash_percent = 0;
2230 +                       p->splash_data->splash_overpaintok = 0;
2231 +                       boxcount = splash_mkpenguin(p->splash_data, p->splash_data->splash_text_xo + 10, p->splash_data->splash_text_yo + 10, p->splash_data->splash_text_wi - 20, p->splash_data->splash_text_he - 20, 0xf0, 0xf0, 0xf0);
2232 +                       splash_start = ndata + 20;
2233 +                       found = 1;
2234 +                       break;
2235 +               }
2236 +               if (*((unsigned int *)(ndata + 4)) == *((unsigned int *)(signature+8))) {
2237 +                       printk(".");
2238 +                       unit = ndata[8];
2239 +                       if (unit >= MAX_NR_CONSOLES)
2240 +                           continue;
2241 +                       if (unit)
2242 +                           vc_allocate(unit);
2243 +                       p = &fb_display[unit];
2244 +                       width = fb_display[unit].var.xres;
2245 +                       height = fb_display[unit].var.yres;
2246 +                       splash_size = ndata[12] + (ndata[13] << 8) + (ndata[14] << 16) + (ndata[15] << 24);
2247 +                       if (splash_size == -1) {
2248 +                           printk(" found, updating values.\n");
2249 +                           if (p->splash_data) {
2250 +                               if (ndata[9] != 255)
2251 +                                   p->splash_data->splash_state = ndata[9];
2252 +                               if (ndata[10] != 255)
2253 +                                   p->splash_data->splash_fg_color = ndata[10];
2254 +                               if (ndata[11] != 255)
2255 +                                   p->splash_data->splash_color = ndata[11];
2256 +                           }
2257 +                           return unit;
2258 +                       }
2259 +                       if (splash_size == 0) {
2260 +                               printk(" found, freeing memory.\n");
2261 +                               if (p->splash_data)
2262 +                                       splash_free(p);
2263 +                               return unit;
2264 +                       }
2265 +                       if (ndata + 35 + splash_size > end) {
2266 +                               printk(" found, but truncated!\n");
2267 +                               return -1;
2268 +                       }
2269 +                       if (!jpeg_check_size(ndata + 35, width, height)) {
2270 +                               ndata += 35 - 1 + splash_size;
2271 +                               continue;
2272 +                       }
2273 +                       if (splash_check_jpeg(ndata + 35, width, height, p->var.bits_per_pixel))
2274 +                               return -1;
2275 +                       if (p->splash_data)
2276 +                               splash_free(p);
2277 +                       p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size + 24);
2278 +                       if (!p->splash_data)
2279 +                               break;
2280 +
2281 +                       p->splash_data->oldscreen_base = 0;
2282 +                       p->splash_data->olddispsw = 0;
2283 +                       p->splash_data->splash_silentjpeg = 0;
2284 +
2285 +                       p->splash_data->splash_state = ndata[9];
2286 +                       p->splash_data->splash_fg_color = ndata[10];
2287 +                       p->splash_data->splash_color = ndata[11];
2288 +                       p->splash_data->splash_text_xo = ndata[16] + (ndata[17] << 8);
2289 +                       p->splash_data->splash_text_yo = ndata[18] + (ndata[19] << 8);
2290 +                       p->splash_data->splash_text_wi = ndata[20] + (ndata[21] << 8);
2291 +                       p->splash_data->splash_text_he = ndata[22] + (ndata[23] << 8);
2292 +                       p->splash_data->splash_percent = 0;
2293 +                       p->splash_data->splash_overpaintok = 0;
2294 +                       boxcount = splash_mkpenguin(p->splash_data, ndata[24] + (ndata[25] << 8), ndata[26] + (ndata[27] << 8), ndata[28] + (ndata[29] << 8), ndata[30] + (ndata[31] << 8), ndata[32], ndata[33], ndata[34]);
2295 +                       splash_start = ndata + 35;
2296 +                       found = 2;
2297 +                       break;
2298 +               }
2299 +               if (*((unsigned int *)(ndata + 4)) == *((unsigned int *)(signature+12))) {
2300 +                       printk(".");
2301 +                       unit = ndata[8];
2302 +                       if (unit >= MAX_NR_CONSOLES)
2303 +                           continue;
2304 +                       if (unit)
2305 +                           vc_allocate(unit);
2306 +                       p = &fb_display[unit];
2307 +                       width = p->var.xres;
2308 +                       height = p->var.yres;
2309 +                       splash_size = ndata[12] + (ndata[13] << 8) + (ndata[14] << 16) + (ndata[15] << 24);
2310 +                       if (splash_size == -1) {
2311 +                           printk(" found, updating values.\n");
2312 +                           if (p->splash_data) {
2313 +                               if (ndata[9] != 255)
2314 +                                   p->splash_data->splash_state = ndata[9];
2315 +                               if (ndata[10] != 255)
2316 +                                   p->splash_data->splash_fg_color = ndata[10];
2317 +                               if (ndata[11] != 255)
2318 +                                   p->splash_data->splash_color = ndata[11];
2319 +                           }
2320 +                           return unit;
2321 +                       }
2322 +                       if (splash_size == 0) {
2323 +                               printk(" found, freeing memory.\n");
2324 +                               if (p->splash_data)
2325 +                                       splash_free(p);
2326 +                               return unit;
2327 +                       }
2328 +                       boxcount = ndata[24] + (ndata[25] << 8);
2329 +                       palcnt = ndata[37] * 3;
2330 +                       if (ndata + 38 + splash_size > end) {
2331 +                               printk(" found, but truncated!\n");
2332 +                               return -1;
2333 +                       }
2334 +                       if (!jpeg_check_size(ndata + 38 + boxcount * 12 + palcnt, width, height)) {
2335 +                               ndata += 38 - 1 + splash_size;
2336 +                               continue;
2337 +                       }
2338 +                       if (splash_check_jpeg(ndata + 38 + boxcount * 12 + palcnt, width, height, p->var.bits_per_pixel))
2339 +                               return -1;
2340 +                       silentsize = ndata[28] + (ndata[29] << 8) + (ndata[30] << 16) + (ndata[31] << 24);
2341 +                       if (silentsize)
2342 +                           printk(" silenjpeg size %d bytes,", silentsize);
2343 +                       if (silentsize >= splash_size) {
2344 +                               printk(" bigger than splashsize!\n");
2345 +                               return -1;
2346 +                       }
2347 +                       splash_size -= silentsize;
2348 +                       if (!splash_usesilent || !p->fb_info->fbops->fb_get_fix ) {
2349 +                               silentsize = 0;
2350 +                       } else {
2351 +                               struct fb_fix_screeninfo fix;
2352 +                               p->fb_info->fbops->fb_get_fix(&fix, unit, 0);
2353 +                               if (height * 2 * p->next_line > fix.smem_len) {
2354 +                                       printk(" does not fit into framebuffer.\n");
2355 +                                       silentsize = 0;
2356 +                               }
2357 +                       }
2358 +
2359 +                       sboxcount = ndata[32] + (ndata[33] << 8);
2360 +                       if (silentsize) {
2361 +                               char *simage=ndata + 38 + splash_size + 12 * sboxcount;
2362 +                               if (!jpeg_check_size(simage, width, height) ||
2363 +                                   splash_check_jpeg(simage, width, height, p->var.bits_per_pixel)) {
2364 +                                       printk(" error in silent jpeg.\n");
2365 +                                       silentsize = 0;
2366 +                               }
2367 +                       }
2368 +                       if (p->splash_data)
2369 +                               splash_free(p);
2370 +                       p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size);
2371 +                       if (!p->splash_data)
2372 +                               break;
2373 +                       p->splash_data->oldscreen_base = 0;
2374 +                       p->splash_data->olddispsw = 0;
2375 +                       p->splash_data->splash_silentjpeg = 0;
2376 +                       if (silentsize) {
2377 +                               p->splash_data->splash_silentjpeg = vmalloc(silentsize);
2378 +                               if (p->splash_data->splash_silentjpeg) {
2379 +                                       memcpy(p->splash_data->splash_silentjpeg, ndata + 38 + splash_size, silentsize);
2380 +                                       p->splash_data->splash_sboxes = p->splash_data->splash_silentjpeg;
2381 +                                       p->splash_data->splash_silentjpeg += 12 * sboxcount;
2382 +                                       p->splash_data->splash_sboxcount = sboxcount;
2383 +                               }
2384 +                       }
2385 +                       p->splash_data->splash_state = ndata[9];
2386 +                       p->splash_data->splash_fg_color = ndata[10];
2387 +                       p->splash_data->splash_color = ndata[11];
2388 +                       p->splash_data->splash_overpaintok = ndata[36];
2389 +                       p->splash_data->splash_text_xo = ndata[16] + (ndata[17] << 8);
2390 +                       p->splash_data->splash_text_yo = ndata[18] + (ndata[19] << 8);
2391 +                       p->splash_data->splash_text_wi = ndata[20] + (ndata[21] << 8);
2392 +                       p->splash_data->splash_text_he = ndata[22] + (ndata[23] << 8);
2393 +                       p->splash_data->splash_percent = ndata[34] + (ndata[35] << 8);
2394 +                       p->splash_data->splash_percent += p->splash_data->splash_percent > 32767;
2395 +                       splash_start = ndata + 38;
2396 +                       found = 3;
2397 +                       break;
2398 +               }
2399 +       }
2400 +       
2401 +       if (!found) {
2402 +               printk(" no good signature found.\n");
2403 +               return -1;
2404 +       }
2405 +       if (p->splash_data->splash_text_xo + p->splash_data->splash_text_wi > width || p->splash_data->splash_text_yo + p->splash_data->splash_text_he > height) {
2406 +               splash_free(p);
2407 +               p->splash_data = 0;
2408 +               printk(" found, but has oversized text area!\n");
2409 +               return -1;
2410 +       }
2411 +       if (p->dispsw->setup != fbcon_cfb16.setup) {
2412 +               splash_free(p);
2413 +               p->splash_data = 0;
2414 +               printk(" found, but framebuffer can't handle it!\n");
2415 +               return -1;
2416 +       }
2417 +       printk(" found (%dx%d, %d bytes, v%d).\n", width, height, splash_size, found);
2418 +
2419 +       if (found==1) {
2420 +               printk(KERN_WARNING "bootsplash: Using deprecated v1 header. Updating your splash utility recommended.\n");
2421 +               printk(KERN_INFO    "bootsplash: Find the latest version at ftp.suse.com/pub/people/stepan/bootsplash/\n");
2422 +       }
2423 +
2424 +       /* copy data so that initrd memory can be freed. */
2425 +       memcpy((char *)p->splash_data + sizeof(*p->splash_data) + (found < 3 ? boxcount * 12 : 0), splash_start, splash_size);
2426 +       p->splash_data->splash_boxcount = boxcount;
2427 +       p->splash_data->splash_boxes = (unsigned char *)p->splash_data + sizeof(*p->splash_data);
2428 +       p->splash_data->splash_jpeg = (unsigned char *)p->splash_data + sizeof(*p->splash_data) + boxcount * 12 + palcnt;
2429 +       p->splash_data->splash_palette = (unsigned char *)p->splash_data + sizeof(*p->splash_data) + boxcount * 12;
2430 +       p->splash_data->splash_palcnt = palcnt / 3;
2431 +       p->splash_data->splash_dosilent = p->splash_data->splash_silentjpeg != 0;
2432 +       return unit;
2433 +}
2434 +
2435 +int splash_verbose(void) 
2436 +{
2437 +    struct display *p;
2438 +
2439 +    p = &fb_display[0];
2440 +    if (!p || !p->splash_data || !p->splash_data->splash_state || !p->conp)
2441 +       return 0;
2442 +    if (fg_console != p->conp->vc_num)
2443 +       return 0;
2444 +    if (!p->splash_data->splash_silentjpeg || !p->splash_data->splash_dosilent)
2445 +       return 0;
2446 +    if (!p->splash_data->oldscreen_base)
2447 +       return 0;
2448 +
2449 +    p->splash_data->splash_dosilent = 0;
2450 +
2451 +    splashfill(p->splash_data->oldscreen_base, p->screen_base, p->var.xres, p->var.yres, p->next_line, p->next_line);
2452 +    p->screen_base = p->splash_data->oldscreen_base;
2453 +
2454 +    return 1;
2455 +}
2456 +
2457 +static void splash_off(struct display *p)
2458 +{
2459 +    if (p->splash_data && p->splash_data->oldscreen_base)
2460 +       p->screen_base = p->splash_data->oldscreen_base;
2461 +    if (p->splash_data && p->splash_data->olddispsw)
2462 +       p->dispsw = p->splash_data->olddispsw;
2463 +    splash_shown = 0;
2464 +}
2465 +
2466 +int splash_prepare(struct display *p)
2467 +{
2468 +       int err;
2469 +        int width, height, depth, size, sbytes;
2470 +
2471 +       if (!p->splash_data || !p->splash_data->splash_state) {
2472 +               if (linux_splash)
2473 +                       vfree(linux_splash);
2474 +               if (decdata)
2475 +                       vfree(decdata);
2476 +               linux_splash = 0;
2477 +               decdata = 0;
2478 +               linux_splash_size = 0;
2479 +               splash_off(p);
2480 +               return -1;
2481 +       }
2482 +
2483 +        width = p->var.xres;
2484 +        height = p->var.yres;
2485 +        depth = p->var.bits_per_pixel;
2486 +       if (depth != 16) {      /* Other targets might need fixing */
2487 +               splash_off(p);
2488 +               return -2;
2489 +       }
2490 +
2491 +       sbytes = ((width + 15) & ~15) * (depth >> 3);
2492 +       size = sbytes * ((height + 15) & ~15);
2493 +       if (size != linux_splash_size) {
2494 +               if (linux_splash)
2495 +                       vfree(linux_splash);
2496 +               linux_splash_size = 0;
2497 +               linux_splash = 0;
2498 +               splash_off(p);
2499 +       }
2500 +       if (!linux_splash)
2501 +               linux_splash = vmalloc(size);
2502 +
2503 +       if (!linux_splash) {
2504 +               linux_splash_size = 0;
2505 +               printk(KERN_INFO "Not enough memory for splash screen.\n");
2506 +               splash_off(p);
2507 +               return -3;
2508 +       }
2509 +
2510 +       if (!decdata)
2511 +           decdata = vmalloc(sizeof(*decdata));
2512 +
2513 +       if (!p->splash_data->oldscreen_base)
2514 +               p->splash_data->oldscreen_base = p->screen_base;
2515 +
2516 +       if (p->splash_data->splash_silentjpeg && p->splash_data->splash_dosilent) {
2517 +               printk(KERN_INFO "Got silent jpeg.\n");
2518 +               /* fill area after framebuffer with other jpeg */
2519 +               if ((err = jpeg_decode(p->splash_data->splash_silentjpeg, linux_splash, 
2520 +                        ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
2521 +                       printk(KERN_INFO "Error %d while decompressing silent jpeg.\n", err);
2522 +                       p->screen_base = p->splash_data->oldscreen_base;
2523 +                       p->splash_data->splash_dosilent = 0;
2524 +               } else {
2525 +                       if (p->splash_data->splash_sboxcount)
2526 +                               boxit(linux_splash, sbytes, p->splash_data->splash_sboxes, 
2527 +                                       p->splash_data->splash_sboxcount, p->splash_data->splash_percent, 0);
2528 +
2529 +                       splashfill(p->screen_base, linux_splash, p->var.xres, p->var.yres, p->next_line, sbytes);
2530 +                       p->screen_base = p->splash_data->oldscreen_base + p->next_line * p->var.yres;
2531 +               }
2532 +       } else
2533 +               p->screen_base = p->splash_data->oldscreen_base;
2534 +
2535 +       if ((err = jpeg_decode(p->splash_data->splash_jpeg, linux_splash, 
2536 +                ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
2537 +               printk(KERN_INFO "Error %d while decompressing splash screen.\n", err);
2538 +               vfree(linux_splash);
2539 +               linux_splash = 0;
2540 +               linux_splash_size = 0;
2541 +               splash_off(p);
2542 +               return -4;
2543 +       }
2544 +       linux_splash_size = size;
2545 +       splash_bytes = sbytes;
2546 +       if (p->splash_data->splash_boxcount)
2547 +               boxit(linux_splash, sbytes, p->splash_data->splash_boxes, p->splash_data->splash_boxcount, p->splash_data->splash_percent, 0);
2548 +       splash_data = *p->splash_data;
2549 +       splash_shown = p->splash_data->splash_state;
2550 +       if (splash_shown) {
2551 +           if (p->dispsw != &fbcon_splash16)
2552 +               p->splash_data->olddispsw = p->dispsw;
2553 +           p->dispsw = &fbcon_splash16;
2554 +       } else
2555 +               splash_off(p);
2556 +       return 0;
2557 +}
2558 +
2559 +
2560 +#ifdef CONFIG_PROC_FS
2561 +#include <linux/proc_fs.h>
2562 +
2563 +struct proc_dir_entry *proc_splash;
2564 +int splash_read_proc(char *buffer, char **start, off_t offset, int size,
2565 +                       int *eof, void *data);
2566 +int splash_write_proc(struct file *file, const char *buffer,
2567 +                       unsigned long count, void *data);
2568 +
2569 +int splash_read_proc(char *buffer, char **start, off_t offset, int size,
2570 +                       int *eof, void *data)
2571 +{
2572 +       int len = 0;
2573 +       
2574 +       off_t begin = 0;
2575 +       struct display *p = &fb_display[0];
2576 +
2577 +       int color = p->splash_data ? p->splash_data->splash_color << 4 |
2578 +                       p->splash_data->splash_fg_color : splash_default >> 4;
2579 +       int status = p->splash_data ? p->splash_data->splash_state & 1 : 0;
2580 +       len += sprintf(buffer + len, "Splash screen v%s (0x%02x, %dx%d%s): %s\n",
2581 +                       SPLASH_VERSION, color, p->var.xres, p->var.yres,
2582 +                       (p->splash_data ?  p->splash_data->splash_dosilent : 0)? ", silent" : "",
2583 +                                       status ? "on" : "off");
2584 +       if (offset >= begin + len)
2585 +               return 0;
2586 +
2587 +       *start = buffer + (begin - offset);
2588 +
2589 +       return (size < begin + len - offset ? size : begin + len - offset);
2590 +}
2591 +
2592 +static int splash_recolor(struct display *p)
2593 +{
2594 +       if (!p->splash_data)
2595 +           return -1;
2596 +       if (!p->splash_data->splash_state)
2597 +           return 0;
2598 +       con_remap_def_color(p->conp->vc_num, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color);
2599 +       if (fg_console == p->conp->vc_num) {
2600 +               splash_data = *p->splash_data;
2601 +               update_region(fg_console,
2602 +                             p->conp->vc_origin +
2603 +                             p->conp->vc_size_row *
2604 +                             p->conp->vc_top,
2605 +                             p->conp->vc_size_row *
2606 +                             (p->conp->vc_bottom -
2607 +                              p->conp->vc_top) / 2);
2608 +       }
2609 +       return 0;
2610 +}
2611 +
2612 +static int splash_status(struct display *p)
2613 +{
2614 +       printk(KERN_INFO "Splash status on console %d changed to %s\n", p->conp->vc_num, p->splash_data && p->splash_data->splash_state ? "on" : "off");
2615 +
2616 +       if (fg_console == p->conp->vc_num)
2617 +               splash_prepare(p);
2618 +       if (p->splash_data && p->splash_data->splash_state) {
2619 +               con_remap_def_color(p->conp->vc_num, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color);
2620 +               /* resize_con also calls con_switch which resets yscroll */
2621 +               vc_resize_con(p->splash_data->splash_text_he / fontheight(p),
2622 +                              p->splash_data->splash_text_wi / fontwidth(p),
2623 +                              p->conp->vc_num);
2624 +               if (fg_console == p->conp->vc_num) {
2625 +                       update_region(fg_console,
2626 +                                     p->conp->vc_origin +
2627 +                                     p->conp->vc_size_row *
2628 +                                     p->conp->vc_top,
2629 +                                     p->conp->vc_size_row *
2630 +                                     (p->conp->vc_bottom -
2631 +                                      p->conp->vc_top) / 2);
2632 +                           fbcon_splash16.clear_margins(p->conp, p, 0);
2633 +               }
2634 +       } else {
2635 +               /* Switch bootsplash off */
2636 +               con_remap_def_color(p->conp->vc_num, 0x07);
2637 +               vc_resize_con(p->var.yres / fontheight(p),
2638 +                             p->var.xres / fontwidth(p),
2639 +                             p->conp->vc_num);
2640 +       }
2641 +       return 0;
2642 +}
2643 +
2644 +int splash_write_proc(struct file *file, const char *buffer,
2645 +                     unsigned long count, void *data)
2646 +{
2647 +        int new, unit;
2648 +       struct display *p;
2649 +       
2650 +       if (!buffer || !splash_default)
2651 +               return count;
2652 +
2653 +       if (!strncmp(buffer, "show", 4) || !strncmp(buffer, "hide", 4)) {
2654 +               int pe;
2655 +
2656 +               p = &fb_display[0];
2657 +               if (buffer[4] == ' ' && buffer[5] == 'p')
2658 +                       pe = 0;
2659 +               else if (buffer[4] == '\n')
2660 +                       pe = 65535;
2661 +               else
2662 +                       pe = simple_strtoul(buffer + 5, NULL, 0);
2663 +               if (pe < 0)
2664 +                       pe = 0;
2665 +               if (pe > 65535)
2666 +                       pe = 65535;
2667 +               if (*buffer == 'h')
2668 +                       pe = 65535 - pe;
2669 +               pe += pe > 32767;
2670 +               if (p->splash_data && p->splash_data->splash_percent != pe) {
2671 +                       p->splash_data->splash_percent = pe;
2672 +                       if (fg_console != p->conp->vc_num || !p->splash_data->splash_state)
2673 +                           return count;
2674 +                       if (!p->splash_data->splash_overpaintok || p->splash_data->splash_percent == 65536) {
2675 +                               if (splash_hasinter(p->splash_data->splash_boxes, p->splash_data->splash_boxcount))
2676 +                                       splash_status(p);
2677 +                               else
2678 +                                       splash_prepare(p);
2679 +                       } else {
2680 +                               if (p->splash_data->splash_silentjpeg && p->splash_data->splash_dosilent && p->splash_data->oldscreen_base)
2681 +                                       boxit(p->splash_data->oldscreen_base, p->next_line, p->splash_data->splash_sboxes, p->splash_data->splash_sboxcount, p->splash_data->splash_percent, 1);
2682 +                               boxit(p->screen_base, p->next_line, p->splash_data->splash_boxes, p->splash_data->splash_boxcount, p->splash_data->splash_percent, 1);
2683 +                       }
2684 +               }
2685 +               return count;
2686 +       }
2687 +       if (!strncmp(buffer,"silent\n",7) || !strncmp(buffer,"verbose\n",8)) {
2688 +               p = &fb_display[0];
2689 +               if (p->splash_data && p->splash_data->splash_silentjpeg) {
2690 +                   if (p->splash_data->splash_dosilent != (buffer[0] == 's')) {
2691 +                       p->splash_data->splash_dosilent = buffer[0] == 's';
2692 +                       splash_status(p);
2693 +                   }
2694 +               }
2695 +               return count;
2696 +       }
2697 +       if (!strncmp(buffer,"freesilent\n",11)) {
2698 +               p = &fb_display[0];
2699 +               if (p->splash_data && p->splash_data->splash_silentjpeg) {
2700 +                   printk(KERN_INFO "bootsplash: freeing silent jpeg\n");
2701 +                   p->splash_data->splash_silentjpeg = 0;
2702 +                   vfree(p->splash_data->splash_sboxes);
2703 +                   p->splash_data->splash_sboxes = 0;
2704 +                   p->splash_data->splash_sboxcount = 0;
2705 +                   if (p->splash_data->splash_dosilent)
2706 +                       splash_status(p);
2707 +                   p->splash_data->splash_dosilent = 0;
2708 +               }
2709 +               return count;
2710 +       }
2711 +
2712 +       if (!strncmp(buffer, signature, 7)) {
2713 +           unit = splash_getraw((unsigned char *)buffer, (unsigned char *)buffer + count);
2714 +           if (unit >= 0) {
2715 +               p = &fb_display[unit];
2716 +               splash_status(p);
2717 +           }
2718 +           return count;
2719 +       }
2720 +       p = &fb_display[0];
2721 +       if (!p->splash_data)
2722 +               return count;
2723 +       if (buffer[0] == 't') {
2724 +               p->splash_data->splash_state ^= 1;
2725 +               splash_status(p);
2726 +               return count;
2727 +       }
2728 +       new = simple_strtoul(buffer, NULL, 0);
2729 +       if (new > 1) {
2730 +               /* expert user */
2731 +               p->splash_data->splash_color    = new >> 8 & 0xff;
2732 +               p->splash_data->splash_fg_color = new >> 4 & 0x0f;
2733 +       }
2734 +       if ((new & 1) == p->splash_data->splash_state)
2735 +               splash_recolor(p);
2736 +       else {
2737 +               p->splash_data->splash_state = new & 1;
2738 +               splash_status(p);
2739 +       }
2740 +       return count;
2741 +}
2742 +
2743 +int splash_proc_register(void)
2744 +{
2745 +       if ((proc_splash = create_proc_entry("splash", 0, 0))) {
2746 +               proc_splash->read_proc = splash_read_proc;
2747 +               proc_splash->write_proc = splash_write_proc;
2748 +               return 0;
2749 +       }
2750 +       return 1;
2751 +}
2752 +
2753 +int splash_proc_unregister(void)
2754 +{
2755 +       if (proc_splash)
2756 +               remove_proc_entry("splash", 0);
2757 +       return 0;
2758 +}
2759 +#endif
2760 diff -urN linux-2.4.24.org/drivers/video/fbcon-splash.h linux-2.4.24/drivers/video/fbcon-splash.h
2761 --- linux-2.4.24.org/drivers/video/fbcon-splash.h       1970-01-01 01:00:00.000000000 +0100
2762 +++ linux-2.4.24/drivers/video/fbcon-splash.h   2004-01-19 21:03:48.218679640 +0100
2763 @@ -0,0 +1,18 @@
2764 +/* 
2765 + *    linux/drivers/video/splash.h - splash screen definition.
2766 + *     
2767 + *     (w) 2001-2003 by Volker Poplawski, <volker@suse.de>
2768 + *                 Stefan Reinauer, <stepan@suse.de>
2769 + *                 
2770 + *                 
2771 + *     idea and SuSE screen work by Ken Wimer, <wimer@suse.de>
2772 + */
2773 +
2774 +extern int splash_getraw(unsigned char *, unsigned char *);
2775 +extern int splash_prepare(struct display *);
2776 +
2777 +extern int splash_shown;               /* is splash shown? */
2778 +extern struct splash_data splash_data; /* image data, copied over
2779 +                                          from display */
2780 +extern unsigned char *linux_splash;    /* decoded pic data */
2781 +extern int splash_bytes;               /* bytes per line */
2782 diff -urN linux-2.4.24.org/drivers/video/Makefile linux-2.4.24/drivers/video/Makefile
2783 --- linux-2.4.24.org/drivers/video/Makefile     2004-01-19 21:01:12.732012987 +0100
2784 +++ linux-2.4.24/drivers/video/Makefile 2004-01-19 21:05:58.628528100 +0100
2785 @@ -14,7 +14,7 @@
2786                   fbcon-vga.o fbcon-iplan2p2.o fbcon-iplan2p4.o \
2787                   fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
2788                   fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
2789 -                 fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o \
2790 +                 fbcon-cfb8.o fbcon-splash16.o fbcon-mac.o fbcon-mfb.o \
2791                   cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o macmodes.o
2792  
2793  # Each configuration option enables a list of files.
2794 @@ -159,6 +159,10 @@
2795  obj-$(CONFIG_FBCON_HGA)           += fbcon-hga.o
2796  obj-$(CONFIG_FBCON_STI)           += fbcon-sti.o
2797  
2798 +obj-$(CONFIG_FBCON_SPLASHSCREEN)  += fbcon-splash.o
2799 +obj-$(CONFIG_FBCON_SPLASHSCREEN)  += fbcon-splash16.o
2800 +obj-$(CONFIG_FBCON_SPLASHSCREEN)  += fbcon-jpegdec.o
2801 +
2802  include $(TOPDIR)/Rules.make
2803  
2804  clean:
2805 diff -urN linux-2.4.24.org/include/video/fbcon.h linux-2.4.24/include/video/fbcon.h
2806 --- linux-2.4.24.org/include/video/fbcon.h      2004-01-19 20:59:23.213788389 +0100
2807 +++ linux-2.4.24/include/video/fbcon.h  2004-01-19 21:03:48.295663632 +0100
2808 @@ -42,6 +42,35 @@
2809      unsigned int fontwidthmask;      /* 1 at (1 << (width - 1)) if width is supported */
2810  }; 
2811  
2812 +#ifdef CONFIG_FBCON_SPLASHSCREEN
2813 +struct splash_data {
2814 +       int     splash_state;                   /* show splash? */
2815 +       int     splash_color;                   /* transparent color */
2816 +       int     splash_fg_color;                /* foreground color */
2817 +       int     splash_width;                   /* width of image */
2818 +       int     splash_height;                  /* height of image */
2819 +       int     splash_text_xo;                 /* text area origin */
2820 +       int     splash_text_yo;
2821 +       int     splash_text_wi;                 /* text area size */ 
2822 +       int     splash_text_he;
2823 +       int     splash_showtext;                /* silent/verbose mode */
2824 +       int     splash_boxcount;
2825 +       int     splash_percent;
2826 +       int     splash_overpaintok;             /* is it ok to overpaint boxes */
2827 +       int     splash_palcnt;
2828 +       struct display_switch *olddispsw;       /* old dispsw, normally &fbcon_cfb16*/
2829 +       char    *oldscreen_base;                /* pointer to top of virtual screen */    
2830 +       unsigned char *splash_boxes;
2831 +       unsigned char *splash_jpeg;             /* jpeg */
2832 +       unsigned char *splash_palette;          /* palette for 8-bit */
2833 +
2834 +       int     splash_dosilent;                /* show silent jpeg */
2835 +       unsigned char *splash_silentjpeg;
2836 +       unsigned char *splash_sboxes;
2837 +       int     splash_sboxcount;
2838 +};
2839 +#endif
2840 +
2841  extern struct display_switch fbcon_dummy;
2842  
2843     /*
2844 @@ -95,6 +124,10 @@
2845      short yscroll;                  /* Hardware scrolling */
2846      unsigned char fgshift, bgshift;
2847      unsigned short charmask;        /* 0xff or 0x1ff */
2848 +
2849 +#ifdef CONFIG_FBCON_SPLASHSCREEN
2850 +    struct splash_data *splash_data;
2851 +#endif
2852  };
2853  
2854  /* drivers/video/fbcon.c */
2855 diff -urN linux-2.4.24.org/kernel/panic.c linux-2.4.24/kernel/panic.c
2856 --- linux-2.4.24.org/kernel/panic.c     2004-01-19 20:58:34.218977671 +0100
2857 +++ linux-2.4.24/kernel/panic.c 2004-01-19 21:03:48.336655108 +0100
2858 @@ -83,6 +83,13 @@
2859                  * We can't use the "normal" timers since we just panicked..
2860                  */
2861                 printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
2862 +
2863 +#ifdef CONFIG_FBCON_SPLASHSCREEN
2864 +               {
2865 +                       extern int splash_verbose(void);
2866 +                       (void)splash_verbose();
2867 +               }
2868 +#endif
2869                 mdelay(panic_timeout*1000);
2870                 /*
2871                  *      Should we run the reboot notifier. For the moment Im
2872 @@ -103,6 +110,12 @@
2873          disabled_wait(caller);
2874  #endif
2875         sti();
2876 +#ifdef CONFIG_FBCON_SPLASHSCREEN
2877 +       {
2878 +               extern int splash_verbose(void);
2879 +               (void)splash_verbose();
2880 +       }
2881 +#endif
2882         for(;;) {
2883  #if defined(CONFIG_X86) && defined(CONFIG_VT) 
2884                 extern void panic_blink(void);
2885
This page took 0.263326 seconds and 3 git commands to generate.