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