Date: Wed, 18 Jun 2014 12:24:52 GMT From: seiya@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r269720 - soc2014/seiya/bootsplash/sys/dev/fb Message-ID: <201406181224.s5ICOqob021784@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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; + } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406181224.s5ICOqob021784>