Date: Sat, 7 Jun 2014 06:26:00 GMT From: seiya@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r269229 - soc2014/seiya/bootsplash/sys/dev/fb Message-ID: <201406070626.s576Q0lm026358@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: seiya Date: Sat Jun 7 06:26:00 2014 New Revision: 269229 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=269229 Log: separate BMP decoder from splash_bmp.c bsplash also uses BMP decoder so I separete it. Added: soc2014/seiya/bootsplash/sys/dev/fb/bmp.c soc2014/seiya/bootsplash/sys/dev/fb/bmp.h soc2014/seiya/bootsplash/sys/dev/fb/bsplash.h Modified: soc2014/seiya/bootsplash/sys/dev/fb/bsplash.c soc2014/seiya/bootsplash/sys/dev/fb/splash_bmp.c Added: soc2014/seiya/bootsplash/sys/dev/fb/bmp.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2014/seiya/bootsplash/sys/dev/fb/bmp.c Sat Jun 7 06:26:00 2014 (r269229) @@ -0,0 +1,420 @@ +/*- + * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> + * Copyright (c) 1999 Kazutaka YOKOTA <yokota@freebsd.org> + * Copyright (c) 2014 Seiya Nuta <seiya@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: soc2014/seiya/bootsplash/sys/dev/fb/splash_bmp.c 175028 2007-12-29 23:26:59Z wkoszek $ + */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/fbio.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 <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); + +/* +** 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; + + bmp_info->data = NULL; /* assume setup failed */ + + /* check file ID */ + if (bmf->bmfh.bfType != 0x4d42) { + printf("bsplash: 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", + 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_bmp: 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; + } + if ((bmp_info->height > bmp_info->sheight) || + (bmp_info->width > bmp_info->swidth) || + (bmp_info->ncols > (1 << sdepth))) { + if (bootverbose) + printf("splash_bmp: 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; + } + return(0); +} + +/* +** bmp_draw +** +** Render the image. Return nonzero if that's not possible. +** +*/ +int +bmp_draw(video_adapter_t *adp, BMP_INFO *bmp_info) +{ + int line; + + 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; + vidd_clear(adp); + vidd_set_win_org(adp, 0); + bmp_info->bank = 0; + + /* initialise the info structure for drawing */ + bmp_info->index = bmp_info->data; +#ifdef PC98 + bmp_info.prev_val = 255; +#endif + + /* 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); + } + return(0); +} + + +/* +** 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; + + /* + * range check to avoid explosions + */ + 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. + */ + sofs = ((info->height - (y+1) + (info->sheight - info->height) / 2) + * info->adp->va_line_width); + x += (info->swidth - info->width) / 2; + + 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 + + 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_DecodeRLE4 +** +** Given (data) pointing to a line of RLE4-format data and (line) being the starting +** line onscreen, decode the line. +*/ +static void +bmp_DecodeRLE4(BMP_INFO *info, int line) +{ + int count; /* run count */ + u_char val; + int x,y; /* screen position */ + + x = 0; /* starting position */ + y = line; + + /* 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) { + for (count = 0; count < *info->index; count++, x++) { + if (count & 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); + } + } + 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 (count = 0; count < *(info->index + 1); count++, x++) { + val = *(info->index + 2 + (count / 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); + } + /* warning, this depends on integer truncation, do not hand-optimise! */ + info->index += 2 + ((count + 3) / 4) * 2; + break; + } + } + } +} + +/* +** bmp_DecodeRLE8 +** Given (data) pointing to a line of RLE8-format data and (line) being the starting +** line onscreen, decode the line. +*/ +static void +bmp_DecodeRLE8(BMP_INFO *info, int line) +{ + int count; /* run count */ + int x,y; /* screen position */ + + x = 0; /* starting position */ + y = line; + + /* 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) { + for (count = 0; count < *info->index; count++, x++) + bmp_SetPix(info, x, y, *(info->index+1)); + 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 (count = 0; count < *(info->index + 1); count++, x++) + bmp_SetPix(info, x, y, *(info->index + 2 + count)); + /* must be an even count */ + info->index += 2 + count + (count & 1); + break; + } + } + } +} + +/* +** 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 line) +{ + int x; + u_char val, mask, *p; + + switch(info->format) { + case BI_RGB: + switch(info->depth) { + case 8: + for (x = 0; x < info->width; x++, info->index++) + bmp_SetPix(info, x, line, *info->index); + info->index += 3 - (--x % 4); + break; + case 4: + p = info->index; + for (x = 0; x < info->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); + } + /* 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 < info->width; x++) { + val = (*p & mask) ? 1 : 0; + mask >>= 1; + if (mask == 0) { + mask = 0x80; + p++; + } + bmp_SetPix(info, x, line, 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, line); + break; + case BI_RLE8: + bmp_DecodeRLE8(info, line); + break; + } +} Added: soc2014/seiya/bootsplash/sys/dev/fb/bmp.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2014/seiya/bootsplash/sys/dev/fb/bmp.h Sat Jun 7 06:26:00 2014 (r269229) @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> + * Copyright (c) 2014 Seiya Nuta <seiya@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: soc2014/seiya/bootsplash/sys/dev/fb/splash_bmp.c 175028 2007-12-29 23:26:59Z wkoszek $ + */ + +#ifndef _FB_BMP_H_ +#define _FB_BMP_H_ + +#include <sys/fbio.h> + +typedef struct tagBITMAPFILEHEADER { /* bmfh */ + u_short bfType; + int bfSize; + u_short bfReserved1; + u_short bfReserved2; + int bfOffBits; +} __packed BITMAPFILEHEADER; + +typedef struct tagBITMAPINFOHEADER { /* bmih */ + int biSize; + int biWidth; + int biHeight; + short biPlanes; + short biBitCount; + int biCompression; + int biSizeImage; + int biXPelsPerMeter; + int biYPelsPerMeter; + int biClrUsed; + int biClrImportant; +} __packed BITMAPINFOHEADER; + +typedef struct tagRGBQUAD { /* rgbq */ + u_char rgbBlue; + u_char rgbGreen; + u_char rgbRed; + u_char rgbReserved; +} __packed RGBQUAD; + +typedef struct tagBITMAPINFO { /* bmi */ + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[256]; +} __packed BITMAPINFO; + +typedef struct tagBITMAPF +{ + BITMAPFILEHEADER bmfh; + BITMAPINFO bmfi; +} __packed BITMAPF; + +#define BI_RGB 0 +#define BI_RLE8 1 +#define BI_RLE4 2 + +/* +** all we actually care about the image +*/ +typedef struct +{ + int width,height; /* image dimensions */ + int swidth,sheight; /* screen dimensions for the current mode */ + u_char depth; /* image depth (1, 4, 8, 24 bits) */ + u_char sdepth; /* screen depth (1, 4, 8 bpp) */ + int ncols; /* number of colours */ + u_char palette[256][3]; /* raw palette data */ + u_char format; /* one of the BI_* constants above */ + u_char *data; /* pointer to the raw data */ + u_char *index; /* running pointer to the data while drawing */ + u_char *vidmem; /* video memory allocated for drawing */ + video_adapter_t *adp; + int bank; +#ifdef PC98 + u_char prev_val; +#endif +} 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); + +#endif /* _FB_BMP_H_ */ Modified: soc2014/seiya/bootsplash/sys/dev/fb/bsplash.c ============================================================================== --- soc2014/seiya/bootsplash/sys/dev/fb/bsplash.c Sat Jun 7 05:14:07 2014 (r269228) +++ soc2014/seiya/bootsplash/sys/dev/fb/bsplash.c Sat Jun 7 06:26:00 2014 (r269229) @@ -27,30 +27,97 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <sys/param.h> +#include <sys/fbio.h> #include <sys/module.h> #include <sys/kernel.h> -#include <sys/systm.h> #include <sys/linker.h> #include <sys/libkern.h> -#include <sys/malloc.h> +#include <sys/systm.h> +#include <sys/param.h> +#include <dev/fb/bmp.h> +#include <dev/fb/bsplash.h> +#include <dev/fb/fbreg.h> +#include <dev/fb/vgareg.h> +#include <isa/isareg.h> -/* - * Load configuration and draw image before kernel thread mechanism is activated. - */ -static void bsplash_early_init (void){ - char *first_image; - - first_image = getenv("bsplash_first_image"); - if (first_image != NULL) { - printf("first_image: %s\n", first_image); - /* TODO: render first_image */ - } - freeenv(first_image); +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 video_adapter_t *adp; + + +int +bsplash_early_init(video_adapter_t *_adp) +{ + adp = _adp; + return 0; +} + + +static int +bsplash_early_init2(void) +{ + caddr_t image = NULL; + void *p; + BMP_INFO bmp_info; + + // get a pointer to the first image + image = preload_search_by_type("bsplash_image"); + if (image == NULL) + return 1; + p = preload_fetch_addr(image); + + if (load_bmp(adp, &bmp_info, p) != 0) + printf("bsplash: failed to load BMP\n"); + + timeout(update_animation, NULL, 15); + + if (draw_bmp(adp, &bmp_info, 0, 0, 0, 0) != 0) + printf("bsplash: failed to draw BMP\n"); + + return 0; } +static void +update_animation(void *unused) +{ + /* TODO */ + timeout(update_animation, NULL, 15); +} + + +static int +load_bmp(video_adapter_t *adp, BMP_INFO *bmp_info, void* data) +{ + video_info_t info; + + if (vidd_get_info(adp, M_VESA_CG1024x768, &info) != 0) + return 1; + + if (bmp_init(bmp_info, (u_char *)data, info.vi_width, + info.vi_height, info.vi_depth) !=0) + return 1; + + return 0; +} + + +static int +draw_bmp(video_adapter_t *adp, BMP_INFO *bmp_info, int x, int y, int height, int width) +{ + + if (vidd_set_mode(adp, M_VESA_CG1024x768) != 0) + return 1; + + if (bmp_draw(adp, bmp_info)) + return 1; + + return 0; +} + static void bsplash_uninit (void){ } @@ -59,7 +126,7 @@ { switch ((modeventtype_t)type) { case MOD_LOAD: - bsplash_early_init(); + bsplash_early_init2(); break; case MOD_UNLOAD: bsplash_uninit(); Added: soc2014/seiya/bootsplash/sys/dev/fb/bsplash.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2014/seiya/bootsplash/sys/dev/fb/bsplash.h Sat Jun 7 06:26:00 2014 (r269229) @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2014, Seiya Nuta <seiya@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FB_BSPLASH_H_ +#define _FB_BSPLASH_H_ + +int bsplash_early_init (video_adapter_t *adp); + +#endif Modified: soc2014/seiya/bootsplash/sys/dev/fb/splash_bmp.c ============================================================================== --- soc2014/seiya/bootsplash/sys/dev/fb/splash_bmp.c Sat Jun 7 05:14:07 2014 (r269228) +++ soc2014/seiya/bootsplash/sys/dev/fb/splash_bmp.c Sat Jun 7 06:26:00 2014 (r269229) @@ -34,6 +34,7 @@ #include <sys/linker.h> #include <sys/fbio.h> +#include <dev/fb/bmp.h> #include <dev/fb/fbreg.h> #include <dev/fb/splashreg.h> #ifndef PC98 @@ -51,8 +52,6 @@ static int bmp_start(video_adapter_t *adp); static int bmp_end(video_adapter_t *adp); static int bmp_splash(video_adapter_t *adp, int on); -static int bmp_Init(char *data, int swidth, int sheight, int sdepth); -static int bmp_Draw(video_adapter_t *adp); static splash_decoder_t bmp_decoder = { "splash_bmp", bmp_start, bmp_end, bmp_splash, SPLASH_IMAGE, @@ -60,6 +59,8 @@ SPLASH_DECODER(splash_bmp, bmp_decoder); +static BMP_INFO bmp_info; + static int bmp_start(video_adapter_t *adp) { @@ -95,7 +96,7 @@ } for (i = 0; modes[i] >= 0; ++i) { if ((vidd_get_info(adp, modes[i], &info) == 0) && - (bmp_Init((u_char *)bmp_decoder.data, info.vi_width, + (bmp_init(&bmp_info, (u_char *)bmp_decoder.data, info.vi_width, info.vi_height, info.vi_depth) == 0)) break; } @@ -129,7 +130,7 @@ /* set up the video mode and draw something */ if (vidd_set_mode(adp, splash_mode)) return 1; - if (bmp_Draw(adp)) + if (bmp_draw(adp, &bmp_info)) return 1; vidd_save_palette(adp, pal); time_stamp = 0; @@ -171,473 +172,3 @@ return 0; } } - -/* -** Code to handle Microsoft DIB (".BMP") format images. -** -** Blame me (msmith@freebsd.org) if this is broken, not Soren. -*/ - -typedef struct tagBITMAPFILEHEADER { /* bmfh */ - u_short bfType; - int bfSize; - u_short bfReserved1; - u_short bfReserved2; - int bfOffBits; -} __packed BITMAPFILEHEADER; - -typedef struct tagBITMAPINFOHEADER { /* bmih */ - int biSize; - int biWidth; - int biHeight; - short biPlanes; - short biBitCount; - int biCompression; - int biSizeImage; - int biXPelsPerMeter; - int biYPelsPerMeter; - int biClrUsed; - int biClrImportant; -} __packed BITMAPINFOHEADER; - -typedef struct tagRGBQUAD { /* rgbq */ - u_char rgbBlue; - u_char rgbGreen; - u_char rgbRed; - u_char rgbReserved; -} __packed RGBQUAD; - -typedef struct tagBITMAPINFO { /* bmi */ - BITMAPINFOHEADER bmiHeader; - RGBQUAD bmiColors[256]; -} __packed BITMAPINFO; - -typedef struct tagBITMAPF -{ - BITMAPFILEHEADER bmfh; - BITMAPINFO bmfi; -} __packed BITMAPF; - -#define BI_RGB 0 -#define BI_RLE8 1 -#define BI_RLE4 2 - -/* -** all we actually care about the image -*/ -typedef struct -{ - int width,height; /* image dimensions */ - int swidth,sheight; /* screen dimensions for the current mode */ - u_char depth; /* image depth (1, 4, 8, 24 bits) */ - u_char sdepth; /* screen depth (1, 4, 8 bpp) */ - int ncols; /* number of colours */ - u_char palette[256][3]; /* raw palette data */ - u_char format; /* one of the BI_* constants above */ - u_char *data; /* pointer to the raw data */ - u_char *index; /* running pointer to the data while drawing */ - u_char *vidmem; /* video memory allocated for drawing */ - video_adapter_t *adp; - int bank; -#ifdef PC98 - u_char prev_val; -#endif -} BMP_INFO; - -static BMP_INFO bmp_info; - -/* -** 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; - - /* - * range check to avoid explosions - */ - 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. - */ - sofs = ((info->height - (y+1) + (info->sheight - info->height) / 2) - * info->adp->va_line_width); - x += (info->swidth - info->width) / 2; - - 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 - - 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_DecodeRLE4 -** -** Given (data) pointing to a line of RLE4-format data and (line) being the starting -** line onscreen, decode the line. -*/ -static void -bmp_DecodeRLE4(BMP_INFO *info, int line) -{ - int count; /* run count */ - u_char val; - int x,y; /* screen position */ - - x = 0; /* starting position */ - y = line; - - /* 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) { - for (count = 0; count < *info->index; count++, x++) { - if (count & 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); - } - } - 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 (count = 0; count < *(info->index + 1); count++, x++) { - val = *(info->index + 2 + (count / 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); - } - /* warning, this depends on integer truncation, do not hand-optimise! */ - info->index += 2 + ((count + 3) / 4) * 2; - break; - } - } - } -} - -/* -** bmp_DecodeRLE8 -** Given (data) pointing to a line of RLE8-format data and (line) being the starting -** line onscreen, decode the line. -*/ -static void -bmp_DecodeRLE8(BMP_INFO *info, int line) -{ - int count; /* run count */ - int x,y; /* screen position */ - - x = 0; /* starting position */ - y = line; - - /* 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) { - for (count = 0; count < *info->index; count++, x++) - bmp_SetPix(info, x, y, *(info->index+1)); - 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 (count = 0; count < *(info->index + 1); count++, x++) - bmp_SetPix(info, x, y, *(info->index + 2 + count)); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406070626.s576Q0lm026358>