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