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