View | Details | Raw Unified | Return to bug 23783
Collapse All | Expand All

(-)linux-2.6.35/drivers/char/keyboard.c (+9 lines)
Lines 1185-1190 Link Here
1185
				pr_warning("can't emulate rawmode for keycode %d\n",
1185
				pr_warning("can't emulate rawmode for keycode %d\n",
1186
					   keycode);
1186
					   keycode);
1187
1187
1188
#ifdef CONFIG_BOOTSPLASH
1189
	/* This code has to be redone for some non-x86 platforms */
1190
	if (down == 1 && (keycode == 0x3c || keycode == 0x01)) {        /* F2 and ESC on PC keyboard */
1191
		extern int splash_verbose(void);
1192
		if (splash_verbose())
1193
			return; 
1194
	}       
1195
#endif
1196
1188
#ifdef CONFIG_SPARC
1197
#ifdef CONFIG_SPARC
1189
	if (keycode == KEY_A && sparc_l1_a_state) {
1198
	if (keycode == KEY_A && sparc_l1_a_state) {
1190
		sparc_l1_a_state = false;
1199
		sparc_l1_a_state = false;
(-)linux-2.6.35/drivers/char/n_tty.c (+9 lines)
Lines 1779-1784 Link Here
1779
			tty->minimum_to_wake = (minimum - (b - buf));
1779
			tty->minimum_to_wake = (minimum - (b - buf));
1780
1780
1781
		if (!input_available_p(tty, 0)) {
1781
		if (!input_available_p(tty, 0)) {
1782
#ifdef CONFIG_BOOTSPLASH
1783
			if (file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,0) ||
1784
			    file->f_dentry->d_inode->i_rdev == MKDEV(TTY_MAJOR,1) ||
1785
			    file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,0) ||
1786
			    file->f_dentry->d_inode->i_rdev == MKDEV(TTYAUX_MAJOR,1)) {
1787
				extern int splash_verbose(void);
1788
				(void)splash_verbose();
1789
			}
1790
#endif
1782
			if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
1791
			if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
1783
				retval = -EIO;
1792
				retval = -EIO;
1784
				break;
1793
				break;
(-)linux-2.6.35/drivers/char/vt.c (+25 lines)
Lines 4097-4102 Link Here
4097
	}
4097
	}
4098
}
4098
}
4099
4099
4100
#ifdef CONFIG_BOOTSPLASH
4101
void con_remap_def_color(struct vc_data *vc, int new_color)
4102
{
4103
       unsigned short *sbuf = vc->vc_screenbuf;
4104
       unsigned c, len = vc->vc_screenbuf_size >> 1;
4105
       int old_color;
4106
4107
       if (sbuf) {
4108
	       old_color = vc->vc_def_color << 8;
4109
	       new_color <<= 8;
4110
	       while(len--) {
4111
		       c = *sbuf;
4112
		       if (((c ^ old_color) & 0xf000) == 0)
4113
			       *sbuf ^= (old_color ^ new_color) & 0xf000; 
4114
		       if (((c ^ old_color) & 0x0f00) == 0)
4115
			       *sbuf ^= (old_color ^ new_color) & 0x0f00;
4116
		       sbuf++;
4117
	       }
4118
	       new_color >>= 8;
4119
       }
4120
       vc->vc_def_color = vc->vc_color = new_color;
4121
       update_attr(vc);
4122
}
4123
#endif
4124
4100
/*
4125
/*
4101
 *	Visible symbols for modules
4126
 *	Visible symbols for modules
4102
 */
4127
 */
(-)linux-2.6.35/drivers/video/bootsplash/bootsplash.c (+983 lines)
Line 0 Link Here
1
/* 
2
 *           linux/drivers/video/bootsplash/bootsplash.c - 
3
 *                 splash screen handling functions.
4
 *	
5
 *	(w) 2001-2004 by Volker Poplawski, <volker@poplawski.de>,
6
 * 		    Stefan Reinauer, <stepan@suse.de>,
7
 * 		    Steffen Winterfeldt, <snwint@suse.de>,
8
 *                  Michael Schroeder <mls@suse.de>
9
 * 		    
10
 *        Ideas & SuSE screen work by Ken Wimer, <wimer@suse.de>
11
 *
12
 *  For more information on this code check http://www.bootsplash.org/
13
 */
14
15
#include <linux/module.h>
16
#include <linux/types.h>
17
#include <linux/fb.h>
18
#include <linux/vt_kern.h>
19
#include <linux/vmalloc.h>
20
#include <linux/unistd.h>
21
#include <linux/syscalls.h>
22
23
#include <asm/irq.h>
24
#include <asm/system.h>
25
26
#include "../console/fbcon.h"
27
#include "bootsplash.h"
28
#include "decode-jpg.h"
29
30
/* extern struct fb_ops vesafb_ops; */
31
extern signed char con2fb_map[MAX_NR_CONSOLES];
32
33
#define SPLASH_VERSION "3.1.6-2004/03/31"
34
35
/* These errors have to match fbcon-jpegdec.h */
36
static unsigned char *jpg_errors[] = {
37
	"no SOI found", 
38
	"not 8 bit", 
39
	"height mismatch", 
40
	"width mismatch",
41
	"bad width or height", 
42
	"too many COMPPs", 
43
	"illegal HV", 
44
	"quant table selector",
45
	"picture is not YCBCR 221111",
46
	"unknow CID in scan",
47
	"dct not sequential",
48
	"wrong marker",
49
	"no EOI",
50
	"bad tables",
51
	"depth mismatch"
52
};
53
54
static struct jpeg_decdata *decdata = 0; /* private decoder data */
55
56
static int splash_registered = 0;
57
static int splash_usesilent = 0;	/* shall we display the silentjpeg? */
58
int splash_default = 0xf01;
59
60
static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth);
61
62
static int __init splash_setup(char *options)
63
{
64
	if(!strncmp("silent", options, 6)) {
65
		printk(KERN_INFO "bootsplash: silent mode.\n");
66
		splash_usesilent = 1;
67
		/* skip "silent," */
68
		if (strlen(options) == 6)
69
			return 0;
70
		options += 7;
71
	}
72
	if(!strncmp("verbose", options, 7)) {
73
		printk(KERN_INFO "bootsplash: verbose mode.\n");
74
		splash_usesilent = 0;
75
		return 0;
76
	}
77
	splash_default = simple_strtoul(options, NULL, 0);
78
	return 0;
79
}
80
81
__setup("splash=", splash_setup);
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
    unsigned int stipple[32], sti, stin, stinn, stixs, stixe, stiys, stiye;
126
    int xs, xe, ys, ye, xo, yo;
127
128
    if (num == 0)
129
	return;
130
    bufend = buf + num * 12;
131
    stipple[0] = 0xffffffff;
132
    stin = 1;
133
    stinn = 0;
134
    stixs = stixe = 0;
135
    stiys = stiye = 0;
136
    while(buf < bufend) {
137
	doblend = 0;
138
	buf += boxextract(buf, data1, cols1, &doblend);
139
	if (data1[0] == 32767 && data1[1] == 32767) {
140
	    /* box stipple */
141
	    if (stinn == 32)
142
		continue;
143
	    if (stinn == 0) {
144
		stixs = data1[2];
145
		stixe = data1[3];
146
		stiys = stiye = 0;
147
	    } else if (stinn == 4) {
148
		stiys = data1[2];
149
		stiye = data1[3];
150
	    }
151
	    stipple[stinn++] = (cols1[ 0] << 24) | (cols1[ 1] << 16) | (cols1[ 2] << 8) | cols1[ 3] ;
152
	    stipple[stinn++] = (cols1[ 4] << 24) | (cols1[ 5] << 16) | (cols1[ 6] << 8) | cols1[ 7] ;
153
	    stipple[stinn++] = (cols1[ 8] << 24) | (cols1[ 9] << 16) | (cols1[10] << 8) | cols1[11] ;
154
	    stipple[stinn++] = (cols1[12] << 24) | (cols1[13] << 16) | (cols1[14] << 8) | cols1[15] ;
155
	    stin = stinn;
156
	    continue;
157
	}
158
	stinn = 0;
159
	if (data1[0] > 32767)
160
	    buf += boxextract(buf, data2, cols2, &doblend);
161
	if (data1[0] == 32767 && data1[1] == 32766) {
162
	    /* box copy */
163
	    i = 12 * (short)data1[3];
164
	    doblend = 0;
165
	    i += boxextract(buf + i, data1, cols1, &doblend);
166
	    if (data1[0] > 32767)
167
		boxextract(buf + i, data2, cols2, &doblend);
168
	}
169
	if (data1[0] == 32767)
170
	    continue;
171
	if (data1[2] > 32767) {
172
	    if (overpaint)
173
		continue;
174
	    data1[2] = ~data1[2];
175
	}
176
	if (data1[3] > 32767) {
177
	    if (percent == 65536)
178
		continue;
179
	    data1[3] = ~data1[3];
180
	}
181
	if (data1[0] > 32767) {
182
	    data1[0] = ~data1[0];
183
	    for (i = 0; i < 4; i++)
184
		data1[i] = (data1[i] * (65536 - percent) + data2[i] * percent) >> 16;
185
	    for (i = 0; i < 16; i++)
186
		cols1[i] = (cols1[i] * (65536 - percent) + cols2[i] * percent) >> 16;
187
	}
188
	*(unsigned int *)cols2 = *(unsigned int *)cols1;
189
	a = cols2[3];
190
	if (a == 0 && !doblend)
191
	    continue;
192
193
	if (stixs >= 32768) {
194
	    xo = xs = (stixs ^ 65535) + data1[0];
195
	    xe = stixe ? stixe + data1[0] : data1[2];
196
	} else if (stixe >= 32768) {
197
	    xs = stixs ? data1[2] - stixs : data1[0];
198
	    xe = data1[2] - (stixe ^ 65535);
199
	    xo = xe + 1;
200
	} else {
201
	    xo = xs = stixs;
202
	    xe = stixe ? stixe : data1[2];
203
	}
204
	if (stiys >= 32768) {
205
	    yo = ys = (stiys ^ 65535) + data1[1];
206
	    ye = stiye ? stiye + data1[1] : data1[3];
207
	} else if (stiye >= 32768) {
208
	    ys = stiys ? data1[3] - stiys : data1[1];
209
	    ye = data1[3] - (stiye ^ 65535);
210
	    yo = ye + 1;
211
	} else {
212
	    yo = ys = stiys;
213
	    ye = stiye ? stiye : data1[3];
214
	}
215
	xo = 32 - (xo & 31);
216
	yo = stin - (yo % stin);
217
	if (xs < data1[0])
218
	    xs = data1[0];
219
	if (xe > data1[2])
220
	    xe = data1[2];
221
	if (ys < data1[1])
222
	    ys = data1[1];
223
	if (ye > data1[3])
224
	    ye = data1[3];
225
226
	for (y = ys; y <= ye; y++) {
227
	    sti = stipple[(y + yo) % stin];
228
	    x = (xs + xo) & 31;
229
	    if (x)
230
		sti = (sti << x) | (sti >> (32 - x));
231
	    if (doblend) {
232
		if ((p = data1[3] - data1[1]) != 0)
233
		    p = ((y - data1[1]) << 16) / p;
234
		for (i = 0; i < 8; i++)
235
		    cols2[i + 8] = (cols1[i] * (65536 - p) + cols1[i + 8] * p) >> 16;
236
	    }
237
	    add = (xs & 1);
238
	    add ^= (add ^ y) & 1 ? 1 : 3;		/* 2x2 ordered dithering */
239
	    picp = (unsigned short *)(pic + xs * 2 + y * bytes);
240
	    for (x = xs; x <= xe; x++) {
241
		if (!(sti & 0x80000000)) {
242
		    sti <<= 1;
243
		    picp++;
244
		    add ^= 3;
245
		    continue;
246
		}
247
		sti = (sti << 1) | 1;
248
		if (doblend) {
249
		    if ((p = data1[2] - data1[0]) != 0)
250
			p = ((x - data1[0]) << 16) / p;
251
		    for (i = 0; i < 4; i++)
252
			cols2[i] = (cols2[i + 8] * (65536 - p) + cols2[i + 12] * p) >> 16;
253
		    a = cols2[3];
254
		}
255
		r = cols2[0];
256
		g = cols2[1];
257
		b = cols2[2];
258
		if (a != 255) {
259
		    i = *picp;
260
		    r = ((i >> 8 & 0xf8) * (255 - a) + r * a) / 255;
261
		    g = ((i >> 3 & 0xfc) * (255 - a) + g * a) / 255;
262
		    b = ((i << 3 & 0xf8) * (255 - a) + b * a) / 255;
263
		}
264
  #define CLAMP(x) ((x) >= 256 ? 255 : (x))
265
		i = ((CLAMP(r + add*2+1) & 0xf8) <<  8) |
266
		    ((CLAMP(g + add    ) & 0xfc) <<  3) |
267
		    ((CLAMP(b + add*2+1)       ) >>  3);
268
		*picp++ = i;
269
		add ^= 3;
270
	    }
271
	}
272
    }
273
}
274
275
static int splash_check_jpeg(unsigned char *jpeg, int width, int height, int depth)
276
{
277
    int size, err;
278
    unsigned char *mem;
279
280
    size = ((width + 15) & ~15) * ((height + 15) & ~15) * (depth >> 3);
281
    mem = vmalloc(size);
282
    if (!mem) {
283
	printk(KERN_INFO "bootsplash: no memory for decoded picture.\n");
284
	return -1;
285
    }
286
    if (!decdata)
287
	decdata = vmalloc(sizeof(*decdata));
288
    if ((err = jpeg_decode(jpeg, mem, ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata)))
289
	  printk(KERN_INFO "bootsplash: error while decompressing picture: %s (%d)\n",jpg_errors[err - 1], err);
290
    vfree(mem);
291
    return err ? -1 : 0;
292
}
293
294
static void splash_free(struct vc_data *vc, struct fb_info *info)
295
{
296
    if (!vc->vc_splash_data)
297
	return;
298
    if (info->silent_screen_base)
299
	    info->screen_base = info->silent_screen_base;
300
    info->silent_screen_base = 0;
301
    if (vc->vc_splash_data->splash_silentjpeg)
302
	    vfree(vc->vc_splash_data->splash_sboxes);
303
    vfree(vc->vc_splash_data);
304
    vc->vc_splash_data = 0;
305
    info->splash_data = 0;
306
}
307
308
static int splash_mkpenguin(struct splash_data *data, int pxo, int pyo, int pwi, int phe, int pr, int pg, int pb)
309
{
310
    unsigned char *buf;
311
    int i;
312
313
    if (pwi ==0 || phe == 0)
314
	return 0;
315
    buf = (unsigned char *)data + sizeof(*data);
316
    pwi += pxo - 1;
317
    phe += pyo - 1;
318
    *buf++ = pxo;
319
    *buf++ = pxo >> 8;
320
    *buf++ = pyo;
321
    *buf++ = pyo >> 8;
322
    *buf++ = pwi;
323
    *buf++ = pwi >> 8;
324
    *buf++ = phe;
325
    *buf++ = phe >> 8;
326
    *buf++ = pr;
327
    *buf++ = pg;
328
    *buf++ = pb;
329
    *buf++ = 0;
330
    for (i = 0; i < 12; i++, buf++)
331
	*buf = buf[-12];
332
    buf[-24] ^= 0xff;
333
    buf[-23] ^= 0xff;
334
    buf[-1] = 0xff;
335
    return 2;
336
}
337
338
static const int splash_offsets[3][16] = {
339
    /* len, unit, size, state, fgcol, col, xo, yo, wi, he
340
       boxcnt, ssize, sboxcnt, percent, overok, palcnt */
341
    /* V1 */
342
    {   20,   -1,   16,    -1,    -1,  -1,  8, 10, 12, 14,
343
           -1,    -1,      -1,      -1,     -1,     -1 },
344
    /* V2 */
345
    {   35,    8,   12,     9,    10,  11, 16, 18, 20, 22,
346
           -1,    -1,      -1,      -1,     -1,     -1 },
347
    /* V3 */
348
    {   38,    8,   12,     9,    10,  11, 16, 18, 20, 22,
349
           24,    28,      32,      34,     36,     37 },
350
};
351
352
#define SPLASH_OFF_LEN     offsets[0]
353
#define SPLASH_OFF_UNIT    offsets[1]
354
#define SPLASH_OFF_SIZE    offsets[2]
355
#define SPLASH_OFF_STATE   offsets[3]
356
#define SPLASH_OFF_FGCOL   offsets[4]
357
#define SPLASH_OFF_COL     offsets[5]
358
#define SPLASH_OFF_XO      offsets[6]
359
#define SPLASH_OFF_YO      offsets[7]
360
#define SPLASH_OFF_WI      offsets[8]
361
#define SPLASH_OFF_HE      offsets[9]
362
#define SPLASH_OFF_BOXCNT  offsets[10]
363
#define SPLASH_OFF_SSIZE   offsets[11]
364
#define SPLASH_OFF_SBOXCNT offsets[12]
365
#define SPLASH_OFF_PERCENT offsets[13]
366
#define SPLASH_OFF_OVEROK  offsets[14]
367
#define SPLASH_OFF_PALCNT  offsets[15]
368
369
static inline int splash_getb(unsigned char *pos, int off)
370
{
371
    return off == -1 ? 0 : pos[off];
372
}
373
374
static inline int splash_gets(unsigned char *pos, int off)
375
{
376
    return off == -1 ? 0 : pos[off] | pos[off + 1] << 8;
377
}
378
379
static inline int splash_geti(unsigned char *pos, int off)
380
{
381
    return off == -1 ? 0 :
382
           pos[off] | pos[off + 1] << 8 | pos[off + 2] << 16 | pos[off + 3] << 24;
383
}
384
385
static int splash_getraw(unsigned char *start, unsigned char *end, int *update)
386
{
387
    unsigned char *ndata;
388
    int version;
389
    int splash_size;
390
    int unit;
391
    int width, height;
392
    int silentsize;
393
    int boxcnt;
394
    int sboxcnt;
395
    int palcnt;
396
    int i, len;
397
    const int *offsets;
398
    struct vc_data *vc;
399
    struct fb_info *info;
400
    struct splash_data *sd;
401
402
    if (update)
403
	*update = -1;
404
405
    if (!update || start[7] < '2' || start[7] > '3' || splash_geti(start, 12) != (int)0xffffffff)
406
	printk(KERN_INFO "bootsplash %s: looking for picture...", SPLASH_VERSION);
407
408
    for (ndata = start; ndata < end; ndata++) {
409
	if (ndata[0] != 'B' || ndata[1] != 'O' || ndata[2] != 'O' || ndata[3] != 'T')
410
	    continue;
411
	if (ndata[4] != 'S' || ndata[5] != 'P' || ndata[6] != 'L' || ndata[7] < '1' || ndata[7] > '3')
412
	    continue;
413
	version = ndata[7] - '0';
414
	offsets = splash_offsets[version - 1];
415
	len = SPLASH_OFF_LEN;
416
	unit = splash_getb(ndata, SPLASH_OFF_UNIT);
417
	if (unit >= MAX_NR_CONSOLES)
418
	    continue;
419
	if (unit) {
420
		vc_allocate(unit);
421
	}
422
	vc = vc_cons[unit].d;
423
	info = registered_fb[(int)con2fb_map[unit]];
424
	width = info->var.xres;
425
	height = info->var.yres;
426
	splash_size = splash_geti(ndata, SPLASH_OFF_SIZE);
427
	if (splash_size == (int)0xffffffff && version > 1) {
428
	    if ((sd = vc->vc_splash_data) != 0) {
429
		int up = 0;
430
		i = splash_getb(ndata, SPLASH_OFF_STATE);
431
		if (i != 255) {
432
		    sd->splash_state = i;
433
		    up = -1;
434
		}
435
		i = splash_getb(ndata, SPLASH_OFF_FGCOL);
436
		if (i != 255) {
437
		    sd->splash_fg_color = i;
438
		    up = -1;
439
		}
440
		i = splash_getb(ndata, SPLASH_OFF_COL);
441
		if (i != 255) {
442
		    sd->splash_color = i;
443
		    up = -1;
444
		}
445
		boxcnt = sboxcnt = 0;
446
		if (ndata + len <= end) {
447
		    boxcnt = splash_gets(ndata, SPLASH_OFF_BOXCNT);
448
		    sboxcnt = splash_gets(ndata, SPLASH_OFF_SBOXCNT);
449
		}
450
		if (boxcnt) {
451
		    i = splash_gets(ndata, len);
452
		    if (boxcnt + i <= sd->splash_boxcount && ndata + len + 2 + boxcnt * 12 <= end) {
453
454
			if (splash_geti(ndata, len + 2) != 0x7ffd7fff || !memcmp(ndata + len + 2, sd->splash_boxes + i * 12, 8)) {
455
456
			    memcpy(sd->splash_boxes + i * 12, ndata + len + 2, boxcnt * 12);
457
			    up |= 1;
458
			}
459
		    }
460
		    len += boxcnt * 12 + 2;
461
		}
462
		if (sboxcnt) {
463
		    i = splash_gets(ndata, len);
464
		    if (sboxcnt + i <= sd->splash_sboxcount && ndata + len + 2 + sboxcnt * 12 <= end) {
465
			if (splash_geti(ndata, len + 2) != 0x7ffd7fff || !memcmp(ndata + len + 2, sd->splash_sboxes + i * 12, 8)) {
466
			    memcpy(sd->splash_sboxes + i * 12, ndata + len + 2, sboxcnt * 12);
467
			    up |= 2;
468
			}
469
		    }
470
		}
471
		if (update)
472
		    *update = up;
473
	    }
474
	    return unit;
475
	}
476
	if (splash_size == 0) {
477
	    printk(KERN_INFO"...found, freeing memory.\n");
478
	    if (vc->vc_splash_data)
479
		splash_free(vc, info);
480
	    return unit;
481
	}
482
	boxcnt = splash_gets(ndata, SPLASH_OFF_BOXCNT);
483
	palcnt = 3 * splash_getb(ndata, SPLASH_OFF_PALCNT);
484
	if (ndata + len + splash_size > end) {
485
	    printk(KERN_INFO "...found, but truncated!\n");
486
	    return -1;
487
	}
488
	if (!jpeg_check_size(ndata + len + boxcnt * 12 + palcnt, width, height)) {
489
	    ndata += len + splash_size - 1;
490
	    continue;
491
	}
492
	if (splash_check_jpeg(ndata + len + boxcnt * 12 + palcnt, width, height, info->var.bits_per_pixel))
493
	    return -1;
494
	silentsize = splash_geti(ndata, SPLASH_OFF_SSIZE);
495
	if (silentsize)
496
	    printk(KERN_INFO" silentjpeg size %d bytes,", silentsize);
497
	if (silentsize >= splash_size) {
498
	    printk(KERN_INFO " bigger than splashsize!\n");
499
	    return -1;
500
	}
501
	splash_size -= silentsize;
502
	if (!splash_usesilent)
503
	    silentsize = 0;
504
	else if (height * 2 * info->fix.line_length > info->fix.smem_len) {
505
	    printk(KERN_INFO " does not fit into framebuffer.\n");
506
	    silentsize = 0;
507
	}
508
	sboxcnt = splash_gets(ndata, SPLASH_OFF_SBOXCNT);
509
	if (silentsize) {
510
	    unsigned char *simage = ndata + len + splash_size + 12 * sboxcnt;
511
	    if (!jpeg_check_size(simage, width, height) ||
512
		splash_check_jpeg(simage, width, height, info->var.bits_per_pixel)) {
513
		    printk(KERN_INFO " error in silent jpeg.\n");
514
		    silentsize = 0;
515
		}
516
	}
517
	if (vc->vc_splash_data)
518
	    splash_free(vc, info);
519
	vc->vc_splash_data = sd = vmalloc(sizeof(*sd) + splash_size + (version < 3 ? 2 * 12 : 0));
520
	if (!sd)
521
	    break;
522
	sd->splash_silentjpeg = 0;
523
	sd->splash_sboxes = 0;
524
	sd->splash_sboxcount = 0;
525
	if (silentsize) {
526
	    sd->splash_silentjpeg = vmalloc(silentsize);
527
	    if (sd->splash_silentjpeg) {
528
		memcpy(sd->splash_silentjpeg, ndata + len + splash_size, silentsize);
529
		sd->splash_sboxes = vc->vc_splash_data->splash_silentjpeg;
530
		sd->splash_silentjpeg += 12 * sboxcnt;
531
		sd->splash_sboxcount = sboxcnt;
532
	    }
533
	}
534
	sd->splash_state = splash_getb(ndata, SPLASH_OFF_STATE);
535
	sd->splash_fg_color = splash_getb(ndata, SPLASH_OFF_FGCOL);
536
	sd->splash_color = splash_getb(ndata, SPLASH_OFF_COL);
537
	sd->splash_overpaintok = splash_getb(ndata, SPLASH_OFF_OVEROK);
538
	sd->splash_text_xo = splash_gets(ndata, SPLASH_OFF_XO);
539
	sd->splash_text_yo = splash_gets(ndata, SPLASH_OFF_YO);
540
	sd->splash_text_wi = splash_gets(ndata, SPLASH_OFF_WI);
541
	sd->splash_text_he = splash_gets(ndata, SPLASH_OFF_HE);
542
	sd->splash_percent = splash_gets(ndata, SPLASH_OFF_PERCENT);
543
	if (version == 1) {
544
	    sd->splash_text_xo *= 8;
545
	    sd->splash_text_wi *= 8;
546
	    sd->splash_text_yo *= 16;
547
	    sd->splash_text_he *= 16;
548
	    sd->splash_color    = (splash_default >> 8) & 0x0f;
549
	    sd->splash_fg_color = (splash_default >> 4) & 0x0f;
550
	    sd->splash_state    = splash_default & 1;
551
	}
552
	if (sd->splash_text_xo + sd->splash_text_wi > width || sd->splash_text_yo + sd->splash_text_he > height) {
553
	    splash_free(vc, info);
554
	    printk(KERN_INFO " found, but has oversized text area!\n");
555
	    return -1;
556
	}
557
/*	if (!vc_cons[unit].d || info->fbops != &vesafb_ops) {
558
	    splash_free(vc, info);
559
	    printk(KERN_INFO " found, but framebuffer can't handle it!\n");
560
	    return -1;
561
	} */
562
	printk(KERN_INFO "...found (%dx%d, %d bytes, v%d).\n", width, height, splash_size, version);
563
	if (version == 1) {
564
	    printk(KERN_WARNING "bootsplash: Using deprecated v1 header. Updating your splash utility recommended.\n");
565
	    printk(KERN_INFO    "bootsplash: Find the latest version at http://www.bootsplash.org/\n");
566
	}
567
568
	/* fake penguin box for older formats */
569
	if (version == 1)
570
	    boxcnt = splash_mkpenguin(sd, sd->splash_text_xo + 10, sd->splash_text_yo + 10, sd->splash_text_wi - 20, sd->splash_text_he - 20, 0xf0, 0xf0, 0xf0);
571
	else if (version == 2)
572
	    boxcnt = splash_mkpenguin(sd, splash_gets(ndata, 24), splash_gets(ndata, 26), splash_gets(ndata, 28), splash_gets(ndata, 30), splash_getb(ndata, 32), splash_getb(ndata, 33), splash_getb(ndata, 34));
573
574
	memcpy((char *)sd + sizeof(*sd) + (version < 3 ? boxcnt * 12 : 0), ndata + len, splash_size);
575
	sd->splash_boxcount = boxcnt;
576
	sd->splash_boxes = (unsigned char *)sd + sizeof(*sd);
577
	sd->splash_palette = sd->splash_boxes + boxcnt * 12;
578
	sd->splash_jpeg = sd->splash_palette + palcnt;
579
	sd->splash_palcnt = palcnt / 3;
580
	sd->splash_dosilent = sd->splash_silentjpeg != 0;
581
	return unit;
582
    }
583
    printk(KERN_INFO "...no good signature found.\n");
584
    return -1;
585
}
586
587
int splash_verbose(void) 
588
{
589
    struct vc_data *vc;
590
    struct fb_info *info;
591
592
    if (!splash_usesilent)
593
        return 0;
594
595
    vc = vc_cons[0].d;
596
597
    if (!vc || !vc->vc_splash_data || !vc->vc_splash_data->splash_state)
598
	return 0;
599
    if (fg_console != vc->vc_num)
600
	return 0;
601
    if (!vc->vc_splash_data->splash_silentjpeg || !vc->vc_splash_data->splash_dosilent)
602
	return 0;
603
    vc->vc_splash_data->splash_dosilent = 0;
604
    info = registered_fb[(int)con2fb_map[0]];
605
    if (!info->silent_screen_base)
606
	return 0;
607
    splashcopy(info->silent_screen_base, info->screen_base, info->var.yres, info->var.xres, info->fix.line_length, info->fix.line_length);
608
    info->screen_base = info->silent_screen_base;
609
    info->silent_screen_base = 0;
610
    return 1;
611
}
612
613
static void splash_off(struct fb_info *info)
614
{
615
	if (info->silent_screen_base)
616
		info->screen_base = info->silent_screen_base;
617
	info->silent_screen_base = 0;
618
	info->splash_data = 0;
619
	if (info->splash_pic)
620
		vfree(info->splash_pic);
621
	info->splash_pic = 0;
622
	info->splash_pic_size = 0;
623
}
624
625
int splash_prepare(struct vc_data *vc, struct fb_info *info)
626
{
627
	int err;
628
        int width, height, depth, size, sbytes;
629
630
	if (!vc->vc_splash_data || !vc->vc_splash_data->splash_state) {
631
		if (decdata)
632
			vfree(decdata);
633
		decdata = 0;
634
		splash_off(info);
635
		return -1;
636
	}
637
638
        width = info->var.xres;
639
        height = info->var.yres;
640
        depth = info->var.bits_per_pixel;
641
	if (depth != 16) {	/* Other targets might need fixing */
642
		splash_off(info);
643
		return -2;
644
	}
645
646
	sbytes = ((width + 15) & ~15) * (depth >> 3);
647
	size = sbytes * ((height + 15) & ~15);
648
	if (size != info->splash_pic_size)
649
		splash_off(info);
650
	if (!info->splash_pic)
651
		info->splash_pic = vmalloc(size);
652
653
	if (!info->splash_pic) {
654
		printk(KERN_INFO "bootsplash: not enough memory.\n");
655
		splash_off(info);
656
		return -3;
657
	}
658
659
	if (!decdata)
660
		decdata = vmalloc(sizeof(*decdata));
661
662
	if (vc->vc_splash_data->splash_silentjpeg && vc->vc_splash_data->splash_dosilent) {
663
		/* fill area after framebuffer with other jpeg */
664
		if ((err = jpeg_decode(vc->vc_splash_data->splash_silentjpeg, info->splash_pic, 
665
			 ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
666
			printk(KERN_INFO "bootsplash: error while decompressing silent picture: %s (%d)\n", jpg_errors[err - 1], err);
667
			if (info->silent_screen_base)
668
				info->screen_base = info->silent_screen_base;
669
			vc->vc_splash_data->splash_dosilent = 0;
670
		} else {
671
			if (vc->vc_splash_data->splash_sboxcount)
672
				boxit(info->splash_pic, sbytes, vc->vc_splash_data->splash_sboxes, 
673
					vc->vc_splash_data->splash_sboxcount, vc->vc_splash_data->splash_percent, 0);
674
675
			if (!info->silent_screen_base)
676
				info->silent_screen_base = info->screen_base;
677
			splashcopy(info->silent_screen_base, info->splash_pic, info->var.yres, info->var.xres, info->fix.line_length, sbytes);
678
			info->screen_base = info->silent_screen_base + info->fix.line_length * info->var.yres;
679
		}
680
	} else if (info->silent_screen_base)
681
		info->screen_base = info->silent_screen_base;
682
683
	if ((err = jpeg_decode(vc->vc_splash_data->splash_jpeg, info->splash_pic, 
684
		 ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
685
		printk(KERN_INFO "bootsplash: error while decompressing picture: %s (%d) .\n", jpg_errors[err - 1], err);
686
		splash_off(info);
687
		return -4;
688
	}
689
	info->splash_pic_size = size;
690
	info->splash_bytes = sbytes;
691
	if (vc->vc_splash_data->splash_boxcount)
692
		boxit(info->splash_pic, sbytes, vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount, vc->vc_splash_data->splash_percent, 0);
693
	if (vc->vc_splash_data->splash_state)
694
		info->splash_data = vc->vc_splash_data;
695
	else
696
		splash_off(info);
697
	return 0;
698
}
699
700
701
#ifdef CONFIG_PROC_FS
702
703
#include <linux/proc_fs.h>
704
705
static int splash_read_proc(char *buffer, char **start, off_t offset, int size,
706
			int *eof, void *data);
707
static int splash_write_proc(struct file *file, const char *buffer,
708
			unsigned long count, void *data);
709
static int splash_status(struct vc_data *vc);
710
static int splash_recolor(struct vc_data *vc);
711
static int splash_proc_register(void);
712
713
static struct proc_dir_entry *proc_splash;
714
715
static int splash_recolor(struct vc_data *vc)
716
{
717
	if (!vc->vc_splash_data)
718
	    return -1;
719
	if (!vc->vc_splash_data->splash_state)
720
	    return 0;
721
	con_remap_def_color(vc, vc->vc_splash_data->splash_color << 4 | vc->vc_splash_data->splash_fg_color);
722
	if (fg_console == vc->vc_num) {
723
		update_region(vc, vc->vc_origin + vc->vc_size_row * vc->vc_top,
724
			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
725
	}
726
	return 0;
727
}
728
729
static int splash_status(struct vc_data *vc)
730
{
731
	struct fb_info *info;
732
	printk(KERN_INFO "bootsplash: status on console %d changed to %s\n", vc->vc_num, vc->vc_splash_data && vc->vc_splash_data->splash_state ? "on" : "off");
733
734
	info = registered_fb[(int) con2fb_map[vc->vc_num]];
735
	if (fg_console == vc->vc_num)
736
		splash_prepare(vc, info);
737
	if (vc->vc_splash_data && vc->vc_splash_data->splash_state) {
738
		con_remap_def_color(vc, vc->vc_splash_data->splash_color << 4 | vc->vc_splash_data->splash_fg_color);
739
		/* vc_resize also calls con_switch which resets yscroll */
740
		vc_resize(vc, vc->vc_splash_data->splash_text_wi / vc->vc_font.width, vc->vc_splash_data->splash_text_he / vc->vc_font.height);
741
		if (fg_console == vc->vc_num) {
742
			update_region(vc, vc->vc_origin + vc->vc_size_row * vc->vc_top,
743
				      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
744
			splash_clear_margins(vc->vc_splash_data, vc, info, 0);
745
		}
746
	} else {
747
	  	/* Switch bootsplash off */
748
		con_remap_def_color(vc, 0x07);
749
		vc_resize(vc, info->var.xres / vc->vc_font.width, info->var.yres / vc->vc_font.height);
750
	}
751
	return 0;
752
}
753
754
static int splash_read_proc(char *buffer, char **start, off_t offset, int size,
755
			int *eof, void *data)
756
{
757
	int len = 0;
758
	off_t begin = 0;
759
	struct vc_data *vc = vc_cons[0].d;
760
	struct fb_info *info = registered_fb[(int)con2fb_map[0]];
761
	int color = vc->vc_splash_data ? vc->vc_splash_data->splash_color << 4 |
762
			vc->vc_splash_data->splash_fg_color : splash_default >> 4;
763
	int status = vc->vc_splash_data ? vc->vc_splash_data->splash_state & 1 : 0;
764
	len += sprintf(buffer + len, "Splash screen v%s (0x%02x, %dx%d%s): %s\n",
765
		        SPLASH_VERSION, color, info->var.xres, info->var.yres,
766
			(vc->vc_splash_data ?  vc->vc_splash_data->splash_dosilent : 0)? ", silent" : "",
767
					status ? "on" : "off");
768
	if (offset >= begin + len)
769
		return 0;
770
771
	*start = buffer + (begin - offset);
772
773
	return (size < begin + len - offset ? size : begin + len - offset);
774
}
775
776
static int splash_write_proc(struct file *file, const char *buffer,
777
		      unsigned long count, void *data)
778
{
779
        int new, unit;
780
	struct vc_data *vc;
781
	
782
	if (!buffer || !splash_default)
783
		return count;
784
785
	acquire_console_sem();
786
	if (!strncmp(buffer, "show", 4) || !strncmp(buffer, "hide", 4)) {
787
		int pe, oldpe;
788
789
		vc = vc_cons[0].d;
790
		if (buffer[4] == ' ' && buffer[5] == 'p')
791
			pe = 0;
792
		else if (buffer[4] == '\n')
793
			pe = 65535;
794
		else
795
			pe = simple_strtoul(buffer + 5, NULL, 0);
796
		if (pe < 0)
797
			pe = 0;
798
		if (pe > 65535)
799
			pe = 65535;
800
		if (*buffer == 'h')
801
			pe = 65535 - pe;
802
		pe += pe > 32767;
803
		if (vc->vc_splash_data && vc->vc_splash_data->splash_percent != pe) {
804
			struct fb_info *info;
805
			struct fbcon_ops *ops;
806
807
			oldpe = vc->vc_splash_data->splash_percent;
808
			vc->vc_splash_data->splash_percent = pe;
809
			if (fg_console != 0 || !vc->vc_splash_data->splash_state) {
810
				release_console_sem();
811
				return count;
812
			}
813
			info = registered_fb[(int) con2fb_map[vc->vc_num]];
814
			ops = info->fbcon_par;
815
			if (ops->blank_state) {
816
				release_console_sem();
817
				return count;
818
			}
819
			if (!vc->vc_splash_data->splash_overpaintok || pe == 65536 || pe < oldpe) {
820
				if (splash_hasinter(vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount))
821
					splash_status(vc);
822
				else
823
					splash_prepare(vc, info);
824
			} else {
825
				if (vc->vc_splash_data->splash_silentjpeg && vc->vc_splash_data->splash_dosilent && info->silent_screen_base)
826
					boxit(info->silent_screen_base, info->fix.line_length, vc->vc_splash_data->splash_sboxes, vc->vc_splash_data->splash_sboxcount, vc->vc_splash_data->splash_percent, 1);
827
				boxit(info->screen_base, info->fix.line_length, vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount, vc->vc_splash_data->splash_percent, 1);
828
			}
829
		}
830
		release_console_sem();
831
		return count;
832
	}
833
	if (!strncmp(buffer,"silent\n",7) || !strncmp(buffer,"verbose\n",8)) {
834
		vc = vc_cons[0].d;
835
		if (vc->vc_splash_data && vc->vc_splash_data->splash_silentjpeg) {
836
		    if (vc->vc_splash_data->splash_dosilent != (buffer[0] == 's')) {
837
			vc->vc_splash_data->splash_dosilent = buffer[0] == 's';
838
			splash_status(vc);
839
		    }
840
		}
841
		release_console_sem();
842
		return count;
843
	}
844
	if (!strncmp(buffer,"freesilent\n",11)) {
845
		vc = vc_cons[0].d;
846
		if (vc->vc_splash_data && vc->vc_splash_data->splash_silentjpeg) {
847
		    printk(KERN_INFO "bootsplash: freeing silent jpeg\n");
848
		    vc->vc_splash_data->splash_silentjpeg = 0;
849
		    vfree(vc->vc_splash_data->splash_sboxes);
850
		    vc->vc_splash_data->splash_sboxes = 0;
851
		    vc->vc_splash_data->splash_sboxcount = 0;
852
		    if (vc->vc_splash_data->splash_dosilent)
853
			splash_status(vc);
854
		    vc->vc_splash_data->splash_dosilent = 0;
855
		}
856
		release_console_sem();
857
		return count;
858
	}
859
860
	if (!strncmp(buffer, "BOOTSPL", 7)) {
861
	    int up = -1;
862
	    unit = splash_getraw((unsigned char *)buffer, (unsigned char *)buffer + count, &up);
863
	    if (unit >= 0) {
864
		vc = vc_cons[unit].d;
865
		if (up == -1)
866
		    splash_status(vc);
867
		else {
868
		    struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
869
		    struct fbcon_ops *ops = info->fbcon_par;
870
		    if (ops->blank_state)
871
			up = 0;
872
		    if ((up & 2) != 0 && vc->vc_splash_data->splash_silentjpeg && vc->vc_splash_data->splash_dosilent && info->silent_screen_base)
873
			boxit(info->silent_screen_base, info->fix.line_length, vc->vc_splash_data->splash_sboxes, vc->vc_splash_data->splash_sboxcount, vc->vc_splash_data->splash_percent, 1);
874
		    if ((up & 1) != 0)
875
			    boxit(info->screen_base, info->fix.line_length, vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount, vc->vc_splash_data->splash_percent, 1);
876
		}
877
	    }
878
	    release_console_sem();
879
	    return count;
880
	}
881
	vc = vc_cons[0].d;
882
	if (!vc->vc_splash_data) {
883
		release_console_sem();
884
		return count;
885
	}
886
	if (buffer[0] == 't') {
887
	        vc->vc_splash_data->splash_state ^= 1;
888
		splash_status(vc);
889
		release_console_sem();
890
		return count;
891
	}
892
	new = simple_strtoul(buffer, NULL, 0);
893
	if (new > 1) {
894
		/* expert user */
895
		vc->vc_splash_data->splash_color    = new >> 8 & 0xff;
896
		vc->vc_splash_data->splash_fg_color = new >> 4 & 0x0f;
897
	}
898
	if ((new & 1) == vc->vc_splash_data->splash_state)
899
		splash_recolor(vc);
900
	else {
901
		vc->vc_splash_data->splash_state = new & 1;
902
		splash_status(vc);
903
	}
904
	release_console_sem();
905
	return count;
906
}
907
908
static int splash_proc_register(void)
909
{
910
	if ((proc_splash = create_proc_entry("splash", 0, 0))) {
911
		proc_splash->read_proc = splash_read_proc;
912
		proc_splash->write_proc = splash_write_proc;
913
		return 0;
914
	}
915
	return 1;
916
}
917
918
# if 0
919
static int splash_proc_unregister(void)
920
{
921
	if (proc_splash)
922
		remove_proc_entry("splash", 0);
923
	return 0;
924
}
925
# endif
926
#endif	/* CONFIG_PROC_FS */
927
928
void splash_init(void)
929
{
930
	struct fb_info *info;
931
	struct vc_data *vc;
932
	int isramfs = 1;
933
	int fd;
934
	int len;
935
	int max_len = 1024*1024*2;
936
	char *mem;
937
938
	if (splash_registered)
939
		return;
940
	vc = vc_cons[0].d;
941
	info = registered_fb[0];
942
	if (!vc || !info || info->var.bits_per_pixel != 16)
943
		return;
944
#ifdef CONFIG_PROC_FS
945
	splash_proc_register();
946
#endif
947
	splash_registered = 1;
948
	if (vc->vc_splash_data)
949
		return;
950
	if ((fd = sys_open("/bootsplash", O_RDONLY, 0)) < 0) {
951
		isramfs = 0;
952
		fd = sys_open("/initrd.image", O_RDONLY, 0);
953
	}
954
	if (fd < 0)
955
		return;
956
	if ((len = (int)sys_lseek(fd, (off_t)0, 2)) <= 0) {
957
		sys_close(fd);
958
		return;
959
	}
960
	/* Don't look for more than the last 2MB */
961
	if (len > max_len) {
962
		printk( KERN_INFO "bootsplash: scanning last %dMB of initrd for signature\n",
963
				max_len>>20);
964
		sys_lseek(fd, (off_t)(len - max_len), 0);
965
		len = max_len;
966
	} else {
967
		sys_lseek(fd, (off_t)0, 0);
968
	}
969
970
	mem = vmalloc(len);
971
	if (mem) {
972
		acquire_console_sem();
973
		if ((int)sys_read(fd, mem, len) == len && splash_getraw((unsigned char *)mem, (unsigned char *)mem + len, (int *)0) == 0 && vc->vc_splash_data)
974
			vc->vc_splash_data->splash_state = splash_default & 1;
975
		release_console_sem();
976
		vfree(mem);
977
	}
978
	sys_close(fd);
979
	if (isramfs)
980
		sys_unlink("/bootsplash");
981
	return;
982
}
983
(-)linux-2.6.35/drivers/video/bootsplash/bootsplash.h (+44 lines)
Line 0 Link Here
1
/* 
2
 *    linux/drivers/video/bootsplash/bootsplash.h - splash screen definition.
3
 *	
4
 *	(w) 2001-2003 by Volker Poplawski, <volker@poplawski.de>
5
 * 		    Stefan Reinauer, <stepan@suse.de>
6
 * 		    
7
 * 		    
8
 * 	idea and SuSE screen work by Ken Wimer, <wimer@suse.de>
9
 */
10
11
#ifndef __BOOTSPLASH_H
12
#define __BOOTSPLASH_H
13
14
struct fb_info;
15
16
/* splash.c */
17
extern int splash_prepare(struct vc_data *, struct fb_info *);
18
extern void splash_init(void);
19
20
/* splash_render.c */
21
extern void splash_putcs(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
22
			const unsigned short *s, int count, int ypos, int xpos);
23
extern void splash_putc(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
24
			int c, int ypos, int xpos);
25
extern void splashcopy(u8 *dst, u8 *src, int height, int width, int dstbytes, int srcbytes);
26
extern void splash_clear(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy,
27
			int sx, int height, int width);
28
extern void splash_bmove(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy, 
29
			int sx, int dy, int dx, int height, int width);
30
extern void splash_clear_margins(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
31
			int bottom_only);
32
extern int splash_cursor(struct splash_data *sd, struct fb_info *info, struct fb_cursor *cursor);
33
extern void splash_bmove_redraw(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
34
			int y, int sx, int dx, int width);
35
extern void splash_blank(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
36
			int blank);
37
38
/* vt.c */
39
extern void con_remap_def_color(struct vc_data *, int new_color);
40
41
extern void acquire_console_sem(void);
42
extern void release_console_sem(void);
43
44
#endif
(-)linux-2.6.35/drivers/video/bootsplash/decode-jpg.c (+957 lines)
Line 0 Link Here
1
/* 
2
 *    linux/drivers/video/bootsplash/decode-jpg.c - a tiny jpeg decoder.
3
 *      
4
 *      (w) August 2001 by Michael Schroeder, <mls@suse.de>
5
 *                  
6
 */
7
8
#include <linux/string.h>
9
#include <asm/byteorder.h>
10
11
#include "decode-jpg.h"
12
13
#define ISHIFT 11
14
15
#define IFIX(a) ((int)((a) * (1 << ISHIFT) + .5))
16
#define IMULT(a, b) (((a) * (b)) >> ISHIFT)
17
#define ITOINT(a) ((a) >> ISHIFT)
18
19
#ifndef __P
20
# define __P(x) x
21
#endif
22
23
/* special markers */
24
#define M_BADHUFF	-1
25
#define M_EOF		0x80
26
27
struct in {
28
	unsigned char *p;
29
	unsigned int bits;
30
	int left;
31
	int marker;
32
33
	int (*func) __P((void *));
34
	void *data;
35
};
36
37
/*********************************/
38
struct dec_hufftbl;
39
struct enc_hufftbl;
40
41
union hufftblp {
42
	struct dec_hufftbl *dhuff;
43
	struct enc_hufftbl *ehuff;
44
};
45
46
struct scan {
47
	int dc;			/* old dc value */
48
49
	union hufftblp hudc;
50
	union hufftblp huac;
51
	int next;		/* when to switch to next scan */
52
53
	int cid;		/* component id */
54
	int hv;			/* horiz/vert, copied from comp */
55
	int tq;			/* quant tbl, copied from comp */
56
};
57
58
/*********************************/
59
60
#define DECBITS 10		/* seems to be the optimum */
61
62
struct dec_hufftbl {
63
	int maxcode[17];
64
	int valptr[16];
65
	unsigned char vals[256];
66
	unsigned int llvals[1 << DECBITS];
67
};
68
69
static void decode_mcus __P((struct in *, int *, int, struct scan *, int *));
70
static int dec_readmarker __P((struct in *));
71
static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *));
72
73
static void setinput __P((struct in *, unsigned char *));
74
/*********************************/
75
76
#undef PREC
77
#define PREC int
78
79
static void idctqtab __P((unsigned char *, PREC *));
80
static void idct __P((int *, int *, PREC *, PREC, int));
81
static void scaleidctqtab __P((PREC *, PREC));
82
83
/*********************************/
84
85
static void initcol __P((PREC[][64]));
86
87
static void col221111 __P((int *, unsigned char *, int));
88
static void col221111_16 __P((int *, unsigned char *, int));
89
90
/*********************************/
91
92
#define M_SOI	0xd8
93
#define M_APP0	0xe0
94
#define M_DQT	0xdb
95
#define M_SOF0	0xc0
96
#define M_DHT   0xc4
97
#define M_DRI	0xdd
98
#define M_SOS	0xda
99
#define M_RST0	0xd0
100
#define M_EOI	0xd9
101
#define M_COM	0xfe
102
103
static unsigned char *datap;
104
105
static int getbyte(void)
106
{
107
	return *datap++;
108
}
109
110
static int getword(void)
111
{
112
	int c1, c2;
113
	c1 = *datap++;
114
	c2 = *datap++;
115
	return c1 << 8 | c2;
116
}
117
118
struct comp {
119
	int cid;
120
	int hv;
121
	int tq;
122
};
123
124
#define MAXCOMP 4
125
struct jpginfo {
126
	int nc;			/* number of components */
127
	int ns;			/* number of scans */
128
	int dri;		/* restart interval */
129
	int nm;			/* mcus til next marker */
130
	int rm;			/* next restart marker */
131
};
132
133
static struct jpginfo info;
134
static struct comp comps[MAXCOMP];
135
136
static struct scan dscans[MAXCOMP];
137
138
static unsigned char quant[4][64];
139
140
static struct dec_hufftbl dhuff[4];
141
142
#define dec_huffdc (dhuff + 0)
143
#define dec_huffac (dhuff + 2)
144
145
static struct in in;
146
147
static int readtables(int till)
148
{
149
	int m, l, i, j, lq, pq, tq;
150
	int tc, th, tt;
151
152
	for (;;) {
153
		if (getbyte() != 0xff)
154
			return -1;
155
		if ((m = getbyte()) == till)
156
			break;
157
158
		switch (m) {
159
		case 0xc2:
160
			return 0;
161
162
		case M_DQT:
163
			lq = getword();
164
			while (lq > 2) {
165
				pq = getbyte();
166
				tq = pq & 15;
167
				if (tq > 3)
168
					return -1;
169
				pq >>= 4;
170
				if (pq != 0)
171
					return -1;
172
				for (i = 0; i < 64; i++)
173
					quant[tq][i] = getbyte();
174
				lq -= 64 + 1;
175
			}
176
			break;
177
178
		case M_DHT:
179
			l = getword();
180
			while (l > 2) {
181
				int hufflen[16], k;
182
				unsigned char huffvals[256];
183
184
				tc = getbyte();
185
				th = tc & 15;
186
				tc >>= 4;
187
				tt = tc * 2 + th;
188
				if (tc > 1 || th > 1)
189
					return -1;
190
				for (i = 0; i < 16; i++)
191
					hufflen[i] = getbyte();
192
				l -= 1 + 16;
193
				k = 0;
194
				for (i = 0; i < 16; i++) {
195
					for (j = 0; j < hufflen[i]; j++)
196
						huffvals[k++] = getbyte();
197
					l -= hufflen[i];
198
				}
199
				dec_makehuff(dhuff + tt, hufflen,
200
					     huffvals);
201
			}
202
			break;
203
204
		case M_DRI:
205
			l = getword();
206
			info.dri = getword();
207
			break;
208
209
		default:
210
			l = getword();
211
			while (l-- > 2)
212
				getbyte();
213
			break;
214
		}
215
	}
216
	return 0;
217
}
218
219
static void dec_initscans(void)
220
{
221
	int i;
222
223
	info.nm = info.dri + 1;
224
	info.rm = M_RST0;
225
	for (i = 0; i < info.ns; i++)
226
		dscans[i].dc = 0;
227
}
228
229
static int dec_checkmarker(void)
230
{
231
	int i;
232
233
	if (dec_readmarker(&in) != info.rm)
234
		return -1;
235
	info.nm = info.dri;
236
	info.rm = (info.rm + 1) & ~0x08;
237
	for (i = 0; i < info.ns; i++)
238
		dscans[i].dc = 0;
239
	return 0;
240
}
241
242
int jpeg_check_size(unsigned char *buf, int width, int height)
243
{
244
  	datap = buf;
245
	getbyte(); 
246
	getbyte(); 
247
	readtables(M_SOF0);
248
	getword();
249
	getbyte();
250
        if (height != getword() || width != getword())
251
		return 0;
252
        return 1;
253
}
254
255
int jpeg_decode(buf, pic, width, height, depth, decdata)
256
unsigned char *buf, *pic;
257
int width, height, depth;
258
struct jpeg_decdata *decdata;
259
{
260
	int i, j, m, tac, tdc;
261
	int mcusx, mcusy, mx, my;
262
	int max[6];
263
264
	if (!decdata || !buf || !pic)
265
		return -1;
266
	datap = buf;
267
	if (getbyte() != 0xff)
268
		return ERR_NO_SOI;
269
	if (getbyte() != M_SOI)
270
		return ERR_NO_SOI;
271
	if (readtables(M_SOF0))
272
		return ERR_BAD_TABLES;
273
	getword();
274
	i = getbyte();
275
	if (i != 8)
276
		return ERR_NOT_8BIT;
277
	if (((getword() + 15) & ~15) != height)
278
		return ERR_HEIGHT_MISMATCH;
279
	if (((getword() + 15) & ~15) != width)
280
		return ERR_WIDTH_MISMATCH;
281
	if ((height & 15) || (width & 15))
282
		return ERR_BAD_WIDTH_OR_HEIGHT;
283
	info.nc = getbyte();
284
	if (info.nc > MAXCOMP)
285
		return ERR_TOO_MANY_COMPPS;
286
	for (i = 0; i < info.nc; i++) {
287
		int h, v;
288
		comps[i].cid = getbyte();
289
		comps[i].hv = getbyte();
290
		v = comps[i].hv & 15;
291
		h = comps[i].hv >> 4;
292
		comps[i].tq = getbyte();
293
		if (h > 3 || v > 3)
294
			return ERR_ILLEGAL_HV;
295
		if (comps[i].tq > 3)
296
			return ERR_QUANT_TABLE_SELECTOR;
297
	}
298
	if (readtables(M_SOS))
299
		return ERR_BAD_TABLES;
300
	getword();
301
	info.ns = getbyte();
302
	if (info.ns != 3)
303
		return ERR_NOT_YCBCR_221111;
304
	for (i = 0; i < 3; i++) {
305
		dscans[i].cid = getbyte();
306
		tdc = getbyte();
307
		tac = tdc & 15;
308
		tdc >>= 4;
309
		if (tdc > 1 || tac > 1)
310
			return ERR_QUANT_TABLE_SELECTOR;
311
		for (j = 0; j < info.nc; j++)
312
			if (comps[j].cid == dscans[i].cid)
313
				break;
314
		if (j == info.nc)
315
			return ERR_UNKNOWN_CID_IN_SCAN;
316
		dscans[i].hv = comps[j].hv;
317
		dscans[i].tq = comps[j].tq;
318
		dscans[i].hudc.dhuff = dec_huffdc + tdc;
319
		dscans[i].huac.dhuff = dec_huffac + tac;
320
	}
321
	
322
	i = getbyte();
323
	j = getbyte();
324
	m = getbyte();
325
	
326
	if (i != 0 || j != 63 || m != 0)
327
		return ERR_NOT_SEQUENTIAL_DCT;
328
	
329
	if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3)
330
		return ERR_NOT_YCBCR_221111;
331
332
	if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11 || dscans[2].hv != 0x11)
333
		return ERR_NOT_YCBCR_221111;
334
335
	mcusx = width >> 4;
336
	mcusy = height >> 4;
337
338
339
	idctqtab(quant[dscans[0].tq], decdata->dquant[0]);
340
	idctqtab(quant[dscans[1].tq], decdata->dquant[1]);
341
	idctqtab(quant[dscans[2].tq], decdata->dquant[2]);
342
	initcol(decdata->dquant);
343
	setinput(&in, datap);
344
345
#if 0
346
	/* landing zone */
347
	img[len] = 0;
348
	img[len + 1] = 0xff;
349
	img[len + 2] = M_EOF;
350
#endif
351
352
	dec_initscans();
353
354
	dscans[0].next = 6 - 4;
355
	dscans[1].next = 6 - 4 - 1;
356
	dscans[2].next = 6 - 4 - 1 - 1;	/* 411 encoding */
357
	for (my = 0; my < mcusy; my++) {
358
		for (mx = 0; mx < mcusx; mx++) {
359
			if (info.dri && !--info.nm)
360
				if (dec_checkmarker())
361
					return ERR_WRONG_MARKER;
362
			
363
			decode_mcus(&in, decdata->dcts, 6, dscans, max);
364
			idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]);
365
			idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]);
366
			idct(decdata->dcts + 128, decdata->out + 128, decdata->dquant[0], IFIX(128.5), max[2]);
367
			idct(decdata->dcts + 192, decdata->out + 192, decdata->dquant[0], IFIX(128.5), max[3]);
368
			idct(decdata->dcts + 256, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]);
369
			idct(decdata->dcts + 320, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]);
370
371
			switch (depth) {
372
			case 24:
373
				col221111(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 3, mcusx * 16 * 3);
374
				break;
375
			case 16:
376
				col221111_16(decdata->out, pic + (my * 16 * mcusx + mx) * (16 * 2), mcusx * (16 * 2));
377
				break;
378
			default:
379
				return ERR_DEPTH_MISMATCH;
380
				break;
381
			}
382
		}
383
	}
384
	
385
	m = dec_readmarker(&in);
386
	if (m != M_EOI)
387
		return ERR_NO_EOI;
388
389
	return 0;
390
}
391
392
/****************************************************************/
393
/**************       huffman decoder             ***************/
394
/****************************************************************/
395
396
static int fillbits __P((struct in *, int, unsigned int));
397
static int dec_rec2
398
__P((struct in *, struct dec_hufftbl *, int *, int, int));
399
400
static void setinput(in, p)
401
struct in *in;
402
unsigned char *p;
403
{
404
	in->p = p;
405
	in->left = 0;
406
	in->bits = 0;
407
	in->marker = 0;
408
}
409
410
static int fillbits(in, le, bi)
411
struct in *in;
412
int le;
413
unsigned int bi;
414
{
415
	int b, m;
416
417
	if (in->marker) {
418
		if (le <= 16)
419
			in->bits = bi << 16, le += 16;
420
		return le;
421
	}
422
	while (le <= 24) {
423
		b = *in->p++;
424
		if (b == 0xff && (m = *in->p++) != 0) {
425
			if (m == M_EOF) {
426
				if (in->func && (m = in->func(in->data)) == 0)
427
					continue;
428
			}
429
			in->marker = m;
430
			if (le <= 16)
431
				bi = bi << 16, le += 16;
432
			break;
433
		}
434
		bi = bi << 8 | b;
435
		le += 8;
436
	}
437
	in->bits = bi;		/* tmp... 2 return values needed */
438
	return le;
439
}
440
441
static int dec_readmarker(in)
442
struct in *in;
443
{
444
	int m;
445
446
	in->left = fillbits(in, in->left, in->bits);
447
	if ((m = in->marker) == 0)
448
		return 0;
449
	in->left = 0;
450
	in->marker = 0;
451
	return m;
452
}
453
454
#define LEBI_DCL	int le, bi
455
#define LEBI_GET(in)	(le = in->left, bi = in->bits)
456
#define LEBI_PUT(in)	(in->left = le, in->bits = bi)
457
458
#define GETBITS(in, n) (					\
459
  (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0),	\
460
  (le -= (n)),							\
461
  bi >> le & ((1 << (n)) - 1)					\
462
)
463
464
#define UNGETBITS(in, n) (	\
465
  le += (n)			\
466
)
467
468
469
static int dec_rec2(in, hu, runp, c, i)
470
struct in *in;
471
struct dec_hufftbl *hu;
472
int *runp;
473
int c, i;
474
{
475
	LEBI_DCL;
476
477
	LEBI_GET(in);
478
	if (i) {
479
		UNGETBITS(in, i & 127);
480
		*runp = i >> 8 & 15;
481
		i >>= 16;
482
	} else {
483
		for (i = DECBITS; (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++);
484
		if (i >= 16) {
485
			in->marker = M_BADHUFF;
486
			return 0;
487
		}
488
		i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];
489
		*runp = i >> 4;
490
		i &= 15;
491
	}
492
	if (i == 0) {		/* sigh, 0xf0 is 11 bit */
493
		LEBI_PUT(in);
494
		return 0;
495
	}
496
	/* receive part */
497
	c = GETBITS(in, i);
498
	if (c < (1 << (i - 1)))
499
		c += (-1 << i) + 1;
500
	LEBI_PUT(in);
501
	return c;
502
}
503
504
#define DEC_REC(in, hu, r, i)	 (	\
505
  r = GETBITS(in, DECBITS),		\
506
  i = hu->llvals[r],			\
507
  i & 128 ?				\
508
    (					\
509
      UNGETBITS(in, i & 127),		\
510
      r = i >> 8 & 15,			\
511
      i >> 16				\
512
    )					\
513
  :					\
514
    (					\
515
      LEBI_PUT(in),			\
516
      i = dec_rec2(in, hu, &r, r, i),	\
517
      LEBI_GET(in),			\
518
      i					\
519
    )					\
520
)
521
522
static void decode_mcus(in, dct, n, sc, maxp)
523
struct in *in;
524
int *dct;
525
int n;
526
struct scan *sc;
527
int *maxp;
528
{
529
	struct dec_hufftbl *hu;
530
	int i, r, t;
531
	LEBI_DCL;
532
533
	memset(dct, 0, n * 64 * sizeof(*dct));
534
	LEBI_GET(in);
535
	while (n-- > 0) {
536
		hu = sc->hudc.dhuff;
537
		*dct++ = (sc->dc += DEC_REC(in, hu, r, t));
538
539
		hu = sc->huac.dhuff;
540
		i = 63;
541
		while (i > 0) {
542
			t = DEC_REC(in, hu, r, t);
543
			if (t == 0 && r == 0) {
544
				dct += i;
545
				break;
546
			}
547
			dct += r;
548
			*dct++ = t;
549
			i -= r + 1;
550
		}
551
		*maxp++ = 64 - i;
552
		if (n == sc->next)
553
			sc++;
554
	}
555
	LEBI_PUT(in);
556
}
557
558
static void dec_makehuff(hu, hufflen, huffvals)
559
struct dec_hufftbl *hu;
560
int *hufflen;
561
unsigned char *huffvals;
562
{
563
	int code, k, i, j, d, x, c, v;
564
	for (i = 0; i < (1 << DECBITS); i++)
565
		hu->llvals[i] = 0;
566
567
/*
568
 * llvals layout:
569
 *
570
 * value v already known, run r, backup u bits:
571
 *  vvvvvvvvvvvvvvvv 0000 rrrr 1 uuuuuuu
572
 * value unknown, size b bits, run r, backup u bits:
573
 *  000000000000bbbb 0000 rrrr 0 uuuuuuu
574
 * value and size unknown:
575
 *  0000000000000000 0000 0000 0 0000000
576
 */
577
	code = 0;
578
	k = 0;
579
	for (i = 0; i < 16; i++, code <<= 1) {	/* sizes */
580
		hu->valptr[i] = k;
581
		for (j = 0; j < hufflen[i]; j++) {
582
			hu->vals[k] = *huffvals++;
583
			if (i < DECBITS) {
584
				c = code << (DECBITS - 1 - i);
585
				v = hu->vals[k] & 0x0f;	/* size */
586
				for (d = 1 << (DECBITS - 1 - i); --d >= 0;) {
587
					if (v + i < DECBITS) {	/* both fit in table */
588
						x = d >> (DECBITS - 1 - v -
589
							  i);
590
						if (v && x < (1 << (v - 1)))
591
							x += (-1 << v) + 1;
592
						x = x << 16 | (hu-> vals[k] & 0xf0) << 4 |
593
							(DECBITS - (i + 1 + v)) | 128;
594
					} else
595
						x = v << 16 | (hu-> vals[k] & 0xf0) << 4 |
596
						        (DECBITS - (i + 1));
597
					hu->llvals[c | d] = x;
598
				}
599
			}
600
			code++;
601
			k++;
602
		}
603
		hu->maxcode[i] = code;
604
	}
605
	hu->maxcode[16] = 0x20000;	/* always terminate decode */
606
}
607
608
/****************************************************************/
609
/**************             idct                  ***************/
610
/****************************************************************/
611
612
#define ONE ((PREC)IFIX(1.))
613
#define S2  ((PREC)IFIX(0.382683432))
614
#define C2  ((PREC)IFIX(0.923879532))
615
#define C4  ((PREC)IFIX(0.707106781))
616
617
#define S22 ((PREC)IFIX(2 * 0.382683432))
618
#define C22 ((PREC)IFIX(2 * 0.923879532))
619
#define IC4 ((PREC)IFIX(1 / 0.707106781))
620
621
#define C3IC1 ((PREC)IFIX(0.847759065))	/* c3/c1 */
622
#define C5IC1 ((PREC)IFIX(0.566454497))	/* c5/c1 */
623
#define C7IC1 ((PREC)IFIX(0.198912367))	/* c7/c1 */
624
625
#define XPP(a,b) (t = a + b, b = a - b, a = t)
626
#define XMP(a,b) (t = a - b, b = a + b, a = t)
627
#define XPM(a,b) (t = a + b, b = b - a, a = t)
628
629
#define ROT(a,b,s,c) (	t = IMULT(a + b, s),	\
630
			a = IMULT(a, c - s) + t,	\
631
			b = IMULT(b, c + s) - t)
632
633
#define IDCT		\
634
(			\
635
  XPP(t0, t1),		\
636
  XMP(t2, t3),		\
637
  t2 = IMULT(t2, IC4) - t3,	\
638
  XPP(t0, t3),		\
639
  XPP(t1, t2),		\
640
  XMP(t4, t7),		\
641
  XPP(t5, t6),		\
642
  XMP(t5, t7),		\
643
  t5 = IMULT(t5, IC4),	\
644
  ROT(t4, t6, S22, C22),\
645
  t6 -= t7,		\
646
  t5 -= t6,		\
647
  t4 -= t5,		\
648
  XPP(t0, t7),		\
649
  XPP(t1, t6),		\
650
  XPP(t2, t5),		\
651
  XPP(t3, t4)		\
652
)
653
654
static unsigned char zig2[64] = {
655
	0, 2, 3, 9, 10, 20, 21, 35,
656
	14, 16, 25, 31, 39, 46, 50, 57,
657
	5, 7, 12, 18, 23, 33, 37, 48,
658
	27, 29, 41, 44, 52, 55, 59, 62,
659
	15, 26, 30, 40, 45, 51, 56, 58,
660
	1, 4, 8, 11, 19, 22, 34, 36,
661
	28, 42, 43, 53, 54, 60, 61, 63,
662
	6, 13, 17, 24, 32, 38, 47, 49
663
};
664
665
void idct(in, out, quant, off, max)
666
int *in;
667
int *out;
668
PREC *quant;
669
PREC off;
670
int max;
671
{
672
	PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
673
	PREC tmp[64], *tmpp;
674
	int i, j;
675
	unsigned char *zig2p;
676
677
	t0 = off;
678
	if (max == 1) {
679
		t0 += in[0] * quant[0];
680
		for (i = 0; i < 64; i++)
681
			out[i] = ITOINT(t0);
682
		return;
683
	}
684
	zig2p = zig2;
685
	tmpp = tmp;
686
	for (i = 0; i < 8; i++) {
687
		j = *zig2p++;
688
		t0 += in[j] * quant[j];
689
		j = *zig2p++;
690
		t5 = in[j] * quant[j];
691
		j = *zig2p++;
692
		t2 = in[j] * quant[j];
693
		j = *zig2p++;
694
		t7 = in[j] * quant[j];
695
		j = *zig2p++;
696
		t1 = in[j] * quant[j];
697
		j = *zig2p++;
698
		t4 = in[j] * quant[j];
699
		j = *zig2p++;
700
		t3 = in[j] * quant[j];
701
		j = *zig2p++;
702
		t6 = in[j] * quant[j];
703
		IDCT;
704
		tmpp[0 * 8] = t0;
705
		tmpp[1 * 8] = t1;
706
		tmpp[2 * 8] = t2;
707
		tmpp[3 * 8] = t3;
708
		tmpp[4 * 8] = t4;
709
		tmpp[5 * 8] = t5;
710
		tmpp[6 * 8] = t6;
711
		tmpp[7 * 8] = t7;
712
		tmpp++;
713
		t0 = 0;
714
	}
715
	for (i = 0; i < 8; i++) {
716
		t0 = tmp[8 * i + 0];
717
		t1 = tmp[8 * i + 1];
718
		t2 = tmp[8 * i + 2];
719
		t3 = tmp[8 * i + 3];
720
		t4 = tmp[8 * i + 4];
721
		t5 = tmp[8 * i + 5];
722
		t6 = tmp[8 * i + 6];
723
		t7 = tmp[8 * i + 7];
724
		IDCT;
725
		out[8 * i + 0] = ITOINT(t0);
726
		out[8 * i + 1] = ITOINT(t1);
727
		out[8 * i + 2] = ITOINT(t2);
728
		out[8 * i + 3] = ITOINT(t3);
729
		out[8 * i + 4] = ITOINT(t4);
730
		out[8 * i + 5] = ITOINT(t5);
731
		out[8 * i + 6] = ITOINT(t6);
732
		out[8 * i + 7] = ITOINT(t7);
733
	}
734
}
735
736
static unsigned char zig[64] = {
737
	0, 1, 5, 6, 14, 15, 27, 28,
738
	2, 4, 7, 13, 16, 26, 29, 42,
739
	3, 8, 12, 17, 25, 30, 41, 43,
740
	9, 11, 18, 24, 31, 40, 44, 53,
741
	10, 19, 23, 32, 39, 45, 52, 54,
742
	20, 22, 33, 38, 46, 51, 55, 60,
743
	21, 34, 37, 47, 50, 56, 59, 61,
744
	35, 36, 48, 49, 57, 58, 62, 63
745
};
746
747
static PREC aaidct[8] = {
748
	IFIX(0.3535533906), IFIX(0.4903926402),
749
	IFIX(0.4619397663), IFIX(0.4157348062),
750
	IFIX(0.3535533906), IFIX(0.2777851165),
751
	IFIX(0.1913417162), IFIX(0.0975451610)
752
};
753
754
755
static void idctqtab(qin, qout)
756
unsigned char *qin;
757
PREC *qout;
758
{
759
	int i, j;
760
761
	for (i = 0; i < 8; i++)
762
		for (j = 0; j < 8; j++)
763
			qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] * 
764
			  			IMULT(aaidct[i], aaidct[j]);
765
}
766
767
static void scaleidctqtab(q, sc)
768
PREC *q;
769
PREC sc;
770
{
771
	int i;
772
773
	for (i = 0; i < 64; i++)
774
		q[i] = IMULT(q[i], sc);
775
}
776
777
/****************************************************************/
778
/**************          color decoder            ***************/
779
/****************************************************************/
780
781
#define ROUND
782
783
/*
784
 * YCbCr Color transformation:
785
 *
786
 * y:0..255   Cb:-128..127   Cr:-128..127
787
 *
788
 *      R = Y                + 1.40200 * Cr
789
 *      G = Y - 0.34414 * Cb - 0.71414 * Cr
790
 *      B = Y + 1.77200 * Cb
791
 *
792
 * =>
793
 *      Cr *= 1.40200;
794
 *      Cb *= 1.77200;
795
 *      Cg = 0.19421 * Cb + .50937 * Cr;
796
 *      R = Y + Cr;
797
 *      G = Y - Cg;
798
 *      B = Y + Cb;
799
 *
800
 * =>
801
 *      Cg = (50 * Cb + 130 * Cr + 128) >> 8;
802
 */
803
804
static void initcol(q)
805
PREC q[][64];
806
{
807
	scaleidctqtab(q[1], IFIX(1.77200));
808
	scaleidctqtab(q[2], IFIX(1.40200));
809
}
810
811
/* This is optimized for the stupid sun SUNWspro compiler. */
812
#define STORECLAMP(a,x)				\
813
(						\
814
  (a) = (x),					\
815
  (unsigned int)(x) >= 256 ? 			\
816
    ((a) = (x) < 0 ? 0 : 255)			\
817
  :						\
818
    0						\
819
)
820
821
#define CLAMP(x) ((unsigned int)(x) >= 256 ? ((x) < 0 ? 0 : 255) : (x))
822
823
#ifdef ROUND
824
825
#define CBCRCG(yin, xin)			\
826
(						\
827
  cb = outc[0 +yin*8+xin],			\
828
  cr = outc[64+yin*8+xin],			\
829
  cg = (50 * cb + 130 * cr + 128) >> 8		\
830
)
831
832
#else
833
834
#define CBCRCG(yin, xin)			\
835
(						\
836
  cb = outc[0 +yin*8+xin],			\
837
  cr = outc[64+yin*8+xin],			\
838
  cg = (3 * cb + 8 * cr) >> 4			\
839
)
840
841
#endif
842
843
#define PIC(yin, xin, p, xout)			\
844
(						\
845
  y = outy[(yin) * 8 + xin],			\
846
  STORECLAMP(p[(xout) * 3 + 0], y + cr),	\
847
  STORECLAMP(p[(xout) * 3 + 1], y - cg),	\
848
  STORECLAMP(p[(xout) * 3 + 2], y + cb)		\
849
)
850
851
#ifdef __LITTLE_ENDIAN
852
#define PIC_16(yin, xin, p, xout, add)		 \
853
(                                                \
854
  y = outy[(yin) * 8 + xin],                     \
855
  y = ((CLAMP(y + cr + add*2+1) & 0xf8) <<  8) | \
856
      ((CLAMP(y - cg + add    ) & 0xfc) <<  3) | \
857
      ((CLAMP(y + cb + add*2+1)       ) >>  3),  \
858
  p[(xout) * 2 + 0] = y & 0xff,                  \
859
  p[(xout) * 2 + 1] = y >> 8                     \
860
)
861
#else
862
#ifdef CONFIG_PPC
863
#define PIC_16(yin, xin, p, xout, add)		 \
864
(                                                \
865
  y = outy[(yin) * 8 + xin],                     \
866
  y = ((CLAMP(y + cr + add*2+1) & 0xf8) <<  7) | \
867
      ((CLAMP(y - cg + add*2+1) & 0xf8) <<  2) | \
868
      ((CLAMP(y + cb + add*2+1)       ) >>  3),  \
869
  p[(xout) * 2 + 0] = y >> 8,                    \
870
  p[(xout) * 2 + 1] = y & 0xff                   \
871
)
872
#else
873
#define PIC_16(yin, xin, p, xout, add)	 	 \
874
(                                                \
875
  y = outy[(yin) * 8 + xin],                     \
876
  y = ((CLAMP(y + cr + add*2+1) & 0xf8) <<  8) | \
877
      ((CLAMP(y - cg + add    ) & 0xfc) <<  3) | \
878
      ((CLAMP(y + cb + add*2+1)       ) >>  3),  \
879
  p[(xout) * 2 + 0] = y >> 8,                    \
880
  p[(xout) * 2 + 1] = y & 0xff                   \
881
)
882
#endif
883
#endif
884
885
#define PIC221111(xin)						\
886
(								\
887
  CBCRCG(0, xin),						\
888
  PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0),	\
889
  PIC(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1),	\
890
  PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0),	\
891
  PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1)	\
892
)
893
894
#define PIC221111_16(xin)                                               \
895
(                                                               	\
896
  CBCRCG(0, xin),                                               	\
897
  PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3),     \
898
  PIC_16(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0),     \
899
  PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1),     \
900
  PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2)      \
901
)
902
903
static void col221111(out, pic, width)
904
int *out;
905
unsigned char *pic;
906
int width;
907
{
908
	int i, j, k;
909
	unsigned char *pic0, *pic1;
910
	int *outy, *outc;
911
	int cr, cg, cb, y;
912
913
	pic0 = pic;
914
	pic1 = pic + width;
915
	outy = out;
916
	outc = out + 64 * 4;
917
	for (i = 2; i > 0; i--) {
918
		for (j = 4; j > 0; j--) {
919
			for (k = 0; k < 8; k++) {
920
				PIC221111(k);
921
			}
922
			outc += 8;
923
			outy += 16;
924
			pic0 += 2 * width;
925
			pic1 += 2 * width;
926
		}
927
		outy += 64 * 2 - 16 * 4;
928
	}
929
}
930
931
static void col221111_16(out, pic, width)
932
int *out;
933
unsigned char *pic;
934
int width;
935
{
936
	int i, j, k;
937
	unsigned char *pic0, *pic1;
938
	int *outy, *outc;
939
	int cr, cg, cb, y;
940
941
	pic0 = pic;
942
	pic1 = pic + width;
943
	outy = out;
944
	outc = out + 64 * 4;
945
	for (i = 2; i > 0; i--) {
946
		for (j = 4; j > 0; j--) {
947
			for (k = 0; k < 8; k++) {
948
			    PIC221111_16(k);
949
			}
950
			outc += 8;
951
			outy += 16;
952
			pic0 += 2 * width;
953
			pic1 += 2 * width;
954
		}
955
		outy += 64 * 2 - 16 * 4;
956
	}
957
}
(-)linux-2.6.35/drivers/video/bootsplash/decode-jpg.h (+35 lines)
Line 0 Link Here
1
/*
2
 *    linux/drivers/video/bootsplash/decode-jpg.h - a tiny jpeg decoder.
3
 *
4
 *      (w) August 2001 by Michael Schroeder, <mls@suse.de>
5
 */
6
7
#ifndef __DECODE_JPG_H
8
#define __DECODE_JPG_H
9
10
#define ERR_NO_SOI 1
11
#define ERR_NOT_8BIT 2
12
#define ERR_HEIGHT_MISMATCH 3
13
#define ERR_WIDTH_MISMATCH 4
14
#define ERR_BAD_WIDTH_OR_HEIGHT 5
15
#define ERR_TOO_MANY_COMPPS 6
16
#define ERR_ILLEGAL_HV 7
17
#define ERR_QUANT_TABLE_SELECTOR 8
18
#define ERR_NOT_YCBCR_221111 9
19
#define ERR_UNKNOWN_CID_IN_SCAN 10
20
#define ERR_NOT_SEQUENTIAL_DCT 11
21
#define ERR_WRONG_MARKER 12
22
#define ERR_NO_EOI 13
23
#define ERR_BAD_TABLES 14
24
#define ERR_DEPTH_MISMATCH 15
25
26
struct jpeg_decdata {
27
	int dcts[6 * 64 + 16];
28
	int out[64 * 6];
29
	int dquant[3][64];
30
};
31
32
extern int jpeg_decode(unsigned char *, unsigned char *, int, int, int, struct jpeg_decdata *);
33
extern int jpeg_check_size(unsigned char *, int, int);
34
35
#endif
(-)linux-2.6.35/drivers/video/bootsplash/Kconfig (+17 lines)
Line 0 Link Here
1
#
2
# Bootsplash configuration
3
#
4
5
menu "Bootsplash configuration"
6
7
config BOOTSPLASH
8
	bool "Bootup splash screen"
9
	depends on FRAMEBUFFER_CONSOLE && FB_VESA
10
	default n
11
        ---help---
12
          This option enables the Linux bootsplash screen. For more 
13
          information on the bootsplash screen have a look at 
14
          http://www.bootsplash.org/.
15
          If you are unsure, say N
16
endmenu
17
(-)linux-2.6.35/drivers/video/bootsplash/Makefile (+5 lines)
Line 0 Link Here
1
# Makefile for the Linux bootsplash
2
3
obj-$(CONFIG_BOOTSPLASH)		+= bootsplash.o
4
obj-$(CONFIG_BOOTSPLASH)		+= decode-jpg.o
5
obj-$(CONFIG_BOOTSPLASH)		+= render.o
(-)linux-2.6.35/drivers/video/bootsplash/render.c (+315 lines)
Line 0 Link Here
1
/* 
2
 *    linux/drivers/video/bootsplash/render.c - splash screen render functions.
3
 */
4
5
#include <linux/module.h>
6
#include <linux/types.h>
7
#include <linux/fb.h>
8
#include <linux/vt_kern.h>
9
#include <asm/irq.h>
10
#include <asm/system.h>
11
12
#include "../console/fbcon.h"
13
#include "bootsplash.h"
14
15
void splash_putcs(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
16
			const unsigned short *s, int count, int ypos, int xpos)
17
{
18
	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
19
	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
20
	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
21
	u8 *src;
22
        u8 *dst, *splashsrc;
23
	unsigned int d, x, y;
24
	u32 dd, fgx, bgx;
25
	u16 c = scr_readw(s);
26
27
	int fg_color, bg_color, transparent;
28
        fg_color = attr_fgcol(fgshift, c);
29
        bg_color = attr_bgcol(bgshift, c);
30
	transparent = sd->splash_color == bg_color;
31
	xpos = xpos * vc->vc_font.width + sd->splash_text_xo;
32
	ypos = ypos * vc->vc_font.height + sd->splash_text_yo;
33
        splashsrc = (u8 *)(info->splash_pic + ypos * info->splash_bytes + xpos * 2);
34
        dst = (u8 *)(info->screen_base + ypos * info->fix.line_length + xpos * 2);
35
36
	fgx = ((u32 *)info->pseudo_palette)[fg_color];
37
	if (transparent && sd->splash_color == 15) {
38
	    if (fgx == 0xffea)
39
		fgx = 0xfe4a;
40
	    else if (fgx == 0x57ea)
41
		fgx = 0x0540;
42
	    else if (fgx == 0xffff)
43
		fgx = 0x52aa;
44
	}
45
	bgx = ((u32 *)info->pseudo_palette)[bg_color];
46
	d = 0;
47
48
	while (count--) {
49
	    c = scr_readw(s++);
50
	    src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * ((vc->vc_font.width + 7) >> 3);
51
52
	    for (y = 0; y < vc->vc_font.height; y++) {
53
		for (x = 0; x < vc->vc_font.width; x += 2) {
54
		    if ((x & 7) == 0)
55
			d = *src++;
56
		    if (d & 0x80)
57
			dd = fgx;
58
		    else
59
			dd = transparent ? *(u16 *)splashsrc : bgx;
60
		    splashsrc += 2;
61
		    if (d & 0x40)
62
			dd |= fgx << 16;
63
		    else
64
			dd |= (transparent ? *(u16 *)splashsrc : bgx) << 16;
65
		    splashsrc += 2;
66
		    d <<= 2;
67
		    fb_writel(dd, dst);
68
		    dst += 4;
69
		}
70
		dst += info->fix.line_length - vc->vc_font.width * 2;
71
		splashsrc += info->splash_bytes - vc->vc_font.width * 2;
72
	    }
73
	    dst -= info->fix.line_length * vc->vc_font.height - vc->vc_font.width * 2;
74
	    splashsrc -= info->splash_bytes * vc->vc_font.height - vc->vc_font.width * 2;
75
	}
76
}
77
78
static void splash_renderc(struct splash_data *sd, struct fb_info *info, int fg_color, int bg_color, u8 *src, int ypos, int xpos, int height, int width)
79
{
80
	int transparent = sd->splash_color == bg_color;
81
	u32 dd, fgx, bgx;
82
	u8 *dst, *splashsrc;
83
	unsigned int d, x, y;
84
85
	splashsrc = (u8 *)(info->splash_pic + ypos * info->splash_bytes + xpos * 2);
86
	dst = (u8 *)(info->screen_base + ypos * info->fix.line_length + xpos * 2);
87
	fgx = ((u32 *)info->pseudo_palette)[fg_color];
88
	if (transparent && sd->splash_color == 15) {
89
	    if (fgx == 0xffea)
90
		fgx = 0xfe4a;
91
	    else if (fgx == 0x57ea)
92
		fgx = 0x0540;
93
	    else if (fgx == 0xffff)
94
		fgx = 0x52aa;
95
	}
96
	bgx = ((u32 *)info->pseudo_palette)[bg_color];
97
	d = 0;
98
	for (y = 0; y < height; y++) {
99
	    for (x = 0; x < width; x += 2) {
100
		if ((x & 7) == 0)
101
		    d = *src++;
102
		if (d & 0x80)
103
		    dd = fgx;
104
		else
105
		    dd = transparent ? *(u16 *)splashsrc : bgx;
106
		splashsrc += 2;
107
		if (d & 0x40)
108
		    dd |= fgx << 16;
109
		else
110
		    dd |= (transparent ? *(u16 *)splashsrc : bgx) << 16;
111
		splashsrc += 2;
112
		d <<= 2;
113
		fb_writel(dd, dst);
114
		dst += 4;
115
	    }
116
	    dst += info->fix.line_length - width * 2;
117
	    splashsrc += info->splash_bytes - width * 2;
118
	}
119
}
120
121
void splash_putc(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
122
                      int c, int ypos, int xpos)
123
{
124
	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
125
	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
126
	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
127
	u8 *src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * ((vc->vc_font.width + 7) >> 3);
128
	xpos = xpos * vc->vc_font.width + sd->splash_text_xo;
129
	ypos = ypos * vc->vc_font.height + sd->splash_text_yo;
130
	splash_renderc(sd, info, attr_fgcol(fgshift, c), attr_bgcol(bgshift, c), src, ypos, xpos, vc->vc_font.height, vc->vc_font.width);
131
}
132
133
void splashcopy(u8 *dst, u8 *src, int height, int width, int dstbytes, int srcbytes)
134
{
135
	int i;
136
137
	while (height-- > 0) {
138
	    u32 *p = (u32 *)dst;
139
	    u32 *q = (u32 *)src;
140
	    for (i=0; i < width/4; i++) {
141
		fb_writel(*q++,p++);
142
		fb_writel(*q++,p++);
143
	    }
144
	    if (width & 2)
145
		fb_writel(*q++,p++);
146
	    if (width & 1)
147
		fb_writew(*(u16*)q,(u16*)p);
148
	    dst += dstbytes;
149
	    src += srcbytes;
150
	}
151
}
152
153
static void splashset(u8 *dst, int height, int width, int dstbytes, u32 bgx) {
154
	int i;
155
156
	bgx |= bgx << 16;
157
	while (height-- > 0) {
158
	    u32 *p = (u32 *)dst;
159
	    for (i=0; i < width/4; i++) {
160
		fb_writel(bgx,p++);
161
		fb_writel(bgx,p++);
162
	    }
163
	    if (width & 2)
164
		fb_writel(bgx,p++);
165
	    if (width & 1)
166
		fb_writew(bgx,(u16*)p);
167
	    dst += dstbytes;
168
	}
169
}
170
171
static void splashfill(struct fb_info *info, int sy, int sx, int height, int width) {
172
	splashcopy((u8 *)(info->screen_base + sy * info->fix.line_length + sx * 2), (u8 *)(info->splash_pic + sy * info->splash_bytes + sx * 2), height, width, info->fix.line_length, info->splash_bytes);
173
}
174
175
void splash_clear(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy,
176
			int sx, int height, int width)
177
{
178
	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
179
	int bg_color = attr_bgcol_ec(bgshift, vc, info);
180
	int transparent = sd->splash_color == bg_color;
181
	u32 bgx;
182
	u8 *dst;
183
184
	sy = sy * vc->vc_font.height + sd->splash_text_yo;
185
	sx = sx * vc->vc_font.width + sd->splash_text_xo;
186
	height *= vc->vc_font.height;
187
	width *= vc->vc_font.width;
188
	if (transparent) {
189
		splashfill(info, sy, sx, height, width);
190
		return;
191
	}
192
        dst = (u8 *)(info->screen_base + sy * info->fix.line_length + sx * 2);
193
	bgx = ((u32 *)info->pseudo_palette)[bg_color];
194
	splashset(dst, height, width, info->fix.line_length, bgx);
195
}
196
197
void splash_bmove(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy, 
198
		int sx, int dy, int dx, int height, int width)
199
{
200
	struct fb_copyarea area;
201
202
	area.sx = sx * vc->vc_font.width;
203
	area.sy = sy * vc->vc_font.height;
204
	area.dx = dx * vc->vc_font.width;
205
	area.dy = dy * vc->vc_font.height;
206
	area.sx += sd->splash_text_xo;
207
	area.sy += sd->splash_text_yo;
208
	area.dx += sd->splash_text_xo;
209
	area.dy += sd->splash_text_yo;
210
	area.height = height * vc->vc_font.height;
211
	area.width = width * vc->vc_font.width;
212
213
	info->fbops->fb_copyarea(info, &area);
214
}
215
216
void splash_clear_margins(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
217
				int bottom_only)
218
{
219
	unsigned int tw = vc->vc_cols*vc->vc_font.width;
220
	unsigned int th = vc->vc_rows*vc->vc_font.height;
221
	
222
	if (!bottom_only) {
223
		/* top margin */
224
		splashfill(info, 0, 0, sd->splash_text_yo, info->var.xres);
225
		/* left margin */
226
		splashfill(info, sd->splash_text_yo, 0, th, sd->splash_text_xo);
227
		/* right margin */
228
		splashfill(info, sd->splash_text_yo, sd->splash_text_xo + tw, th, info->var.xres - sd->splash_text_xo - tw);
229
230
	}
231
	splashfill(info, sd->splash_text_yo + th, 0, info->var.yres - sd->splash_text_yo - th, info->var.xres);
232
}
233
234
int splash_cursor(struct splash_data *sd, struct fb_info *info, struct fb_cursor *cursor)
235
{
236
	int i;
237
	unsigned int dsize, s_pitch;
238
239
	if (info->state != FBINFO_STATE_RUNNING)
240
		return 0;
241
	
242
	s_pitch = (cursor->image.width + 7) >> 3;
243
        dsize = s_pitch * cursor->image.height;
244
        if (cursor->enable) {
245
                switch (cursor->rop) {
246
                case ROP_XOR:
247
                        for (i = 0; i < dsize; i++)
248
                                info->fb_cursordata[i] = cursor->image.data[i] ^ cursor->mask[i];
249
                        break;
250
                case ROP_COPY:
251
                default:
252
                        for (i = 0; i < dsize; i++)
253
                                info->fb_cursordata[i] = cursor->image.data[i] & cursor->mask[i];
254
                        break;
255
                }
256
        } else if (info->fb_cursordata != cursor->image.data)
257
                memcpy(info->fb_cursordata, cursor->image.data, dsize);
258
	cursor->image.data = info->fb_cursordata;
259
	splash_renderc(sd, info, cursor->image.fg_color, cursor->image.bg_color, (u8 *)info->fb_cursordata, cursor->image.dy + sd->splash_text_yo, cursor->image.dx + sd->splash_text_xo, cursor->image.height, cursor->image.width);
260
	return 0;
261
}
262
263
void splash_bmove_redraw(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width)
264
{
265
	unsigned short *d = (unsigned short *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
266
	unsigned short *s = d + (dx - sx);
267
	unsigned short *start = d;
268
	unsigned short *ls = d;
269
	unsigned short *le = d + width;
270
	unsigned short c;
271
	int x = dx;
272
	unsigned short attr = 1;
273
274
	do {
275
		c = scr_readw(d);
276
		if (attr != (c & 0xff00)) {
277
			attr = c & 0xff00;
278
			if (d > start) {
279
				splash_putcs(sd, vc, info, start, d - start, y, x);
280
				x += d - start;
281
				start = d;
282
			}
283
		}
284
		if (s >= ls && s < le && c == scr_readw(s)) {
285
			if (d > start) {
286
				splash_putcs(sd, vc, info, start, d - start, y, x);
287
				x += d - start + 1;
288
				start = d + 1;
289
			} else {
290
				x++;
291
				start++;
292
			}
293
		}
294
		s++;
295
		d++;
296
	} while (d < le);
297
	if (d > start)
298
		splash_putcs(sd, vc, info, start, d - start, y, x);
299
}
300
301
void splash_blank(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int blank)
302
{
303
	if (blank) {
304
		if (info->silent_screen_base)
305
		    splashset((u8 *)info->silent_screen_base, info->var.yres, info->var.xres, info->fix.line_length, 0);
306
		splashset((u8 *)info->screen_base, info->var.yres, info->var.xres, info->fix.line_length, 0);
307
	} else {
308
		if (info->silent_screen_base)
309
			splash_prepare(vc, info);
310
		splash_clear_margins(vc->vc_splash_data, vc, info, 0);
311
		/* no longer needed, done in fbcon_blank */
312
		/* update_screen(vc->vc_num); */
313
	}
314
}
315
(-)linux-2.6.35/drivers/video/console/bitblit.c (-1 / +39 lines)
Lines 18-23 Link Here
18
#include <linux/console.h>
18
#include <linux/console.h>
19
#include <asm/types.h>
19
#include <asm/types.h>
20
#include "fbcon.h"
20
#include "fbcon.h"
21
#ifdef CONFIG_BOOTSPLASH
22
#include "../bootsplash/bootsplash.h"
23
#endif
21
24
22
/*
25
/*
23
 * Accelerated handlers.
26
 * Accelerated handlers.
Lines 48-53 Link Here
48
{
51
{
49
	struct fb_copyarea area;
52
	struct fb_copyarea area;
50
53
54
#ifdef CONFIG_BOOTSPLASH
55
	if (info->splash_data) {
56
		splash_bmove(info->splash_data, vc, info,
57
			sy, sx, dy, dx, height, width);
58
		return;
59
	}
60
#endif
51
	area.sx = sx * vc->vc_font.width;
61
	area.sx = sx * vc->vc_font.width;
52
	area.sy = sy * vc->vc_font.height;
62
	area.sy = sy * vc->vc_font.height;
53
	area.dx = dx * vc->vc_font.width;
63
	area.dx = dx * vc->vc_font.width;
Lines 63-69 Link Here
63
{
73
{
64
	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
74
	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
65
	struct fb_fillrect region;
75
	struct fb_fillrect region;
66
76
#ifdef CONFIG_BOOTSPLASH
77
 	if (info->splash_data) {
78
 		splash_clear(info->splash_data, vc, info,
79
 						sy, sx, height, width);
80
 		return;
81
 	}
82
#endif
67
	region.color = attr_bgcol_ec(bgshift, vc, info);
83
	region.color = attr_bgcol_ec(bgshift, vc, info);
68
	region.dx = sx * vc->vc_font.width;
84
	region.dx = sx * vc->vc_font.width;
69
	region.dy = sy * vc->vc_font.height;
85
	region.dy = sy * vc->vc_font.height;
Lines 161-166 Link Here
161
	image.height = vc->vc_font.height;
177
	image.height = vc->vc_font.height;
162
	image.depth = 1;
178
	image.depth = 1;
163
179
180
#ifdef CONFIG_BOOTSPLASH
181
	if (info->splash_data) {
182
		splash_putcs(info->splash_data, vc, info, s, count, yy, xx);
183
		return;
184
	}
185
#endif
186
164
	if (attribute) {
187
	if (attribute) {
165
		buf = kmalloc(cellsize, GFP_KERNEL);
188
		buf = kmalloc(cellsize, GFP_KERNEL);
166
		if (!buf)
189
		if (!buf)
Lines 214-219 Link Here
214
	unsigned int bs = info->var.yres - bh;
237
	unsigned int bs = info->var.yres - bh;
215
	struct fb_fillrect region;
238
	struct fb_fillrect region;
216
239
240
#ifdef CONFIG_BOOTSPLASH
241
 	if (info->splash_data) {
242
 		splash_clear_margins(info->splash_data, vc, info, bottom_only);
243
 		return;
244
 	}
245
#endif
246
217
	region.color = attr_bgcol_ec(bgshift, vc, info);
247
	region.color = attr_bgcol_ec(bgshift, vc, info);
218
	region.rop = ROP_COPY;
248
	region.rop = ROP_COPY;
219
249
Lines 380-385 Link Here
380
	cursor.image.depth = 1;
410
	cursor.image.depth = 1;
381
	cursor.rop = ROP_XOR;
411
	cursor.rop = ROP_XOR;
382
412
413
#ifdef CONFIG_BOOTSPLASH
414
	if (info->splash_data) {
415
		splash_cursor(info->splash_data, info, &cursor);
416
		ops->cursor_reset = 0;
417
		return;
418
	}
419
#endif
420
383
	if (info->fbops->fb_cursor)
421
	if (info->fbops->fb_cursor)
384
		err = info->fbops->fb_cursor(info, &cursor);
422
		err = info->fbops->fb_cursor(info, &cursor);
385
423
(-)linux-2.6.35/drivers/video/console/fbcon.c (-2 / +53 lines)
Lines 81-86 Link Here
81
81
82
#include "fbcon.h"
82
#include "fbcon.h"
83
83
84
#ifdef CONFIG_BOOTSPLASH
85
#include "../bootsplash/bootsplash.h"
86
#endif
87
84
#ifdef FBCONDEBUG
88
#ifdef FBCONDEBUG
85
#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
89
#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
86
#else
90
#else
Lines 94-101 Link Here
94
};
98
};
95
99
96
static struct display fb_display[MAX_NR_CONSOLES];
100
static struct display fb_display[MAX_NR_CONSOLES];
97
101
signed char con2fb_map[MAX_NR_CONSOLES];
98
static signed char con2fb_map[MAX_NR_CONSOLES];
99
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
102
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
100
103
101
static int logo_lines;
104
static int logo_lines;
Lines 537-542 Link Here
537
	for (i = first_fb_vc; i <= last_fb_vc; i++)
540
	for (i = first_fb_vc; i <= last_fb_vc; i++)
538
		con2fb_map[i] = info_idx;
541
		con2fb_map[i] = info_idx;
539
542
543
#ifdef CONFIG_BOOTSPLASH
544
	splash_init();
545
#endif
546
540
	err = take_over_console(&fb_con, first_fb_vc, last_fb_vc,
547
	err = take_over_console(&fb_con, first_fb_vc, last_fb_vc,
541
				fbcon_is_default);
548
				fbcon_is_default);
542
549
Lines 1099-1104 Link Here
1099
	new_cols /= vc->vc_font.width;
1106
	new_cols /= vc->vc_font.width;
1100
	new_rows /= vc->vc_font.height;
1107
	new_rows /= vc->vc_font.height;
1101
1108
1109
#ifdef CONFIG_BOOTSPLASH
1110
 	if (vc->vc_splash_data && vc->vc_splash_data->splash_state) {
1111
 		new_cols = vc->vc_splash_data->splash_text_wi / vc->vc_font.width;
1112
 		new_rows = vc->vc_splash_data->splash_text_he / vc->vc_font.height;
1113
 		logo = 0;
1114
 		con_remap_def_color(vc, vc->vc_splash_data->splash_color << 4 | vc->vc_splash_data->splash_fg_color);
1115
 	}
1116
#endif
1117
 			
1102
	/*
1118
	/*
1103
	 * We must always set the mode. The mode of the previous console
1119
	 * We must always set the mode. The mode of the previous console
1104
	 * driver could be in the same resolution but we are using different
1120
	 * driver could be in the same resolution but we are using different
Lines 1800-1805 Link Here
1800
			fbcon_softback_note(vc, t, count);
1816
			fbcon_softback_note(vc, t, count);
1801
		if (logo_shown >= 0)
1817
		if (logo_shown >= 0)
1802
			goto redraw_up;
1818
			goto redraw_up;
1819
#ifdef CONFIG_BOOTSPLASH
1820
		if (info->splash_data)
1821
			goto redraw_up;
1822
#endif
1803
		switch (p->scrollmode) {
1823
		switch (p->scrollmode) {
1804
		case SCROLL_MOVE:
1824
		case SCROLL_MOVE:
1805
			fbcon_redraw_blit(vc, info, p, t, b - t - count,
1825
			fbcon_redraw_blit(vc, info, p, t, b - t - count,
Lines 1889-1894 Link Here
1889
	case SM_DOWN:
1909
	case SM_DOWN:
1890
		if (count > vc->vc_rows)	/* Maximum realistic size */
1910
		if (count > vc->vc_rows)	/* Maximum realistic size */
1891
			count = vc->vc_rows;
1911
			count = vc->vc_rows;
1912
#ifdef CONFIG_BOOTSPLASH
1913
		if (info->splash_data)
1914
			goto redraw_down;
1915
#endif
1892
		if (logo_shown >= 0)
1916
		if (logo_shown >= 0)
1893
			goto redraw_down;
1917
			goto redraw_down;
1894
		switch (p->scrollmode) {
1918
		switch (p->scrollmode) {
Lines 2039-2044 Link Here
2039
		}
2063
		}
2040
		return;
2064
		return;
2041
	}
2065
	}
2066
2067
#ifdef CONFIG_BOOTSPLASH
2068
	if (info->splash_data && sy == dy && height == 1) {
2069
		/* must use slower redraw bmove to keep background pic intact */
2070
		splash_bmove_redraw(info->splash_data, vc, info, sy, sx, dx, width);
2071
		return;
2072
	}
2073
#endif
2042
	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2074
	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
2043
		   height, width);
2075
		   height, width);
2044
}
2076
}
Lines 2147-2152 Link Here
2147
	info = registered_fb[con2fb_map[vc->vc_num]];
2179
	info = registered_fb[con2fb_map[vc->vc_num]];
2148
	ops = info->fbcon_par;
2180
	ops = info->fbcon_par;
2149
2181
2182
#ifdef CONFIG_BOOTSPLASH
2183
	splash_prepare(vc, info);
2184
#endif
2185
2150
	if (softback_top) {
2186
	if (softback_top) {
2151
		if (softback_lines)
2187
		if (softback_lines)
2152
			fbcon_set_origin(vc);
2188
			fbcon_set_origin(vc);
Lines 2280-2285 Link Here
2280
{
2316
{
2281
	struct fb_event event;
2317
	struct fb_event event;
2282
2318
2319
#ifdef CONFIG_BOOTSPLASH
2320
	if (info->splash_data) {
2321
		splash_blank(info->splash_data, vc, info, blank);
2322
		return;
2323
	}
2324
#endif
2283
	if (blank) {
2325
	if (blank) {
2284
		unsigned short charmask = vc->vc_hi_font_mask ?
2326
		unsigned short charmask = vc->vc_hi_font_mask ?
2285
			0x1ff : 0xff;
2327
			0x1ff : 0xff;
Lines 2479-2488 Link Here
2479
	if (resize) {
2521
	if (resize) {
2480
		int cols, rows;
2522
		int cols, rows;
2481
2523
2524
		u32 xres = info->var.xres, yres = info->var.yres;
2482
		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2525
		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2483
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2526
		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2484
		cols /= w;
2527
		cols /= w;
2485
		rows /= h;
2528
		rows /= h;
2529
2530
#ifdef CONFIG_BOOTSPLASH
2531
		if (info->splash_data) {
2532
			xres = info->splash_data->splash_text_wi;
2533
			yres = info->splash_data->splash_text_he;
2534
		}
2535
#endif
2536
					
2486
		vc_resize(vc, cols, rows);
2537
		vc_resize(vc, cols, rows);
2487
		if (CON_IS_VISIBLE(vc) && softback_buf)
2538
		if (CON_IS_VISIBLE(vc) && softback_buf)
2488
			fbcon_update_softback(vc);
2539
			fbcon_update_softback(vc);
(-)linux-2.6.35/drivers/video/console/fbcon.h (+28 lines)
Lines 25-30 Link Here
25
    *    low-level frame buffer device
25
    *    low-level frame buffer device
26
    */
26
    */
27
27
28
#ifdef CONFIG_BOOTSPLASH
29
struct splash_data {
30
    int splash_state;			/* show splash? */
31
    int splash_color;			/* transparent color */
32
    int splash_fg_color;		/* foreground color */
33
    int splash_width;			/* width of image */
34
    int splash_height;			/* height of image */
35
    int splash_text_xo;			/* text area origin */
36
    int splash_text_yo;
37
    int splash_text_wi;			/* text area size */ 
38
    int splash_text_he;
39
    int splash_showtext;		/* silent/verbose mode */
40
    int splash_boxcount;
41
    int splash_percent;
42
    int splash_overpaintok;		/* is it ok to overpaint boxes */
43
    int splash_palcnt;
44
    char *oldscreen_base;		/* pointer to top of virtual screen */
45
    unsigned char *splash_boxes;
46
    unsigned char *splash_jpeg;		/* jpeg */
47
    unsigned char *splash_palette;	/* palette for 8-bit */
48
49
    int splash_dosilent;		/* show silent jpeg */
50
    unsigned char *splash_silentjpeg;
51
    unsigned char *splash_sboxes;
52
    int splash_sboxcount;
53
};
54
#endif
55
28
struct display {
56
struct display {
29
    /* Filled in by the low-level console driver */
57
    /* Filled in by the low-level console driver */
30
    const u_char *fontdata;
58
    const u_char *fontdata;
(-)linux-2.6.35/drivers/video/Kconfig (+4 lines)
Lines 2243-2246 Link Here
2243
	source "drivers/video/logo/Kconfig"
2243
	source "drivers/video/logo/Kconfig"
2244
endif
2244
endif
2245
2245
2246
if FB
2247
	source "drivers/video/bootsplash/Kconfig"
2248
endif
2249
2246
endmenu
2250
endmenu
(-)linux-2.6.35/drivers/video/Makefile (+1 lines)
Lines 14-19 Link Here
14
obj-$(CONFIG_VT)		  += console/
14
obj-$(CONFIG_VT)		  += console/
15
obj-$(CONFIG_LOGO)		  += logo/
15
obj-$(CONFIG_LOGO)		  += logo/
16
obj-y				  += backlight/ display/
16
obj-y				  += backlight/ display/
17
obj-$(CONFIG_BOOTSPLASH)	  += bootsplash/
17
18
18
obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
19
obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
19
obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
20
obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
(-)linux-2.6.35/drivers/video/vesafb.c (-1 / +9 lines)
Lines 181-187 Link Here
181
	framebuffer_release(info);
181
	framebuffer_release(info);
182
}
182
}
183
183
184
static struct fb_ops vesafb_ops = {
184
#ifndef CONFIG_BOOTSPLASH
185
static
186
#endif
187
struct fb_ops vesafb_ops = {
185
	.owner		= THIS_MODULE,
188
	.owner		= THIS_MODULE,
186
	.fb_destroy     = vesafb_destroy,
189
	.fb_destroy     = vesafb_destroy,
187
	.fb_setcolreg	= vesafb_setcolreg,
190
	.fb_setcolreg	= vesafb_setcolreg,
Lines 266-271 Link Here
266
	 *                 option to simply use size_total as that
269
	 *                 option to simply use size_total as that
267
	 *                 wastes plenty of kernel address space. */
270
	 *                 wastes plenty of kernel address space. */
268
	size_remap  = size_vmode * 2;
271
	size_remap  = size_vmode * 2;
272
	
273
#ifdef CONFIG_BOOTSPLASH
274
	size_remap *= 2;	/* some more for the images */
275
#endif
276
269
	if (vram_remap)
277
	if (vram_remap)
270
		size_remap = vram_remap * 1024 * 1024;
278
		size_remap = vram_remap * 1024 * 1024;
271
	if (size_remap < size_vmode)
279
	if (size_remap < size_vmode)
(-)linux-2.6.35/include/linux/console_struct.h (+5 lines)
Lines 105-110 Link Here
105
	struct vc_data **vc_display_fg;		/* [!] Ptr to var holding fg console for this display */
105
	struct vc_data **vc_display_fg;		/* [!] Ptr to var holding fg console for this display */
106
	unsigned long	vc_uni_pagedir;
106
	unsigned long	vc_uni_pagedir;
107
	unsigned long	*vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
107
	unsigned long	*vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
108
	
109
#ifdef CONFIG_BOOTSPLASH
110
        struct splash_data *vc_splash_data;
111
#endif
112
108
	/* additional information is in vt_kern.h */
113
	/* additional information is in vt_kern.h */
109
};
114
};
110
115
(-)linux-2.6.35/include/linux/fb.h (+8 lines)
Lines 858-863 Link Here
858
	void *fbcon_par;                /* fbcon use-only private area */
858
	void *fbcon_par;                /* fbcon use-only private area */
859
	/* From here on everything is device dependent */
859
	/* From here on everything is device dependent */
860
	void *par;
860
	void *par;
861
#ifdef CONFIG_BOOTSPLASH
862
 	struct splash_data *splash_data;
863
 	unsigned char *splash_pic;
864
 	int splash_pic_size;
865
 	int splash_bytes;
866
 	char *silent_screen_base;	/* real screen base */
867
 	char fb_cursordata[64];
868
#endif
861
	/* we need the PCI or similiar aperture base/size not
869
	/* we need the PCI or similiar aperture base/size not
862
	   smem_start/size as smem_start may just be an object
870
	   smem_start/size as smem_start may just be an object
863
	   allocated inside the aperture so may not actually overlap */
871
	   allocated inside the aperture so may not actually overlap */

Return to bug 23783