Home Home > GIT Browse > openSUSE-15.0
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEgbert Eich <eich@suse.de>2011-08-18 11:38:15 +0200
committerEgbert Eich <eich@suse.de>2011-08-18 11:38:15 +0200
commit6beb4413bebc9a37e9bf64da6da044227b9c0333 (patch)
treedc90cf90d4b7b905f82bcb40da56a6e7c4c8984f
parent690965465a6c61d812518712531e2a767460eef5 (diff)
* Refresh patches.suse/SUSE-bootsplash.rpm-3.0.0-4--openSUSE-12.1-Milestone5rpm-3.0.0-4
* Fix bootsplash code for 15bpp framebuffers. These framebuffers are rare these days, the legendary and still popular server chipset Radeon ES1000 supports it, though. suse-commit: f25ce3ee68e7642e2394493bc6385e018dee1030
-rw-r--r--drivers/video/bootsplash/bootsplash.c240
-rw-r--r--drivers/video/bootsplash/decode-jpg.c73
-rw-r--r--drivers/video/bootsplash/decode-jpg.h3
-rw-r--r--include/linux/bootsplash.h12
4 files changed, 228 insertions, 100 deletions
diff --git a/drivers/video/bootsplash/bootsplash.c b/drivers/video/bootsplash/bootsplash.c
index d044ce91280f..4ab2ca97ee2a 100644
--- a/drivers/video/bootsplash/bootsplash.c
+++ b/drivers/video/bootsplash/bootsplash.c
@@ -66,7 +66,7 @@ static int splash_usesilent;
static unsigned long splash_default = 0xf01;
static int jpeg_get(unsigned char *buf, unsigned char *pic,
- int width, int height, int depth,
+ int width, int height, enum splash_color_format cf,
struct jpeg_decdata *decdata);
static int splash_look_for_jpeg(struct vc_data *vc, int width, int height);
@@ -85,7 +85,9 @@ static int __init splash_setup(char *options)
if (!strncmp("verbose", options, 7)) {
printk(KERN_INFO "bootsplash: verbose mode.\n");
splash_usesilent = 0;
- return 0;
+ if (strlen(options) == 7)
+ return 0;
+ options += 8;
}
if (strict_strtoul(options, 0, &splash_default) == -EINVAL)
splash_default = 0;
@@ -130,7 +132,8 @@ static int boxextract(unsigned char *buf, unsigned short *dp,
}
static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num,
- int percent, int xoff, int yoff, int overpaint, int octpp)
+ int percent, int xoff, int yoff, int overpaint,
+ enum splash_color_format cf)
{
int x, y, p, doblend, r, g, b, a, add;
unsigned int i = 0;
@@ -142,6 +145,7 @@ static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num,
union pt picp;
unsigned int stipple[32], sti, stin, stinn, stixs, stixe, stiys, stiye;
int xs, xe, ys, ye, xo, yo;
+ int octpp = splash_octpp(cf);
SPLASH_DEBUG();
if (num == 0 || percent < -1)
@@ -309,8 +313,23 @@ static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num,
b = cols2[2];
#define CLAMP(x) ((x) >= 256 ? 255 : (x))
#define BLEND(x, v, a) ((x * (255 - a) + v * a) / 255)
- switch (octpp) {
- case 2:
+ switch (cf) {
+ case SPLASH_DEPTH_15:
+ if (a != 255) {
+ i = *picp.us;
+ r = BLEND((i>>7 & 0xf8), r, a);
+ g = BLEND((i>>2 & 0xf8), g, a);
+ b = BLEND((i<<3 & 0xf8), b, a);
+ }
+ r += add * 2 + 1;
+ g += add;
+ b += add * 2 + 1;
+ i = ((CLAMP(r) & 0xf8) << 7) |
+ ((CLAMP(g) & 0xf8) << 2) |
+ ((CLAMP(b)) >> 3);
+ *(picp.us++) = i;
+ break;
+ case SPLASH_DEPTH_16:
if (a != 255) {
i = *picp.us;
r = BLEND((i>>8 & 0xf8), r, a);
@@ -320,12 +339,12 @@ static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num,
r += add * 2 + 1;
g += add;
b += add * 2 + 1;
- i = ((CLAMP(r) & 0xf8) << 8) |
- ((CLAMP(g) & 0xfc) << 3) |
- ((CLAMP(b)) >> 3);
+ i = ((CLAMP(r) & 0xf8) << 8) |
+ ((CLAMP(g) & 0xfc) << 3) |
+ ((CLAMP(b)) >> 3);
*(picp.us++) = i;
break;
- case 3:
+ case SPLASH_DEPTH_24_PACKED:
if (a != 255) {
i = *picp.ub;
r = BLEND((i & 0xff), r, a);
@@ -337,9 +356,8 @@ static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num,
*(picp.ub++) = CLAMP(r);
*(picp.ub++) = CLAMP(g);
*(picp.ub++) = CLAMP(b);
- picp.ub += 3;
break;
- case 4:
+ case SPLASH_DEPTH_24:
if (a != 255) {
i = *picp.ul;
r = BLEND((i>>16 & 0xff), r, a);
@@ -351,6 +369,8 @@ static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num,
| (CLAMP(b)));
*(picp.ul++) = i;
break;
+ default:
+ break;
}
add ^= 3;
}
@@ -507,15 +527,14 @@ static void box_offsets(unsigned char *buf, int num,
}
static int splash_check_jpeg(unsigned char *jpeg,
- int width, int height, int depth)
+ int width, int height)
{
int size, err;
unsigned char *mem;
struct jpeg_decdata *decdata; /* private decoder data */
- size = ((width + 15) & ~15) * ((height + 15) & ~15)
- * ((depth + 1) >> 3);
+ size = ((width + 15) & ~15) * ((height + 15) & ~15) * 2;
mem = vmalloc(size);
if (!mem) {
printk(KERN_INFO "bootsplash: no memory for decoded picture.\n");
@@ -527,8 +546,10 @@ static int splash_check_jpeg(unsigned char *jpeg,
vfree(mem);
return -1;
}
+ /* test decode: use fixed depth of 16 */
err = jpeg_decode(jpeg, mem,
- ((width + 15) & ~15), ((height + 15) & ~15), depth,
+ ((width + 15) & ~15), ((height + 15) & ~15),
+ SPLASH_DEPTH_16,
decdata);
if (err)
printk(KERN_INFO "bootsplash: "
@@ -930,8 +951,8 @@ static int splash_getraw(unsigned char *start, unsigned char *end, int *update)
jpeg_get_size(ndata + len + boxcnt * 12 + palcnt,
&imgd->splash_width, &imgd->splash_height);
if (splash_check_jpeg(ndata + len + boxcnt * 12 + palcnt,
- imgd->splash_width, imgd->splash_height,
- info ? info->var.bits_per_pixel : 16)) {
+ imgd->splash_width,
+ imgd->splash_height)) {
ndata += len + splash_size - 1;
vfree(imgd);
vfree(sd);
@@ -961,7 +982,6 @@ static int splash_getraw(unsigned char *start, unsigned char *end, int *update)
imgd->splash_text_he *= 16;
imgd->splash_color = (splash_default >> 8) & 0x0f;
imgd->splash_fg_color = (splash_default >> 4) & 0x0f;
- sd->splash_state = splash_default & 1; /*@!@*/
}
/* fake penguin box for older formats */
@@ -1229,7 +1249,8 @@ static int splash_recolor(struct vc_data *vc, struct fb_info *info)
int splash_prepare(struct vc_data *vc, struct fb_info *info)
{
int err;
- int width, height, depth, octpp, size, sbytes;
+ int width, height, octpp, size, sbytes;
+ enum splash_color_format cf = SPLASH_DEPTH_UNKNOWN;
int pic_update = 0;
struct jpeg_decdata *decdata; /* private decoder data */
@@ -1251,13 +1272,30 @@ int splash_prepare(struct vc_data *vc, struct fb_info *info)
width = info->var.xres;
height = info->var.yres;
- depth = info->var.bits_per_pixel;
- octpp = (depth + 1) >> 3;
-
- if (depth == 24 || depth < 15) { /* Other targets might need fixing */
+ switch (info->var.bits_per_pixel) {
+ case 16:
+ if ((info->var.red.length +
+ info->var.green.length +
+ info->var.blue.length) == 15)
+ cf = SPLASH_DEPTH_15;
+ else
+ cf = SPLASH_DEPTH_16;
+ break;
+ case 24:
+ cf = SPLASH_DEPTH_24_PACKED;
+ break;
+ case 32:
+ cf = SPLASH_DEPTH_24;
+ break;
+ }
+ if (cf == SPLASH_DEPTH_UNKNOWN) {
+ printk(KERN_INFO "bootsplash: unsupported pixel format: %i\n",
+ info->var.bits_per_pixel);
splash_off(vc, info);
return -2;
}
+ octpp = splash_octpp(cf);
+
if (splash_look_for_jpeg(vc, width, height) < 0) {
printk(KERN_INFO "bootsplash: no matching splash %dx%d\n",
width, height);
@@ -1303,7 +1341,7 @@ int splash_prepare(struct vc_data *vc, struct fb_info *info)
pic_update = 1;
err = jpeg_get(vc->vc_splash_data->imgd->splash_silentjpeg,
vc->vc_splash_data->pic->splash_pic,
- width, height, depth, decdata);
+ width, height, cf, decdata);
if (err) {
printk(KERN_INFO "bootsplash: "
"error while decompressing silent picture: "
@@ -1321,7 +1359,7 @@ int splash_prepare(struct vc_data *vc, struct fb_info *info)
vc->vc_splash_data->splash_sboxes_yoff,
vc->vc_splash_data->splash_percent < 0 ?
1 : 0,
- octpp);
+ cf);
splashcopy(info->screen_base,
vc->vc_splash_data->pic->splash_pic,
info->var.yres,
@@ -1335,7 +1373,7 @@ int splash_prepare(struct vc_data *vc, struct fb_info *info)
if (pic_update) {
err = jpeg_get(vc->vc_splash_data->imgd->splash_jpeg,
vc->vc_splash_data->pic->splash_pic,
- width, height, depth, decdata);
+ width, height, cf, decdata);
if (err) {
printk(KERN_INFO "bootsplash: "
"error while decompressing picture: %s (%d) .\n",
@@ -1359,7 +1397,7 @@ int splash_prepare(struct vc_data *vc, struct fb_info *info)
vc->vc_splash_data->splash_boxes_xoff,
vc->vc_splash_data->splash_boxes_yoff,
0,
- octpp);
+ cf);
if (vc->vc_splash_data->splash_state) {
int cols = vc->vc_splash_data->splash_vc_text_wi
/ vc->vc_font.width;
@@ -1374,6 +1412,7 @@ int splash_prepare(struct vc_data *vc, struct fb_info *info)
if (!vc->vc_splash_data->color_set)
splash_recolor(vc, NULL);
} else {
+ SPLASH_DEBUG("Splash Status is off\n");
splash_off(vc, info);
return -5;
}
@@ -1565,9 +1604,26 @@ void splash_set_percent(struct vc_data *vc, int pe)
} else
splash_prepare(vc, info);
} else {
- int octpp = (info->var.bits_per_pixel + 1) >> 3;
struct splash_data *splash_data = info->splash_data;
-
+ enum splash_color_format cf = SPLASH_DEPTH_UNKNOWN;
+ switch (info->var.bits_per_pixel) {
+ case 16:
+ if ((info->var.red.length +
+ info->var.green.length +
+ info->var.blue.length) == 15)
+ cf = SPLASH_DEPTH_15;
+ else
+ cf = SPLASH_DEPTH_16;
+ break;
+ case 24:
+ cf = SPLASH_DEPTH_24_PACKED;
+ break;
+ case 32:
+ cf = SPLASH_DEPTH_24;
+ break;
+ }
+ if (cf == SPLASH_DEPTH_UNKNOWN)
+ return;
if (splash_data) {
if (splash_data->imgd->splash_silentjpeg
&& splash_data->splash_dosilent)
@@ -1579,19 +1635,7 @@ void splash_set_percent(struct vc_data *vc, int pe)
splash_data->splash_sboxes_xoff,
splash_data->splash_sboxes_yoff,
1,
- octpp);
-#if 0
- if (!info->splash_dosilent)
- boxit(info->screen_base,
- info->fix.line_length,
- splash_data->imgd->splash_boxes,
- splash_data->imgd->splash_boxcount,
- splash_data->splash_percent,
- splash_data->splash_boxes_xoff,
- splash_data->splash_boxes_yoff,
- 1,
- octpp);
-#endif
+ cf);
}
}
}
@@ -1752,7 +1796,26 @@ static int splash_write_proc(struct file *file, const char *buffer,
struct splash_data *splash_data
= info->splash_data;
struct fbcon_ops *ops = info->fbcon_par;
- int octpp = (info->var.bits_per_pixel + 1) >> 3;
+ enum splash_color_format cf = SPLASH_DEPTH_UNKNOWN;
+
+ switch (info->var.bits_per_pixel) {
+ case 16:
+ if ((info->var.red.length +
+ info->var.green.length +
+ info->var.blue.length) == 15)
+ cf = SPLASH_DEPTH_15;
+ else
+ cf = SPLASH_DEPTH_16;
+ break;
+ case 24:
+ cf = SPLASH_DEPTH_24_PACKED;
+ break;
+ case 32:
+ cf = SPLASH_DEPTH_24;
+ break;
+ }
+ if (cf == SPLASH_DEPTH_UNKNOWN)
+ up = 0;
if (ops->blank_state ||
!vc_splash_data ||
!splash_data)
@@ -1768,7 +1831,7 @@ static int splash_write_proc(struct file *file, const char *buffer,
splash_data->splash_sboxes_xoff,
splash_data->splash_sboxes_yoff,
1,
- octpp);
+ cf);
} else if ((up & 1) != 0) {
boxit(info->screen_base,
info->fix.line_length,
@@ -1778,7 +1841,7 @@ static int splash_write_proc(struct file *file, const char *buffer,
splash_data->splash_boxes_xoff,
splash_data->splash_boxes_yoff,
1,
- octpp);
+ cf);
}
}
}
@@ -1847,8 +1910,7 @@ void splash_init(void)
info = registered_fb[(int)con2fb_map[INIT_CONSOLE]];
if (!vc
|| !info
- || info->var.bits_per_pixel == 24 /* not tested */
- || info->var.bits_per_pixel < 15) /* not supported */
+ || info->var.bits_per_pixel < 16) /* not supported */
return;
#ifdef CONFIG_PROC_FS
splash_proc_register();
@@ -1997,59 +2059,63 @@ struct pixel {
u32 blue;
};
-#define put_pixel(pix, buf, depth) \
- switch (depth) { \
- case 15: \
+#define put_pixel(pix, buf, cf) \
+ switch (cf) { \
+ case SPLASH_DEPTH_15: \
*(u16 *)(buf) = (u16)((pix).red << 10 | \
(pix).green << 5 | (pix).blue); \
(buf) += 2; \
break; \
- case 16: \
+ case SPLASH_DEPTH_16: \
*(u16 *)(buf) = (u16)((pix).red << 11 | \
(pix).green << 5 | (pix).blue); \
(buf) += 2; \
break; \
- case 24: \
+ case SPLASH_DEPTH_24_PACKED: \
*(u16 *)(buf) = (u16)((pix).red << 8 | (pix).green); \
buf += 2; \
*((buf)++) = (pix).blue; \
break; \
- case 32: \
+ case SPLASH_DEPTH_24: \
*(u32 *)(buf) = (u32)((pix).red << 16 | \
(pix).green << 8 | (pix).blue); \
(buf) += 4; \
break; \
+ case SPLASH_DEPTH_UNKNOWN: \
+ break; \
}
#define get_pixel(pix, buf, depth) \
switch (depth) { \
- case 15: \
+ case SPLASH_DEPTH_15: \
(pix).red = ((*(u16 *)(buf)) >> 10) & 0x1f; \
(pix).green = ((*(u16 *)(buf)) >> 5) & 0x1f; \
(pix).blue = (*(u16 *)(buf)) & 0x1f; \
(buf) += 2; \
break; \
- case 16: \
+ case SPLASH_DEPTH_16: \
(pix).red = ((*(u16 *)(buf)) >> 11) & 0x1f; \
(pix).green = ((*(u16 *)(buf)) >> 5) & 0x3f; \
(pix).blue = (*(u16 *)(buf)) & 0x1f; \
(buf) += 2; \
break; \
- case 24: \
+ case SPLASH_DEPTH_24_PACKED: \
(pix).blue = *(((buf))++); \
(pix).green = *(((buf))++); \
(pix).red = *(((buf))++); \
break; \
- case 32: \
+ case SPLASH_DEPTH_24: \
(pix).blue = *(((buf))++); \
(pix).green = *(((buf))++); \
(pix).red = *(((buf))++); \
(buf)++; \
break; \
+ case SPLASH_DEPTH_UNKNOWN: \
+ break; \
}
static inline void
-scale_x_down(int depth, int src_w,
+scale_x_down(enum splash_color_format cf, int src_w,
unsigned char **src_p, u32 *x_coeff,
u32 x_shift, u32 y_coeff, struct pixel *row_buffer)
{
@@ -2064,7 +2130,7 @@ scale_x_down(int depth, int src_w,
for (i = 0; i < src_w; ) {
curr_x_coeff = 1;
- get_pixel(tmp_pixel, *src_p, depth);
+ get_pixel(tmp_pixel, *src_p, cf);
i++;
for (l = 0; l < x_array_size; l++) {
x_column_num = x_coeff[curr_x_coeff++];
@@ -2079,7 +2145,7 @@ scale_x_down(int depth, int src_w,
curr_pixel.blue += tmp_pixel.blue
* x_coeff[curr_x_coeff];
curr_x_coeff++;
- get_pixel(tmp_pixel, *src_p, depth);
+ get_pixel(tmp_pixel, *src_p, cf);
i++;
}
curr_pixel.red += tmp_pixel.red * x_coeff[curr_x_coeff];
@@ -2100,7 +2166,8 @@ scale_x_down(int depth, int src_w,
}
static inline void
-scale_x_up(int depth, int src_w, unsigned char **src_p, u32 *x_coeff,
+scale_x_up(enum splash_color_format cf, int src_w,
+ unsigned char **src_p, u32 *x_coeff,
u32 x_shift, u32 y_coeff, struct pixel *row_buffer)
{
u32 curr_x_coeff = 1;
@@ -2114,7 +2181,7 @@ scale_x_up(int depth, int src_w, unsigned char **src_p, u32 *x_coeff,
for (i = 0; i < src_w;) {
curr_x_coeff = 1;
- get_pixel(tmp_pixel, *src_p, depth);
+ get_pixel(tmp_pixel, *src_p, cf);
i++;
for (l = 0; l < x_array_size - 1; l++) {
x_column_num = x_coeff[curr_x_coeff++];
@@ -2129,7 +2196,7 @@ scale_x_up(int depth, int src_w, unsigned char **src_p, u32 *x_coeff,
* x_coeff[curr_x_coeff];
curr_pixel.blue = tmp_pixel.blue * x_coeff[curr_x_coeff];
curr_x_coeff++;
- get_pixel(tmp_pixel, *src_p, depth);
+ get_pixel(tmp_pixel, *src_p, cf);
i++;
row_buffer[k].red += ((curr_pixel.red
+ (tmp_pixel.red
@@ -2156,9 +2223,10 @@ scale_x_up(int depth, int src_w, unsigned char **src_p, u32 *x_coeff,
}
static int scale_y_down(unsigned char *src, unsigned char *dst,
- int depth, int src_w, int src_h, int dst_w, int dst_h)
+ enum splash_color_format cf,
+ int src_w, int src_h, int dst_w, int dst_h)
{
- int octpp = (depth + 1) >> 3;
+ int octpp = splash_octpp(cf);
int src_x_bytes = octpp * ((src_w + SPLASH_ALIGN) & ~SPLASH_ALIGN);
int dst_x_bytes = octpp * ((dst_w + SPLASH_ALIGN) & ~SPLASH_ALIGN);
int j;
@@ -2204,11 +2272,11 @@ static int scale_y_down(unsigned char *src, unsigned char *dst,
}
src_p = src_p_line;
if (xup)
- scale_x_up(depth, src_w, &src_p, x_coeff,
+ scale_x_up(cf, src_w, &src_p, x_coeff,
x_shift, y_coeff[curr_y_coeff],
row_buffer);
else
- scale_x_down(depth, src_w, &src_p, x_coeff,
+ scale_x_down(cf, src_w, &src_p, x_coeff,
x_shift, y_coeff[curr_y_coeff],
row_buffer);
curr_y_coeff++;
@@ -2216,12 +2284,12 @@ static int scale_y_down(unsigned char *src, unsigned char *dst,
src_p = src_p_line = src_p_line + src_x_bytes;
j++;
if (xup)
- scale_x_up(depth, src_w, &src_p,
+ scale_x_up(cf, src_w, &src_p,
x_coeff, x_shift,
y_coeff[curr_y_coeff],
row_buffer);
else
- scale_x_down(depth, src_w, &src_p,
+ scale_x_down(cf, src_w, &src_p,
x_coeff, x_shift,
y_coeff[curr_y_coeff],
row_buffer);
@@ -2235,7 +2303,7 @@ static int scale_y_down(unsigned char *src, unsigned char *dst,
>> y_shift;
row_buffer[k].blue = (row_buffer[k].blue + rnd)
>> y_shift;
- put_pixel(row_buffer[k], dst, depth);
+ put_pixel(row_buffer[k], dst, cf);
}
dst = dst_p_line = dst_p_line + dst_x_bytes;
}
@@ -2249,9 +2317,10 @@ static int scale_y_down(unsigned char *src, unsigned char *dst,
}
static int scale_y_up(unsigned char *src, unsigned char *dst,
- int depth, int src_w, int src_h, int dst_w, int dst_h)
+ enum splash_color_format cf,
+ int src_w, int src_h, int dst_w, int dst_h)
{
- int octpp = (depth + 1) >> 3;
+ int octpp = splash_octpp(cf);
int src_x_bytes = octpp * ((src_w + SPLASH_ALIGN) & ~SPLASH_ALIGN);
int dst_x_bytes = octpp * ((dst_w + SPLASH_ALIGN) & ~SPLASH_ALIGN);
int j;
@@ -2301,10 +2370,10 @@ static int scale_y_up(unsigned char *src, unsigned char *dst,
* (dst_w + 1)));
curr_y_coeff = 1;
if (xup)
- scale_x_up(depth, src_w, &src_p, x_coeff,
+ scale_x_up(cf, src_w, &src_p, x_coeff,
x_shift, 1, row_buffer);
else
- scale_x_down(depth, src_w, &src_p, x_coeff, x_shift, 1,
+ scale_x_down(cf, src_w, &src_p, x_coeff, x_shift, 1,
row_buffer);
src_p = src_p_line = src_p_line + src_x_bytes;
j++;
@@ -2315,7 +2384,7 @@ static int scale_y_up(unsigned char *src, unsigned char *dst,
y_column_num = y_coeff[curr_y_coeff];
for (s = 0; s < y_column_num; s++) {
for (k = 0; k < dst_w; k++)
- put_pixel(row_buffer[k], dst, depth);
+ put_pixel(row_buffer[k], dst, cf);
dst = dst_p_line = dst_p_line + dst_x_bytes;
writes++;
}
@@ -2323,10 +2392,10 @@ static int scale_y_up(unsigned char *src, unsigned char *dst,
row_buffer = row_buf_list[(bi++) % 2];
prev_y_coeff_val = y_coeff[curr_y_coeff++];
if (xup)
- scale_x_up(depth, src_w, &src_p, x_coeff,
+ scale_x_up(cf, src_w, &src_p, x_coeff,
x_shift, 1, row_buffer);
else
- scale_x_down(depth, src_w, &src_p, x_coeff,
+ scale_x_down(cf, src_w, &src_p, x_coeff,
x_shift, 1, row_buffer);
src_p = src_p_line = src_p_line + src_x_bytes;
j++;
@@ -2350,7 +2419,7 @@ static int scale_y_up(unsigned char *src, unsigned char *dst,
old_row_buffer[k].red = 0;
old_row_buffer[k].green = 0;
old_row_buffer[k].blue = 0;
- put_pixel(pix, dst, depth);
+ put_pixel(pix, dst, cf);
}
dst = dst_p_line = dst_p_line + dst_x_bytes;
writes++;
@@ -2358,7 +2427,7 @@ static int scale_y_up(unsigned char *src, unsigned char *dst,
}
for (r = 0; r < y_coeff[curr_y_coeff]; r++) {
for (k = 0; k < dst_w; k++)
- put_pixel(row_buffer[k], dst, depth);
+ put_pixel(row_buffer[k], dst, cf);
dst = dst_p_line = dst_p_line + dst_x_bytes;
writes++;
@@ -2372,22 +2441,23 @@ static int scale_y_up(unsigned char *src, unsigned char *dst,
}
static int jpeg_get(unsigned char *buf, unsigned char *pic,
- int width, int height, int depth,
+ int width, int height, enum splash_color_format cf,
struct jpeg_decdata *decdata)
{
int my_width, my_height;
int err;
+ int octpp = splash_octpp(cf);
jpeg_get_size(buf, &my_width, &my_height);
if (my_height != height || my_width != width) {
int my_size = ((my_width + 15) & ~15)
- * ((my_height + 15) & ~15) * ((depth + 1) >> 3);
+ * ((my_height + 15) & ~15) * octpp;
unsigned char *mem = vmalloc(my_size);
if (!mem)
return 17;
err = jpeg_decode(buf, mem, ((my_width + 15) & ~15),
- ((my_height + 15) & ~15), depth, decdata);
+ ((my_height + 15) & ~15), cf, decdata);
if (err) {
vfree(mem);
return err;
@@ -2396,11 +2466,11 @@ static int jpeg_get(unsigned char *buf, unsigned char *pic,
"bootsplash: scaling image from %dx%d to %dx%d\n",
my_width, my_height, width, height);
if (my_height <= height)
- err = scale_y_up(mem, pic, depth, my_width, my_height,
+ err = scale_y_up(mem, pic, cf, my_width, my_height,
((width + 15) & ~15),
((height + 15) & ~15));
else
- err = scale_y_down(mem, pic, depth, my_width, my_height,
+ err = scale_y_down(mem, pic, cf, my_width, my_height,
((width + 15) & ~15),
((height + 15) & ~15));
vfree(mem);
@@ -2408,7 +2478,7 @@ static int jpeg_get(unsigned char *buf, unsigned char *pic,
return 17;
} else {
err = jpeg_decode(buf, pic, ((width + 15) & ~15),
- ((height + 15) & ~15), depth, decdata);
+ ((height + 15) & ~15), cf, decdata);
if (err)
return err;
}
diff --git a/drivers/video/bootsplash/decode-jpg.c b/drivers/video/bootsplash/decode-jpg.c
index ee1e3292f4ec..617632e680f9 100644
--- a/drivers/video/bootsplash/decode-jpg.c
+++ b/drivers/video/bootsplash/decode-jpg.c
@@ -7,7 +7,7 @@
#include <linux/string.h>
#include <asm/byteorder.h>
-
+#include <linux/bootsplash.h>
#include "decode-jpg.h"
#define ISHIFT 11
@@ -80,9 +80,10 @@ static void scaleidctqtab(PREC *, PREC);
static void initcol(PREC[][64]);
-static void col221111(int *, unsigned char *, int);
-static void col221111_16(int *, unsigned char *, int);
-static void col221111_32(int *, unsigned char *, int);
+static void col221111(int *out, unsigned char *pic, int width);
+static void col221111_15(int *out, unsigned char *pic, int width);
+static void col221111_16(int *out, unsigned char *pic, int width);
+static void col221111_32(int *out, unsigned char *pic, int width);
/*********************************/
@@ -250,7 +251,7 @@ void jpeg_get_size(unsigned char *buf, int *width, int *height)
}
int jpeg_decode(unsigned char *buf, unsigned char *pic,
- int width, int height, int depth,
+ int width, int height, enum splash_color_format cf,
struct jpeg_decdata *decdata)
{
int i, j, m, tac, tdc;
@@ -377,24 +378,29 @@ int jpeg_decode(unsigned char *buf, unsigned char *pic,
decdata->out + 320,
decdata->dquant[2], IFIX(0.5), max[5]);
- switch (depth) {
- case 32:
+ switch (cf) {
+ case SPLASH_DEPTH_24:
col221111_32(decdata->out,
(pic + (my * 16 * mcusx + mx)
* 16 * 4),
mcusx * 16 * 4);
break;
- case 24:
+ case SPLASH_DEPTH_24_PACKED:
col221111(decdata->out,
(pic + (my * 16 * mcusx + mx)
* 16 * 3),
mcusx * 16 * 3);
break;
- case 16:
+ case SPLASH_DEPTH_16:
col221111_16(decdata->out,
(pic + (my * 16 * mcusx + mx)
* 16 * 2), mcusx * 16 * 2);
break;
+ case SPLASH_DEPTH_15:
+ col221111_15(decdata->out,
+ (pic + (my * 16 * mcusx + mx)
+ * 16 * 2), mcusx * 16 * 2);
+ break;
default:
return ERR_DEPTH_MISMATCH;
break;
@@ -856,6 +862,16 @@ PREC q[][64];
)
#ifdef __LITTLE_ENDIAN
+#define PIC_15(yin, xin, p, xout, add) \
+ ( \
+ y = outy[(yin) * 8 + xin], \
+ y = ((CLAMP(y + cr + add * 2 + 1) & 0xf8) << 7) | \
+ ((CLAMP(y - cg + add * 2 + 1) & 0xf8) << 2) | \
+ ((CLAMP(y + cb + add * 2 + 1)) >> 3), \
+ p[(xout) * 2 + 0] = y & 0xff, \
+ p[(xout) * 2 + 1] = y >> 8 \
+ )
+
#define PIC_16(yin, xin, p, xout, add) \
( \
y = outy[(yin) * 8 + xin], \
@@ -866,8 +882,7 @@ PREC q[][64];
p[(xout) * 2 + 1] = y >> 8 \
)
#else
-#ifdef CONFIG_PPC
-#define PIC_16(yin, xin, p, xout, add) \
+#define PIC_15(yin, xin, p, xout, add) \
( \
y = outy[(yin) * 8 + xin], \
y = ((CLAMP(y + cr + add * 2 + 1) & 0xf8) << 7) | \
@@ -876,7 +891,7 @@ PREC q[][64];
p[(xout) * 2 + 0] = y >> 8, \
p[(xout) * 2 + 1] = y & 0xff \
)
-#else
+
#define PIC_16(yin, xin, p, xout, add) \
( \
y = outy[(yin) * 8 + xin], \
@@ -887,7 +902,6 @@ PREC q[][64];
p[(xout) * 2 + 1] = y & 0xff \
)
#endif
-#endif
#define PIC_32(yin, xin, p, xout) \
( \
@@ -907,6 +921,15 @@ PREC q[][64];
PIC(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
)
+#define PIC221111_15(xin) \
+ ( \
+ CBCRCG(0, xin), \
+ PIC_15(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0, 3), \
+ PIC_15(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1, 0), \
+ PIC_15(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0, 1), \
+ PIC_15(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
+ )
+
#define PIC221111_16(xin) \
( \
CBCRCG(0, xin), \
@@ -949,6 +972,30 @@ static void col221111(int *out, unsigned char *pic, int width)
}
}
+static void col221111_15(int *out, unsigned char *pic, int width)
+{
+ int i, j, k;
+ unsigned char *pic0, *pic1;
+ int *outy, *outc;
+ int cr, cg, cb, y;
+
+ pic0 = pic;
+ pic1 = pic + width;
+ outy = out;
+ outc = out + 64 * 4;
+ for (i = 2; i > 0; i--) {
+ for (j = 4; j > 0; j--) {
+ for (k = 0; k < 8; k++)
+ PIC221111_15(k);
+ outc += 8;
+ outy += 16;
+ pic0 += 2 * width;
+ pic1 += 2 * width;
+ }
+ outy += 64 * 2 - 16 * 4;
+ }
+}
+
static void col221111_16(int *out, unsigned char *pic, int width)
{
int i, j, k;
diff --git a/drivers/video/bootsplash/decode-jpg.h b/drivers/video/bootsplash/decode-jpg.h
index 712ba5a1a4e7..241fab87a91c 100644
--- a/drivers/video/bootsplash/decode-jpg.h
+++ b/drivers/video/bootsplash/decode-jpg.h
@@ -29,7 +29,8 @@ struct jpeg_decdata {
int dquant[3][64];
};
-extern int jpeg_decode(unsigned char *, unsigned char *, int, int, int,
+extern int jpeg_decode(unsigned char *buf, unsigned char *pic,
+ int width, int height, enum splash_color_format cf,
struct jpeg_decdata *);
extern void jpeg_get_size(unsigned char *, int *, int *);
diff --git a/include/linux/bootsplash.h b/include/linux/bootsplash.h
index 223f2160b25e..3c99eb38f551 100644
--- a/include/linux/bootsplash.h
+++ b/include/linux/bootsplash.h
@@ -20,6 +20,16 @@ union pt {
u8 *ub;
};
+enum splash_color_format {
+ SPLASH_DEPTH_UNKNOWN = 0,
+ SPLASH_DEPTH_15 = 15,
+ SPLASH_DEPTH_16 = 16,
+ SPLASH_DEPTH_24_PACKED = 24,
+ SPLASH_DEPTH_24 = 32
+};
+
+#define splash_octpp(cf) (((int)cf + 1) >> 3)
+
struct vc_data;
struct fb_info;
struct fb_cursor;
@@ -35,7 +45,7 @@ extern void splash_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count,
int ypos, int xpos);
extern void splashcopy(u8 *dst, u8 *src, int height, int width,
- int dstbytes, int srcbytes, int depth);
+ int dstbytes, int srcbytes, int octpp);
extern void splash_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width);
extern void splash_bmove(struct vc_data *vc, struct fb_info *info, int sy,