bmp.c
上传用户:hengzhunsh
上传日期:2013-09-07
资源大小:19k
文件大小:5k
- /*
- fbv -- simple image viewer for the linux framebuffer
- Copyright (C) 2002 Tomasz Sterna
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- #include "config.h"
- #ifdef FBV_SUPPORT_BMP
- #include "fbv.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #define BMP_TORASTER_OFFSET 10
- #define BMP_SIZE_OFFSET 18
- #define BMP_BPP_OFFSET 28
- #define BMP_RLE_OFFSET 30
- #define BMP_COLOR_OFFSET 54
- #define fill4B(a) ( ( 4 - ( (a) % 4 ) ) & 0x03)
- struct color {
- unsigned char red;
- unsigned char green;
- unsigned char blue;
- };
- int fh_bmp_id(char *name)
- {
- int fd;
- char id[2];
-
- fd = open(name, O_RDONLY);
- if (fd == -1) {
- return(0);
- }
-
- read(fd, id, 2);
- close(fd);
- if ( id[0]=='B' && id[1]=='M' ) {
- return(1);
- }
- return(0);
- }
- void fetch_pallete(int fd, struct color pallete[], int count)
- {
- unsigned char buff[4];
- int i;
- lseek(fd, BMP_COLOR_OFFSET, SEEK_SET);
- for (i=0; i<count; i++) {
- read(fd, buff, 4);
- pallete[i].red = buff[2];
- pallete[i].green = buff[1];
- pallete[i].blue = buff[0];
- }
- return;
- }
- int fh_bmp_load(char *name,unsigned char *buffer, unsigned char **alpha, int x,int y)
- {
- int fd, bpp, raster, i, j, k, skip;
- unsigned char buff[4];
- unsigned char *wr_buffer = buffer + x*(y-1)*3;
- struct color pallete[256];
- fd = open(name, O_RDONLY);
- if (fd == -1) {
- return(FH_ERROR_FILE);
- }
- if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) {
- return(FH_ERROR_FORMAT);
- }
- read(fd, buff, 4);
- raster = buff[0] + (buff[1]<<8) + (buff[2]<<16) + (buff[3]<<24);
- if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) {
- return(FH_ERROR_FORMAT);
- }
- read(fd, buff, 2);
- bpp = buff[0] + (buff[1]<<8);
-
- switch (bpp){
- case 1: /* monochrome */
- skip = fill4B(x/8+(x%8?1:0));
- lseek(fd, raster, SEEK_SET);
- for (i=0; i<y; i++) {
- for (j=0; j<x/8; j++) {
- read(fd, buff, 1);
- for (k=0; k<8; k++) {
- if (buff[0] & 0x80) {
- *wr_buffer++ = 0xff;
- *wr_buffer++ = 0xff;
- *wr_buffer++ = 0xff;
- } else {
- *wr_buffer++ = 0x00;
- *wr_buffer++ = 0x00;
- *wr_buffer++ = 0x00;
- }
- buff[0] = buff[0]<<1;
- }
-
- }
- if (x%8) {
- read(fd, buff, 1);
- for (k=0; k<x%8; k++) {
- if (buff[0] & 0x80) {
- *wr_buffer++ = 0xff;
- *wr_buffer++ = 0xff;
- *wr_buffer++ = 0xff;
- } else {
- *wr_buffer++ = 0x00;
- *wr_buffer++ = 0x00;
- *wr_buffer++ = 0x00;
- }
- buff[0] = buff[0]<<1;
- }
-
- }
- if (skip) {
- read(fd, buff, skip);
- }
- wr_buffer -= x*6; /* backoff 2 lines - x*2 *3 */
- }
- break;
- case 4: /* 4bit palletized */
- skip = fill4B(x/2+x%2);
- fetch_pallete(fd, pallete, 16);
- lseek(fd, raster, SEEK_SET);
- for (i=0; i<y; i++) {
- for (j=0; j<x/2; j++) {
- read(fd, buff, 1);
- buff[1] = buff[0]>>4;
- buff[2] = buff[0] & 0x0f;
- *wr_buffer++ = pallete[buff[1]].red;
- *wr_buffer++ = pallete[buff[1]].green;
- *wr_buffer++ = pallete[buff[1]].blue;
- *wr_buffer++ = pallete[buff[2]].red;
- *wr_buffer++ = pallete[buff[2]].green;
- *wr_buffer++ = pallete[buff[2]].blue;
- }
- if (x%2) {
- read(fd, buff, 1);
- buff[1] = buff[0]>>4;
- *wr_buffer++ = pallete[buff[1]].red;
- *wr_buffer++ = pallete[buff[1]].green;
- *wr_buffer++ = pallete[buff[1]].blue;
- }
- if (skip) {
- read(fd, buff, skip);
- }
- wr_buffer -= x*6; /* backoff 2 lines - x*2 *3 */
- }
- break;
- case 8: /* 8bit palletized */
- skip = fill4B(x);
- fetch_pallete(fd, pallete, 256);
- lseek(fd, raster, SEEK_SET);
- for (i=0; i<y; i++) {
- for (j=0; j<x; j++) {
- read(fd, buff, 1);
- *wr_buffer++ = pallete[buff[0]].red;
- *wr_buffer++ = pallete[buff[0]].green;
- *wr_buffer++ = pallete[buff[0]].blue;
- }
- if (skip) {
- read(fd, buff, skip);
- }
- wr_buffer -= x*6; /* backoff 2 lines - x*2 *3 */
- }
- break;
- case 16: /* 16bit RGB */
- return(FH_ERROR_FORMAT);
- break;
- case 24: /* 24bit RGB */
- skip = fill4B(x*3);
- lseek(fd, raster, SEEK_SET);
- for (i=0; i<y; i++) {
- for (j=0; j<x; j++) {
- read(fd, buff, 3);
- *wr_buffer++ = buff[2];
- *wr_buffer++ = buff[1];
- *wr_buffer++ = buff[0];
- }
- if (skip) {
- read(fd, buff, skip);
- }
- wr_buffer -= x*6; /* backoff 2 lines - x*2 *3 */
- }
- break;
- default:
- return(FH_ERROR_FORMAT);
- }
- close(fd);
- return(FH_ERROR_OK);
- }
- int fh_bmp_getsize(char *name,int *x,int *y)
- {
- int fd;
- unsigned char size[4];
- fd = open(name, O_RDONLY);
- if (fd == -1) {
- return(FH_ERROR_FILE);
- }
- if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) {
- return(FH_ERROR_FORMAT);
- }
-
- read(fd, size, 4);
- *x = size[0] + (size[1]<<8) + (size[2]<<16) + (size[3]<<24);
- // *x-=1;
- read(fd, size, 4);
- *y = size[0] + (size[1]<<8) + (size[2]<<16) + (size[3]<<24);
-
- close(fd);
- return(FH_ERROR_OK);
- }
- #endif