Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 23369 | Differences between
and this patch

Collapse All | Expand All

(-)linux-2.4.21/drivers/char/console.c (+26 lines)
Lines 3005-3014 Link Here
3005
		break;
3005
		break;
3006
	}
3006
	}
3007
	return 0;
3007
	return 0;
3008
}
3008
}
3009
3009
3010
#ifdef CONFIG_FBCON_SPLASHSCREEN
3011
void con_remap_def_color(int currcons, int new_color)
3012
{
3013
   unsigned short *sbuf = screenbuf;
3014
   unsigned c, len = screenbuf_size >> 1;
3015
   int old_color;
3016
   
3017
   if (sbuf) {
3018
       old_color = def_color << 8;
3019
       new_color <<= 8;
3020
       while(len--) {
3021
           c = *sbuf;
3022
           if (((c ^ old_color) & 0xf000) == 0)
3023
               *sbuf ^= (old_color ^ new_color) & 0xf000;
3024
           if (((c ^ old_color) & 0x0f00) == 0)
3025
               *sbuf ^= (old_color ^ new_color) & 0x0f00;
3026
           sbuf++;
3027
       }
3028
       new_color >>= 8;
3029
   }
3030
   def_color = color = new_color;
3031
   update_attr(currcons);
3032
}
3033
#endif
3034
3035
3010
/*
3036
/*
3011
 *	Visible symbols for modules
3037
 *	Visible symbols for modules
3012
 */
3038
 */
3013
3039
3014
EXPORT_SYMBOL(color_table);
3040
EXPORT_SYMBOL(color_table);
(-)linux-2.4.21/drivers/char/keyboard.c (+10 lines)
Lines 249-258 Link Here
249
		if(!test_and_clear_bit(keycode, key_down))
249
		if(!test_and_clear_bit(keycode, key_down))
250
		    up_flag = kbd_unexpected_up(keycode);
250
		    up_flag = kbd_unexpected_up(keycode);
251
	} else
251
	} else
252
		rep = test_and_set_bit(keycode, key_down);
252
		rep = test_and_set_bit(keycode, key_down);
253
253
254
#ifdef CONFIG_FBCON_SPLASHSCREEN
255
   /* This code has to be redone for some non-x86 platforms */
256
   if (keycode == 0x3c || keycode == 0x01) {   /* F2 and ESC on a PC keyboard */
257
       extern int splash_verbose(void);
258
       if (splash_verbose())
259
           goto out;
260
   }
261
#endif
262
263
254
#ifdef CONFIG_MAGIC_SYSRQ		/* Handle the SysRq Hack */
264
#ifdef CONFIG_MAGIC_SYSRQ		/* Handle the SysRq Hack */
255
	if (keycode == SYSRQ_KEY) {
265
	if (keycode == SYSRQ_KEY) {
256
		sysrq_pressed = !up_flag;
266
		sysrq_pressed = !up_flag;
257
		goto out;
267
		goto out;
258
	} else if (sysrq_pressed) {
268
	} else if (sysrq_pressed) {
(-)linux-2.4.21/drivers/char/n_tty.c (+11 lines)
Lines 43-52 Link Here
43
#include <linux/kd.h>
43
#include <linux/kd.h>
44
#include <linux/mm.h>
44
#include <linux/mm.h>
45
#include <linux/string.h>
45
#include <linux/string.h>
46
#include <linux/slab.h>
46
#include <linux/slab.h>
47
#include <linux/poll.h>
47
#include <linux/poll.h>
48
#include <linux/config.h>
48
49
49
#include <asm/uaccess.h>
50
#include <asm/uaccess.h>
50
#include <asm/system.h>
51
#include <asm/system.h>
51
#include <asm/bitops.h>
52
#include <asm/bitops.h>
52
53
Lines 969-978 Link Here
969
	if (!tty->read_buf) {
970
	if (!tty->read_buf) {
970
		printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
971
		printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
971
		return -EIO;
972
		return -EIO;
972
	}
973
	}
973
974
975
#ifdef CONFIG_FBCON_SPLASHSCREEN
976
    if (file->f_dentry->d_inode->i_rdev == CONSOLE_DEV ||
977
                   file->f_dentry->d_inode->i_rdev == SYSCONS_DEV ||
978
                   file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,0) ||
979
                   file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,1)) {
980
       extern int splash_verbose(void);
981
       (void)splash_verbose();
982
    }
983
#endif
984
974
	/* Job control check -- must be done at start and after
985
	/* Job control check -- must be done at start and after
975
	   every sleep (POSIX.1 7.1.1.4). */
986
	   every sleep (POSIX.1 7.1.1.4). */
976
	/* NOTE: not yet done after every sleep pending a thorough
987
	/* NOTE: not yet done after every sleep pending a thorough
977
	   check of the logic of this change. -- jlc */
988
	   check of the logic of this change. -- jlc */
978
	/* don't stop on /dev/console */
989
	/* don't stop on /dev/console */
(-)linux-2.4.21/drivers/video/Config.in (-3 / +16 lines)
Lines 227-243 Link Here
227
   fi
227
   fi
228
   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
228
   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
229
      tristate '  Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL
229
      tristate '  Virtual Frame Buffer support (ONLY FOR TESTING!) (EXPERIMENTAL)' CONFIG_FB_VIRTUAL
230
   fi
230
   fi
231
231
232
   dep_bool '  Use splash screen instead of boot logo' CONFIG_FBCON_SPLASHSCREEN $CONFIG_BLK_DEV_INITRD
233
   if [ "$CONFIG_FBCON_SPLASHSCREEN" = "y" ]; then
234
      define_bool CONFIG_FBCON_CFB16 y
235
   fi
236
232
   bool '  Advanced low level driver options' CONFIG_FBCON_ADVANCED
237
   bool '  Advanced low level driver options' CONFIG_FBCON_ADVANCED
233
   if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then
238
   if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then
234
      tristate '    Monochrome support' CONFIG_FBCON_MFB
239
      tristate '    Monochrome support' CONFIG_FBCON_MFB
235
      tristate '    2 bpp packed pixels support' CONFIG_FBCON_CFB2
240
      tristate '    2 bpp packed pixels support' CONFIG_FBCON_CFB2
236
      tristate '    4 bpp packed pixels support' CONFIG_FBCON_CFB4
241
      tristate '    4 bpp packed pixels support' CONFIG_FBCON_CFB4
237
      tristate '    8 bpp packed pixels support' CONFIG_FBCON_CFB8
242
      tristate '    8 bpp packed pixels support' CONFIG_FBCON_CFB8
238
      tristate '    16 bpp packed pixels support' CONFIG_FBCON_CFB16
243
      if [ "$CONFIG_FBCON_SPLASHSCREEN" != "y" ]; then
244
	  	tristate '    16 bpp packed pixels support' CONFIG_FBCON_CFB16
245
	  fi
239
      tristate '    24 bpp packed pixels support' CONFIG_FBCON_CFB24
246
      tristate '    24 bpp packed pixels support' CONFIG_FBCON_CFB24
240
      tristate '    32 bpp packed pixels support' CONFIG_FBCON_CFB32
247
      tristate '    32 bpp packed pixels support' CONFIG_FBCON_CFB32
241
      tristate '    Amiga bitplanes support' CONFIG_FBCON_AFB
248
      tristate '    Amiga bitplanes support' CONFIG_FBCON_AFB
242
      tristate '    Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM
249
      tristate '    Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM
243
      tristate '    Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2
250
      tristate '    Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2
Lines 339-349 Link Here
339
	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
346
	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
340
	   "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y"  -o \
347
	   "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y"  -o \
341
	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
348
	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
342
	   "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
349
	   "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
343
	   "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_INTEL" = "y" ]; then
350
	   "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_INTEL" = "y" ]; then
344
	 define_tristate CONFIG_FBCON_CFB16 y
351
	   if [ "$CONFIG_FBCON_CFB16" != "m" ]; then
352
	    define_tristate CONFIG_FBCON_CFB16 y
353
	   fi
354
345
      else
355
      else
346
	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
356
	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
347
	      "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
357
	      "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
348
	      "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
358
	      "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
349
	      "$CONFIG_FB_Q40" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
359
	      "$CONFIG_FB_Q40" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
Lines 356-366 Link Here
356
	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
366
	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
357
	      "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
367
	      "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
358
	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
368
	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
359
	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
369
	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
360
	      "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_INTEL" = "m" ]; then
370
	      "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_INTEL" = "m" ]; then
361
	    define_tristate CONFIG_FBCON_CFB16 m
371
	    if [ "$CONFIG_FBCON_CFB16" != "y" ]; then
372
		  define_tristate CONFIG_FBCON_CFB16 m
373
		fi
374
362
	 fi
375
	 fi
363
      fi
376
      fi
364
      if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
377
      if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
365
	   "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" -o \
378
	   "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" -o \
366
	   "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
379
	   "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
(-)linux-2.4.21/drivers/video/Makefile (-1 / +6 lines)
Lines 12-22 Link Here
12
export-objs    := fbmem.o fbcmap.o fbcon.o fbmon.o modedb.o \
12
export-objs    := fbmem.o fbcmap.o fbcon.o fbmon.o modedb.o \
13
		  fbcon-afb.o fbcon-ilbm.o \
13
		  fbcon-afb.o fbcon-ilbm.o \
14
		  fbcon-vga.o fbcon-iplan2p2.o fbcon-iplan2p4.o \
14
		  fbcon-vga.o fbcon-iplan2p2.o fbcon-iplan2p4.o \
15
		  fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
15
		  fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
16
		  fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
16
		  fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
17
		  fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o \
17
		  fbcon-cfb8.o fbcon-splash16.o fbcon-mac.o fbcon-mfb.o \
18
		  cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o
18
		  cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o
19
19
20
# Each configuration option enables a list of files.
20
# Each configuration option enables a list of files.
21
21
22
obj-$(CONFIG_DUMMY_CONSOLE)       += dummycon.o
22
obj-$(CONFIG_DUMMY_CONSOLE)       += dummycon.o
Lines 150-159 Link Here
150
obj-$(CONFIG_FBCON_MFB)           += fbcon-mfb.o
150
obj-$(CONFIG_FBCON_MFB)           += fbcon-mfb.o
151
obj-$(CONFIG_FBCON_VGA)           += fbcon-vga.o
151
obj-$(CONFIG_FBCON_VGA)           += fbcon-vga.o
152
obj-$(CONFIG_FBCON_HGA)           += fbcon-hga.o
152
obj-$(CONFIG_FBCON_HGA)           += fbcon-hga.o
153
obj-$(CONFIG_FBCON_STI)           += fbcon-sti.o
153
obj-$(CONFIG_FBCON_STI)           += fbcon-sti.o
154
154
155
obj-$(CONFIG_FBCON_SPLASHSCREEN)  += fbcon-splash.o
156
obj-$(CONFIG_FBCON_SPLASHSCREEN)  += fbcon-splash16.o
157
obj-$(CONFIG_FBCON_SPLASHSCREEN)  += fbcon-jpegdec.o
158
159
155
include $(TOPDIR)/Rules.make
160
include $(TOPDIR)/Rules.make
156
161
157
clean:
162
clean:
158
	rm -f core *.o *.a *.s
163
	rm -f core *.o *.a *.s
159
164
(-)linux-2.4.21/drivers/video/fbcon-jpegdec.c (+960 lines)
Line 0 Link Here
1
/* 
2
 *    linux/drivers/video/fbcon-jpegdec.c - a tiny jpeg decoder.
3
 *      
4
 *      (w) August 2001 by Michael Schroeder, <mls@suse.de>
5
 *                  
6
 */
7
8
#include <linux/config.h>
9
#include <linux/string.h>
10
#include <asm/byteorder.h>
11
12
struct display;
13
#include "fbcon-splash.h"
14
#include "fbcon-jpegdec.h"
15
16
#define ISHIFT 11
17
18
#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5))
19
#define IMULT(a, b) (((a) * (b)) >> ISHIFT)
20
#define ITOINT(a) ((a) >> ISHIFT)
21
22
#ifndef __P
23
# define __P(x) x
24
#endif
25
26
/* special markers */
27
#define M_BADHUFF	-1
28
#define M_EOF		0x80
29
30
struct in {
31
	unsigned char *p;
32
	unsigned int bits;
33
	int left;
34
	int marker;
35
36
	int (*func) __P((void *));
37
	void *data;
38
};
39
40
/*********************************/
41
struct dec_hufftbl;
42
struct enc_hufftbl;
43
44
union hufftblp {
45
	struct dec_hufftbl *dhuff;
46
	struct enc_hufftbl *ehuff;
47
};
48
49
struct scan {
50
	int dc;			/* old dc value */
51
52
	union hufftblp hudc;
53
	union hufftblp huac;
54
	int next;		/* when to switch to next scan */
55
56
	int cid;		/* component id */
57
	int hv;			/* horiz/vert, copied from comp */
58
	int tq;			/* quant tbl, copied from comp */
59
};
60
61
/*********************************/
62
63
#define DECBITS 10		/* seems to be the optimum */
64
65
struct dec_hufftbl {
66
	int maxcode[17];
67
	int valptr[16];
68
	unsigned char vals[256];
69
	unsigned int llvals[1 << DECBITS];
70
};
71
72
static void decode_mcus __P((struct in *, int *, int, struct scan *, int *));
73
static int dec_readmarker __P((struct in *));
74
static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *));
75
76
static void setinput __P((struct in *, unsigned char *));
77
/*********************************/
78
79
#undef PREC
80
#define PREC int
81
82
static void idctqtab __P((unsigned char *, PREC *));
83
static void idct __P((int *, int *, PREC *, PREC, int));
84
static void scaleidctqtab __P((PREC *, PREC));
85
86
/*********************************/
87
88
static void initcol __P((PREC[][64]));
89
90
static void col221111 __P((int *, unsigned char *, int));
91
static void col221111_16 __P((int *, unsigned char *, int));
92
93
/*********************************/
94
95
#define M_SOI	0xd8
96
#define M_APP0	0xe0
97
#define M_DQT	0xdb
98
#define M_SOF0	0xc0
99
#define M_DHT   0xc4
100
#define M_DRI	0xdd
101
#define M_SOS	0xda
102
#define M_RST0	0xd0
103
#define M_EOI	0xd9
104
#define M_COM	0xfe
105
106
static unsigned char *datap;
107
108
static int getbyte(void)
109
{
110
	return *datap++;
111
}
112
113
static int getword(void)
114
{
115
	int c1, c2;
116
	c1 = *datap++;
117
	c2 = *datap++;
118
	return c1 << 8 | c2;
119
}
120
121
struct comp {
122
	int cid;
123
	int hv;
124
	int tq;
125
};
126
127
#define MAXCOMP 4
128
struct jpginfo {
129
	int nc;			/* number of components */
130
	int ns;			/* number of scans */
131
	int dri;		/* restart interval */
132
	int nm;			/* mcus til next marker */
133
	int rm;			/* next restart marker */
134
};
135
136
static struct jpginfo info;
137
static struct comp comps[MAXCOMP];
138
139
static struct scan dscans[MAXCOMP];
140
141
static unsigned char quant[4][64];
142
143
static struct dec_hufftbl dhuff[4];
144
145
#define dec_huffdc (dhuff + 0)
146
#define dec_huffac (dhuff + 2)
147
148
static struct in in;
149
150
static int readtables(int till)
151
{
152
	int m, l, i, j, lq, pq, tq;
153
	int tc, th, tt;
154
155
	for (;;) {
156
		if (getbyte() != 0xff)
157
			return -1;
158
		if ((m = getbyte()) == till)
159
			break;
160
161
		switch (m) {
162
		case 0xc2:
163
			return 0;
164
165
		case M_DQT:
166
			lq = getword();
167
			while (lq > 2) {
168
				pq = getbyte();
169
				tq = pq & 15;
170
				if (tq > 3)
171
					return -1;
172
				pq >>= 4;
173
				if (pq != 0)
174
					return -1;
175
				for (i = 0; i < 64; i++)
176
					quant[tq][i] = getbyte();
177
				lq -= 64 + 1;
178
			}
179
			break;
180
181
		case M_DHT:
182
			l = getword();
183
			while (l > 2) {
184
				int hufflen[16], k;
185
				unsigned char huffvals[256];
186
187
				tc = getbyte();
188
				th = tc & 15;
189
				tc >>= 4;
190
				tt = tc * 2 + th;
191
				if (tc > 1 || th > 1)
192
					return -1;
193
				for (i = 0; i < 16; i++)
194
					hufflen[i] = getbyte();
195
				l -= 1 + 16;
196
				k = 0;
197
				for (i = 0; i < 16; i++) {
198
					for (j = 0; j < hufflen[i]; j++)
199
						huffvals[k++] = getbyte();
200
					l -= hufflen[i];
201
				}
202
				dec_makehuff(dhuff + tt, hufflen,
203
					     huffvals);
204
			}
205
			break;
206
207
		case M_DRI:
208
			l = getword();
209
			info.dri = getword();
210
			break;
211
212
		default:
213
			l = getword();
214
			while (l-- > 2)
215
				getbyte();
216
			break;
217
		}
218
	}
219
	return 0;
220
}
221
222
static void dec_initscans(void)
223
{
224
	int i;
225
226
	info.nm = info.dri + 1;
227
	info.rm = M_RST0;
228
	for (i = 0; i < info.ns; i++)
229
		dscans[i].dc = 0;
230
}
231
232
static int dec_checkmarker(void)
233
{
234
	int i;
235
236
	if (dec_readmarker(&in) != info.rm)
237
		return -1;
238
	info.nm = info.dri;
239
	info.rm = (info.rm + 1) & ~0x08;
240
	for (i = 0; i < info.ns; i++)
241
		dscans[i].dc = 0;
242
	return 0;
243
}
244
245
int jpeg_check_size(unsigned char *buf, int width, int height)
246
{
247
  	datap = buf;
248
	getbyte(); 
249
	getbyte(); 
250
	readtables(M_SOF0);
251
	getword();
252
	getbyte();
253
        if (height != getword() || width != getword())
254
		return 0;
255
        return 1;
256
}
257
258
int jpeg_decode(buf, pic, width, height, depth, decdata)
259
unsigned char *buf, *pic;
260
int width, height, depth;
261
struct jpeg_decdata *decdata;
262
{
263
	int i, j, m, tac, tdc;
264
	int mcusx, mcusy, mx, my;
265
	int max[6];
266
267
	if (!decdata)
268
		return -1;
269
	datap = buf;
270
	if (getbyte() != 0xff)
271
		return ERR_NO_SOI;
272
	if (getbyte() != M_SOI)
273
		return ERR_NO_SOI;
274
	if (readtables(M_SOF0))
275
		return ERR_BAD_TABLES;
276
	getword();
277
	i = getbyte();
278
	if (i != 8)
279
		return ERR_NOT_8BIT;
280
	if (((getword() + 15) & ~15) != height)
281
		return ERR_HEIGHT_MISMATCH;
282
	if (((getword() + 15) & ~15) != width)
283
		return ERR_WIDTH_MISMATCH;
284
	if ((height & 15) || (width & 15))
285
		return ERR_BAD_WIDTH_OR_HEIGHT;
286
	info.nc = getbyte();
287
	if (info.nc > MAXCOMP)
288
		return ERR_TOO_MANY_COMPPS;
289
	for (i = 0; i < info.nc; i++) {
290
		int h, v;
291
		comps[i].cid = getbyte();
292
		comps[i].hv = getbyte();
293
		v = comps[i].hv & 15;
294
		h = comps[i].hv >> 4;
295
		comps[i].tq = getbyte();
296
		if (h > 3 || v > 3)
297
			return ERR_ILLEGAL_HV;
298
		if (comps[i].tq > 3)
299
			return ERR_QUANT_TABLE_SELECTOR;
300
	}
301
	if (readtables(M_SOS))
302
		return ERR_BAD_TABLES;
303
	getword();
304
	info.ns = getbyte();
305
	if (info.ns != 3)
306
		return ERR_NOT_YCBCR_221111;
307
	for (i = 0; i < 3; i++) {
308
		dscans[i].cid = getbyte();
309
		tdc = getbyte();
310
		tac = tdc & 15;
311
		tdc >>= 4;
312
		if (tdc > 1 || tac > 1)
313
			return ERR_QUANT_TABLE_SELECTOR;
314
		for (j = 0; j < info.nc; j++)
315
			if (comps[j].cid == dscans[i].cid)
316
				break;
317
		if (j == info.nc)
318
			return ERR_UNKNOWN_CID_IN_SCAN;
319
		dscans[i].hv = comps[j].hv;
320
		dscans[i].tq = comps[j].tq;
321
		dscans[i].hudc.dhuff = dec_huffdc + tdc;
322
		dscans[i].huac.dhuff = dec_huffac + tac;
323
	}
324
	
325
	i = getbyte();
326
	j = getbyte();
327
	m = getbyte();
328
	
329
	if (i != 0 || j != 63 || m != 0)
330
		return ERR_NOT_SEQUENTIAL_DCT;
331
	
332
	if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3)
333
		return ERR_NOT_YCBCR_221111;
334
335
	if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11 || dscans[2].hv != 0x11)
336
		return ERR_NOT_YCBCR_221111;
337
338
	mcusx = width >> 4;
339
	mcusy = height >> 4;
340
341
342
	idctqtab(quant[dscans[0].tq], decdata->dquant[0]);
343
	idctqtab(quant[dscans[1].tq], decdata->dquant[1]);
344
	idctqtab(quant[dscans[2].tq], decdata->dquant[2]);
345
	initcol(decdata->dquant);
346
	setinput(&in, datap);
347
348
#if 0
349
	/* landing zone */
350
	img[len] = 0;
351
	img[len + 1] = 0xff;
352
	img[len + 2] = M_EOF;
353
#endif
354
355
	dec_initscans();
356
357
	dscans[0].next = 6 - 4;
358
	dscans[1].next = 6 - 4 - 1;
359
	dscans[2].next = 6 - 4 - 1 - 1;	/* 411 encoding */
360
	for (my = 0; my < mcusy; my++) {
361
		for (mx = 0; mx < mcusx; mx++) {
362
			if (info.dri && !--info.nm)
363
				if (dec_checkmarker())
364
					return ERR_WRONG_MARKER;
365
			
366
			decode_mcus(&in, decdata->dcts, 6, dscans, max);
367
			idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]);
368
			idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]);
369
			idct(decdata->dcts + 128, decdata->out + 128, decdata->dquant[0], IFIX(128.5), max[2]);
370
			idct(decdata->dcts + 192, decdata->out + 192, decdata->dquant[0], IFIX(128.5), max[3]);
371
			idct(decdata->dcts + 256, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]);
372
			idct(decdata->dcts + 320, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]);
373
374
			switch (depth) {
375
			case 24:
376
				col221111(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 3, mcusx * 16 * 3);
377
				break;
378
			case 16:
379
				col221111_16(decdata->out, pic + (my * 16 * mcusx + mx) * (16 * 2), mcusx * (16 * 2));
380
				break;
381
			default:
382
				return ERR_DEPTH_MISMATCH;
383
				break;
384
			}
385
		}
386
	}
387
	
388
	m = dec_readmarker(&in);
389
	if (m != M_EOI)
390
		return ERR_NO_EOI;
391
392
	return 0;
393
}
394
395
/****************************************************************/
396
/**************       huffman decoder             ***************/
397
/****************************************************************/
398
399
static int fillbits __P((struct in *, int, unsigned int));
400
static int dec_rec2
401
__P((struct in *, struct dec_hufftbl *, int *, int, int));
402
403
static void setinput(in, p)
404
struct in *in;
405
unsigned char *p;
406
{
407
	in->p = p;
408
	in->left = 0;
409
	in->bits = 0;
410
	in->marker = 0;
411
}
412
413
static int fillbits(in, le, bi)
414
struct in *in;
415
int le;
416
unsigned int bi;
417
{
418
	int b, m;
419
420
	if (in->marker) {
421
		if (le <= 16)
422
			in->bits = bi << 16, le += 16;
423
		return le;
424
	}
425
	while (le <= 24) {
426
		b = *in->p++;
427
		if (b == 0xff && (m = *in->p++) != 0) {
428
			if (m == M_EOF) {
429
				if (in->func && (m = in->func(in->data)) == 0)
430
					continue;
431
			}
432
			in->marker = m;
433
			if (le <= 16)
434
				bi = bi << 16, le += 16;
435
			break;
436
		}
437
		bi = bi << 8 | b;
438
		le += 8;
439
	}
440
	in->bits = bi;		/* tmp... 2 return values needed */
441
	return le;
442
}
443
444
static int dec_readmarker(in)
445
struct in *in;
446
{
447
	int m;
448
449
	in->left = fillbits(in, in->left, in->bits);
450
	if ((m = in->marker) == 0)
451
		return 0;
452
	in->left = 0;
453
	in->marker = 0;
454
	return m;
455
}
456
457
#define LEBI_DCL	int le, bi
458
#define LEBI_GET(in)	(le = in->left, bi = in->bits)
459
#define LEBI_PUT(in)	(in->left = le, in->bits = bi)
460
461
#define GETBITS(in, n) (					\
462
  (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0),	\
463
  (le -= (n)),							\
464
  bi >> le & ((1 << (n)) - 1)					\
465
)
466
467
#define UNGETBITS(in, n) (	\
468
  le += (n)			\
469
)
470
471
472
static int dec_rec2(in, hu, runp, c, i)
473
struct in *in;
474
struct dec_hufftbl *hu;
475
int *runp;
476
int c, i;
477
{
478
	LEBI_DCL;
479
480
	LEBI_GET(in);
481
	if (i) {
482
		UNGETBITS(in, i & 127);
483
		*runp = i >> 8 & 15;
484
		i >>= 16;
485
	} else {
486
		for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++);
487
		if (i >= 16) {
488
			in->marker = M_BADHUFF;
489
			return 0;
490
		}
491
		i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
492
		*runp = i >> 4;
493
		i &= 15;
494
	}
495
	if (i == 0) {		/* sigh, 0xf0 is 11 bit */
496
		LEBI_PUT(in);
497
		return 0;
498
	}
499
	/* receive part */
500
	c = GETBITS(in, i);
501
	if (c < (1 << (i - 1)))
502
		c += (-1 << i) + 1;
503
	LEBI_PUT(in);
504
	return c;
505
}
506
507
#define DEC_REC(in, hu, r, i)	 (	\
508
  r = GETBITS(in, DECBITS),		\
509
  i = hu->llvals[r],			\
510
  i & 128 ?				\
511
    (					\
512
      UNGETBITS(in, i & 127),		\
513
      r = i >> 8 & 15,			\
514
      i >> 16				\
515
    )					\
516
  :					\
517
    (					\
518
      LEBI_PUT(in),			\
519
      i = dec_rec2(in, hu, &r, r, i),	\
520
      LEBI_GET(in),			\
521
      i					\
522
    )					\
523
)
524
525
static void decode_mcus(in, dct, n, sc, maxp)
526
struct in *in;
527
int *dct;
528
int n;
529
struct scan *sc;
530
int *maxp;
531
{
532
	struct dec_hufftbl *hu;
533
	int i, r, t;
534
	LEBI_DCL;
535
536
	memset(dct, 0, n * 64 * sizeof(*dct));
537
	LEBI_GET(in);
538
	while (n-- > 0) {
539
		hu = sc->hudc.dhuff;
540
		*dct++ = (sc->dc += DEC_REC(in, hu, r, t));
541
542
		hu = sc->huac.dhuff;
543
		i = 63;
544
		while (i > 0) {
545
			t = DEC_REC(in, hu, r, t);
546
			if (t == 0 && r == 0) {
547
				dct += i;
548
				break;
549
			}
550
			dct += r;
551
			*dct++ = t;
552
			i -= r + 1;
553
		}
554
		*maxp++ = 64 - i;
555
		if (n == sc->next)
556
			sc++;
557
	}
558
	LEBI_PUT(in);
559
}
560
561
static void dec_makehuff(hu, hufflen, huffvals)
562
struct dec_hufftbl *hu;
563
int *hufflen;
564
unsigned char *huffvals;
565
{
566
	int code, k, i, j, d, x, c, v;
567
	for (i = 0; i < (1 << DECBITS); i++)
568
		hu->llvals[i] = 0;
569
570
/*
571
 * llvals layout:
572
 *
573
 * value v already known, run r, backup u bits:
574
 *  vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
575
 * value unknown, size b bits, run r, backup u bits:
576
 *  000000000000bbbb 0000 rrrr 0 uuuuuuu
577
 * value and size unknown:
578
 *  0000000000000000 0000 0000 0 0000000
579
 */
580
	code = 0;
581
	k = 0;
582
	for (i = 0; i < 16; i++, code <<= 1) {	/* sizes */
583
		hu->valptr[i] = k;
584
		for (j = 0; j < hufflen[i]; j++) {
585
			hu->vals[k] = *huffvals++;
586
			if (i < DECBITS) {
587
				c = code << (DECBITS - 1 - i);
588
				v = hu->vals[k] & 0x0f;	/* size */
589
				for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
590
					if (v + i < DECBITS) {	/* both fit in table */
591
						x = d >> (DECBITS - 1 - v -
592
							  i);
593
						if (v && x < (1 << (v - 1)))
594
							x += (-1 << v) + 1;
595
						x = x << 16 | (hu-> vals[k] & 0xf0) << 4 |
596
							(DECBITS - (i + 1 + v)) | 128;
597
					} else
598
						x = v << 16 | (hu-> vals[k] & 0xf0) << 4 |
599
						        (DECBITS - (i + 1));
600
					hu->llvals[c | d] = x;
601
				}
602
			}
603
			code++;
604
			k++;
605
		}
606
		hu->maxcode[i] = code;
607
	}
608
	hu->maxcode[16] = 0x20000;	/* always terminate decode */
609
}
610
611
/****************************************************************/
612
/**************             idct                  ***************/
613
/****************************************************************/
614
615
#define ONE ((PREC)IFIX(1.))
616
#define S2  ((PREC)IFIX(0.382683432))
617
#define C2  ((PREC)IFIX(0.923879532))
618
#define C4  ((PREC)IFIX(0.707106781))
619
620
#define S22 ((PREC)IFIX(2 * 0.382683432))
621
#define C22 ((PREC)IFIX(2 * 0.923879532))
622
#define IC4 ((PREC)IFIX(1 / 0.707106781))
623
624
#define C3IC1 ((PREC)IFIX(0.847759065))	/* c3/c1 */
625
#define C5IC1 ((PREC)IFIX(0.566454497))	/* c5/c1 */
626
#define C7IC1 ((PREC)IFIX(0.198912367))	/* c7/c1 */
627
628
#define XPP(a,b) (t = a + b, b = a - b, a = t)
629
#define XMP(a,b) (t = a - b, b = a + b, a = t)
630
#define XPM(a,b) (t = a + b, b = b - a, a = t)
631
632
#define ROT(a,b,s,c) (	t = IMULT(a + b, s),	\
633
			a = IMULT(a, c - s) + t,	\
634
			b = IMULT(b, c + s) - t)
635
636
#define IDCT		\
637
(			\
638
  XPP(t0, t1),		\
639
  XMP(t2, t3),		\
640
  t2 = IMULT(t2, IC4) - t3,	\
641
  XPP(t0, t3),		\
642
  XPP(t1, t2),		\
643
  XMP(t4, t7),		\
644
  XPP(t5, t6),		\
645
  XMP(t5, t7),		\
646
  t5 = IMULT(t5, IC4),	\
647
  ROT(t4, t6, S22, C22),\
648
  t6 -= t7,		\
649
  t5 -= t6,		\
650
  t4 -= t5,		\
651
  XPP(t0, t7),		\
652
  XPP(t1, t6),		\
653
  XPP(t2, t5),		\
654
  XPP(t3, t4)		\
655
)
656
657
static unsigned char zig2[64] = {
658
	0, 2, 3, 9, 10, 20, 21, 35,
659
	14, 16, 25, 31, 39, 46, 50, 57,
660
	5, 7, 12, 18, 23, 33, 37, 48,
661
	27, 29, 41, 44, 52, 55, 59, 62,
662
	15, 26, 30, 40, 45, 51, 56, 58,
663
	1, 4, 8, 11, 19, 22, 34, 36,
664
	28, 42, 43, 53, 54, 60, 61, 63,
665
	6, 13, 17, 24, 32, 38, 47, 49
666
};
667
668
void idct(in, out, quant, off, max)
669
int *in;
670
int *out;
671
PREC *quant;
672
PREC off;
673
int max;
674
{
675
	PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
676
	PREC tmp[64], *tmpp;
677
	int i, j;
678
	unsigned char *zig2p;
679
680
	t0 = off;
681
	if (max == 1) {
682
		t0 += in[0] * quant[0];
683
		for (i = 0; i < 64; i++)
684
			out[i] = ITOINT(t0);
685
		return;
686
	}
687
	zig2p = zig2;
688
	tmpp = tmp;
689
	for (i = 0; i < 8; i++) {
690
		j = *zig2p++;
691
		t0 += in[j] * quant[j];
692
		j = *zig2p++;
693
		t5 = in[j] * quant[j];
694
		j = *zig2p++;
695
		t2 = in[j] * quant[j];
696
		j = *zig2p++;
697
		t7 = in[j] * quant[j];
698
		j = *zig2p++;
699
		t1 = in[j] * quant[j];
700
		j = *zig2p++;
701
		t4 = in[j] * quant[j];
702
		j = *zig2p++;
703
		t3 = in[j] * quant[j];
704
		j = *zig2p++;
705
		t6 = in[j] * quant[j];
706
		IDCT;
707
		tmpp[0 * 8] = t0;
708
		tmpp[1 * 8] = t1;
709
		tmpp[2 * 8] = t2;
710
		tmpp[3 * 8] = t3;
711
		tmpp[4 * 8] = t4;
712
		tmpp[5 * 8] = t5;
713
		tmpp[6 * 8] = t6;
714
		tmpp[7 * 8] = t7;
715
		tmpp++;
716
		t0 = 0;
717
	}
718
	for (i = 0; i < 8; i++) {
719
		t0 = tmp[8 * i + 0];
720
		t1 = tmp[8 * i + 1];
721
		t2 = tmp[8 * i + 2];
722
		t3 = tmp[8 * i + 3];
723
		t4 = tmp[8 * i + 4];
724
		t5 = tmp[8 * i + 5];
725
		t6 = tmp[8 * i + 6];
726
		t7 = tmp[8 * i + 7];
727
		IDCT;
728
		out[8 * i + 0] = ITOINT(t0);
729
		out[8 * i + 1] = ITOINT(t1);
730
		out[8 * i + 2] = ITOINT(t2);
731
		out[8 * i + 3] = ITOINT(t3);
732
		out[8 * i + 4] = ITOINT(t4);
733
		out[8 * i + 5] = ITOINT(t5);
734
		out[8 * i + 6] = ITOINT(t6);
735
		out[8 * i + 7] = ITOINT(t7);
736
	}
737
}
738
739
static unsigned char zig[64] = {
740
	0, 1, 5, 6, 14, 15, 27, 28,
741
	2, 4, 7, 13, 16, 26, 29, 42,
742
	3, 8, 12, 17, 25, 30, 41, 43,
743
	9, 11, 18, 24, 31, 40, 44, 53,
744
	10, 19, 23, 32, 39, 45, 52, 54,
745
	20, 22, 33, 38, 46, 51, 55, 60,
746
	21, 34, 37, 47, 50, 56, 59, 61,
747
	35, 36, 48, 49, 57, 58, 62, 63
748
};
749
750
static PREC aaidct[8] = {
751
	IFIX(0.3535533906), IFIX(0.4903926402),
752
	IFIX(0.4619397663), IFIX(0.4157348062),
753
	IFIX(0.3535533906), IFIX(0.2777851165),
754
	IFIX(0.1913417162), IFIX(0.0975451610)
755
};
756
757
758
static void idctqtab(qin, qout)
759
unsigned char *qin;
760
PREC *qout;
761
{
762
	int i, j;
763
764
	for (i = 0; i < 8; i++)
765
		for (j = 0; j < 8; j++)
766
			qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] * 
767
			  			IMULT(aaidct[i], aaidct[j]);
768
}
769
770
static void scaleidctqtab(q, sc)
771
PREC *q;
772
PREC sc;
773
{
774
	int i;
775
776
	for (i = 0; i < 64; i++)
777
		q[i] = IMULT(q[i], sc);
778
}
779
780
/****************************************************************/
781
/**************          color decoder            ***************/
782
/****************************************************************/
783
784
#define ROUND
785
786
/*
787
 * YCbCr Color transformation:
788
 *
789
 * y:0..255   Cb:-128..127   Cr:-128..127
790
 *
791
 *      R = Y                + 1.40200 * Cr
792
 *      G = Y - 0.34414 * Cb - 0.71414 * Cr
793
 *      B = Y + 1.77200 * Cb
794
 *
795
 * =>
796
 *      Cr *= 1.40200;
797
 *      Cb *= 1.77200;
798
 *      Cg = 0.19421 * Cb + .50937 * Cr;
799
 *      R = Y + Cr;
800
 *      G = Y - Cg;
801
 *      B = Y + Cb;
802
 *
803
 * =>
804
 *      Cg = (50 * Cb + 130 * Cr + 128) >> 8;
805
 */
806
807
static void initcol(q)
808
PREC q[][64];
809
{
810
	scaleidctqtab(q[1], IFIX(1.77200));
811
	scaleidctqtab(q[2], IFIX(1.40200));
812
}
813
814
/* This is optimized for the stupid sun SUNWspro compiler. */
815
#define STORECLAMP(a,x)				\
816
(						\
817
  (a) = (x),					\
818
  (unsigned int)(x) >= 256 ? 			\
819
    ((a) = (x) < 0 ? 0 : 255)			\
820
  :						\
821
    0						\
822
)
823
824
#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
825
826
#ifdef ROUND
827
828
#define CBCRCG(yin, xin)			\
829
(						\
830
  cb = outc[0 +yin*8+xin],			\
831
  cr = outc[64+yin*8+xin],			\
832
  cg = (50 * cb + 130 * cr + 128) >> 8		\
833
)
834
835
#else
836
837
#define CBCRCG(yin, xin)			\
838
(						\
839
  cb = outc[0 +yin*8+xin],			\
840
  cr = outc[64+yin*8+xin],			\
841
  cg = (3 * cb + 8 * cr) >> 4			\
842
)
843
844
#endif
845
846
#define PIC(yin, xin, p, xout)			\
847
(						\
848
  y = outy[(yin) * 8 + xin],			\
849
  STORECLAMP(p[(xout) * 3 + 0], y + cr),	\
850
  STORECLAMP(p[(xout) * 3 + 1], y - cg),	\
851
  STORECLAMP(p[(xout) * 3 + 2], y + cb)		\
852
)
853
854
#ifdef __LITTLE_ENDIAN
855
#define PIC_16(yin, xin, p, xout, add)		 \
856
(                                                \
857
  y = outy[(yin) * 8 + xin],                     \
858
  y = ((CLAMP(y + cr + add*2+1) & 0xf8) <<  8) | \
859
      ((CLAMP(y - cg + add    ) & 0xfc) <<  3) | \
860
      ((CLAMP(y + cb + add*2+1)       ) >>  3),  \
861
  p[(xout) * 2 + 0] = y & 0xff,                  \
862
  p[(xout) * 2 + 1] = y >> 8                     \
863
)
864
#else
865
#ifdef CONFIG_PPC
866
#define PIC_16(yin, xin, p, xout, add)		 \
867
(                                                \
868
  y = outy[(yin) * 8 + xin],                     \
869
  y = ((CLAMP(y + cr + add*2+1) & 0xf8) <<  7) | \
870
      ((CLAMP(y - cg + add*2+1) & 0xf8) <<  2) | \
871
      ((CLAMP(y + cb + add*2+1)       ) >>  3),  \
872
  p[(xout) * 2 + 0] = y >> 8,                    \
873
  p[(xout) * 2 + 1] = y & 0xff                   \
874
)
875
#else
876
#define PIC_16(yin, xin, p, xout, add)	 	 \
877
(                                                \
878
  y = outy[(yin) * 8 + xin],                     \
879
  y = ((CLAMP(y + cr + add*2+1) & 0xf8) <<  8) | \
880
      ((CLAMP(y - cg + add    ) & 0xfc) <<  3) | \
881
      ((CLAMP(y + cb + add*2+1)       ) >>  3),  \
882
  p[(xout) * 2 + 0] = y >> 8,                    \
883
  p[(xout) * 2 + 1] = y & 0xff                   \
884
)
885
#endif
886
#endif
887
888
#define PIC221111(xin)						\
889
(								\
890
  CBCRCG(0, xin),						\
891
  PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0),	\
892
  PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1),	\
893
  PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0),	\
894
  PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1)	\
895
)
896
897
#define PIC221111_16(xin)                                               \
898
(                                                               	\
899
  CBCRCG(0, xin),                                               	\
900
  PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3),     \
901
  PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0),     \
902
  PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1),     \
903
  PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2)      \
904
)
905
906
static void col221111(out, pic, width)
907
int *out;
908
unsigned char *pic;
909
int width;
910
{
911
	int i, j, k;
912
	unsigned char *pic0, *pic1;
913
	int *outy, *outc;
914
	int cr, cg, cb, y;
915
916
	pic0 = pic;
917
	pic1 = pic + width;
918
	outy = out;
919
	outc = out + 64 * 4;
920
	for (i = 2; i > 0; i--) {
921
		for (j = 4; j > 0; j--) {
922
			for (k = 0; k < 8; k++) {
923
				PIC221111(k);
924
			}
925
			outc += 8;
926
			outy += 16;
927
			pic0 += 2 * width;
928
			pic1 += 2 * width;
929
		}
930
		outy += 64 * 2 - 16 * 4;
931
	}
932
}
933
934
static void col221111_16(out, pic, width)
935
int *out;
936
unsigned char *pic;
937
int width;
938
{
939
	int i, j, k;
940
	unsigned char *pic0, *pic1;
941
	int *outy, *outc;
942
	int cr, cg, cb, y;
943
944
	pic0 = pic;
945
	pic1 = pic + width;
946
	outy = out;
947
	outc = out + 64 * 4;
948
	for (i = 2; i > 0; i--) {
949
		for (j = 4; j > 0; j--) {
950
			for (k = 0; k < 8; k++) {
951
			    PIC221111_16(k);
952
			}
953
			outc += 8;
954
			outy += 16;
955
			pic0 += 2 * width;
956
			pic1 += 2 * width;
957
		}
958
		outy += 64 * 2 - 16 * 4;
959
	}
960
}
(-)linux-2.4.21/drivers/video/fbcon-jpegdec.h (+24 lines)
Line 0 Link Here
1
#define ERR_NO_SOI 1
2
#define ERR_NOT_8BIT 2
3
#define ERR_HEIGHT_MISMATCH 3
4
#define ERR_WIDTH_MISMATCH 4
5
#define ERR_BAD_WIDTH_OR_HEIGHT 5
6
#define ERR_TOO_MANY_COMPPS 6
7
#define ERR_ILLEGAL_HV 7
8
#define ERR_QUANT_TABLE_SELECTOR 8
9
#define ERR_NOT_YCBCR_221111 9
10
#define ERR_UNKNOWN_CID_IN_SCAN 10
11
#define ERR_NOT_SEQUENTIAL_DCT 11
12
#define ERR_WRONG_MARKER 12
13
#define ERR_NO_EOI 13
14
#define ERR_BAD_TABLES 14
15
#define ERR_DEPTH_MISMATCH 15
16
17
struct jpeg_decdata {
18
	int dcts[6 * 64 + 16];
19
	int out[64 * 6];
20
	int dquant[3][64];
21
};
22
23
extern int jpeg_decode(unsigned char *, unsigned char *, int, int, int, struct jpeg_decdata *);
24
extern int jpeg_check_size(unsigned char *, int, int);
(-)linux-2.4.21/drivers/video/fbcon-splash.c (+848 lines)
Line 0 Link Here
1
/* 
2
 *    linux/drivers/video/fbcon-splash.c - splash screen handling functions.
3
 *	
4
 *	(w) 2001-2003 by Volker Poplawski, <volker@suse.de>
5
 * 		    Stefan Reinauer, <stepan@suse.de>
6
 * 		    Steffen Winterfeldt, <snwint@suse.de>
7
 * 		    
8
 * 	       Ideas & SuSE screen work by Ken Wimer, <wimer@suse.de>
9
 */
10
11
#include <linux/version.h>
12
#include <linux/config.h>
13
#include <linux/module.h>
14
#include <linux/fb.h>
15
#include <linux/vt_kern.h>
16
#include <linux/vmalloc.h>
17
18
#include <asm/irq.h>
19
#include <asm/system.h>
20
21
#include <video/fbcon.h>
22
#include <video/font.h>
23
#include <video/fbcon-cfb16.h>  /* for fbcon_cfb16 */
24
25
#include "fbcon-splash.h"
26
#include "fbcon-jpegdec.h"
27
28
#define SPLASH_VERSION "3.0.7-2003/03/10"
29
30
#ifdef CONFIG_BLK_DEV_INITRD
31
unsigned char signature[] = "BOOTSPL1SPL2SPL3";
32
#endif
33
34
/* from drivers/char/console.c */
35
extern void con_remap_def_color(int currcons, int new_color);
36
37
/* from drivers/video/fbcon-splash16.c */
38
extern void splashfill(u8 *dest, u8 *src, int width, int height, 
39
			int dest_linesize, int src_linesize);
40
41
/* internal control states and data pointers */
42
struct splash_data splash_data;
43
44
unsigned char *linux_splash;	/* decoded picture */
45
int linux_splash_size = 0;
46
47
static struct jpeg_decdata *decdata = 0; /* private decoder data */
48
49
int splash_bytes;		/* bytes per line in linux_splash */
50
int splash_shown = 0;		/* is the splash onscreen? */
51
int splash_usesilent = 0;	/* shall we display the silentjpeg */
52
int splash_default = 0xf01;
53
54
static int splash_status(struct display *p);
55
static int splash_recolor(struct display *p);
56
static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth);
57
58
extern struct display_switch fbcon_splash16;
59
60
int __init splash_init(char *options)
61
{
62
	if(!strncmp("silent",options,6)) {
63
		printk(KERN_INFO "bootsplash: silent mode.\n");
64
		splash_usesilent = 1;
65
		/* skip "silent," */
66
		if (strlen(options)==6)
67
			return 0;
68
		options+=7;
69
	}
70
	if(!strncmp("verbose",options,7)) {
71
		printk(KERN_INFO "bootsplash: verbose mode.\n");
72
		splash_usesilent = 0;
73
		return 0;
74
	}
75
		
76
	splash_default = simple_strtoul(options, NULL, 0);
77
78
	return 0;
79
}
80
81
__setup("splash=", splash_init);
82
83
84
static int splash_hasinter(unsigned char *buf, int num)
85
{
86
    unsigned char *bufend = buf + num * 12;
87
    while(buf < bufend) {
88
	if (buf[1] > 127)		/* inter? */
89
	    return 1;
90
	buf += buf[3] > 127 ? 24 : 12;	/* blend? */
91
    }
92
    return 0;
93
}
94
95
static int boxextract(unsigned char *buf, unsigned short *dp, unsigned char *cols, int *blendp)
96
{
97
    dp[0] = buf[0] | buf[1] << 8;
98
    dp[1] = buf[2] | buf[3] << 8;
99
    dp[2] = buf[4] | buf[5] << 8;
100
    dp[3] = buf[6] | buf[7] << 8;
101
    *(unsigned int *)(cols + 0) =
102
	*(unsigned int *)(cols + 4) =
103
	*(unsigned int *)(cols + 8) =
104
	*(unsigned int *)(cols + 12) = *(unsigned int *)(buf + 8);
105
    if (dp[1] > 32767) {
106
	dp[1] = ~dp[1];
107
	*(unsigned int *)(cols + 4) = *(unsigned int *)(buf + 12);
108
	*(unsigned int *)(cols + 8) = *(unsigned int *)(buf + 16);
109
	*(unsigned int *)(cols + 12) = *(unsigned int *)(buf + 20);
110
	*blendp = 1;
111
	return 24;
112
    }
113
    return 12;
114
}
115
116
static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num, int percent, int overpaint)
117
{
118
    int x, y, i, p, doblend, r, g, b, a, add;
119
    unsigned short data1[4];
120
    unsigned char cols1[16];
121
    unsigned short data2[4];
122
    unsigned char cols2[16];
123
    unsigned char *bufend;
124
    unsigned short *picp;
125
126
    if (num == 0)
127
	return;
128
    bufend = buf + num * 12;
129
    while(buf < bufend) {
130
	doblend = 0;
131
	buf += boxextract(buf, data1, cols1, &doblend);
132
	if (data1[0] > 32767)
133
	    buf += boxextract(buf, data2, cols2, &doblend);
134
	if (data1[2] > 32767) {
135
	    if (overpaint)
136
		continue;
137
	    data1[2] = ~data1[2];
138
	}
139
	if (data1[3] > 32767) {
140
	    if (percent == 65536)
141
		continue;
142
	    data1[3] = ~data1[3];
143
	}
144
	if (data1[0] > 32767) {
145
	    data1[0] = ~data1[0];
146
	    for (i = 0; i < 4; i++)
147
		data1[i] = (data1[i] * (65536 - percent) + data2[i] * percent) >> 16;
148
	    for (i = 0; i < 16; i++)
149
		cols1[i] = (cols1[i] * (65536 - percent) + cols2[i] * percent) >> 16;
150
	}
151
	*(unsigned int *)cols2 = *(unsigned int *)cols1;
152
	a = cols2[3];
153
	if (a == 0 && !doblend)
154
	    continue;
155
	for (y = data1[1]; y <= data1[3]; y++) {
156
	    if (doblend) {
157
		if ((p = data1[3] - data1[1]) != 0)
158
		    p = ((y - data1[1]) << 16) / p;
159
		for (i = 0; i < 8; i++)
160
		    cols2[i + 8] = (cols1[i] * (65536 - p) + cols1[i + 8] * p) >> 16;
161
	    }
162
	    add = (data1[0] & 1);
163
	    add ^= (add ^ y) & 1 ? 1 : 3;		/* 2x2 ordered dithering */
164
	    picp = (unsigned short *)(pic + data1[0] * 2 + y * bytes);
165
	    for (x = data1[0]; x <= data1[2]; x++) {
166
		if (doblend) {
167
		    if ((p = data1[2] - data1[0]) != 0)
168
			p = ((x - data1[0]) << 16) / p;
169
		    for (i = 0; i < 4; i++)
170
			cols2[i] = (cols2[i + 8] * (65536 - p) + cols2[i + 12] * p) >> 16;
171
		    a = cols2[3];
172
		}
173
		r = cols2[0];
174
		g = cols2[1];
175
		b = cols2[2];
176
		if (a != 255) {
177
		    i = *picp;
178
		    r = ((i >> 8 & 0xf8) * (255 - a) + r * a) / 255;
179
		    g = ((i >> 3 & 0xfc) * (255 - a) + g * a) / 255;
180
		    b = ((i << 3 & 0xf8) * (255 - a) + b * a) / 255;
181
		}
182
  #define CLAMP(x) ((x) >= 256 ? 255 : (x))
183
		i = ((CLAMP(r + add*2+1) & 0xf8) <<  8) |
184
		    ((CLAMP(g + add    ) & 0xfc) <<  3) |
185
		    ((CLAMP(b + add*2+1)       ) >>  3);
186
		*picp++ = i;
187
		add ^= 3;
188
	    }
189
	}
190
    }
191
}
192
193
static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth)
194
{
195
    int size, err;
196
    unsigned char *mem;
197
198
    size = ((width + 15) & ~15) * ((height + 15) & ~15) * (depth >> 3);
199
    mem = vmalloc(size);
200
    if (!mem) {
201
	printk(KERN_INFO "No memory for decoded picture!\n");
202
	return -1;
203
    }
204
    if (!decdata)
205
	decdata = vmalloc(sizeof(*decdata));
206
    if ((err = jpeg_decode(jpeg, mem, ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata)))
207
	  printk(KERN_INFO "error %d while decompressing picture.\n",err);
208
    vfree(mem);
209
    return err ? -1 : 0;
210
}
211
212
static void splash_free(struct display * p)
213
{
214
    if (!p->splash_data)
215
	return;
216
    if (p->splash_data->oldscreen_base)
217
	    p->screen_base = p->splash_data->oldscreen_base;
218
    if (p->splash_data->olddispsw)
219
	    p->dispsw = p->splash_data->olddispsw;
220
    if (p->splash_data->splash_silentjpeg)
221
	    vfree(p->splash_data->splash_sboxes);
222
    vfree(p->splash_data);
223
    p->splash_data = 0;
224
}
225
226
static int splash_mkpenguin(struct splash_data *data, int pxo, int pyo, int pwi, int phe, int pr, int pg, int pb)
227
{
228
    unsigned char *buf;
229
    int i;
230
231
    if (pwi ==0 || phe == 0)
232
	return 0;
233
    buf = (unsigned char *)data + sizeof(*data);
234
    pwi += pxo - 1;
235
    phe += pyo - 1;
236
    *buf++ = pxo;
237
    *buf++ = pxo >> 8;
238
    *buf++ = pyo;
239
    *buf++ = pyo >> 8;
240
    *buf++ = pwi;
241
    *buf++ = pwi >> 8;
242
    *buf++ = phe;
243
    *buf++ = phe >> 8;
244
    *buf++ = pr;
245
    *buf++ = pg;
246
    *buf++ = pb;
247
    *buf++ = 0;
248
    for (i = 0; i < 12; i++, buf++)
249
	*buf = buf[-12];
250
    buf[-24] ^= 0xff;
251
    buf[-23] ^= 0xff;
252
    buf[-1] = 0xff;
253
    return 2;
254
}
255
256
int splash_getraw(unsigned char *start, unsigned char *end)
257
{
258
	unsigned char *ndata;
259
	int found = 0;
260
	int splash_size = 0;
261
	void *splash_start = 0;
262
        int unit = 0;
263
        int width = 0, height = 0;
264
	int silentsize;
265
	int boxcount = 0;
266
	int sboxcount = 0;
267
	int palcnt = 0;
268
	struct display *p;
269
270
	printk(KERN_INFO "Looking for splash picture...");
271
272
	p = &fb_display[0];
273
        silentsize = 0;
274
275
	for (ndata = start; ndata < end; ndata++) {
276
		if (*((unsigned int *)ndata) != *((unsigned int *)signature))
277
			continue;
278
		if (*((unsigned int *)(ndata+4))==*((unsigned int *)(signature+4))) {
279
			printk(".");
280
			unit = 0;
281
			p = &fb_display[0];
282
			width = p->var.xres;
283
			height = p->var.yres;
284
285
			splash_size = ndata[16] + (ndata[17] << 8) + (ndata[18] << 16) + (ndata[19] << 24);
286
			if (ndata + 20 + splash_size > end) {
287
				printk(" found, but truncated!\n");
288
				return -1;
289
			}
290
			if (!jpeg_check_size(ndata + 20, width, height)) { 
291
				ndata += 20 - 1 + splash_size;
292
				continue;
293
			}
294
			if (splash_check_jpeg(ndata + 20, width, height, p->var.bits_per_pixel))
295
				return -1;
296
			if (p->splash_data)
297
				splash_free(p);
298
			p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size + 24);
299
			if (!p->splash_data)
300
				break;
301
302
			p->splash_data->oldscreen_base = 0;
303
			p->splash_data->olddispsw = 0;
304
			p->splash_data->splash_silentjpeg = 0;
305
306
			p->splash_data->splash_text_xo = ndata[ 8] + (ndata[ 9] << 8);
307
			p->splash_data->splash_text_yo = ndata[10] + (ndata[11] << 8);
308
			p->splash_data->splash_text_wi = ndata[12] + (ndata[13] << 8);
309
			p->splash_data->splash_text_he = ndata[14] + (ndata[15] << 8);
310
			/* use 8x16 font... */
311
			p->splash_data->splash_text_xo *= 8;
312
			p->splash_data->splash_text_wi *= 8;
313
			p->splash_data->splash_text_yo *= 16;
314
			p->splash_data->splash_text_he *= 16;
315
			p->splash_data->splash_color = (splash_default >> 8) & 0x0f;
316
			p->splash_data->splash_fg_color = (splash_default >> 4) & 0x0f;
317
			p->splash_data->splash_state = splash_default & 1;
318
			p->splash_data->splash_percent = 0;
319
			p->splash_data->splash_overpaintok = 0;
320
			boxcount = splash_mkpenguin(p->splash_data, p->splash_data->splash_text_xo + 10, p->splash_data->splash_text_yo + 10, p->splash_data->splash_text_wi - 20, p->splash_data->splash_text_he - 20, 0xf0, 0xf0, 0xf0);
321
			splash_start = ndata + 20;
322
			found = 1;
323
			break;
324
		}
325
		if (*((unsigned int *)(ndata + 4)) == *((unsigned int *)(signature+8))) {
326
			printk(".");
327
			unit = ndata[8];
328
			if (unit >= MAX_NR_CONSOLES)
329
			    continue;
330
			if (unit)
331
			    vc_allocate(unit);
332
			p = &fb_display[unit];
333
			width = fb_display[unit].var.xres;
334
			height = fb_display[unit].var.yres;
335
			splash_size = ndata[12] + (ndata[13] << 8) + (ndata[14] << 16) + (ndata[15] << 24);
336
			if (splash_size == -1) {
337
			    printk(" found, updating values.\n");
338
			    if (p->splash_data) {
339
				if (ndata[9] != 255)
340
				    p->splash_data->splash_state = ndata[9];
341
				if (ndata[10] != 255)
342
				    p->splash_data->splash_fg_color = ndata[10];
343
				if (ndata[11] != 255)
344
				    p->splash_data->splash_color = ndata[11];
345
			    }
346
			    return unit;
347
			}
348
			if (splash_size == 0) {
349
				printk(" found, freeing memory.\n");
350
				if (p->splash_data)
351
					splash_free(p);
352
				return unit;
353
			}
354
			if (ndata + 35 + splash_size > end) {
355
				printk(" found, but truncated!\n");
356
				return -1;
357
			}
358
			if (!jpeg_check_size(ndata + 35, width, height)) {
359
				ndata += 35 - 1 + splash_size;
360
				continue;
361
			}
362
			if (splash_check_jpeg(ndata + 35, width, height, p->var.bits_per_pixel))
363
				return -1;
364
			if (p->splash_data)
365
				splash_free(p);
366
			p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size + 24);
367
			if (!p->splash_data)
368
				break;
369
370
			p->splash_data->oldscreen_base = 0;
371
			p->splash_data->olddispsw = 0;
372
			p->splash_data->splash_silentjpeg = 0;
373
374
			p->splash_data->splash_state = ndata[9];
375
			p->splash_data->splash_fg_color = ndata[10];
376
			p->splash_data->splash_color = ndata[11];
377
			p->splash_data->splash_text_xo = ndata[16] + (ndata[17] << 8);
378
			p->splash_data->splash_text_yo = ndata[18] + (ndata[19] << 8);
379
			p->splash_data->splash_text_wi = ndata[20] + (ndata[21] << 8);
380
			p->splash_data->splash_text_he = ndata[22] + (ndata[23] << 8);
381
			p->splash_data->splash_percent = 0;
382
			p->splash_data->splash_overpaintok = 0;
383
			boxcount = splash_mkpenguin(p->splash_data, ndata[24] + (ndata[25] << 8), ndata[26] + (ndata[27] << 8), ndata[28] + (ndata[29] << 8), ndata[30] + (ndata[31] << 8), ndata[32], ndata[33], ndata[34]);
384
			splash_start = ndata + 35;
385
			found = 2;
386
			break;
387
		}
388
		if (*((unsigned int *)(ndata + 4)) == *((unsigned int *)(signature+12))) {
389
			printk(".");
390
			unit = ndata[8];
391
			if (unit >= MAX_NR_CONSOLES)
392
			    continue;
393
			if (unit)
394
			    vc_allocate(unit);
395
			p = &fb_display[unit];
396
			width = p->var.xres;
397
			height = p->var.yres;
398
			splash_size = ndata[12] + (ndata[13] << 8) + (ndata[14] << 16) + (ndata[15] << 24);
399
			if (splash_size == -1) {
400
			    printk(" found, updating values.\n");
401
			    if (p->splash_data) {
402
				if (ndata[9] != 255)
403
				    p->splash_data->splash_state = ndata[9];
404
				if (ndata[10] != 255)
405
				    p->splash_data->splash_fg_color = ndata[10];
406
				if (ndata[11] != 255)
407
				    p->splash_data->splash_color = ndata[11];
408
			    }
409
			    return unit;
410
			}
411
			if (splash_size == 0) {
412
				printk(" found, freeing memory.\n");
413
				if (p->splash_data)
414
					splash_free(p);
415
				return unit;
416
			}
417
			boxcount = ndata[24] + (ndata[25] << 8);
418
			palcnt = ndata[37] * 3;
419
			if (ndata + 38 + splash_size > end) {
420
				printk(" found, but truncated!\n");
421
				return -1;
422
			}
423
			if (!jpeg_check_size(ndata + 38 + boxcount * 12 + palcnt, width, height)) {
424
				ndata += 38 - 1 + splash_size;
425
				continue;
426
			}
427
			if (splash_check_jpeg(ndata + 38 + boxcount * 12 + palcnt, width, height, p->var.bits_per_pixel))
428
				return -1;
429
			silentsize = ndata[28] + (ndata[29] << 8) + (ndata[30] << 16) + (ndata[31] << 24);
430
			if (silentsize)
431
			    printk(" silenjpeg size %d bytes,", silentsize);
432
			if (silentsize >= splash_size) {
433
				printk(" bigger than splashsize!\n");
434
				return -1;
435
			}
436
			splash_size -= silentsize;
437
			if (!splash_usesilent || !p->fb_info->fbops->fb_get_fix ) {
438
				silentsize = 0;
439
			} else {
440
				struct fb_fix_screeninfo fix;
441
				p->fb_info->fbops->fb_get_fix(&fix, unit, 0);
442
				if (height * 2 * p->next_line > fix.smem_len) {
443
					printk(" does not fit into framebuffer.\n");
444
					silentsize = 0;
445
				}
446
			}
447
448
			sboxcount = ndata[32] + (ndata[33] << 8);
449
			if (silentsize) {
450
				char *simage=ndata + 38 + splash_size + 12 * sboxcount;
451
				if (!jpeg_check_size(simage, width, height) ||
452
				    splash_check_jpeg(simage, width, height, p->var.bits_per_pixel)) {
453
					printk(" error in silent jpeg.\n");
454
					silentsize = 0;
455
				}
456
			}
457
			if (p->splash_data)
458
				splash_free(p);
459
			p->splash_data = vmalloc(sizeof(*p->splash_data) + splash_size);
460
			if (!p->splash_data)
461
				break;
462
			p->splash_data->oldscreen_base = 0;
463
			p->splash_data->olddispsw = 0;
464
			p->splash_data->splash_silentjpeg = 0;
465
			if (silentsize) {
466
				p->splash_data->splash_silentjpeg = vmalloc(silentsize);
467
				if (p->splash_data->splash_silentjpeg) {
468
					memcpy(p->splash_data->splash_silentjpeg, ndata + 38 + splash_size, silentsize);
469
					p->splash_data->splash_sboxes = p->splash_data->splash_silentjpeg;
470
					p->splash_data->splash_silentjpeg += 12 * sboxcount;
471
					p->splash_data->splash_sboxcount = sboxcount;
472
				}
473
			}
474
			p->splash_data->splash_state = ndata[9];
475
			p->splash_data->splash_fg_color = ndata[10];
476
			p->splash_data->splash_color = ndata[11];
477
			p->splash_data->splash_overpaintok = ndata[36];
478
			p->splash_data->splash_text_xo = ndata[16] + (ndata[17] << 8);
479
			p->splash_data->splash_text_yo = ndata[18] + (ndata[19] << 8);
480
			p->splash_data->splash_text_wi = ndata[20] + (ndata[21] << 8);
481
			p->splash_data->splash_text_he = ndata[22] + (ndata[23] << 8);
482
			p->splash_data->splash_percent = ndata[34] + (ndata[35] << 8);
483
			p->splash_data->splash_percent += p->splash_data->splash_percent > 32767;
484
			splash_start = ndata + 38;
485
			found = 3;
486
			break;
487
		}
488
	}
489
	
490
	if (!found) {
491
		printk(" no good signature found.\n");
492
		return -1;
493
	}
494
	if (p->splash_data->splash_text_xo + p->splash_data->splash_text_wi > width || p->splash_data->splash_text_yo + p->splash_data->splash_text_he > height) {
495
		splash_free(p);
496
		p->splash_data = 0;
497
		printk(" found, but has oversized text area!\n");
498
		return -1;
499
	}
500
	if (p->dispsw->setup != fbcon_cfb16.setup) {
501
		splash_free(p);
502
		p->splash_data = 0;
503
		printk(" found, but framebuffer can't handle it!\n");
504
		return -1;
505
	}
506
	printk(" found (%dx%d, %d bytes, v%d).\n", width, height, splash_size, found);
507
508
	if (found==1) {
509
		printk(KERN_WARNING "bootsplash: Using deprecated v1 header. Updating your splash utility recommended.\n");
510
		printk(KERN_INFO    "bootsplash: Find the latest version at ftp.suse.com/pub/people/stepan/bootsplash/\n");
511
	}
512
513
	/* copy data so that initrd memory can be freed. */
514
	memcpy((char *)p->splash_data + sizeof(*p->splash_data) + (found < 3 ? boxcount * 12 : 0), splash_start, splash_size);
515
	p->splash_data->splash_boxcount = boxcount;
516
	p->splash_data->splash_boxes = (unsigned char *)p->splash_data + sizeof(*p->splash_data);
517
	p->splash_data->splash_jpeg = (unsigned char *)p->splash_data + sizeof(*p->splash_data) + boxcount * 12 + palcnt;
518
	p->splash_data->splash_palette = (unsigned char *)p->splash_data + sizeof(*p->splash_data) + boxcount * 12;
519
	p->splash_data->splash_palcnt = palcnt / 3;
520
	p->splash_data->splash_dosilent = p->splash_data->splash_silentjpeg != 0;
521
	return unit;
522
}
523
524
int splash_verbose(void) 
525
{
526
    struct display *p;
527
528
    p = &fb_display[0];
529
    if (!p || !p->splash_data || !p->splash_data->splash_state || !p->conp)
530
	return 0;
531
    if (fg_console != p->conp->vc_num)
532
	return 0;
533
    if (!p->splash_data->splash_silentjpeg || !p->splash_data->splash_dosilent)
534
	return 0;
535
    if (!p->splash_data->oldscreen_base)
536
	return 0;
537
538
    p->splash_data->splash_dosilent = 0;
539
540
    splashfill(p->splash_data->oldscreen_base, p->screen_base, p->var.xres, p->var.yres, p->next_line, p->next_line);
541
    p->screen_base = p->splash_data->oldscreen_base;
542
543
    return 1;
544
}
545
546
static void splash_off(struct display *p)
547
{
548
    if (p->splash_data && p->splash_data->oldscreen_base)
549
	p->screen_base = p->splash_data->oldscreen_base;
550
    if (p->splash_data && p->splash_data->olddispsw)
551
	p->dispsw = p->splash_data->olddispsw;
552
    splash_shown = 0;
553
}
554
555
int splash_prepare(struct display *p)
556
{
557
	int err;
558
        int width, height, depth, size, sbytes;
559
560
	if (!p->splash_data || !p->splash_data->splash_state) {
561
		if (linux_splash)
562
			vfree(linux_splash);
563
		if (decdata)
564
			vfree(decdata);
565
		linux_splash = 0;
566
		decdata = 0;
567
		linux_splash_size = 0;
568
		splash_off(p);
569
		return -1;
570
	}
571
572
        width = p->var.xres;
573
        height = p->var.yres;
574
        depth = p->var.bits_per_pixel;
575
	if (depth != 16) {	/* Other targets might need fixing */
576
		splash_off(p);
577
		return -2;
578
	}
579
580
	sbytes = ((width + 15) & ~15) * (depth >> 3);
581
	size = sbytes * ((height + 15) & ~15);
582
	if (size != linux_splash_size) {
583
		if (linux_splash)
584
			vfree(linux_splash);
585
		linux_splash_size = 0;
586
		linux_splash = 0;
587
		splash_off(p);
588
	}
589
	if (!linux_splash)
590
		linux_splash = vmalloc(size);
591
592
	if (!linux_splash) {
593
		linux_splash_size = 0;
594
		printk(KERN_INFO "Not enough memory for splash screen.\n");
595
		splash_off(p);
596
		return -3;
597
	}
598
599
	if (!decdata)
600
	    decdata = vmalloc(sizeof(*decdata));
601
602
	if (!p->splash_data->oldscreen_base)
603
		p->splash_data->oldscreen_base = p->screen_base;
604
605
	if (p->splash_data->splash_silentjpeg && p->splash_data->splash_dosilent) {
606
		printk(KERN_INFO "Got silent jpeg.\n");
607
		/* fill area after framebuffer with other jpeg */
608
		if ((err = jpeg_decode(p->splash_data->splash_silentjpeg, linux_splash, 
609
			 ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
610
			printk(KERN_INFO "Error %d while decompressing silent jpeg.\n", err);
611
			p->screen_base = p->splash_data->oldscreen_base;
612
			p->splash_data->splash_dosilent = 0;
613
		} else {
614
			if (p->splash_data->splash_sboxcount)
615
				boxit(linux_splash, sbytes, p->splash_data->splash_sboxes, 
616
					p->splash_data->splash_sboxcount, p->splash_data->splash_percent, 0);
617
618
			splashfill(p->screen_base, linux_splash, p->var.xres, p->var.yres, p->next_line, sbytes);
619
			p->screen_base = p->splash_data->oldscreen_base + p->next_line * p->var.yres;
620
		}
621
	} else
622
		p->screen_base = p->splash_data->oldscreen_base;
623
624
	if ((err = jpeg_decode(p->splash_data->splash_jpeg, linux_splash, 
625
		 ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
626
		printk(KERN_INFO "Error %d while decompressing splash screen.\n", err);
627
		vfree(linux_splash);
628
		linux_splash = 0;
629
		linux_splash_size = 0;
630
		splash_off(p);
631
		return -4;
632
	}
633
	linux_splash_size = size;
634
	splash_bytes = sbytes;
635
	if (p->splash_data->splash_boxcount)
636
		boxit(linux_splash, sbytes, p->splash_data->splash_boxes, p->splash_data->splash_boxcount, p->splash_data->splash_percent, 0);
637
	splash_data = *p->splash_data;
638
	splash_shown = p->splash_data->splash_state;
639
	if (splash_shown) {
640
	    if (p->dispsw != &fbcon_splash16)
641
		p->splash_data->olddispsw = p->dispsw;
642
	    p->dispsw = &fbcon_splash16;
643
	} else
644
		splash_off(p);
645
	return 0;
646
}
647
648
649
#ifdef CONFIG_PROC_FS
650
#include <linux/proc_fs.h>
651
652
struct proc_dir_entry *proc_splash;
653
int splash_read_proc(char *buffer, char **start, off_t offset, int size,
654
			int *eof, void *data);
655
int splash_write_proc(struct file *file, const char *buffer,
656
			unsigned long count, void *data);
657
658
int splash_read_proc(char *buffer, char **start, off_t offset, int size,
659
			int *eof, void *data)
660
{
661
	int len = 0;
662
	
663
	off_t begin = 0;
664
	struct display *p = &fb_display[0];
665
666
	int color = p->splash_data ? p->splash_data->splash_color << 4 |
667
			p->splash_data->splash_fg_color : splash_default >> 4;
668
	int status = p->splash_data ? p->splash_data->splash_state & 1 : 0;
669
	len += sprintf(buffer + len, "Splash screen v%s (0x%02x, %dx%d%s): %s\n",
670
		        SPLASH_VERSION, color, p->var.xres, p->var.yres,
671
			(p->splash_data ?  p->splash_data->splash_dosilent : 0)? ", silent" : "",
672
					status ? "on" : "off");
673
	if (offset >= begin + len)
674
		return 0;
675
676
	*start = buffer + (begin - offset);
677
678
	return (size < begin + len - offset ? size : begin + len - offset);
679
}
680
681
static int splash_recolor(struct display *p)
682
{
683
	if (!p->splash_data)
684
	    return -1;
685
	if (!p->splash_data->splash_state)
686
	    return 0;
687
	con_remap_def_color(p->conp->vc_num, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color);
688
	if (fg_console == p->conp->vc_num) {
689
	        splash_data = *p->splash_data;
690
		update_region(fg_console,
691
			      p->conp->vc_origin +
692
			      p->conp->vc_size_row *
693
			      p->conp->vc_top,
694
			      p->conp->vc_size_row *
695
			      (p->conp->vc_bottom -
696
			       p->conp->vc_top) / 2);
697
	}
698
	return 0;
699
}
700
701
static int splash_status(struct display *p)
702
{
703
	printk(KERN_INFO "Splash status on console %d changed to %s\n", p->conp->vc_num, p->splash_data && p->splash_data->splash_state ? "on" : "off");
704
705
	if (fg_console == p->conp->vc_num)
706
		splash_prepare(p);
707
	if (p->splash_data && p->splash_data->splash_state) {
708
		con_remap_def_color(p->conp->vc_num, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color);
709
		/* resize_con also calls con_switch which resets yscroll */
710
		vc_resize_con(p->splash_data->splash_text_he / fontheight(p),
711
                              p->splash_data->splash_text_wi / fontwidth(p),
712
                              p->conp->vc_num);
713
		if (fg_console == p->conp->vc_num) {
714
			update_region(fg_console,
715
				      p->conp->vc_origin +
716
				      p->conp->vc_size_row *
717
				      p->conp->vc_top,
718
				      p->conp->vc_size_row *
719
				      (p->conp->vc_bottom -
720
				       p->conp->vc_top) / 2);
721
			    fbcon_splash16.clear_margins(p->conp, p, 0);
722
		}
723
	} else {
724
	  	/* Switch bootsplash off */
725
		con_remap_def_color(p->conp->vc_num, 0x07);
726
		vc_resize_con(p->var.yres / fontheight(p),
727
			      p->var.xres / fontwidth(p),
728
			      p->conp->vc_num);
729
	}
730
	return 0;
731
}
732
733
int splash_write_proc(struct file *file, const char *buffer,
734
		      unsigned long count, void *data)
735
{
736
        int new, unit;
737
	struct display *p;
738
	
739
	if (!buffer || !splash_default)
740
		return count;
741
742
	if (!strncmp(buffer, "show", 4) || !strncmp(buffer, "hide", 4)) {
743
		int pe;
744
745
		p = &fb_display[0];
746
		if (buffer[4] == ' ' && buffer[5] == 'p')
747
			pe = 0;
748
		else if (buffer[4] == '\n')
749
			pe = 65535;
750
		else
751
			pe = simple_strtoul(buffer + 5, NULL, 0);
752
		if (pe < 0)
753
			pe = 0;
754
		if (pe > 65535)
755
			pe = 65535;
756
		if (*buffer == 'h')
757
			pe = 65535 - pe;
758
		pe += pe > 32767;
759
		if (p->splash_data && p->splash_data->splash_percent != pe) {
760
			p->splash_data->splash_percent = pe;
761
			if (fg_console != p->conp->vc_num || !p->splash_data->splash_state)
762
			    return count;
763
			if (!p->splash_data->splash_overpaintok || p->splash_data->splash_percent == 65536) {
764
				if (splash_hasinter(p->splash_data->splash_boxes, p->splash_data->splash_boxcount))
765
					splash_status(p);
766
				else
767
					splash_prepare(p);
768
			} else {
769
				if (p->splash_data->splash_silentjpeg && p->splash_data->splash_dosilent && p->splash_data->oldscreen_base)
770
					boxit(p->splash_data->oldscreen_base, p->next_line, p->splash_data->splash_sboxes, p->splash_data->splash_sboxcount, p->splash_data->splash_percent, 1);
771
				boxit(p->screen_base, p->next_line, p->splash_data->splash_boxes, p->splash_data->splash_boxcount, p->splash_data->splash_percent, 1);
772
			}
773
		}
774
		return count;
775
	}
776
	if (!strncmp(buffer,"silent\n",7) || !strncmp(buffer,"verbose\n",8)) {
777
		p = &fb_display[0];
778
		if (p->splash_data && p->splash_data->splash_silentjpeg) {
779
		    if (p->splash_data->splash_dosilent != (buffer[0] == 's')) {
780
			p->splash_data->splash_dosilent = buffer[0] == 's';
781
			splash_status(p);
782
		    }
783
		}
784
		return count;
785
	}
786
	if (!strncmp(buffer,"freesilent\n",11)) {
787
		p = &fb_display[0];
788
		if (p->splash_data && p->splash_data->splash_silentjpeg) {
789
		    printk(KERN_INFO "bootsplash: freeing silent jpeg\n");
790
		    p->splash_data->splash_silentjpeg = 0;
791
		    vfree(p->splash_data->splash_sboxes);
792
		    p->splash_data->splash_sboxes = 0;
793
		    p->splash_data->splash_sboxcount = 0;
794
		    if (p->splash_data->splash_dosilent)
795
			splash_status(p);
796
		    p->splash_data->splash_dosilent = 0;
797
		}
798
		return count;
799
	}
800
801
	if (!strncmp(buffer, signature, 7)) {
802
	    unit = splash_getraw((unsigned char *)buffer, (unsigned char *)buffer + count);
803
	    if (unit >= 0) {
804
		p = &fb_display[unit];
805
		splash_status(p);
806
	    }
807
	    return count;
808
	}
809
	p = &fb_display[0];
810
	if (!p->splash_data)
811
		return count;
812
	if (buffer[0] == 't') {
813
	        p->splash_data->splash_state ^= 1;
814
		splash_status(p);
815
		return count;
816
	}
817
	new = simple_strtoul(buffer, NULL, 0);
818
	if (new > 1) {
819
		/* expert user */
820
		p->splash_data->splash_color    = new >> 8 & 0xff;
821
		p->splash_data->splash_fg_color = new >> 4 & 0x0f;
822
	}
823
	if ((new & 1) == p->splash_data->splash_state)
824
		splash_recolor(p);
825
	else {
826
	        p->splash_data->splash_state = new & 1;
827
		splash_status(p);
828
	}
829
	return count;
830
}
831
832
int splash_proc_register(void)
833
{
834
	if ((proc_splash = create_proc_entry("splash", 0, 0))) {
835
		proc_splash->read_proc = splash_read_proc;
836
		proc_splash->write_proc = splash_write_proc;
837
		return 0;
838
	}
839
	return 1;
840
}
841
842
int splash_proc_unregister(void)
843
{
844
	if (proc_splash)
845
		remove_proc_entry("splash", 0);
846
	return 0;
847
}
848
#endif
(-)linux-2.4.21/drivers/video/fbcon-splash.h (+19 lines)
Line 0 Link Here
1
/* 
2
	 *    linux/drivers/video/splash.h - splash screen definition.
3
	 * 
4
	 * (w) 2001-2003 by Volker Poplawski, <volker@suse.de>
5
	 *             Stefan Reinauer, <stepan@suse.de>
6
	 *             
7
	 *             
8
	 *     idea and SuSE screen work by Ken Wimer, <wimer@suse.de>
9
	 */
10
11
extern int splash_getraw(unsigned char *, unsigned char *);
12
extern int splash_prepare(struct display *);
13
14
extern int splash_shown;       /* is splash shown? */
15
extern struct splash_data splash_data; /* image data, copied over
16
										                         from display */
17
extern unsigned char *linux_splash;    /* decoded pic data */
18
extern int splash_bytes;       /* bytes per line */
19
(-)linux-2.4.21/drivers/video/fbcon-splash16.c (+488 lines)
Line 0 Link Here
1
/*
2
 *  linux/drivers/video/fbcon-splash16.c -- Low level frame buffer operations for 16 bpp
3
 *                                          framebuffer operation. Modified to present
4
 *					    boot splash screen. 2002/11/7 stepan@suse.de
5
 * 
6
 * Based on linux/drivers/video/fbcon-cfb16.c, which is
7
 *
8
 *	Created 5 Apr 1997 by Geert Uytterhoeven
9
 *
10
 *  This file is subject to the terms and conditions of the GNU General Public
11
 *  License.  See the file COPYING in the main directory of this archive for
12
 *  more details.
13
 */
14
15
#include <linux/module.h>
16
#include <linux/config.h>
17
#include <linux/tty.h>
18
#include <linux/console.h>
19
#include <linux/string.h>
20
#include <linux/fb.h>
21
#include <asm/io.h>
22
23
#include <video/fbcon.h>
24
#include <video/fbcon-cfb16.h>
25
26
#include "fbcon-splash.h"
27
28
    /*
29
     *  16 bpp packed pixels
30
     */
31
32
static u32 tab_cfb16[] = {
33
#if defined(__BIG_ENDIAN)
34
    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
35
#elif defined(__LITTLE_ENDIAN)
36
    0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
37
#else
38
#error FIXME: No endianness??
39
#endif
40
};
41
42
void fbcon_splash16_bmove(struct display *p, int sy, int sx, int dy, int dx,
43
		       int height, int width)
44
{
45
    int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
46
    u8 *src, *dst;
47
48
    if (sx == 0 && dx == 0 && width * fontwidth(p) * 2 == bytes) {
49
	fb_memmove(p->screen_base + dy * linesize,
50
		  p->screen_base + sy * linesize,
51
		  height * linesize);
52
	return;
53
    }
54
    if (fontwidthlog(p)) {
55
	sx <<= fontwidthlog(p)+1;
56
	dx <<= fontwidthlog(p)+1;
57
	width <<= fontwidthlog(p)+1;
58
    } else {
59
	sx *= fontwidth(p)*2;
60
	dx *= fontwidth(p)*2;
61
	width *= fontwidth(p)*2;
62
    }
63
    sx += splash_data.splash_text_xo*2 + splash_data.splash_text_yo * bytes;
64
    dx += splash_data.splash_text_xo*2 + splash_data.splash_text_yo * bytes;
65
    if (dy < sy || (dy == sy && dx < sx)) {
66
	src = p->screen_base + sy * linesize + sx;
67
	dst = p->screen_base + dy * linesize + dx;
68
	for (rows = height * fontheight(p); rows--;) {
69
	    fb_memmove(dst, src, width);
70
	    src += bytes;
71
	    dst += bytes;
72
	}
73
    } else {
74
	src = p->screen_base + (sy+height) * linesize + sx - bytes;
75
	dst = p->screen_base + (dy+height) * linesize + dx - bytes;
76
	for (rows = height * fontheight(p); rows--;) {
77
	    fb_memmove(dst, src, width);
78
	    src -= bytes;
79
	    dst -= bytes;
80
	}
81
    }
82
}
83
84
static inline void rectfill(u8 *dest, int width, int height, u32 data,
85
			    int linesize)
86
{
87
    int i;
88
89
    data |= data<<16;
90
91
    while (height-- > 0) {
92
	u32 *p = (u32 *)dest;
93
	for (i = 0; i < width/4; i++) {
94
	    fb_writel(data, p++);
95
	    fb_writel(data, p++);
96
	}
97
	if (width & 2)
98
	    fb_writel(data, p++);
99
	if (width & 1)
100
	    fb_writew(data, (u16*)p);
101
	dest += linesize;
102
    }
103
}
104
105
void splashfill(u8 *dest, u8 *src, int width, int height,
106
                       int dest_linesize, int src_linesize)
107
{
108
109
    int i;
110
111
    while (height-- > 0) {
112
	u32 *p = (u32 *)dest;
113
	u32 *q = (u32 *)src;
114
115
	for (i=0; i < width/4; i++) {
116
	    fb_writel(*q++,p++);
117
	    fb_writel(*q++,p++);
118
	}
119
	if (width & 2)
120
	    fb_writel(*q++,p++);
121
	if (width & 1)
122
	    fb_writew(*(u16*)q,(u16*)p);
123
	dest += dest_linesize;
124
	src  += src_linesize;
125
    }
126
}
127
128
void fbcon_splash16_clear(struct vc_data *conp, struct display *p, int sy, int sx,
129
		       int height, int width)
130
{
131
    u8 *dest;
132
    int bytes = p->next_line, lines = height * fontheight(p);
133
    u32 bgx;
134
    int offset, transparent=0;
135
136
    dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 2;
137
138
    bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
139
140
    width *= fontwidth(p)/4;
141
142
    dest   += splash_data.splash_text_yo * bytes  +
143
		  splash_data.splash_text_xo * 2;
144
145
    transparent = (splash_data.splash_color == attr_bgcol_ec(p, conp));
146
    
147
    if (transparent) {
148
	offset = (sy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes +
149
		 (sx * fontwidth(p) + splash_data.splash_text_xo) *  2;
150
	
151
	if ((width * 8 == bytes && splash_bytes == bytes))
152
	    splashfill(dest,linux_splash + offset, lines * width * 4, 
153
			    1, bytes, splash_bytes);
154
	else
155
	    splashfill(dest,linux_splash + offset, width*4, lines,
156
			    bytes, splash_bytes);
157
    } else {
158
	 if (width * 8 == bytes)
159
	    rectfill(dest, lines * width * 4, 1, bgx, bytes);
160
	 else
161
	    rectfill(dest, width * 4, lines, bgx, bytes);
162
    }
163
}
164
165
166
/*
167
 *  Helper function to read the background from the splashscreen
168
 */
169
# define SPLASH_BGX(off)			\
170
	if (transparent) {			\
171
	    bgx = *(u32*)(splashbgx + (off));	\
172
	    eorx = fgx ^ bgx;			\
173
	}
174
175
176
void fbcon_splash16_putc(struct vc_data *conp, struct display *p, int c, int yy,
177
		      int xx)
178
{
179
    u8 *dest, *cdat, bits;
180
    int bytes = p->next_line, rows;
181
    u32 eorx, fgx, bgx;
182
    int transparent = 0;
183
    u8 *splashbgx = 0;
184
 
185
    dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
186
187
    fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
188
    bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
189
190
    transparent = (splash_data.splash_color == attr_bgcol(p, c));
191
    
192
    dest += splash_data.splash_text_xo * 2 + splash_data.splash_text_yo * bytes;
193
    splashbgx = linux_splash +
194
	    (yy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes + 
195
	    (xx * fontwidth(p) + splash_data.splash_text_xo) * 2;
196
197
    if (transparent && splash_data.splash_color == 0xf) {
198
	if (fgx == 0xffea)
199
	    fgx = 0xfe4a;
200
	else if (fgx == 0x57ea)
201
	    fgx = 0x0540;
202
	else if (fgx == 0xffff)
203
	    fgx = 0x52aa;
204
    }
205
206
    fgx |= (fgx << 16);
207
    bgx |= (bgx << 16);
208
    eorx = fgx ^ bgx;
209
210
    switch (fontwidth(p)) {
211
    case 4:
212
    case 8:
213
	cdat = p->fontdata + (c & p->charmask) * fontheight(p);
214
	for (rows = fontheight(p); rows--; dest += bytes) {
215
	    bits = *cdat++;
216
	    SPLASH_BGX(0);
217
	    fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
218
	    SPLASH_BGX(4);
219
	    fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
220
	    if (fontwidth(p) == 8) {
221
		SPLASH_BGX(8);
222
		fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
223
		SPLASH_BGX(12);
224
		fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
225
	    }
226
227
	    splashbgx += splash_bytes;
228
229
	}
230
	break;
231
    case 12:
232
    case 16:
233
	cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
234
	for (rows = fontheight(p); rows--; dest += bytes) {
235
	    bits = *cdat++;
236
	    SPLASH_BGX(0);
237
	    fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
238
	    SPLASH_BGX(4);
239
	    fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
240
	    SPLASH_BGX(8);
241
	    fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
242
	    SPLASH_BGX(12);
243
	    fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
244
	    bits = *cdat++;
245
	    SPLASH_BGX(16);
246
	    fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
247
	    SPLASH_BGX(20);
248
	    fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
249
	    if (fontwidth(p) == 16) {
250
		SPLASH_BGX(24);
251
		fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
252
		SPLASH_BGX(28);
253
		fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
254
	    }
255
	}
256
	break;
257
    }
258
}
259
260
void fbcon_splash16_putcs(struct vc_data *conp, struct display *p,
261
		       const unsigned short *s, int count, int yy, int xx)
262
{
263
    u8 *cdat, *dest, *dest0;
264
    u16 c;
265
    int rows, bytes = p->next_line;
266
    u32 eorx, fgx, bgx;
267
    int transparent = 0;
268
    u8 *splashbgx0 = 0, *splashbgx;
269
270
    dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
271
    c = scr_readw(s);
272
    fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
273
    bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
274
275
    transparent = (splash_data.splash_color == attr_bgcol(p, c));
276
    
277
    dest0 += splash_data.splash_text_xo * 2 + splash_data.splash_text_yo * bytes;
278
    splashbgx0 = linux_splash +
279
	      (yy * fontheight(p) + splash_data.splash_text_yo) * splash_bytes +
280
	      (xx * fontwidth(p) + splash_data.splash_text_xo) * 2;
281
282
    if (transparent && splash_data.splash_color == 0xf) {
283
	if (fgx == 0xffea)
284
	    fgx = 0xfe4a;
285
	else if (fgx == 0x57ea)
286
	    fgx = 0x0540;
287
	else if (fgx == 0xffff)
288
	    fgx = 0x52aa;
289
    }
290
291
    fgx |= (fgx << 16);
292
    bgx |= (bgx << 16);
293
    eorx = fgx ^ bgx;
294
295
    switch (fontwidth(p)) {
296
    case 4:
297
    case 8:
298
	while (count--) {
299
	    c = scr_readw(s++) & p->charmask;
300
	    cdat = p->fontdata + c * fontheight(p);
301
302
	    splashbgx = splashbgx0;
303
304
	    for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
305
		u8 bits = *cdat++;
306
		SPLASH_BGX(0);
307
	        fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
308
		SPLASH_BGX(4);
309
	        fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
310
		if (fontwidth(p) == 8) {
311
		    SPLASH_BGX(8);
312
		    fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
313
		    SPLASH_BGX(12);
314
		    fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
315
		}
316
		splashbgx += splash_bytes;
317
	    }
318
319
	    dest0 += fontwidth(p)*2;
320
	    splashbgx0 += fontwidth(p) * 2;
321
	}
322
323
	break;
324
    case 12:
325
    case 16:
326
	while (count--) {
327
	    c = scr_readw(s++) & p->charmask;
328
	    cdat = p->fontdata + (c * fontheight(p) << 1);
329
330
	    splashbgx = splashbgx0;
331
332
	    for (rows = fontheight(p), dest = dest0; rows--; dest += bytes) {
333
		u8 bits = *cdat++;
334
		SPLASH_BGX(0);
335
	        fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest);
336
		SPLASH_BGX(4);
337
	        fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+4);
338
		SPLASH_BGX(8);
339
	        fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+8);
340
		SPLASH_BGX(12);
341
	        fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+12);
342
		bits = *cdat++;
343
		SPLASH_BGX(16);
344
	        fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest+16);
345
		SPLASH_BGX(20);
346
	        fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest+20);
347
		if (fontwidth(p) == 16) {
348
		    SPLASH_BGX(24);
349
		    fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest+24);
350
		    SPLASH_BGX(28);
351
		    fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest+28);
352
		}
353
		splashbgx += splash_bytes;
354
	    }
355
356
	    dest0 += fontwidth(p)*2;
357
	    splashbgx0 += fontwidth(p) * 2;
358
	}
359
360
	break;
361
    }
362
}
363
364
void fbcon_splash16_revc(struct display *p, int xx, int yy)
365
{
366
    u8 *dest;
367
    int bytes = p->next_line, rows;
368
369
    dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p)*2;
370
    dest += splash_data.splash_text_yo * bytes + splash_data.splash_text_xo * 2;
371
372
    for (rows = fontheight(p); rows--; dest += bytes) {
373
	switch (fontwidth(p)) {
374
	case 16:
375
	    fb_writel(fb_readl(dest+24) ^ 0xffffffff, dest+24);
376
	    fb_writel(fb_readl(dest+28) ^ 0xffffffff, dest+28);
377
	    /* FALL THROUGH */
378
	case 12:
379
	    fb_writel(fb_readl(dest+16) ^ 0xffffffff, dest+16);
380
	    fb_writel(fb_readl(dest+20) ^ 0xffffffff, dest+20);
381
	    /* FALL THROUGH */
382
	case 8:
383
	    fb_writel(fb_readl(dest+8) ^ 0xffffffff, dest+8);
384
	    fb_writel(fb_readl(dest+12) ^ 0xffffffff, dest+12);
385
	    /* FALL THROUGH */
386
	case 4:
387
	    fb_writel(fb_readl(dest+0) ^ 0xffffffff, dest+0);
388
	    fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4);
389
	}
390
    }
391
}
392
393
void fbcon_splash16_clear_margins(struct vc_data *conp, struct display *p,
394
			       int bottom_only)
395
{
396
    int bytes = p->next_line;
397
    u32 bgx;
398
399
    unsigned int right_start = conp->vc_cols*fontwidth(p);
400
    unsigned int bottom_start = conp->vc_rows*fontheight(p);
401
    unsigned int right_width, bottom_width;
402
403
    int left_margin_width = splash_data.splash_text_xo;
404
    int text_width = conp->vc_cols * fontwidth(p);
405
    int right_margin_width = p->var.xres - text_width - left_margin_width;
406
    int top_margin_height = splash_data.splash_text_yo;
407
    int text_height = conp->vc_rows * fontheight(p);
408
    int bottom_margin_height = p->var.yres - text_height - top_margin_height;
409
 
410
    bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
411
412
    if (bottom_only == -1) {
413
	printk(KERN_DEBUG "Called with bottom-only\n");
414
	splashfill(p->screen_base, linux_splash, p->var.xres, p->var.yres, bytes, splash_bytes); 
415
	return;
416
    }
417
418
    if (!bottom_only && (right_width = p->var.xres-right_start)) {
419
  	/* left margin */
420
	splashfill(p->screen_base + top_margin_height * bytes,
421
		   linux_splash + top_margin_height * 
422
		   splash_bytes, left_margin_width,
423
		   text_height, bytes, splash_bytes);
424
425
	/* right margin */
426
	splashfill(p->screen_base + left_margin_width*2 + text_width*2 +
427
		    top_margin_height * bytes, linux_splash +
428
		    left_margin_width*2 + text_width*2 + top_margin_height *
429
		    splash_bytes, right_margin_width, text_height,
430
		    bytes, splash_bytes);
431
    }
432
433
    if ((bottom_width = p->var.yres-bottom_start))
434
	/* bottom margin */
435
	splashfill(p->screen_base + (top_margin_height + text_height) *
436
		    bytes, linux_splash + (top_margin_height +
437
		    text_height) * splash_bytes, p->var.xres, 
438
		    bottom_margin_height, bytes, splash_bytes);
439
440
    /* top margin */
441
    splashfill(p->screen_base, linux_splash,
442
	    p->var.xres, top_margin_height,
443
	    bytes, splash_bytes);
444
445
    /* leave function if work is done */
446
    return;
447
}
448
449
450
    /*
451
     *  `switch' for the low level operations
452
     */
453
454
struct display_switch fbcon_splash16 = {
455
    bmove:		fbcon_splash16_bmove,
456
    clear:		fbcon_splash16_clear,
457
    putc:		fbcon_splash16_putc,
458
    putcs:		fbcon_splash16_putcs,
459
    revc:		fbcon_splash16_revc,
460
    clear_margins:	fbcon_splash16_clear_margins,
461
    fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
462
};
463
464
465
#ifdef MODULE
466
MODULE_LICENSE("GPL");
467
468
int init_module(void)
469
{
470
    return 0;
471
}
472
473
void cleanup_module(void)
474
{}
475
#endif /* MODULE */
476
477
478
    /*
479
     *  Visible symbols for modules
480
     */
481
482
EXPORT_SYMBOL(fbcon_splash16);
483
EXPORT_SYMBOL(fbcon_splash16_bmove);
484
EXPORT_SYMBOL(fbcon_splash16_clear);
485
EXPORT_SYMBOL(fbcon_splash16_putc);
486
EXPORT_SYMBOL(fbcon_splash16_putcs);
487
EXPORT_SYMBOL(fbcon_splash16_revc);
488
EXPORT_SYMBOL(fbcon_splash16_clear_margins);
(-)linux-2.4.21/drivers/video/fbcon.c (-8 / +138 lines)
Lines 74-83 Link Here
74
#include <linux/vt_kern.h>
74
#include <linux/vt_kern.h>
75
#include <linux/selection.h>
75
#include <linux/selection.h>
76
#include <linux/smp.h>
76
#include <linux/smp.h>
77
#include <linux/init.h>
77
#include <linux/init.h>
78
#include <linux/pm.h>
78
#include <linux/pm.h>
79
#include <linux/vmalloc.h>
79
80
80
#include <asm/irq.h>
81
#include <asm/irq.h>
81
#include <asm/system.h>
82
#include <asm/system.h>
82
#include <asm/uaccess.h>
83
#include <asm/uaccess.h>
83
#ifdef CONFIG_AMIGA
84
#ifdef CONFIG_AMIGA
Lines 101-110 Link Here
101
#include <asm/linux_logo.h>
102
#include <asm/linux_logo.h>
102
103
103
#include <video/fbcon.h>
104
#include <video/fbcon.h>
104
#include <video/fbcon-mac.h>	/* for 6x11 font on mac */
105
#include <video/fbcon-mac.h>	/* for 6x11 font on mac */
105
#include <video/font.h>
106
#include <video/font.h>
107
#ifdef CONFIG_FBCON_SPLASHSCREEN
108
#include <video/fbcon-cfb16.h> /* for fbcon_cfb16 */
109
#include "fbcon-splash.h"
110
111
extern void con_remap_def_color(int currcons, int new_color);
112
113
extern int splash_default;
114
extern int splash_shown;
115
116
extern struct display_switch fbcon_splash16;
117
118
#ifdef CONFIG_PROC_FS
119
int splash_proc_register(void);
120
int splash_proc_unregister(void);
121
#endif
122
#endif
123
106
124
107
#ifdef FBCONDEBUG
125
#ifdef FBCONDEBUG
108
#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
126
#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
109
#else
127
#else
110
#  define DPRINTK(fmt, args...)
128
#  define DPRINTK(fmt, args...)
Lines 476-485 Link Here
476
#endif
494
#endif
477
495
478
    return display_desc;
496
    return display_desc;
479
}
497
}
480
498
499
#ifdef CONFIG_FBCON_SPLASHSCREEN
500
    static int splash_registered=0;
501
#endif
481
502
482
static void fbcon_init(struct vc_data *conp, int init)
503
static void fbcon_init(struct vc_data *conp, int init)
483
{
504
{
484
    int unit = conp->vc_num;
505
    int unit = conp->vc_num;
485
    struct fb_info *info;
506
    struct fb_info *info;
Lines 500-509 Link Here
500
    fb_display[unit].cmap.len = 0;
521
    fb_display[unit].cmap.len = 0;
501
    fb_display[unit].cmap.red = 0;
522
    fb_display[unit].cmap.red = 0;
502
    fb_display[unit].cmap.green = 0;
523
    fb_display[unit].cmap.green = 0;
503
    fb_display[unit].cmap.blue = 0;
524
    fb_display[unit].cmap.blue = 0;
504
    fb_display[unit].cmap.transp = 0;
525
    fb_display[unit].cmap.transp = 0;
526
527
#ifdef CONFIG_FBCON_SPLASHSCREEN 
528
   if (!splash_registered && fb_display[unit].var.bits_per_pixel == 16 ) {
529
   if (unit == 0 && !fb_display[unit].splash_data) {
530
       extern unsigned long initrd_start, initrd_end;
531
532
       if (initrd_start && !splash_getraw((unsigned char *)initrd_start, (unsigned char *)initrd_end) && fb_display[unit].splash_data)
533
       fb_display[unit].splash_data->splash_state = splash_default & 1;
534
   }
535
   splash_registered = 1;
536
#ifdef CONFIG_PROC_FS
537
   splash_proc_register();
538
#endif
539
    }
540
    if (fb_display[unit].splash_data && fb_display[unit].var.bits_per_pixel != 16 ) {
541
        vfree(fb_display[unit].splash_data);
542
        fb_display[unit].splash_data = 0;
543
    }
544
#endif
545
505
    fbcon_setup(unit, init, !init);
546
    fbcon_setup(unit, init, !init);
506
    /* Must be done after fbcon_setup to prevent excess updates */
547
    /* Must be done after fbcon_setup to prevent excess updates */
507
    conp->vc_display_fg = &info->display_fg;
548
    conp->vc_display_fg = &info->display_fg;
508
    if (!info->display_fg)
549
    if (!info->display_fg)
509
        info->display_fg = conp;
550
        info->display_fg = conp;
Lines 516-525 Link Here
516
    struct display *p = &fb_display[unit];
557
    struct display *p = &fb_display[unit];
517
558
518
    fbcon_free_font(p);
559
    fbcon_free_font(p);
519
    p->dispsw = &fbcon_dummy;
560
    p->dispsw = &fbcon_dummy;
520
    p->conp = 0;
561
    p->conp = 0;
562
#ifdef CONFIG_FBCON_SPLASHSCREEN
563
    if (splash_registered) {
564
#ifdef CONFIG_PROC_FS
565
        splash_proc_unregister();
566
#endif
567
   splash_registered = 0;
568
    }
569
#endif
521
}
570
}
522
571
523
572
524
static int fbcon_changevar(int con)
573
static int fbcon_changevar(int con)
525
{
574
{
Lines 656-666 Link Here
656
    old_cols = conp->vc_cols;
705
    old_cols = conp->vc_cols;
657
    old_rows = conp->vc_rows;
706
    old_rows = conp->vc_rows;
658
    
707
    
659
    nr_cols = p->var.xres/fontwidth(p);
708
    nr_cols = p->var.xres/fontwidth(p);
660
    nr_rows = p->var.yres/fontheight(p);
709
    nr_rows = p->var.yres/fontheight(p);
661
    
710
#ifdef CONFIG_FBCON_SPLASHSCREEN
711
    if (p->splash_data && p->splash_data->splash_state) {
712
   nr_cols = p->splash_data->splash_text_wi / fontwidth(p);
713
   nr_rows = p->splash_data->splash_text_he / fontheight(p);
714
   logo = 0;
715
    }
716
#endif
717
662
    if (logo) {
718
    if (logo) {
663
    	/* Need to make room for the logo */
719
    	/* Need to make room for the logo */
664
	int cnt;
720
	int cnt;
665
	int step;
721
	int step;
666
    
722
    
Lines 732-741 Link Here
732
	       "supported\n", p->type, p->type_aux, p->var.bits_per_pixel);
788
	       "supported\n", p->type, p->type_aux, p->var.bits_per_pixel);
733
    p->dispsw->setup(p);
789
    p->dispsw->setup(p);
734
790
735
    p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
791
    p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
736
    p->bgcol = 0;
792
    p->bgcol = 0;
793
#ifdef CONFIG_FBCON_SPLASHSCREEN
794
    if(p->splash_data && p->splash_data->splash_state)
795
   con_remap_def_color(con, p->splash_data->splash_color << 4 | p->splash_data->splash_fg_color);
796
#endif 
797
737
798
738
    if (!init) {
799
    if (!init) {
739
	if (conp->vc_cols != nr_cols || conp->vc_rows != nr_rows)
800
	if (conp->vc_cols != nr_cols || conp->vc_rows != nr_rows)
740
	    vc_resize_con(nr_rows, nr_cols, con);
801
	    vc_resize_con(nr_rows, nr_cols, con);
741
	else if (CON_IS_VISIBLE(conp) &&
802
	else if (CON_IS_VISIBLE(conp) &&
Lines 1321-1330 Link Here
1321
	    if (count > conp->vc_rows)	/* Maximum realistic size */
1382
	    if (count > conp->vc_rows)	/* Maximum realistic size */
1322
		count = conp->vc_rows;
1383
		count = conp->vc_rows;
1323
	    if (softback_top)
1384
	    if (softback_top)
1324
	        fbcon_softback_note(conp, t, count);
1385
	        fbcon_softback_note(conp, t, count);
1325
	    if (logo_shown >= 0) goto redraw_up;
1386
	    if (logo_shown >= 0) goto redraw_up;
1387
#ifdef CONFIG_FBCON_SPLASHSCREEN
1388
       if (splash_shown) goto redraw_up;
1389
#endif
1326
	    switch (p->scrollmode & __SCROLL_YMASK) {
1390
	    switch (p->scrollmode & __SCROLL_YMASK) {
1327
	    case __SCROLL_YMOVE:
1391
	    case __SCROLL_YMOVE:
1328
		p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,
1392
		p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,
1329
				 conp->vc_cols);
1393
				 conp->vc_cols);
1330
		p->dispsw->clear(conp, p, b-count, 0, count,
1394
		p->dispsw->clear(conp, p, b-count, 0, count,
Lines 1381-1390 Link Here
1381
	    break;
1445
	    break;
1382
1446
1383
	case SM_DOWN:
1447
	case SM_DOWN:
1384
	    if (count > conp->vc_rows)	/* Maximum realistic size */
1448
	    if (count > conp->vc_rows)	/* Maximum realistic size */
1385
		count = conp->vc_rows;
1449
		count = conp->vc_rows;
1450
#ifdef CONFIG_FBCON_SPLASHSCREEN
1451
       if (splash_shown) goto redraw_down;
1452
#endif
1386
	    switch (p->scrollmode & __SCROLL_YMASK) {
1453
	    switch (p->scrollmode & __SCROLL_YMASK) {
1387
	    case __SCROLL_YMOVE:
1454
	    case __SCROLL_YMOVE:
1388
		p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count,
1455
		p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count,
1389
				 conp->vc_cols);
1456
				 conp->vc_cols);
1390
		p->dispsw->clear(conp, p, t, 0,
1457
		p->dispsw->clear(conp, p, t, 0,
Lines 1497-1515 Link Here
1497
	    fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
1564
	    fbcon_bmove_rec(p, sy+b, sx, dy+b, dx, height-b, width, y_break);
1498
	    fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
1565
	    fbcon_bmove_rec(p, sy, sx, dy, dx, b, width, y_break);
1499
	}
1566
	}
1500
	return;
1567
	return;
1501
    }
1568
    }
1569
#ifdef CONFIG_FBCON_SPLASHSCREEN
1570
   if (splash_shown && sy == dy) {
1571
   /* must use slower redraw bmove to keep background pic intact */
1572
    fbcon_redraw_bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
1573
    return;
1574
   }
1575
#endif
1502
    p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
1576
    p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height, width);
1503
}
1577
}
1504
1578
1505
1579
1506
static int fbcon_switch(struct vc_data *conp)
1580
static int fbcon_switch(struct vc_data *conp)
1507
{
1581
{
1508
    int unit = conp->vc_num;
1582
    int unit = conp->vc_num;
1509
    struct display *p = &fb_display[unit];
1583
    struct display *p = &fb_display[unit];
1510
    struct fb_info *info = p->fb_info;
1584
    struct fb_info *info = p->fb_info;
1585
#ifdef CONFIG_FBCON_SPLASHSCREEN
1586
    splash_prepare(p);
1587
#endif
1511
1588
1512
    if (softback_top) {
1589
    if (softback_top) {
1513
    	int l = fbcon_softback_size / conp->vc_size_row;
1590
    	int l = fbcon_softback_size / conp->vc_size_row;
1514
	if (softback_lines)
1591
	if (softback_lines)
1515
	    fbcon_set_origin(conp);
1592
	    fbcon_set_origin(conp);
Lines 1566-1604 Link Here
1566
1643
1567
static int fbcon_blank(struct vc_data *conp, int blank)
1644
static int fbcon_blank(struct vc_data *conp, int blank)
1568
{
1645
{
1569
    struct display *p = &fb_display[conp->vc_num];
1646
    struct display *p = &fb_display[conp->vc_num];
1570
    struct fb_info *info = p->fb_info;
1647
    struct fb_info *info = p->fb_info;
1648
#ifdef CONFIG_FBCON_SPLASHSCREEN
1649
    struct display_switch *olddispsw=NULL;
1650
    char    *oldscreen_base=NULL;
1651
#endif
1571
1652
1572
    if (blank < 0)	/* Entering graphics mode */
1653
    if (blank < 0)	/* Entering graphics mode */
1573
	return 0;
1654
	return 0;
1574
1655
1656
#ifdef CONFIG_FBCON_SPLASHSCREEN
1657
    if (p->splash_data && p->splash_data->oldscreen_base) {
1658
        oldscreen_base = p->screen_base;
1659
        p->screen_base = p->splash_data->oldscreen_base;
1660
    }
1661
    if (p->splash_data && p->splash_data->olddispsw) {
1662
        olddispsw = p->dispsw;
1663
        p->dispsw = p->splash_data->olddispsw;
1664
    }
1665
#endif
1666
1575
    fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
1667
    fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
1576
1668
1577
    if (!p->can_soft_blank) {
1669
    if (!p->can_soft_blank) {
1578
	if (blank) {
1670
	if (blank) {
1671
#ifdef CONFIG_FBCON_SPLASHSCREEN
1672
       if (p->splash_data && p->splash_data->oldscreen_base) {
1673
           oldscreen_base = p->screen_base;
1674
           p->screen_base = p->splash_data->oldscreen_base;
1675
       }
1676
       if (p->splash_data && p->splash_data->olddispsw) {
1677
           olddispsw = p->dispsw;
1678
           p->dispsw = p->splash_data->olddispsw;
1679
       }
1680
#endif
1681
1579
	    if (p->visual == FB_VISUAL_MONO01) {
1682
	    if (p->visual == FB_VISUAL_MONO01) {
1580
		if (p->screen_base)
1683
		if (p->screen_base)
1581
		    fb_memset255(p->screen_base,
1684
		    fb_memset255(p->screen_base,
1582
				 p->var.xres_virtual*p->var.yres_virtual*
1685
				 p->var.xres_virtual*p->var.yres_virtual*
1583
				 p->var.bits_per_pixel>>3);
1686
				 p->var.bits_per_pixel>>3);
1584
	    } else {
1687
	    } else {
1585
	    	unsigned short oldc;
1688
	    	unsigned short oldc;
1586
	    	u_int height;
1689
	    	u_int height;
1690
            u_int width;
1587
	    	u_int y_break;
1691
	    	u_int y_break;
1588
1692
1589
	    	oldc = conp->vc_video_erase_char;
1693
	    	oldc = conp->vc_video_erase_char;
1590
	    	conp->vc_video_erase_char &= p->charmask;
1694
	    	conp->vc_video_erase_char &= p->charmask;
1591
	    	height = conp->vc_rows;
1695
	    	height = conp->vc_rows;
1592
		y_break = p->vrows-p->yscroll;
1696
            width  = conp->vc_cols;
1697
		    y_break = p->vrows-p->yscroll;
1698
#ifdef CONFIG_FBCON_SPLASHSCREEN
1699
       if (splash_shown) {
1700
           width=p->var.xres/fontwidth(p);
1701
           height=p->var.yres/fontheight(p);
1702
       }
1703
#endif
1593
		if (height > y_break) {
1704
		if (height > y_break) {
1594
			p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, conp->vc_cols);
1705
            p->dispsw->clear(conp, p, real_y(p, 0), 0, y_break, width);
1595
			p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, conp->vc_cols);
1706
            p->dispsw->clear(conp, p, real_y(p, y_break), 0, height-y_break, width);
1596
		} else
1707
		} else
1597
			p->dispsw->clear(conp, p, real_y(p, 0), 0, height, conp->vc_cols);
1708
			p->dispsw->clear(conp, p, real_y(p, 0), 0, height, width);
1598
		conp->vc_video_erase_char = oldc;
1709
		conp->vc_video_erase_char = oldc;
1599
	    }
1710
	    }
1711
#ifdef CONFIG_FBCON_SPLASHSCREEN
1712
       if(oldscreen_base)
1713
       p->screen_base=oldscreen_base;
1714
       if(olddispsw)
1715
       p->dispsw=olddispsw;
1716
#endif
1600
	    return 0;
1717
	    return 0;
1601
	} else {
1718
	} else {
1602
	    /* Tell console.c that it has to restore the screen itself */
1719
	    /* Tell console.c that it has to restore the screen itself */
1603
	    return 1;
1720
	    return 1;
1604
	}
1721
	}
Lines 1760-1776 Link Here
1760
    }
1877
    }
1761
    fbcon_font_widths(p);
1878
    fbcon_font_widths(p);
1762
1879
1763
    if (resize) {
1880
    if (resize) {
1764
    	struct vc_data *conp = p->conp;
1881
    	struct vc_data *conp = p->conp;
1882
        __u32 xres = p->var.xres, yres = p->var.yres;
1765
	/* reset wrap/pan */
1883
	/* reset wrap/pan */
1766
	p->var.xoffset = p->var.yoffset = p->yscroll = 0;
1884
	p->var.xoffset = p->var.yoffset = p->yscroll = 0;
1767
	p->vrows = p->var.yres_virtual/h;
1885
	p->vrows = p->var.yres_virtual/h;
1768
	if ((p->var.yres % h) && (p->var.yres_virtual % h < p->var.yres % h))
1886
#ifdef CONFIG_FBCON_SPLASHSCREEN
1887
   if (p->splash_data && p->splash_data->splash_state) {
1888
       xres = p->splash_data->splash_text_wi;
1889
       yres = p->splash_data->splash_text_he;
1890
        }
1891
#endif
1892
   if ((yres % h) && (p->var.yres_virtual % h < p->var.yres % h))
1769
	    p->vrows--;
1893
	    p->vrows--;
1770
	updatescrollmode(p);
1894
	updatescrollmode(p);
1771
	vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
1895
	vc_resize_con( yres/h, xres/w, unit );
1772
        if (CON_IS_VISIBLE(conp) && softback_buf) {
1896
        if (CON_IS_VISIBLE(conp) && softback_buf) {
1773
	    int l = fbcon_softback_size / conp->vc_size_row;
1897
	    int l = fbcon_softback_size / conp->vc_size_row;
1774
	    if (l > 5)
1898
	    if (l > 5)
1775
		softback_end = softback_buf + l * conp->vc_size_row;
1899
		softback_end = softback_buf + l * conp->vc_size_row;
1776
	    else {
1900
	    else {
Lines 2186-2195 Link Here
2186
	logo_depth = 1;
2310
	logo_depth = 1;
2187
    }
2311
    }
2188
    
2312
    
2189
    if (p->fb_info->fbops->fb_rasterimg)
2313
    if (p->fb_info->fbops->fb_rasterimg)
2190
    	p->fb_info->fbops->fb_rasterimg(p->fb_info, 1);
2314
    	p->fb_info->fbops->fb_rasterimg(p->fb_info, 1);
2315
#ifdef CONFIG_FBCON_SPLASHSCREEN
2316
    if (!splash_shown) {
2317
#endif
2191
2318
2192
    for (x = 0; x < smp_num_cpus * (LOGO_W + 8) &&
2319
    for (x = 0; x < smp_num_cpus * (LOGO_W + 8) &&
2193
    	 x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
2320
    	 x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
2194
    	 
2321
    	 
2195
#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
2322
#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
Lines 2448-2458 Link Here
2448
		}
2575
		}
2449
		done = 1;
2576
		done = 1;
2450
	}
2577
	}
2451
#endif			
2578
#endif			
2452
    }
2579
    }
2453
    
2580
#ifdef CONFIG_FBCON_SPLASHSCREEN
2581
    }
2582
#endif
2583
2454
    if (p->fb_info->fbops->fb_rasterimg)
2584
    if (p->fb_info->fbops->fb_rasterimg)
2455
    	p->fb_info->fbops->fb_rasterimg(p->fb_info, 0);
2585
    	p->fb_info->fbops->fb_rasterimg(p->fb_info, 0);
2456
2586
2457
    /* Modes not yet supported: packed pixels with depth != 8 (does such a
2587
    /* Modes not yet supported: packed pixels with depth != 8 (does such a
2458
     * thing exist in reality?) */
2588
     * thing exist in reality?) */
(-)linux-2.4.21/include/video/fbcon.h (+33 lines)
Lines 40-49 Link Here
40
    void (*clear_margins)(struct vc_data *conp, struct display *p,
40
    void (*clear_margins)(struct vc_data *conp, struct display *p,
41
			  int bottom_only);
41
			  int bottom_only);
42
    unsigned int fontwidthmask;      /* 1 at (1 << (width - 1)) if width is supported */
42
    unsigned int fontwidthmask;      /* 1 at (1 << (width - 1)) if width is supported */
43
}; 
43
}; 
44
44
45
#ifdef CONFIG_FBCON_SPLASHSCREEN
46
struct splash_data {
47
   int splash_state;           /* show splash? */
48
   int splash_color;           /* transparent color */
49
   int splash_fg_color;        /* foreground color */
50
   int splash_width;           /* width of image */
51
   int splash_height;          /* height of image */
52
   int splash_text_xo;         /* text area origin */
53
   int splash_text_yo;
54
   int splash_text_wi;         /* text area size */ 
55
   int splash_text_he;
56
   int splash_showtext;        /* silent/verbose mode */
57
   int splash_boxcount;
58
   int splash_percent;
59
   int splash_overpaintok;     /* is it ok to overpaint boxes */
60
   int splash_palcnt;
61
   struct display_switch *olddispsw;   /* old dispsw, normally &fbcon_cfb16*/
62
   char    *oldscreen_base;        /* pointer to top of virtual screen */    
63
   unsigned char *splash_boxes;
64
   unsigned char *splash_jpeg;     /* jpeg */
65
   unsigned char *splash_palette;      /* palette for 8-bit */
66
67
   int splash_dosilent;        /* show silent jpeg */
68
   unsigned char *splash_silentjpeg;
69
   unsigned char *splash_sboxes;
70
   int splash_sboxcount;
71
};
72
#endif
73
45
extern struct display_switch fbcon_dummy;
74
extern struct display_switch fbcon_dummy;
46
75
47
   /*
76
   /*
48
    *    This is the interface between the low-level console driver and the
77
    *    This is the interface between the low-level console driver and the
49
    *    low-level frame buffer device
78
    *    low-level frame buffer device
Lines 93-102 Link Here
93
    int userfont;                   /* != 0 if fontdata kmalloc()ed */
122
    int userfont;                   /* != 0 if fontdata kmalloc()ed */
94
    u_short scrollmode;             /* Scroll Method */
123
    u_short scrollmode;             /* Scroll Method */
95
    short yscroll;                  /* Hardware scrolling */
124
    short yscroll;                  /* Hardware scrolling */
96
    unsigned char fgshift, bgshift;
125
    unsigned char fgshift, bgshift;
97
    unsigned short charmask;        /* 0xff or 0x1ff */
126
    unsigned short charmask;        /* 0xff or 0x1ff */
127
#ifdef CONFIG_FBCON_SPLASHSCREEN
128
    struct splash_data *splash_data;
129
#endif
130
98
};
131
};
99
132
100
/* drivers/video/fbcon.c */
133
/* drivers/video/fbcon.c */
101
extern struct display fb_display[MAX_NR_CONSOLES];
134
extern struct display fb_display[MAX_NR_CONSOLES];
102
extern char con2fb_map[MAX_NR_CONSOLES];
135
extern char con2fb_map[MAX_NR_CONSOLES];
(-)linux-2.4.21/kernel/panic.c (-1 / +13 lines)
Lines 73-82 Link Here
73
		/*
73
		/*
74
	 	 * Delay timeout seconds before rebooting the machine. 
74
	 	 * Delay timeout seconds before rebooting the machine. 
75
		 * We can't use the "normal" timers since we just panicked..
75
		 * We can't use the "normal" timers since we just panicked..
76
	 	 */
76
	 	 */
77
		printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
77
		printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
78
#ifdef CONFIG_FBCON_SPLASHSCREEN
79
       {
80
           extern int splash_verbose(void);
81
           (void)splash_verbose();
82
       }
83
#endif
78
		mdelay(panic_timeout*1000);
84
		mdelay(panic_timeout*1000);
79
		/*
85
		/*
80
		 *	Should we run the reboot notifier. For the moment Im
86
		 *	Should we run the reboot notifier. For the moment Im
81
		 *	choosing not too. It might crash, be corrupt or do
87
		 *	choosing not too. It might crash, be corrupt or do
82
		 *	more harm than good for other reasons.
88
		 *	more harm than good for other reasons.
Lines 92-102 Link Here
92
	}
98
	}
93
#endif
99
#endif
94
#if defined(CONFIG_ARCH_S390)
100
#if defined(CONFIG_ARCH_S390)
95
        disabled_wait(caller);
101
        disabled_wait(caller);
96
#endif
102
#endif
97
	sti();
103
    sti();
104
#ifdef CONFIG_FBCON_SPLASHSCREEN
105
    {
106
        extern int splash_verbose(void);
107
        (void)splash_verbose();
108
    }
109
#endif
98
	for(;;) {
110
	for(;;) {
99
#if defined(CONFIG_X86) && defined(CONFIG_VT) 
111
#if defined(CONFIG_X86) && defined(CONFIG_VT) 
100
		extern void panic_blink(void);
112
		extern void panic_blink(void);
101
		panic_blink(); 
113
		panic_blink(); 
102
#endif
114
#endif

Return to bug 23369