socsvn commit: r269253 - in soc2014/seiya/bootsplash/sys: conf dev/fb dev/syscons modules/bsplash modules/splash/bmp
seiya at FreeBSD.org
seiya at FreeBSD.org
Sun Jun 8 13:20:55 UTC 2014
Author: seiya
Date: Sun Jun 8 13:20:51 2014
New Revision: 269253
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269253
Log:
enhance bmp decoder
Modified:
soc2014/seiya/bootsplash/sys/conf/files
soc2014/seiya/bootsplash/sys/dev/fb/bmp.c
soc2014/seiya/bootsplash/sys/dev/fb/bmp.h
soc2014/seiya/bootsplash/sys/dev/fb/bsplash.c
soc2014/seiya/bootsplash/sys/dev/fb/splash_bmp.c
soc2014/seiya/bootsplash/sys/dev/syscons/syscons.c
soc2014/seiya/bootsplash/sys/modules/bsplash/Makefile
soc2014/seiya/bootsplash/sys/modules/splash/bmp/Makefile
Modified: soc2014/seiya/bootsplash/sys/conf/files
==============================================================================
--- soc2014/seiya/bootsplash/sys/conf/files Sun Jun 8 11:27:21 2014 (r269252)
+++ soc2014/seiya/bootsplash/sys/conf/files Sun Jun 8 13:20:51 2014 (r269253)
@@ -1369,6 +1369,8 @@
dev/fb/fbd.c optional fbd | vt
dev/fb/fb_if.m standard
dev/fb/splash.c optional sc splash
+dev/fb/bsplash.c optional sc bsplash
+dev/fb/bmp.c optional sc bsplash
dev/fdt/fdt_common.c optional fdt
dev/fdt/fdt_slicer.c optional fdt cfi | fdt nand
dev/fdt/fdt_static_dtb.S optional fdt fdt_dtb_static \
Modified: soc2014/seiya/bootsplash/sys/dev/fb/bmp.c
==============================================================================
--- soc2014/seiya/bootsplash/sys/dev/fb/bmp.c Sun Jun 8 11:27:21 2014 (r269252)
+++ soc2014/seiya/bootsplash/sys/dev/fb/bmp.c Sun Jun 8 13:20:51 2014 (r269253)
@@ -43,11 +43,10 @@
#include <dev/fb/vgareg.h>
#include <isa/isareg.h>
-static void bmp_DecodeLine(BMP_INFO *info, int line);
static void bmp_SetPix(BMP_INFO *info, int x, int y, u_char val);
-static void bmp_DecodeRLE4(BMP_INFO *info, int line);
-static void bmp_DecodeRLE8(BMP_INFO *info, int line);
-static void bmp_DecodeLine(BMP_INFO *info, int line);
+static void bmp_DecodeRLE4(BMP_INFO *info, int line, int sx, int width);
+static void bmp_DecodeRLE8(BMP_INFO *info, int line, int sx, int width);
+static void bmp_DecodeLine(BMP_INFO *info, int line, int sx, int width);
/*
** bmp_init
@@ -68,13 +67,13 @@
/* check file ID */
if (bmf->bmfh.bfType != 0x4d42) {
- printf("bsplash: not a BMP file\n");
+ printf("splash: not a BMP file\n");
return(1); /* XXX check word ordering for big-endian ports? */
}
/* do we understand this bitmap format? */
if (bmf->bmfi.bmiHeader.biSize > sizeof(bmf->bmfi.bmiHeader)) {
- printf("bsplash: unsupported BMP format (size=%d)\n",
+ printf("splash: unsupported BMP format (size=%d)\n",
bmf->bmfi.bmiHeader.biSize);
return(1);
}
@@ -99,7 +98,7 @@
case BI_RLE8:
break;
default:
- printf("splash_bmp: unsupported compression format\n");
+ printf("splash: unsupported compression format\n");
return(1); /* unsupported compression format */
}
@@ -113,7 +112,7 @@
(bmp_info->width > bmp_info->swidth) ||
(bmp_info->ncols > (1 << sdepth))) {
if (bootverbose)
- printf("splash_bmp: beyond screen capacity (%dx%d, %d colors)\n",
+ printf("splash: beyond screen capacity (%dx%d, %d colors)\n",
bmp_info->width, bmp_info->height, bmp_info->ncols);
return(1);
}
@@ -130,18 +129,21 @@
/*
** bmp_draw
**
-** Render the image. Return nonzero if that's not possible.
+** Render the image. (sy, sx) is the origin in the screen. (iy) is the origin in the image.
+** (height) is the vertical length to be drawn. (width) is the horizontal length to be drawn.
+** Return nonzero if that's not possible.
**
*/
int
-bmp_draw(video_adapter_t *adp, BMP_INFO *bmp_info)
+bmp_draw(video_adapter_t *adp, BMP_INFO *bmp_info, int sx, int sy, int iy,
+ int height, int width)
{
- int line;
+ int i;
if (bmp_info->data == NULL) { /* init failed, do nothing */
return(1);
}
-
+
/* clear the screen */
bmp_info->vidmem = (u_char *)adp->va_window;
bmp_info->adp = adp;
@@ -158,9 +160,39 @@
/* set the palette for our image */
vidd_load_palette(adp, (u_char *)&bmp_info->palette);
- for (line = 0; (line < bmp_info->height) && bmp_info->index; line++) {
- bmp_DecodeLine(bmp_info, line);
+ /* don't draw out of image */
+ if (bmp_info->height < iy + height)
+ return(1);
+ if (bmp_info->width < width)
+ return(1);
+
+ if (height < 0)
+ height = bmp_info->height;
+
+ if (width < 0)
+ width = bmp_info->width;
+
+ /* skip image data not to be drawn */
+ switch(bmp_info->format) {
+ case BI_RGB:
+ bmp_info->index += bmp_info->width * (bmp_info->height - iy - height);
+ break;
+
+ case BI_RLE4: case BI_RLE8:
+ for (i = bmp_info->height; i > iy + height; i--){
+ while (*bmp_info->index != 0 && *(bmp_info->index+1))
+ bmp_info->index++;
+ }
+ bmp_info->index += 2;
+ break;
+ }
+
+
+ /* draw from bottom-left */
+ for (i = sy + height; i > sy && bmp_info->index; i--) {
+ bmp_DecodeLine(bmp_info, i, sx, width);
}
+
return(0);
}
@@ -168,7 +200,7 @@
/*
** bmp_SetPix
**
-** Given (info), set the pixel at (x),(y) to (val)
+** Given (info), set the pixel at (x),(y) to (val)
**
*/
static void
@@ -182,14 +214,11 @@
*/
if ((x < 0) || (x >= info->swidth) || (y < 0) || (y >= info->sheight))
return;
-
- /*
- * calculate offset into video memory;
- * because 0,0 is bottom-left for DIB, we have to convert.
+
+ /*
+ * calculate offset into video memory
*/
- sofs = ((info->height - (y+1) + (info->sheight - info->height) / 2)
- * info->adp->va_line_width);
- x += (info->swidth - info->width) / 2;
+ sofs = y * info->adp->va_line_width;
switch(info->sdepth) {
#ifdef PC98
@@ -240,23 +269,25 @@
break;
}
}
-
+
/*
** bmp_DecodeRLE4
**
** Given (data) pointing to a line of RLE4-format data and (line) being the starting
-** line onscreen, decode the line.
+** line onscreen, decode the line from (sx). (width) is the horizontal length to be drawn.
*/
static void
-bmp_DecodeRLE4(BMP_INFO *info, int line)
+bmp_DecodeRLE4(BMP_INFO *info, int line, int sx, int width)
{
- int count; /* run count */
+ int count; /* number of drawn pixels */
+ int i;
u_char val;
int x,y; /* screen position */
-
- x = 0; /* starting position */
+
+ count = 0;
+ x = sx; /* starting position */
y = line;
-
+
/* loop reading data */
for (;;) {
/*
@@ -264,16 +295,25 @@
* two colour indexes to alternate between for the run
*/
if (*info->index) {
- for (count = 0; count < *info->index; count++, x++) {
- if (count & 1) { /* odd count, low nybble */
+ for (i = 0; i < *info->index && count < *info->index; i++, count++, x++) {
+ if (i & 1) { /* odd count, low nybble */
bmp_SetPix(info, x, y, *(info->index+1) & 0x0f);
} else { /* even count, high nybble */
bmp_SetPix(info, x, y, (*(info->index+1) >>4) & 0x0f);
}
}
+
+ /* go to the next line */
+ if(count == width){
+ for (; *info->index != 0 && *(info->index+1) != 0; info->index++)
+ ;
+ info->index += 2;
+ return;
+ }
+
info->index += 2;
- /*
- * A leading zero is an escape; it may signal the end of the
+ /*
+ * A leading zero is an escape; it may signal the end of the
* bitmap, a cursor move, or some absolute data.
*/
} else { /* zero tag may be absolute mode or an escape */
@@ -290,8 +330,8 @@
info->index += 4;
break;
default: /* literal bitmap data */
- for (count = 0; count < *(info->index + 1); count++, x++) {
- val = *(info->index + 2 + (count / 2)); /* byte with nybbles */
+ for (i = 0; i < *(info->index + 1) && i < *info->index; i++, count++, x++) {
+ val = *(info->index + 2 + (i / 2)); /* byte with nybbles */
if (count & 1) {
val &= 0xf; /* get low nybble */
} else {
@@ -299,8 +339,17 @@
}
bmp_SetPix(info, x, y, val);
}
+
+ /* go to the next line */
+ if(count == width){
+ for (; *info->index != 0 && *(info->index+1) != 0; info->index++)
+ ;
+ info->index += 2;
+ return;
+ }
+
/* warning, this depends on integer truncation, do not hand-optimise! */
- info->index += 2 + ((count + 3) / 4) * 2;
+ info->index += 2 + ((i + 3) / 4) * 2;
break;
}
}
@@ -310,17 +359,19 @@
/*
** bmp_DecodeRLE8
** Given (data) pointing to a line of RLE8-format data and (line) being the starting
-** line onscreen, decode the line.
+** line onscreen, decode the line from (sx). (width) is the horizontal length to be drawn.
*/
static void
-bmp_DecodeRLE8(BMP_INFO *info, int line)
+bmp_DecodeRLE8(BMP_INFO *info, int line, int sx, int width)
{
- int count; /* run count */
+ int i;
+ int count; /* number of drawn pixels */
int x,y; /* screen position */
-
- x = 0; /* starting position */
+
+ count = 0;
+ x = sx; /* starting position */
y = line;
-
+
/* loop reading data */
for(;;) {
/*
@@ -328,11 +379,20 @@
* two colour indexes to alternate between for the run
*/
if (*info->index) {
- for (count = 0; count < *info->index; count++, x++)
+ for (i = 0; i < *info->index && count < width; i++, count++, x++)
bmp_SetPix(info, x, y, *(info->index+1));
+
+ /* go to the next line */
+ if(count == width){
+ for (; *info->index != 0 && *(info->index+1) != 0; info->index++)
+ ;
+ info->index += 2;
+ return;
+ }
+
info->index += 2;
- /*
- * A leading zero is an escape; it may signal the end of the
+ /*
+ * A leading zero is an escape; it may signal the end of the
* bitmap, a cursor move, or some absolute data.
*/
} else { /* zero tag may be absolute mode or an escape */
@@ -349,10 +409,20 @@
info->index += 4;
break;
default: /* literal bitmap data */
- for (count = 0; count < *(info->index + 1); count++, x++)
- bmp_SetPix(info, x, y, *(info->index + 2 + count));
+ for (i = 0; i < *(info->index + 1) && count < width; i++, count++, x++)
+ bmp_SetPix(info, x, y, *(info->index + 2 + i));
+
+ /* go to the next line */
+ if(count == width){
+ for (; *info->index != 0 && *(info->index+1) != 0; info->index++)
+ ;
+ info->index += 2;
+ return;
+ }
+
/* must be an even count */
- info->index += 2 + count + (count & 1);
+ info->index += 2 + i + (i & 1);
+
break;
}
}
@@ -366,7 +436,7 @@
** being displayed, decode a line of data.
*/
static void
-bmp_DecodeLine(BMP_INFO *info, int line)
+bmp_DecodeLine(BMP_INFO *info, int sy, int sx, int width)
{
int x;
u_char val, mask, *p;
@@ -375,20 +445,22 @@
case BI_RGB:
switch(info->depth) {
case 8:
- for (x = 0; x < info->width; x++, info->index++)
- bmp_SetPix(info, x, line, *info->index);
+ for (x = 0; x < width; x++, info->index++)
+ bmp_SetPix(info, x, sy, *info->index);
+
+ for (; x < info->width; x++, info->index++);
info->index += 3 - (--x % 4);
break;
case 4:
p = info->index;
- for (x = 0; x < info->width; x++) {
+ for (x = 0; x < width; x++) {
if (x & 1) {
val = *p & 0xf; /* get low nybble */
p++;
} else {
val = *p >> 4; /* get high nybble */
}
- bmp_SetPix(info, x, line, val);
+ bmp_SetPix(info, x, sy, val);
}
/* warning, this depends on integer truncation, do not hand-optimise! */
info->index += ((x + 7) / 8) * 4;
@@ -396,14 +468,14 @@
case 1:
p = info->index;
mask = 0x80;
- for (x = 0; x < info->width; x++) {
+ for (x = 0; x < width; x++) {
val = (*p & mask) ? 1 : 0;
mask >>= 1;
if (mask == 0) {
mask = 0x80;
p++;
}
- bmp_SetPix(info, x, line, val);
+ bmp_SetPix(info, x, sy, val);
}
/* warning, this depends on integer truncation, do not hand-optimise! */
info->index += ((x + 31) / 32) * 4;
@@ -411,10 +483,10 @@
}
break;
case BI_RLE4:
- bmp_DecodeRLE4(info, line);
+ bmp_DecodeRLE4(info, sy, sx, width);
break;
case BI_RLE8:
- bmp_DecodeRLE8(info, line);
+ bmp_DecodeRLE8(info, sy, sx, width);
break;
}
}
Modified: soc2014/seiya/bootsplash/sys/dev/fb/bmp.h
==============================================================================
--- soc2014/seiya/bootsplash/sys/dev/fb/bmp.h Sun Jun 8 11:27:21 2014 (r269252)
+++ soc2014/seiya/bootsplash/sys/dev/fb/bmp.h Sun Jun 8 13:20:51 2014 (r269253)
@@ -99,6 +99,7 @@
} BMP_INFO;
int bmp_init(BMP_INFO *bmp_info, char *data, int swidth, int sheight, int sdepth);
-int bmp_draw(video_adapter_t *adp, BMP_INFO *bmp_info);
+int bmp_draw(video_adapter_t *adp, BMP_INFO *bmp_info, int vx, int vy, int iy,
+ int height, int width);
#endif /* _FB_BMP_H_ */
Modified: soc2014/seiya/bootsplash/sys/dev/fb/bsplash.c
==============================================================================
--- soc2014/seiya/bootsplash/sys/dev/fb/bsplash.c Sun Jun 8 11:27:21 2014 (r269252)
+++ soc2014/seiya/bootsplash/sys/dev/fb/bsplash.c Sun Jun 8 13:20:51 2014 (r269253)
@@ -43,7 +43,7 @@
static void update_animation(void *unused);
static int load_bmp(video_adapter_t *adp, BMP_INFO *bmp_info, void* data);
-static int draw_bmp(video_adapter_t *adp, BMP_INFO *bmp_info, int x, int y, int height, int width);
+static int draw_bmp(video_adapter_t *adp, BMP_INFO *bmp_info, int y, int height, int width);
static video_adapter_t *adp;
@@ -74,7 +74,7 @@
timeout(update_animation, NULL, 15);
- if (draw_bmp(adp, &bmp_info, 0, 0, 0, 0) != 0)
+ if (draw_bmp(adp, &bmp_info, 0, -1, -1) != 0)
printf("bsplash: failed to draw BMP\n");
return 0;
@@ -106,13 +106,13 @@
static int
-draw_bmp(video_adapter_t *adp, BMP_INFO *bmp_info, int x, int y, int height, int width)
+draw_bmp(video_adapter_t *adp, BMP_INFO *bmp_info, int y, int height, int width)
{
if (vidd_set_mode(adp, M_VESA_CG1024x768) != 0)
return 1;
- if (bmp_draw(adp, bmp_info))
+ if (bmp_draw(adp, bmp_info, 0, 0, y, height, width))
return 1;
return 0;
Modified: soc2014/seiya/bootsplash/sys/dev/fb/splash_bmp.c
==============================================================================
--- soc2014/seiya/bootsplash/sys/dev/fb/splash_bmp.c Sun Jun 8 11:27:21 2014 (r269252)
+++ soc2014/seiya/bootsplash/sys/dev/fb/splash_bmp.c Sun Jun 8 13:20:51 2014 (r269253)
@@ -130,7 +130,7 @@
/* set up the video mode and draw something */
if (vidd_set_mode(adp, splash_mode))
return 1;
- if (bmp_draw(adp, &bmp_info))
+ if (bmp_draw(adp, &bmp_info, 0, 0, 0, -1, -1))
return 1;
vidd_save_palette(adp, pal);
time_stamp = 0;
Modified: soc2014/seiya/bootsplash/sys/dev/syscons/syscons.c
==============================================================================
--- soc2014/seiya/bootsplash/sys/dev/syscons/syscons.c Sun Jun 8 11:27:21 2014 (r269252)
+++ soc2014/seiya/bootsplash/sys/dev/syscons/syscons.c Sun Jun 8 13:20:51 2014 (r269253)
@@ -35,6 +35,7 @@
#include "opt_compat.h"
#include "opt_syscons.h"
#include "opt_splash.h"
+#include "opt_bsplash.h"
#include "opt_ddb.h"
#include <sys/param.h>
@@ -77,6 +78,7 @@
#include <dev/kbd/kbdreg.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/splashreg.h>
+#include <dev/fb/bsplash.h>
#include <dev/syscons/syscons.h>
#define COLD 0
@@ -3015,6 +3017,12 @@
sc->flags |= SC_SPLASH_SCRN;
}
#endif
+
+
+#ifdef DEV_BSPLASH
+ bsplash_early_init(sc->adp);
+#endif
+
}
/* the rest is not necessary, if we have done it once */
Modified: soc2014/seiya/bootsplash/sys/modules/bsplash/Makefile
==============================================================================
--- soc2014/seiya/bootsplash/sys/modules/bsplash/Makefile Sun Jun 8 11:27:21 2014 (r269252)
+++ soc2014/seiya/bootsplash/sys/modules/bsplash/Makefile Sun Jun 8 13:20:51 2014 (r269253)
@@ -3,6 +3,7 @@
.PATH: ${.CURDIR}/../../dev/fb
KMOD= bsplash
-SRCS= bsplash.c
+SRCS= bmp.c bsplash.c
+SRCS+= bmp.h
.include <bsd.kmod.mk>
Modified: soc2014/seiya/bootsplash/sys/modules/splash/bmp/Makefile
==============================================================================
--- soc2014/seiya/bootsplash/sys/modules/splash/bmp/Makefile Sun Jun 8 11:27:21 2014 (r269252)
+++ soc2014/seiya/bootsplash/sys/modules/splash/bmp/Makefile Sun Jun 8 13:20:51 2014 (r269253)
@@ -3,6 +3,6 @@
.PATH: ${.CURDIR}/../../../dev/fb
KMOD= splash_bmp
-SRCS= splash_bmp.c
+SRCS= splash_bmp.c bmp.c bmp.h
.include <bsd.kmod.mk>
More information about the svn-soc-all
mailing list