socsvn commit: r269720 - soc2014/seiya/bootsplash/sys/dev/fb
seiya at FreeBSD.org
seiya at FreeBSD.org
Wed Jun 18 12:24:53 UTC 2014
Author: seiya
Date: Wed Jun 18 12:24:52 2014
New Revision: 269720
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269720
Log:
fix indentation and refactor bmp_DecodeLine()
Modified:
soc2014/seiya/bootsplash/sys/dev/fb/bmp.c
Modified: soc2014/seiya/bootsplash/sys/dev/fb/bmp.c
==============================================================================
--- soc2014/seiya/bootsplash/sys/dev/fb/bmp.c Wed Jun 18 10:56:59 2014 (r269719)
+++ soc2014/seiya/bootsplash/sys/dev/fb/bmp.c Wed Jun 18 12:24:52 2014 (r269720)
@@ -30,183 +30,185 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/fbio.h>
+#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/libkern.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <dev/fb/bmp.h>
-#include <dev/fb/bsplash.h>
-#include <dev/fb/fbreg.h>
-#include <dev/fb/vgareg.h>
+#include <sys/fbio.h>
#include <isa/isareg.h>
+#include "bmp.h"
+#include "bsplash.h"
+#include "fbreg.h"
+#include "vgareg.h"
+
static void bmp_SetPix(BMP_INFO *info, int x, int y, u_char val);
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_DecodeRGB(BMP_INFO *info, int sy, int sx, int width);
static void bmp_DecodeLine(BMP_INFO *info, int line, int sx, int width);
/*
-** bmp_init
-**
-** Given a pointer (data) to the image of a BMP file, fill in (bmp_info) with what
-** can be learnt from it. Return nonzero if the file isn't usable.
-**
-** Take screen dimensions (swidth), (sheight) and (sdepth) and make sure we
-** can work with these.
-*/
+ * bmp_init
+ *
+ * Given a pointer (data) to the image of a BMP file, fill in (bmp_info) with what
+ * can be learnt from it. Return nonzero if the file isn't usable.
+ *
+ * Take screen dimensions (swidth), (sheight) and (sdepth) and make sure we
+ * can work with these.
+ */
int
bmp_init(BMP_INFO *bmp_info, char *data, int swidth, int sheight, int sdepth)
{
- BITMAPF *bmf = (BITMAPF *)data;
- int pind;
+ BITMAPF *bmf = (BITMAPF *)data;
+ int pind;
- bmp_info->data = NULL; /* assume setup failed */
+ bmp_info->data = NULL; /* assume setup failed */
- /* check file ID */
- if (bmf->bmfh.bfType != 0x4d42) {
- printf("splash: not a BMP file\n");
- return(1); /* XXX check word ordering for big-endian ports? */
- }
+ /* check file ID */
+ if (bmf->bmfh.bfType != 0x4d42) {
+ printf("splash: not a BMP file\n");
+ return(1); /* XXX check word ordering for big-endian ports? */
+ }
- /* do we understand this bitmap format? (it only supports W*ndows 3.x format) */
- if (bmf->bmfi.bmiHeader.biSize > sizeof(bmf->bmfi.bmiHeader)) {
- printf("splash: unsupported BMP format (size=%d)\n",
- bmf->bmfi.bmiHeader.biSize);
- return(1);
- }
+ /* do we understand this bitmap format? (it only supports W*ndows 3.x format) */
+ if (bmf->bmfi.bmiHeader.biSize > sizeof(bmf->bmfi.bmiHeader)) {
+ printf("splash: unsupported BMP format (size=%d)\n",
+ bmf->bmfi.bmiHeader.biSize);
+ return(1);
+ }
- /* save what we know about the screen */
- bmp_info->swidth = swidth;
- bmp_info->sheight = sheight;
- bmp_info->sdepth = sdepth;
-
- /* where's the data? */
- bmp_info->data = (u_char *)data + bmf->bmfh.bfOffBits;
-
- /* image parameters */
- bmp_info->width = bmf->bmfi.bmiHeader.biWidth;
- bmp_info->height = bmf->bmfi.bmiHeader.biHeight;
- bmp_info->depth = bmf->bmfi.bmiHeader.biBitCount;
- bmp_info->format = bmf->bmfi.bmiHeader.biCompression;
-
- switch(bmp_info->format) { /* check compression format */
- case BI_RGB:
- case BI_RLE4:
- case BI_RLE8:
- break;
- default:
- printf("splash: unsupported compression format\n");
- return(1); /* unsupported compression format */
- }
+ /* save what we know about the screen */
+ bmp_info->swidth = swidth;
+ bmp_info->sheight = sheight;
+ bmp_info->sdepth = sdepth;
+
+ /* where's the data? */
+ bmp_info->data = (u_char *)data + bmf->bmfh.bfOffBits;
+
+ /* image parameters */
+ bmp_info->width = bmf->bmfi.bmiHeader.biWidth;
+ bmp_info->height = bmf->bmfi.bmiHeader.biHeight;
+ bmp_info->depth = bmf->bmfi.bmiHeader.biBitCount;
+ bmp_info->format = bmf->bmfi.bmiHeader.biCompression;
+
+ switch(bmp_info->format) { /* check compression format */
+ case BI_RGB:
+ case BI_RLE4:
+ case BI_RLE8:
+ break;
+ default:
+ printf("splash: unsupported compression format\n");
+ return(1); /* unsupported compression format */
+ }
- /* palette details */
- bmp_info->ncols = bmf->bmfi.bmiHeader.biClrUsed;
- bzero(bmp_info->palette, sizeof(bmp_info->palette));
- if (bmp_info->ncols == 0) { /* uses all of them */
- bmp_info->ncols = 1 << bmf->bmfi.bmiHeader.biBitCount;
- }
+ /* palette details */
+ bmp_info->ncols = bmf->bmfi.bmiHeader.biClrUsed;
+ bzero(bmp_info->palette, sizeof(bmp_info->palette));
+ if (bmp_info->ncols == 0) { /* uses all of them */
+ bmp_info->ncols = 1 << bmf->bmfi.bmiHeader.biBitCount;
+ }
- if ((bmp_info->width > bmp_info->swidth) || (bmp_info->ncols > (1 << sdepth))) {
- if (bootverbose)
- printf("splash: beyond screen capacity (%dx%d, %d colors)\n",
- bmp_info->width, bmp_info->height, bmp_info->ncols);
- return(1);
- }
+ if ((bmp_info->width > bmp_info->swidth) || (bmp_info->ncols > (1 << sdepth))) {
+ if (bootverbose)
+ printf("splash: beyond screen capacity (%dx%d, %d colors)\n",
+ bmp_info->width, bmp_info->height, bmp_info->ncols);
+ return(1);
+ }
- /* read palette */
- for (pind = 0; pind < bmp_info->ncols; pind++) {
- bmp_info->palette[pind][0] = bmf->bmfi.bmiColors[pind].rgbRed;
- bmp_info->palette[pind][1] = bmf->bmfi.bmiColors[pind].rgbGreen;
- bmp_info->palette[pind][2] = bmf->bmfi.bmiColors[pind].rgbBlue;
- }
+ /* read palette */
+ for (pind = 0; pind < bmp_info->ncols; pind++) {
+ bmp_info->palette[pind][0] = bmf->bmfi.bmiColors[pind].rgbRed;
+ bmp_info->palette[pind][1] = bmf->bmfi.bmiColors[pind].rgbGreen;
+ bmp_info->palette[pind][2] = bmf->bmfi.bmiColors[pind].rgbBlue;
+ }
- return(0);
+ return(0);
}
/*
-** bmp_draw
-**
-** 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.
-**
-*/
+ * bmp_draw
+ *
+ * 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, int sx, int sy, int iy,
int width, int height)
{
- int i, next_line;
- static int cleared;
+ int i, next_line;
+ static int cleared;
- if (bmp_info->data == NULL) { /* init failed, do nothing */
- return(1);
- }
+ 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;
-
- if(!cleared){
- vidd_clear(adp);
- cleared = 1;
- }
+ /* clear the screen */
+ bmp_info->vidmem = (u_char *)adp->va_window;
+ bmp_info->adp = adp;
+
+ if (!cleared) {
+ vidd_clear(adp);
+ cleared = 1;
+ }
- vidd_set_win_org(adp, 0);
- bmp_info->bank = 0;
+ vidd_set_win_org(adp, 0);
+ bmp_info->bank = 0;
- /* initialise the info structure for drawing */
- bmp_info->index = bmp_info->data;
+ /* initialise the info structure for drawing */
+ bmp_info->index = bmp_info->data;
#ifdef PC98
- bmp_info.prev_val = 255;
+ bmp_info.prev_val = 255;
#endif
- /* set the palette for our image */
- vidd_load_palette(adp, (u_char *)&bmp_info->palette);
+ /* set the palette for our image */
+ vidd_load_palette(adp, (u_char *)&bmp_info->palette);
- /* 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:
- return(1); /* TODO */
+ /* 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:
+ return(1); /* TODO */
case BI_RLE8:
- for (i = bmp_info->height; i > iy + height; i--) {
-
- for(next_line = 0; next_line == 0;){
- if (*bmp_info->index) {
- bmp_info->index += 2;
- } else {
- switch(*(bmp_info->index+1)) {
- case 0: /* end of line */
- bmp_info->index += 2;
- next_line = 1;
- break;
- case 1: /* end of bitmap */
- bmp_info->index = NULL;
- return(1);
- case 2: /* move */
- bmp_info->index += 4;
- break;
- default: /* literal bitmap data */
- bmp_info->index += 2 + *(bmp_info->index + 1) + (*(bmp_info->index + 1) & 1);
+ for (i = bmp_info->height; i > iy + height; i--) {
+ for (next_line = 0; next_line == 0;) {
+ if (*bmp_info->index) {
+ bmp_info->index += 2;
+ } else {
+
+ switch(*(bmp_info->index+1)) {
+ case 0: /* end of line */
+ bmp_info->index += 2;
+ next_line = 1;
+ break;
+ case 1: /* end of bitmap */
+ bmp_info->index = NULL;
+ return(1);
+ case 2: /* move */
+ bmp_info->index += 4;
+ break;
+ default: /* literal bitmap data */
+ bmp_info->index += 2 + *(bmp_info->index + 1) +
+ (*(bmp_info->index + 1) & 1);
break;
}
}
@@ -216,327 +218,366 @@
}
- /* draw from bottom-left */
- for (i = sy + height; i > sy && bmp_info->index; i--) {
- bmp_DecodeLine(bmp_info, i, sx, width);
- }
+ /* draw from bottom-left */
+ for (i = sy + height; i > sy && bmp_info->index; i--) {
+ bmp_DecodeLine(bmp_info, i, sx, width);
+ }
- return(0);
+ return(0);
}
/*
-** bmp_draw_line
-**
-** Given (info), set the pixels from (x_origin) to (x_origin) + (count) at (y) to (val)
-**
-*/
+ * bmp_draw_line
+ *
+ * Given (info), set the pixels from (x_origin) to (x_origin) + (count) at (y) to (val)
+ *
+ */
static void
bmp_draw_line(BMP_INFO *info, int y, int x_origin, int count, int val)
{
- int i;
- int sofs;
- int newbank;
-
- /*
- * range check to avoid explosions
- */
- if ((x_origin < 0) || (x_origin + count >= info->swidth) || (y < 0) || (y >= info->sheight))
- return;
-
- /*
- * calculate offset into video memory
- */
- sofs = (y * info->adp->va_line_width) + x_origin;
-
- switch(info->sdepth) {
- case 1: break; /* TODO */
- case 4: break; /* TODO */
-
- case 8:
- for(i = 0; i < count; i++, sofs++) {
- newbank = sofs / info->adp->va_window_size;
- if (info->bank != newbank) {
- vidd_set_win_org(info->adp, newbank*info->adp->va_window_size);
- info->bank = newbank;
- }
- *(info->vidmem + (sofs % info->adp->va_window_size)) = val;
- }
- break;
- }
-}
-
-/*
-** bmp_SetPix
-**
-** Given (info), set the pixel at (x),(y) to (val)
-**
-*/
-static void
-bmp_SetPix(BMP_INFO *info, int x, int y, u_char val)
-{
- int sofs, bofs;
- int newbank;
+ int i;
+ int sofs;
+ int newbank;
- /*
- * range check to avoid explosions
- */
- if ((x < 0) || (x >= info->swidth) || (y < 0) || (y >= info->sheight))
- return;
-
- /*
- * calculate offset into video memory
- */
- sofs = y * info->adp->va_line_width;
+ /*
+ * range check to avoid explosions
+ */
+ if ((x_origin < 0) || (x_origin + count >= info->swidth) ||
+ (y < 0) || (y >= info->sheight))
+ return;
- switch(info->sdepth) {
-#ifdef PC98
- case 4:
- sofs += (x >> 3);
- bofs = x & 0x7; /* offset within byte */
-
- outb(0x7c, 0x80 | 0x40); /* GRCG on & RMW mode */
- if (val != info->prev_val) {
- outb(0x7e, (val & 1) ? 0xff : 0); /* tile B */
- outb(0x7e, (val & 2) ? 0xff : 0); /* tile R */
- outb(0x7e, (val & 4) ? 0xff : 0); /* tile G */
- outb(0x7e, (val & 8) ? 0xff : 0); /* tile I */
-
- info->prev_val = val;
- }
-
- *(info->vidmem+sofs) = (0x80 >> bofs); /* write new bit */
- outb(0x7c, 0); /* GRCG off */
- break;
-#else
- case 4:
- case 1:
- /* EGA/VGA planar modes */
- sofs += (x >> 3);
- newbank = sofs/info->adp->va_window_size;
- if (info->bank != newbank) {
- vidd_set_win_org(info->adp, newbank*info->adp->va_window_size);
- info->bank = newbank;
- }
- sofs %= info->adp->va_window_size;
- bofs = x & 0x7; /* offset within byte */
- outw(GDCIDX, (0x8000 >> bofs) | 0x08); /* bit mask */
- outw(GDCIDX, (val << 8) | 0x00); /* set/reset */
- *(info->vidmem + sofs) ^= 0xff; /* read-modify-write */
- break;
-#endif
+ /*
+ * calculate offset into video memory
+ */
+ sofs = (y * info->adp->va_line_width) + x_origin;
- case 8:
- sofs += x;
- newbank = sofs/info->adp->va_window_size;
- if (info->bank != newbank) {
- vidd_set_win_org(info->adp, newbank*info->adp->va_window_size);
- info->bank = newbank;
- }
- sofs %= info->adp->va_window_size;
- *(info->vidmem+sofs) = val;
- break;
- }
+ switch(info->sdepth) {
+ case 1: break; /* TODO */
+ case 4: break; /* TODO */
+ case 8:
+ for(i = 0; i < count; i++, sofs++) {
+ newbank = sofs / info->adp->va_window_size;
+ if (info->bank != newbank) {
+ vidd_set_win_org(info->adp, newbank*info->adp->va_window_size);
+ info->bank = newbank;
+ }
+ *(info->vidmem + (sofs % info->adp->va_window_size)) = val;
+ }
+ break;
+ }
}
/*
-** bmp_DecodeRLE4
-**
-** Given (data) pointing to a line of RLE4-format data and (line) being the starting
-** line onscreen, decode the line from (sx). (width) is the horizontal length to be drawn.
-*/
+ * bmp_SetPix
+ *
+ * Given (info), set the pixel at (x),(y) to (val)
+ *
+ */
static void
-bmp_DecodeRLE4(BMP_INFO *info, int line, int sx, int width)
+bmp_SetPix(BMP_INFO *info, int x, int y, u_char val)
{
- int count; /* number of drawn pixels */
- int i;
- u_char val;
- int x,y; /* screen position */
-
- count = 0;
- x = sx; /* starting position */
- y = line;
+ int sofs, bofs;
+ int newbank;
- /* loop reading data */
- for (;;) {
/*
- * encoded mode starts with a run length, and then a byte with
- * two colour indexes to alternate between for the run
+ * range check to avoid explosions
*/
- if (*info->index) {
- 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;
+ if ((x < 0) || (x >= info->swidth) || (y < 0) || (y >= info->sheight))
return;
- }
- info->index += 2;
- /*
- * A leading zero is an escape; it may signal the end of the
- * bitmap, a cursor move, or some absolute data.
+ /*
+ * calculate offset into video memory
*/
- } else { /* zero tag may be absolute mode or an escape */
- switch (*(info->index+1)) {
- case 0: /* end of line */
- info->index += 2;
- return;
- case 1: /* end of bitmap */
- info->index = NULL;
- return;
- case 2: /* move */
- x += *(info->index + 2); /* new coords */
- y += *(info->index + 3);
- info->index += 4;
- break;
- default: /* literal bitmap data */
- 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 {
- val = (val >> 4); /* get high nybble */
- }
- bmp_SetPix(info, x, y, val);
+ sofs = y * info->adp->va_line_width;
+
+ switch(info->sdepth) {
+#ifdef PC98
+ case 4:
+ sofs += (x >> 3);
+ bofs = x & 0x7; /* offset within byte */
+
+ outb(0x7c, 0x80 | 0x40); /* GRCG on & RMW mode */
+ if (val != info->prev_val) {
+ outb(0x7e, (val & 1) ? 0xff : 0); /* tile B */
+ outb(0x7e, (val & 2) ? 0xff : 0); /* tile R */
+ outb(0x7e, (val & 4) ? 0xff : 0); /* tile G */
+ outb(0x7e, (val & 8) ? 0xff : 0); /* tile I */
+ info->prev_val = val;
}
- /* go to the next line */
- if(count == width){
- for (; *info->index != 0 && *(info->index+1) != 0; info->index++)
- ;
- info->index += 2;
- return;
+ *(info->vidmem+sofs) = (0x80 >> bofs); /* write new bit */
+ outb(0x7c, 0); /* GRCG off */
+ break;
+#else /* !PC98 */
+ case 4:
+ case 1:
+ /* EGA/VGA planar modes */
+ sofs += (x >> 3);
+ newbank = sofs/info->adp->va_window_size;
+ if (info->bank != newbank) {
+ vidd_set_win_org(info->adp, newbank*info->adp->va_window_size);
+ info->bank = newbank;
}
- /* warning, this depends on integer truncation, do not hand-optimise! */
- info->index += 2 + ((i + 3) / 4) * 2;
+ sofs %= info->adp->va_window_size;
+ bofs = x & 0x7; /* offset within byte */
+ outw(GDCIDX, (0x8000 >> bofs) | 0x08); /* bit mask */
+ outw(GDCIDX, (val << 8) | 0x00); /* set/reset */
+ *(info->vidmem + sofs) ^= 0xff; /* read-modify-write */
+ break;
+#endif /* PC98 */
+
+ case 8:
+ sofs += x;
+ newbank = sofs/info->adp->va_window_size;
+ if (info->bank != newbank) {
+ vidd_set_win_org(info->adp, newbank*info->adp->va_window_size);
+ info->bank = newbank;
+ }
+ sofs %= info->adp->va_window_size;
+ *(info->vidmem+sofs) = val;
break;
- }
}
- }
}
/*
-** bmp_DecodeRLE8
-** Given (data) pointing to a line of RLE8-format data and (line) being the starting
-** line onscreen, decode the line from (sx). (width) is the horizontal length to be drawn.
-*/
+ * bmp_DecodeRLE4
+ *
+ * Given (data) pointing to a line of RLE4-format data and (line) being the starting
+ * line onscreen, decode the line from (sx). (width) is the horizontal length to be drawn.
+ */
static void
-bmp_DecodeRLE8(BMP_INFO *info, int line, int sx, int width)
+bmp_DecodeRLE4(BMP_INFO *info, int line, int sx, int width)
{
- int i;
- int count; /* number of pixels to be drawn at once by bmp_draw_line() */
- int x,y; /* screen position on screen */
+ int count; /* number of drawn pixels */
+ int i;
+ int x, y; /* screen position */
+ u_char val;
+
+ count = 0;
+ x = sx; /* starting position */
+ y = line;
+
+ /* loop vreading data */
+ for (;;) {
+ /*
+ * encoded mode starts with a run length, and then a byte with
+ * two colour indexes to alternate between for the run
+ */
+ if (*info->index) {
+ 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);
+ }
+ }
+
+ /* TODO: use bmp_draw_line() instead */
+
+ /* 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
+ * bitmap, a cursor move, or some absolute data.
+ */
+ } else { /* zero tag may be absolute mode or an escape */
+ switch (*(info->index+1)) {
+ case 0: /* end of line */
+ info->index += 2;
+ return;
+ case 1: /* end of bitmap */
+ info->index = NULL;
+ return;
+ case 2: /* move */
+ x += *(info->index + 2); /* new coords */
+ y += *(info->index + 3);
+ info->index += 4;
+ break;
+ default: /* literal bitmap data */
+ for (i = 0; i < *(info->index + 1) && i < *info->index;
+ i++, count++, x++) {
+ /* byte with nybbles */
+ val = *(info->index + 2 + (i / 2));
+ if (count & 1) {
+ val &= 0xf; /* get low nybble */
+ } else {
+ val = (val >> 4); /* get high nybble */
+ }
+
+ 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 + ((i + 3) / 4) * 2;
+ break;
+ }
+ }
+ }
+}
- y = line;
- x = sx;
+/*
+ * bmp_DecodeRLE8
+ *
+ * Given (data) pointing to a line of RLE8-format data and (line) being the starting
+ * line onscreen, decode the line from (sx). (width) is the horizontal length to be drawn.
+ */
+static void
+bmp_DecodeRLE8(BMP_INFO *info, int line, int sx, int width)
+{
+ int i;
+ int count; /* number of pixels to be drawn at once by bmp_draw_line() */
+ int x,y; /* screen position on screen */
+
+ y = line;
+ x = sx;
+
+ /* loop reading data */
+ for(;;) {
+ /*
+ * encoded mode starts with a run length, and then a byte with
+ * two colour indexes to alternate between for the run
+ */
+ if (*info->index) {
+ count = ((width - x - sx - 1) > *info->index)? *info->index :
+ (width - x - sx - 1);
+ bmp_draw_line(info, y, x, count, *(info->index+1));
+ x += count;
+ info->index += 2;
+
+ /*
+ * 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 */
+ switch(*(info->index+1)) {
+ case 0: /* end of line */
+ info->index += 2;
+ return;
+ case 1: /* end of bitmap */
+ info->index = NULL;
+ return;
+ case 2: /* move */
+ x += *(info->index + 2); /* new coords */
+ y += *(info->index + 3);
+ info->index += 4;
+ break;
+ default: /* literal bitmap data */
+ for (i = 0; i < *(info->index + 1) && (x - sx) < width;
+ i++, x++){
+ bmp_SetPix(info, x, y, *(info->index + 2 + i));
+ }
+
+ info->index += 2 + i + (i & 1);
+ break;
+ }
+ }
+ }
+}
- /* loop reading data */
- for(;;) {
- /*
- * encoded mode starts with a run length, and then a byte with
- * two colour indexes to alternate between for the run
- */
- if (*info->index) {
- count = ((width - x - sx - 1) > *info->index)? *info->index : (width - x - sx - 1);
- bmp_draw_line(info, y, x, count, *(info->index+1));
- x += count;
- info->index += 2;
-
- /*
- * 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 */
- switch(*(info->index+1)) {
- case 0: /* end of line */
- info->index += 2;
- return;
- case 1: /* end of bitmap */
- info->index = NULL;
- return;
- case 2: /* move */
- x += *(info->index + 2); /* new coords */
- y += *(info->index + 3);
- info->index += 4;
- break;
- default: /* literal bitmap data */
- for (i = 0; i < *(info->index + 1) && (x - sx) < width; i++, x++)
- bmp_SetPix(info, x, y, *(info->index + 2 + i));
+/*
+ * bmp_DecodeRGB
+ *
+ * Given (data) pointing to a line of uncompressed data and (sy) being the starting
+ * line onscreen, decode the line from (sx). (width) is the horizontal length to be drawn.
+ */
+static void
+bmp_DecodeRGB(BMP_INFO *info, int sy, int sx, int width)
+{
+ int x;
+ u_char val, mask, *p;
- info->index += 2 + i + (i & 1);
- break;
- }
+ switch(info->depth) {
+ case 8:
+ 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 < width; x++) {
+ if (x & 1) {
+ val = *p & 0xf; /* get low nybble */
+ p++;
+ } else {
+ val = *p >> 4; /* get high nybble */
+ }
+
+ bmp_SetPix(info, x, sy, val);
+ }
+
+ /*
+ * warning, this depends on integer truncation,
+ * do not hand-optimise!
+ */
+ info->index += ((x + 7) / 8) * 4;
+ break;
+ case 1:
+ p = info->index;
+ mask = 0x80;
+
+ for (x = 0; x < width; x++) {
+ val = (*p & mask) ? 1 : 0;
+ mask >>= 1;
+ if (mask == 0) {
+ mask = 0x80;
+ p++;
+ }
+
+ bmp_SetPix(info, x, sy, val);
+ }
+
+ /*
+ * warning, this depends on integer truncation,
+ * do not hand-optimise!
+ */
+ info->index += ((x + 31) / 32) * 4;
+ break;
}
- }
}
/*
-** bmp_DecodeLine
-**
-** Given (info) pointing to an image being decoded, (line) being the line currently
-** being displayed, decode a line of data.
-*/
+ * bmp_DecodeLine
+ *
+ * Given (info) pointing to an image being decoded, (line) being the line currently
+ * being displayed, decode a line of data.
+ */
static void
bmp_DecodeLine(BMP_INFO *info, int sy, int sx, int width)
{
- int x;
- u_char val, mask, *p;
-
- switch(info->format) {
- case BI_RGB:
- switch(info->depth) {
- case 8:
- 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 < width; x++) {
- if (x & 1) {
- val = *p & 0xf; /* get low nybble */
- p++;
- } else {
- val = *p >> 4; /* get high nybble */
- }
- bmp_SetPix(info, x, sy, val);
- }
- /* warning, this depends on integer truncation, do not hand-optimise! */
- info->index += ((x + 7) / 8) * 4;
- break;
- case 1:
- p = info->index;
- mask = 0x80;
- for (x = 0; x < width; x++) {
- val = (*p & mask) ? 1 : 0;
- mask >>= 1;
- if (mask == 0) {
- mask = 0x80;
- p++;
- }
- bmp_SetPix(info, x, sy, val);
- }
- /* warning, this depends on integer truncation, do not hand-optimise! */
- info->index += ((x + 31) / 32) * 4;
- break;
- }
- break;
- case BI_RLE4:
- bmp_DecodeRLE4(info, sy, sx, width);
- break;
- case BI_RLE8:
- bmp_DecodeRLE8(info, sy, sx, width);
- break;
- }
+ switch(info->format) {
+ case BI_RGB:
+ bmp_DecodeRGB(info, sy, sx, width);
+ break;
+ case BI_RLE4:
+ bmp_DecodeRLE4(info, sy, sx, width);
+ break;
+ case BI_RLE8:
+ bmp_DecodeRLE8(info, sy, sx, width);
+ break;
+ }
}
More information about the svn-soc-all
mailing list