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
8 +#ifdef CONFIG_FBCON_SPLASHSCREEN
9 +void con_remap_def_color(int currcons, int new_color)
11 + unsigned short *sbuf = screenbuf;
12 + unsigned c, len = screenbuf_size >> 1;
16 + old_color = def_color << 8;
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;
28 + def_color = color = new_color;
29 + update_attr(currcons);
34 * Visible symbols for modules
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
41 rep = test_and_set_bit(keycode, key_down);
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())
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
59 #include <linux/string.h>
60 #include <linux/slab.h>
61 #include <linux/poll.h>
62 +#include <linux/config.h>
64 #include <asm/uaccess.h>
65 #include <asm/system.h>
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();
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
87 tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL
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
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
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
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
117 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
118 "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
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
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
134 #include <linux/smp.h>
135 #include <linux/init.h>
136 #include <linux/pm.h>
137 +#include <linux/vmalloc.h>
140 #include <asm/system.h>
142 #include <video/fbcon-mac.h> /* for 6x11 font on mac */
143 #include <video/font.h>
145 +#ifdef CONFIG_FBCON_SPLASHSCREEN
146 +#include <video/fbcon-cfb16.h> /* for fbcon_cfb16 */
147 +#include "fbcon-splash.h"
149 +extern void con_remap_def_color(int currcons, int new_color);
151 +extern int splash_default;
152 +extern int splash_shown;
154 +extern struct display_switch fbcon_splash16;
156 +#ifdef CONFIG_PROC_FS
157 +int splash_proc_register(void);
158 +int splash_proc_unregister(void);
163 # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
170 +#ifdef CONFIG_FBCON_SPLASHSCREEN
171 +static int splash_registered=0;
173 static void fbcon_init(struct vc_data *conp, int init)
175 int unit = conp->vc_num;
177 fb_display[unit].cmap.green = 0;
178 fb_display[unit].cmap.blue = 0;
179 fb_display[unit].cmap.transp = 0;
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;
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;
189 + splash_registered = 1;
190 +#ifdef CONFIG_PROC_FS
191 + splash_proc_register();
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;
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;
205 p->dispsw = &fbcon_dummy;
207 +#ifdef CONFIG_FBCON_SPLASHSCREEN
208 + if (splash_registered) {
209 +#ifdef CONFIG_PROC_FS
210 + splash_proc_unregister();
212 + splash_registered = 0;
221 nr_cols = p->var.xres/fontwidth(p);
222 nr_rows = p->var.yres/fontheight(p);
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);
233 /* Need to make room for the logo */
236 p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
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);
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 @@
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;
254 switch (p->scrollmode & __SCROLL_YMASK) {
256 p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,
257 @@ -1383,6 +1447,9 @@
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;
264 switch (p->scrollmode & __SCROLL_YMASK) {
266 p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count,
267 @@ -1499,6 +1566,13 @@
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);
278 p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
281 @@ -1509,6 +1583,10 @@
282 struct display *p = &fb_display[unit];
283 struct fb_info *info = p->fb_info;
285 +#ifdef CONFIG_FBCON_SPLASHSCREEN
290 int l = fbcon_softback_size / conp->vc_size_row;
292 @@ -1568,14 +1646,41 @@
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;
302 if (blank < 0) /* Entering graphics mode */
305 +#ifdef CONFIG_FBCON_SPLASHSCREEN
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;
311 + if (p->splash_data && p->splash_data->olddispsw) {
312 + olddispsw = p->dispsw;
313 + p->dispsw = p->splash_data->olddispsw;
317 fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
319 if (!p->can_soft_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;
326 + if (p->splash_data && p->splash_data->olddispsw) {
327 + olddispsw = p->dispsw;
328 + p->dispsw = p->splash_data->olddispsw;
331 if (p->visual == FB_VISUAL_MONO01) {
333 fb_memset255(p->screen_base,
334 @@ -1583,25 +1688,39 @@
335 p->var.bits_per_pixel>>3);
339 + u_int height, width;
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);
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);
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;
363 +#ifdef CONFIG_FBCON_SPLASHSCREEN
365 + p->screen_base=oldscreen_base;
367 + p->dispsw=olddispsw;
371 /* Tell console.c that it has to restore the screen itself */
376 (*info->blank)(blank, info);
378 @@ -1762,13 +1881,21 @@
381 struct vc_data *conp = p->conp;
382 + __u32 xres = p->var.xres, yres = p->var.yres;
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;
394 + if ((yres % h) && (p->var.yres_virtual % h < p->var.yres % h))
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;
402 @@ -2189,6 +2316,9 @@
403 if (p->fb_info->fbops->fb_rasterimg)
404 p->fb_info->fbops->fb_rasterimg(p->fb_info, 1);
406 +#ifdef CONFIG_FBCON_SPLASHSCREEN
407 + if (!splash_shown) {
409 for (x = 0; x < smp_num_cpus * (LOGO_W + 8) &&
410 x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
412 @@ -2450,7 +2580,10 @@
417 +#ifdef CONFIG_FBCON_SPLASHSCREEN
421 if (p->fb_info->fbops->fb_rasterimg)
422 p->fb_info->fbops->fb_rasterimg(p->fb_info, 0);
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
429 + * linux/drivers/video/fbcon-jpegdec.c - a tiny jpeg decoder.
431 + * (w) August 2001 by Michael Schroeder, <mls@suse.de>
435 +#include <linux/config.h>
436 +#include <linux/string.h>
437 +#include <asm/byteorder.h>
440 +#include "fbcon-splash.h"
441 +#include "fbcon-jpegdec.h"
445 +#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5))
446 +#define IMULT(a, b) (((a) * (b)) >> ISHIFT)
447 +#define ITOINT(a) ((a) >> ISHIFT)
453 +/* special markers */
454 +#define M_BADHUFF -1
463 + int (*func) __P((void *));
467 +/*********************************/
472 + struct dec_hufftbl *dhuff;
473 + struct enc_hufftbl *ehuff;
477 + int dc; /* old dc value */
479 + union hufftblp hudc;
480 + union hufftblp huac;
481 + int next; /* when to switch to next scan */
483 + int cid; /* component id */
484 + int hv; /* horiz/vert, copied from comp */
485 + int tq; /* quant tbl, copied from comp */
488 +/*********************************/
490 +#define DECBITS 10 /* seems to be the optimum */
492 +struct dec_hufftbl {
495 + unsigned char vals[256];
496 + unsigned int llvals[1 << DECBITS];
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 *));
503 +static void setinput __P((struct in *, unsigned char *));
504 +/*********************************/
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));
513 +/*********************************/
515 +static void initcol __P((PREC[][64]));
517 +static void col221111 __P((int *, unsigned char *, int));
518 +static void col221111_16 __P((int *, unsigned char *, int));
520 +/*********************************/
533 +static unsigned char *datap;
535 +static int getbyte(void)
540 +static int getword(void)
545 + return c1 << 8 | c2;
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 */
563 +static struct jpginfo info;
564 +static struct comp comps[MAXCOMP];
566 +static struct scan dscans[MAXCOMP];
568 +static unsigned char quant[4][64];
570 +static struct dec_hufftbl dhuff[4];
572 +#define dec_huffdc (dhuff + 0)
573 +#define dec_huffac (dhuff + 2)
575 +static struct in in;
577 +static int readtables(int till)
579 + int m, l, i, j, lq, pq, tq;
583 + if (getbyte() != 0xff)
585 + if ((m = getbyte()) == till)
602 + for (i = 0; i < 64; i++)
603 + quant[tq][i] = getbyte();
611 + int hufflen[16], k;
612 + unsigned char huffvals[256];
618 + if (tc > 1 || th > 1)
620 + for (i = 0; i < 16; i++)
621 + hufflen[i] = getbyte();
624 + for (i = 0; i < 16; i++) {
625 + for (j = 0; j < hufflen[i]; j++)
626 + huffvals[k++] = getbyte();
629 + dec_makehuff(dhuff + tt, hufflen,
636 + info.dri = getword();
649 +static void dec_initscans(void)
653 + info.nm = info.dri + 1;
655 + for (i = 0; i < info.ns; i++)
659 +static int dec_checkmarker(void)
663 + if (dec_readmarker(&in) != info.rm)
665 + info.nm = info.dri;
666 + info.rm = (info.rm + 1) & ~0x08;
667 + for (i = 0; i < info.ns; i++)
672 +int jpeg_check_size(unsigned char *buf, int width, int height)
677 + readtables(M_SOF0);
680 + if (height != getword() || width != getword())
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;
690 + int i, j, m, tac, tdc;
691 + int mcusx, mcusy, mx, my;
697 + if (getbyte() != 0xff)
699 + if (getbyte() != M_SOI)
701 + if (readtables(M_SOF0))
702 + return ERR_BAD_TABLES;
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++) {
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;
728 + if (readtables(M_SOS))
729 + return ERR_BAD_TABLES;
731 + info.ns = getbyte();
733 + return ERR_NOT_YCBCR_221111;
734 + for (i = 0; i < 3; i++) {
735 + dscans[i].cid = getbyte();
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)
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;
756 + if (i != 0 || j != 63 || m != 0)
757 + return ERR_NOT_SEQUENTIAL_DCT;
759 + if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3)
760 + return ERR_NOT_YCBCR_221111;
762 + if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11 || dscans[2].hv != 0x11)
763 + return ERR_NOT_YCBCR_221111;
765 + mcusx = width >> 4;
766 + mcusy = height >> 4;
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);
778 + img[len + 1] = 0xff;
779 + img[len + 2] = M_EOF;
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;
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]);
803 + col221111(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 3, mcusx * 16 * 3);
806 + col221111_16(decdata->out, pic + (my * 16 * mcusx + mx) * (16 * 2), mcusx * (16 * 2));
809 + return ERR_DEPTH_MISMATCH;
815 + m = dec_readmarker(&in);
822 +/****************************************************************/
823 +/************** huffman decoder ***************/
824 +/****************************************************************/
826 +static int fillbits __P((struct in *, int, unsigned int));
828 +__P((struct in *, struct dec_hufftbl *, int *, int, int));
830 +static void setinput(in, p)
840 +static int fillbits(in, le, bi)
849 + in->bits = bi << 16, le += 16;
854 + if (b == 0xff && (m = *in->p++) != 0) {
856 + if (in->func && (m = in->func(in->data)) == 0)
861 + bi = bi << 16, le += 16;
867 + in->bits = bi; /* tmp... 2 return values needed */
871 +static int dec_readmarker(in)
876 + in->left = fillbits(in, in->left, in->bits);
877 + if ((m = in->marker) == 0)
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)
888 +#define GETBITS(in, n) ( \
889 + (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0), \
891 + bi >> le & ((1 << (n)) - 1) \
894 +#define UNGETBITS(in, n) ( \
899 +static int dec_rec2(in, hu, runp, c, i)
901 +struct dec_hufftbl *hu;
909 + UNGETBITS(in, i & 127);
910 + *runp = i >> 8 & 15;
913 + for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++);
915 + in->marker = M_BADHUFF;
918 + i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
922 + if (i == 0) { /* sigh, 0xf0 is 11 bit */
927 + c = GETBITS(in, i);
928 + if (c < (1 << (i - 1)))
929 + c += (-1 << i) + 1;
934 +#define DEC_REC(in, hu, r, i) ( \
935 + r = GETBITS(in, DECBITS), \
936 + i = hu->llvals[r], \
939 + UNGETBITS(in, i & 127), \
946 + i = dec_rec2(in, hu, &r, r, i), \
952 +static void decode_mcus(in, dct, n, sc, maxp)
959 + struct dec_hufftbl *hu;
963 + memset(dct, 0, n * 64 * sizeof(*dct));
966 + hu = sc->hudc.dhuff;
967 + *dct++ = (sc->dc += DEC_REC(in, hu, r, t));
969 + hu = sc->huac.dhuff;
972 + t = DEC_REC(in, hu, r, t);
973 + if (t == 0 && r == 0) {
988 +static void dec_makehuff(hu, hufflen, huffvals)
989 +struct dec_hufftbl *hu;
991 +unsigned char *huffvals;
993 + int code, k, i, j, d, x, c, v;
994 + for (i = 0; i < (1 << DECBITS); i++)
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
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 -
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;
1025 + x = v << 16 | (hu-> vals[k] & 0xf0) << 4 |
1026 + (DECBITS - (i + 1));
1027 + hu->llvals[c | d] = x;
1033 + hu->maxcode[i] = code;
1035 + hu->maxcode[16] = 0x20000; /* always terminate decode */
1038 +/****************************************************************/
1039 +/************** idct ***************/
1040 +/****************************************************************/
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))
1047 +#define S22 ((PREC)IFIX(2 * 0.382683432))
1048 +#define C22 ((PREC)IFIX(2 * 0.923879532))
1049 +#define IC4 ((PREC)IFIX(1 / 0.707106781))
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 */
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)
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)
1067 + t2 = IMULT(t2, IC4) - t3, \
1073 + t5 = IMULT(t5, IC4), \
1074 + ROT(t4, t6, S22, C22),\
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
1095 +void idct(in, out, quant, off, max)
1102 + PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
1103 + PREC tmp[64], *tmpp;
1105 + unsigned char *zig2p;
1109 + t0 += in[0] * quant[0];
1110 + for (i = 0; i < 64; i++)
1111 + out[i] = ITOINT(t0);
1116 + for (i = 0; i < 8; i++) {
1118 + t0 += in[j] * quant[j];
1120 + t5 = in[j] * quant[j];
1122 + t2 = in[j] * quant[j];
1124 + t7 = in[j] * quant[j];
1126 + t1 = in[j] * quant[j];
1128 + t4 = in[j] * quant[j];
1130 + t3 = in[j] * quant[j];
1132 + t6 = in[j] * quant[j];
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];
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);
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
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)
1185 +static void idctqtab(qin, qout)
1186 +unsigned char *qin;
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]);
1197 +static void scaleidctqtab(q, sc)
1203 + for (i = 0; i < 64; i++)
1204 + q[i] = IMULT(q[i], sc);
1207 +/****************************************************************/
1208 +/************** color decoder ***************/
1209 +/****************************************************************/
1214 + * YCbCr Color transformation:
1216 + * y:0..255 Cb:-128..127 Cr:-128..127
1218 + * R = Y + 1.40200 * Cr
1219 + * G = Y - 0.34414 * Cb - 0.71414 * Cr
1220 + * B = Y + 1.77200 * Cb
1225 + * Cg = 0.19421 * Cb + .50937 * Cr;
1231 + * Cg = (50 * Cb + 130 * Cr + 128) >> 8;
1234 +static void initcol(q)
1237 + scaleidctqtab(q[1], IFIX(1.77200));
1238 + scaleidctqtab(q[2], IFIX(1.40200));
1241 +/* This is optimized for the stupid sun SUNWspro compiler. */
1242 +#define STORECLAMP(a,x) \
1245 + (unsigned int)(x) >= 256 ? \
1246 + ((a) = (x) < 0 ? 0 : 255) \
1251 +#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
1255 +#define CBCRCG(yin, xin) \
1257 + cb = outc[0 +yin*8+xin], \
1258 + cr = outc[64+yin*8+xin], \
1259 + cg = (50 * cb + 130 * cr + 128) >> 8 \
1264 +#define CBCRCG(yin, xin) \
1266 + cb = outc[0 +yin*8+xin], \
1267 + cr = outc[64+yin*8+xin], \
1268 + cg = (3 * cb + 8 * cr) >> 4 \
1273 +#define PIC(yin, xin, p, xout) \
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) \
1281 +#ifdef __LITTLE_ENDIAN
1282 +#define PIC_16(yin, xin, p, xout, add) \
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 \
1293 +#define PIC_16(yin, xin, p, xout, add) \
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 \
1303 +#define PIC_16(yin, xin, p, xout, add) \
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 \
1315 +#define PIC221111(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) \
1324 +#define PIC221111_16(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) \
1333 +static void col221111(out, pic, width)
1335 +unsigned char *pic;
1339 + unsigned char *pic0, *pic1;
1341 + int cr, cg, cb, y;
1344 + pic1 = pic + width;
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++) {
1354 + pic0 += 2 * width;
1355 + pic1 += 2 * width;
1357 + outy += 64 * 2 - 16 * 4;
1361 +static void col221111_16(out, pic, width)
1363 +unsigned char *pic;
1367 + unsigned char *pic0, *pic1;
1369 + int cr, cg, cb, y;
1372 + pic1 = pic + width;
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++) {
1382 + pic0 += 2 * width;
1383 + pic1 += 2 * width;
1385 + outy += 64 * 2 - 16 * 4;
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
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
1408 +struct jpeg_decdata {
1409 + int dcts[6 * 64 + 16];
1411 + int dquant[3][64];
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
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
1425 + * Based on linux/drivers/video/fbcon-cfb16.c, which is
1427 + * Created 5 Apr 1997 by Geert Uytterhoeven
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
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>
1442 +#include <video/fbcon.h>
1443 +#include <video/fbcon-cfb16.h>
1445 +#include "fbcon-splash.h"
1448 + * 16 bpp packed pixels
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
1457 +#error FIXME: No endianness??
1461 +void fbcon_splash16_bmove(struct display *p, int sy, int sx, int dy, int dx,
1462 + int height, int width)
1464 + int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
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);
1473 + if (fontwidthlog(p)) {
1474 + sx <<= fontwidthlog(p)+1;
1475 + dx <<= fontwidthlog(p)+1;
1476 + width <<= fontwidthlog(p)+1;
1478 + sx *= fontwidth(p)*2;
1479 + dx *= fontwidth(p)*2;
1480 + width *= fontwidth(p)*2;
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);
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);
1503 +static inline void rectfill(u8 *dest, int width, int height, u32 data,
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++);
1517 + fb_writel(data, p++);
1519 + fb_writew(data, (u16*)p);
1524 +void splashfill(u8 *dest, u8 *src, int width, int height,
1525 + int dest_linesize, int src_linesize)
1530 + while (height-- > 0) {
1531 + u32 *p = (u32 *)dest;
1532 + u32 *q = (u32 *)src;
1534 + for (i=0; i < width/4; i++) {
1535 + fb_writel(*q++,p++);
1536 + fb_writel(*q++,p++);
1539 + fb_writel(*q++,p++);
1541 + fb_writew(*(u16*)q,(u16*)p);
1542 + dest += dest_linesize;
1543 + src += src_linesize;
1547 +void fbcon_splash16_clear(struct vc_data *conp, struct display *p, int sy, int sx,
1548 + int height, int width)
1551 + int bytes = p->next_line, lines = height * fontheight(p);
1553 + int offset, transparent=0;
1555 + dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 2;
1557 + bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
1559 + width *= fontwidth(p)/4;
1561 + dest += splash_data.splash_text_yo * bytes +
1562 + splash_data.splash_text_xo * 2;
1564 + transparent = (splash_data.splash_color == attr_bgcol_ec(p, conp));
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;
1570 + if ((width * 8 == bytes && splash_bytes == bytes))
1571 + splashfill(dest,linux_splash + offset, lines * width * 4,
1572 + 1, bytes, splash_bytes);
1574 + splashfill(dest,linux_splash + offset, width*4, lines,
1575 + bytes, splash_bytes);
1577 + if (width * 8 == bytes)
1578 + rectfill(dest, lines * width * 4, 1, bgx, bytes);
1580 + rectfill(dest, width * 4, lines, bgx, bytes);
1586 + * Helper function to read the background from the splashscreen
1588 +# define SPLASH_BGX(off) \
1589 + if (transparent) { \
1590 + bgx = *(u32*)(splashbgx + (off)); \
1591 + eorx = fgx ^ bgx; \
1595 +void fbcon_splash16_putc(struct vc_data *conp, struct display *p, int c, int yy,
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;
1604 + dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
1606 + fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
1607 + bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
1609 + transparent = (splash_data.splash_color == attr_bgcol(p, c));
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;
1616 + if (transparent && splash_data.splash_color == 0xf) {
1617 + if (fgx == 0xffea)
1619 + else if (fgx == 0x57ea)
1621 + else if (fgx == 0xffff)
1625 + fgx |= (fgx << 16);
1626 + bgx |= (bgx << 16);
1629 + switch (fontwidth(p)) {
1632 + cdat = p->fontdata + (c & p->charmask) * fontheight(p);
1633 + for (rows = fontheight(p); rows--; dest += bytes) {
1636 + fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
1638 + fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
1639 + if (fontwidth(p) == 8) {
1641 + fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
1643 + fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
1646 + splashbgx += splash_bytes;
1652 + cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
1653 + for (rows = fontheight(p); rows--; dest += bytes) {
1656 + fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
1658 + fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
1660 + fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
1662 + fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
1665 + fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
1667 + fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
1668 + if (fontwidth(p) == 16) {
1670 + fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
1672 + fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
1679 +void fbcon_splash16_putcs(struct vc_data *conp, struct display *p,
1680 + const unsigned short *s, int count, int yy, int xx)
1682 + u8 *cdat, *dest, *dest0;
1684 + int rows, bytes = p->next_line;
1685 + u32 eorx, fgx, bgx;
1686 + int transparent = 0;
1687 + u8 *splashbgx0 = 0, *splashbgx;
1689 + dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
1691 + fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
1692 + bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
1694 + transparent = (splash_data.splash_color == attr_bgcol(p, c));
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;
1701 + if (transparent && splash_data.splash_color == 0xf) {
1702 + if (fgx == 0xffea)
1704 + else if (fgx == 0x57ea)
1706 + else if (fgx == 0xffff)
1710 + fgx |= (fgx << 16);
1711 + bgx |= (bgx << 16);
1714 + switch (fontwidth(p)) {
1718 + c = scr_readw(s++) & p->charmask;
1719 + cdat = p->fontdata + c * fontheight(p);
1721 + splashbgx = splashbgx0;
1723 + for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
1724 + u8 bits = *cdat++;
1726 + fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
1728 + fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
1729 + if (fontwidth(p) == 8) {
1731 + fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
1733 + fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
1735 + splashbgx += splash_bytes;
1738 + dest0 += fontwidth(p)*2;
1739 + splashbgx0 += fontwidth(p) * 2;
1746 + c = scr_readw(s++) & p->charmask;
1747 + cdat = p->fontdata + (c * fontheight(p) << 1);
1749 + splashbgx = splashbgx0;
1751 + for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
1752 + u8 bits = *cdat++;
1754 + fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
1756 + fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
1758 + fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
1760 + fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
1763 + fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
1765 + fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
1766 + if (fontwidth(p) == 16) {
1768 + fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
1770 + fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
1772 + splashbgx += splash_bytes;
1775 + dest0 += fontwidth(p)*2;
1776 + splashbgx0 += fontwidth(p) * 2;
1783 +void fbcon_splash16_revc(struct display *p, int xx, int yy)
1786 + int bytes = p->next_line, rows;
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;
1791 + for (rows = fontheight(p); rows--; dest += bytes) {
1792 + switch (fontwidth(p)) {
1794 + fb_writel(fb_readl(dest+24) ^ 0xffffffff, dest+24);
1795 + fb_writel(fb_readl(dest+28) ^ 0xffffffff, dest+28);
1796 + /* FALL THROUGH */
1798 + fb_writel(fb_readl(dest+16) ^ 0xffffffff, dest+16);
1799 + fb_writel(fb_readl(dest+20) ^ 0xffffffff, dest+20);
1800 + /* FALL THROUGH */
1802 + fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8);
1803 + fb_writel(fb_readl(dest+12) ^ 0xffffffff, dest+12);
1804 + /* FALL THROUGH */
1806 + fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
1807 + fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4);
1812 +void fbcon_splash16_clear_margins(struct vc_data *conp, struct display *p,
1815 + int bytes = p->next_line;
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;
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;
1829 + bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
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);
1837 + if (!bottom_only && (right_width = p->var.xres-right_start)) {
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);
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);
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);
1860 + splashfill(p->screen_base, linux_splash,
1861 + p->var.xres, top_margin_height,
1862 + bytes, splash_bytes);
1864 + /* leave function if work is done */
1870 + * `switch' for the low level operations
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)
1885 +MODULE_LICENSE("GPL");
1887 +int init_module(void)
1892 +void cleanup_module(void)
1894 +#endif /* MODULE */
1898 + * Visible symbols for modules
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
1913 + * linux/drivers/video/fbcon-splash.c - splash screen handling functions.
1915 + * (w) 2001-2003 by Volker Poplawski, <volker@suse.de>
1916 + * Stefan Reinauer, <stepan@suse.de>
1917 + * Steffen Winterfeldt, <snwint@suse.de>
1919 + * Ideas & SuSE screen work by Ken Wimer, <wimer@suse.de>
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>
1929 +#include <asm/irq.h>
1930 +#include <asm/system.h>
1932 +#include <video/fbcon.h>
1933 +#include <video/font.h>
1934 +#include <video/fbcon-cfb16.h> /* for fbcon_cfb16 */
1936 +#include "fbcon-splash.h"
1937 +#include "fbcon-jpegdec.h"
1939 +#define SPLASH_VERSION "3.0.7-2003/03/10"
1941 +#ifdef CONFIG_BLK_DEV_INITRD
1942 +unsigned char signature[] = "BOOTSPL1SPL2SPL3";
1945 +/* from drivers/char/console.c */
1946 +extern void con_remap_def_color(int currcons, int new_color);
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);
1952 +/* internal control states and data pointers */
1953 +struct splash_data splash_data;
1955 +unsigned char *linux_splash; /* decoded picture */
1956 +int linux_splash_size = 0;
1958 +static struct jpeg_decdata *decdata = 0; /* private decoder data */
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;
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);
1969 +extern struct display_switch fbcon_splash16;
1971 +int __init splash_init(char *options)
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)
1981 + if(!strncmp("verbose",options,7)) {
1982 + printk(KERN_INFO "bootsplash: verbose mode.\n");
1983 + splash_usesilent = 0;
1987 + splash_default = simple_strtoul(options, NULL, 0);
1992 +__setup("splash=", splash_init);
1995 +static int splash_hasinter(unsigned char *buf, int num)
1997 + unsigned char *bufend = buf + num * 12;
1998 + while(buf < bufend) {
1999 + if (buf[1] > 127) /* inter? */
2001 + buf += buf[3] > 127 ? 24 : 12; /* blend? */
2006 +static int boxextract(unsigned char *buf, unsigned short *dp, unsigned char *cols, int *blendp)
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) {
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);
2027 +static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num, int percent, int overpaint)
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;
2039 + bufend = buf + num * 12;
2040 + while(buf < bufend) {
2042 + buf += boxextract(buf, data1, cols1, &doblend);
2043 + if (data1[0] > 32767)
2044 + buf += boxextract(buf, data2, cols2, &doblend);
2045 + if (data1[2] > 32767) {
2048 + data1[2] = ~data1[2];
2050 + if (data1[3] > 32767) {
2051 + if (percent == 65536)
2053 + data1[3] = ~data1[3];
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;
2062 + *(unsigned int *)cols2 = *(unsigned int *)cols1;
2064 + if (a == 0 && !doblend)
2066 + for (y = data1[1]; y <= data1[3]; y++) {
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;
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++) {
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;
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;
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);
2104 +static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth)
2107 + unsigned char *mem;
2109 + size = ((width + 15) & ~15) * ((height + 15) & ~15) * (depth >> 3);
2110 + mem = vmalloc(size);
2112 + printk(KERN_INFO "No memory for decoded picture!\n");
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);
2120 + return err ? -1 : 0;
2123 +static void splash_free(struct display * p)
2125 + if (!p->splash_data)
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;
2137 +static int splash_mkpenguin(struct splash_data *data, int pxo, int pyo, int pwi, int phe, int pr, int pg, int pb)
2139 + unsigned char *buf;
2142 + if (pwi ==0 || phe == 0)
2144 + buf = (unsigned char *)data + sizeof(*data);
2148 + *buf++ = pxo >> 8;
2150 + *buf++ = pyo >> 8;
2152 + *buf++ = pwi >> 8;
2154 + *buf++ = phe >> 8;
2159 + for (i = 0; i < 12; i++, buf++)
2167 +int splash_getraw(unsigned char *start, unsigned char *end)
2169 + unsigned char *ndata;
2171 + int splash_size = 0;
2172 + void *splash_start = 0;
2174 + int width = 0, height = 0;
2177 + int sboxcount = 0;
2179 + struct display *p;
2181 + printk(KERN_INFO "Looking for splash picture...");
2183 + p = &fb_display[0];
2186 + for (ndata = start; ndata < end; ndata++) {
2187 + if (*((unsigned int *)ndata) != *((unsigned int *)signature))
2189 + if (*((unsigned int *)(ndata+4))==*((unsigned int *)(signature+4))) {
2192 + p = &fb_display[0];
2193 + width = p->var.xres;
2194 + height = p->var.yres;
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");
2201 + if (!jpeg_check_size(ndata + 20, width, height)) {
2202 + ndata += 20 - 1 + splash_size;
2205 + if (splash_check_jpeg(ndata + 20, width, height, p->var.bits_per_pixel))
2207 + if (p->splash_data)
2209 + p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size + 24);
2210 + if (!p->splash_data)
2213 + p->splash_data->oldscreen_base = 0;
2214 + p->splash_data->olddispsw = 0;
2215 + p->splash_data->splash_silentjpeg = 0;
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;
2236 + if (*((unsigned int *)(ndata + 4)) == *((unsigned int *)(signature+8))) {
2239 + if (unit >= MAX_NR_CONSOLES)
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];
2259 + if (splash_size == 0) {
2260 + printk(" found, freeing memory.\n");
2261 + if (p->splash_data)
2265 + if (ndata + 35 + splash_size > end) {
2266 + printk(" found, but truncated!\n");
2269 + if (!jpeg_check_size(ndata + 35, width, height)) {
2270 + ndata += 35 - 1 + splash_size;
2273 + if (splash_check_jpeg(ndata + 35, width, height, p->var.bits_per_pixel))
2275 + if (p->splash_data)
2277 + p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size + 24);
2278 + if (!p->splash_data)
2281 + p->splash_data->oldscreen_base = 0;
2282 + p->splash_data->olddispsw = 0;
2283 + p->splash_data->splash_silentjpeg = 0;
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;
2299 + if (*((unsigned int *)(ndata + 4)) == *((unsigned int *)(signature+12))) {
2302 + if (unit >= MAX_NR_CONSOLES)
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];
2322 + if (splash_size == 0) {
2323 + printk(" found, freeing memory.\n");
2324 + if (p->splash_data)
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");
2334 + if (!jpeg_check_size(ndata + 38 + boxcount * 12 + palcnt, width, height)) {
2335 + ndata += 38 - 1 + splash_size;
2338 + if (splash_check_jpeg(ndata + 38 + boxcount * 12 + palcnt, width, height, p->var.bits_per_pixel))
2340 + silentsize = ndata[28] + (ndata[29] << 8) + (ndata[30] << 16) + (ndata[31] << 24);
2342 + printk(" silenjpeg size %d bytes,", silentsize);
2343 + if (silentsize >= splash_size) {
2344 + printk(" bigger than splashsize!\n");
2347 + splash_size -= silentsize;
2348 + if (!splash_usesilent || !p->fb_info->fbops->fb_get_fix ) {
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");
2359 + sboxcount = ndata[32] + (ndata[33] << 8);
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");
2368 + if (p->splash_data)
2370 + p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size);
2371 + if (!p->splash_data)
2373 + p->splash_data->oldscreen_base = 0;
2374 + p->splash_data->olddispsw = 0;
2375 + p->splash_data->splash_silentjpeg = 0;
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;
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;
2402 + printk(" no good signature found.\n");
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) {
2407 + p->splash_data = 0;
2408 + printk(" found, but has oversized text area!\n");
2411 + if (p->dispsw->setup != fbcon_cfb16.setup) {
2413 + p->splash_data = 0;
2414 + printk(" found, but framebuffer can't handle it!\n");
2417 + printk(" found (%dx%d, %d bytes, v%d).\n", width, height, splash_size, found);
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");
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;
2435 +int splash_verbose(void)
2437 + struct display *p;
2439 + p = &fb_display[0];
2440 + if (!p || !p->splash_data || !p->splash_data->splash_state || !p->conp)
2442 + if (fg_console != p->conp->vc_num)
2444 + if (!p->splash_data->splash_silentjpeg || !p->splash_data->splash_dosilent)
2446 + if (!p->splash_data->oldscreen_base)
2449 + p->splash_data->splash_dosilent = 0;
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;
2457 +static void splash_off(struct display *p)
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;
2466 +int splash_prepare(struct display *p)
2469 + int width, height, depth, size, sbytes;
2471 + if (!p->splash_data || !p->splash_data->splash_state) {
2473 + vfree(linux_splash);
2478 + linux_splash_size = 0;
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 */
2491 + sbytes = ((width + 15) & ~15) * (depth >> 3);
2492 + size = sbytes * ((height + 15) & ~15);
2493 + if (size != linux_splash_size) {
2495 + vfree(linux_splash);
2496 + linux_splash_size = 0;
2500 + if (!linux_splash)
2501 + linux_splash = vmalloc(size);
2503 + if (!linux_splash) {
2504 + linux_splash_size = 0;
2505 + printk(KERN_INFO "Not enough memory for splash screen.\n");
2511 + decdata = vmalloc(sizeof(*decdata));
2513 + if (!p->splash_data->oldscreen_base)
2514 + p->splash_data->oldscreen_base = p->screen_base;
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;
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);
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;
2533 + p->screen_base = p->splash_data->oldscreen_base;
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);
2540 + linux_splash_size = 0;
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;
2560 +#ifdef CONFIG_PROC_FS
2561 +#include <linux/proc_fs.h>
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);
2569 +int splash_read_proc(char *buffer, char **start, off_t offset, int size,
2570 + int *eof, void *data)
2575 + struct display *p = &fb_display[0];
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)
2587 + *start = buffer + (begin - offset);
2589 + return (size < begin + len - offset ? size : begin + len - offset);
2592 +static int splash_recolor(struct display *p)
2594 + if (!p->splash_data)
2596 + if (!p->splash_data->splash_state)
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 *
2605 + p->conp->vc_size_row *
2606 + (p->conp->vc_bottom -
2607 + p->conp->vc_top) / 2);
2612 +static int splash_status(struct display *p)
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");
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),
2624 + if (fg_console == p->conp->vc_num) {
2625 + update_region(fg_console,
2626 + p->conp->vc_origin +
2627 + p->conp->vc_size_row *
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);
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),
2644 +int splash_write_proc(struct file *file, const char *buffer,
2645 + unsigned long count, void *data)
2648 + struct display *p;
2650 + if (!buffer || !splash_default)
2653 + if (!strncmp(buffer, "show", 4) || !strncmp(buffer, "hide", 4)) {
2656 + p = &fb_display[0];
2657 + if (buffer[4] == ' ' && buffer[5] == 'p')
2659 + else if (buffer[4] == '\n')
2662 + pe = simple_strtoul(buffer + 5, NULL, 0);
2667 + if (*buffer == 'h')
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)
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))
2678 + splash_prepare(p);
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);
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';
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)
2707 + p->splash_data->splash_dosilent = 0;
2712 + if (!strncmp(buffer, signature, 7)) {
2713 + unit = splash_getraw((unsigned char *)buffer, (unsigned char *)buffer + count);
2715 + p = &fb_display[unit];
2720 + p = &fb_display[0];
2721 + if (!p->splash_data)
2723 + if (buffer[0] == 't') {
2724 + p->splash_data->splash_state ^= 1;
2728 + new = simple_strtoul(buffer, NULL, 0);
2731 + p->splash_data->splash_color = new >> 8 & 0xff;
2732 + p->splash_data->splash_fg_color = new >> 4 & 0x0f;
2734 + if ((new & 1) == p->splash_data->splash_state)
2735 + splash_recolor(p);
2737 + p->splash_data->splash_state = new & 1;
2743 +int splash_proc_register(void)
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;
2753 +int splash_proc_unregister(void)
2756 + remove_proc_entry("splash", 0);
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
2765 + * linux/drivers/video/splash.h - splash screen definition.
2767 + * (w) 2001-2003 by Volker Poplawski, <volker@suse.de>
2768 + * Stefan Reinauer, <stepan@suse.de>
2771 + * idea and SuSE screen work by Ken Wimer, <wimer@suse.de>
2774 +extern int splash_getraw(unsigned char *, unsigned char *);
2775 +extern int splash_prepare(struct display *);
2777 +extern int splash_shown; /* is splash shown? */
2778 +extern struct splash_data splash_data; /* image data, copied over
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
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
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
2798 +obj-$(CONFIG_FBCON_SPLASHSCREEN) += fbcon-splash.o
2799 +obj-$(CONFIG_FBCON_SPLASHSCREEN) += fbcon-splash16.o
2800 +obj-$(CONFIG_FBCON_SPLASHSCREEN) += fbcon-jpegdec.o
2802 include $(TOPDIR)/Rules.make
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
2809 unsigned int fontwidthmask; /* 1 at (1 << (width - 1)) if width is supported */
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 */
2834 + int splash_dosilent; /* show silent jpeg */
2835 + unsigned char *splash_silentjpeg;
2836 + unsigned char *splash_sboxes;
2837 + int splash_sboxcount;
2841 extern struct display_switch fbcon_dummy;
2845 short yscroll; /* Hardware scrolling */
2846 unsigned char fgshift, bgshift;
2847 unsigned short charmask; /* 0xff or 0x1ff */
2849 +#ifdef CONFIG_FBCON_SPLASHSCREEN
2850 + struct splash_data *splash_data;
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
2859 * We can't use the "normal" timers since we just panicked..
2861 printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
2863 +#ifdef CONFIG_FBCON_SPLASHSCREEN
2865 + extern int splash_verbose(void);
2866 + (void)splash_verbose();
2869 mdelay(panic_timeout*1000);
2871 * Should we run the reboot notifier. For the moment Im
2872 @@ -103,6 +110,12 @@
2873 disabled_wait(caller);
2876 +#ifdef CONFIG_FBCON_SPLASHSCREEN
2878 + extern int splash_verbose(void);
2879 + (void)splash_verbose();
2883 #if defined(CONFIG_X86) && defined(CONFIG_VT)
2884 extern void panic_blink(void);