Files
recycled-ni-neutrino/src/driver/pictureviewer/bmp.cpp
Stefan Seyfried aa2c86bd56 pictureviewer: rename config.h to pv_config.h
this avoids confusion with the global config.h, which in turn
caused very hard to debug runtime failures when objects were
compiled with different defines, causing e.g. g_settings to
have different sizes...

git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-experimental@1022 e54a6e83-5905-42d5-8d5c-058d10e6a962


Origin commit data
------------------
Commit: 7a98888017
Author: Stefan Seyfried <seife@tuxbox-git.slipkontur.de>
Date: 2011-01-08 (Sat, 08 Jan 2011)
2011-01-08 22:37:13 +00:00

268 lines
5.6 KiB
C++

#include "pv_config.h"
#ifdef FBV_SUPPORT_BMP
#include "pictureviewer.h"
#include <cstdlib>
#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(const char *name)
{
int fd;
char id[2];
fd = open(name, O_RDONLY);
if (fd == -1) {
// dbout("fh_bmp_id {\n");
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)
{
// dbout("fetch_palette {\n");
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];
}
// dbout("fetch_palette }\n");
return;
}
int fh_bmp_load(const char *name,unsigned char **buffer,int* xp,int* yp)
{
// dbout("fh_bmp_load {\n");
int fd, bpp, raster, i, j, k, skip, x=*xp, y=*yp;
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) {
close(fd);//Resource leak: fd
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) {
close(fd);
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);
{
int bytes=x/8;
if(x%8 >0)
bytes++;
unsigned char* tbuffer = (unsigned char*) malloc(bytes);
if(tbuffer==NULL)
{
printf("Error: malloc\n");
close(fd);
return (FH_ERROR_MALLOC);
}
for (i=0; i<y; i++) {
read(fd, tbuffer, bytes);
for (j=0; j<x/8; j++) {
for (k=0; k<8; k++) {
if (tbuffer[j] & 0x80) {
*wr_buffer++ = 0xff;
*wr_buffer++ = 0xff;
*wr_buffer++ = 0xff;
} else {
*wr_buffer++ = 0x00;
*wr_buffer++ = 0x00;
*wr_buffer++ = 0x00;
}
tbuffer[j] = tbuffer[j]<<1;
}
}
if (x%8) {
for (k=0; k<x%8; k++) {
if (tbuffer[j] & 0x80) {
*wr_buffer++ = 0xff;
*wr_buffer++ = 0xff;
*wr_buffer++ = 0xff;
} else {
*wr_buffer++ = 0x00;
*wr_buffer++ = 0x00;
*wr_buffer++ = 0x00;
}
tbuffer[j] = tbuffer[j]<<1;
}
}
if (skip) {
read(fd, tbuffer, skip);
}
wr_buffer -= x*6; /* backoff 2 lines - x*2 *3 */
}
free(tbuffer);
}
break;
case 4: /* 4bit palletized */
{
skip = fill4B(x/2+x%2);
fetch_pallete(fd, pallete, 16);
lseek(fd, raster, SEEK_SET);
unsigned char* tbuffer = (unsigned char*) malloc(x/2+1);
if(tbuffer==NULL)
{
printf("Error: malloc\n");
close(fd);
return (FH_ERROR_MALLOC);
}
unsigned char c1,c2;
for (i=0; i<y; i++) {
read(fd, tbuffer, x/2 + x%2);
for (j=0; j<x/2; j++) {
c1 = tbuffer[j]>>4;
c2 = tbuffer[j] & 0x0f;
*wr_buffer++ = pallete[c1].red;
*wr_buffer++ = pallete[c1].green;
*wr_buffer++ = pallete[c1].blue;
*wr_buffer++ = pallete[c2].red;
*wr_buffer++ = pallete[c2].green;
*wr_buffer++ = pallete[c2].blue;
}
if (x%2) {
c1 = tbuffer[j]>>4;
*wr_buffer++ = pallete[c1].red;
*wr_buffer++ = pallete[c1].green;
*wr_buffer++ = pallete[c1].blue;
}
if (skip) {
read(fd, buff, skip);
}
wr_buffer -= x*6; /* backoff 2 lines - x*2 *3 */
}
free(tbuffer);
}
break;
case 8: /* 8bit palletized */
{
skip = fill4B(x);
fetch_pallete(fd, pallete, 256);
lseek(fd, raster, SEEK_SET);
unsigned char* tbuffer = (unsigned char*) malloc(x);
if(tbuffer==NULL)
{
printf("Error: malloc\n");
close(fd);
return (FH_ERROR_MALLOC);
}
for (i=0; i<y; i++)
{
read(fd, tbuffer, x);
for (j=0; j<x; j++) {
wr_buffer[j*3] = pallete[tbuffer[j]].red;
wr_buffer[j*3+1] = pallete[tbuffer[j]].green;
wr_buffer[j*3+2] = pallete[tbuffer[j]].blue;
}
if (skip) {
read(fd, buff, skip);
}
wr_buffer -= x*3; /* backoff 2 lines - x*2 *3 */
}
free(tbuffer);
}
break;
case 16: /* 16bit RGB */
return(FH_ERROR_FORMAT);
break;
case 24: /* 24bit RGB */
skip = fill4B(x*3);
lseek(fd, raster, SEEK_SET);
unsigned char c;
for (i=0; i<y; i++)
{
read(fd,wr_buffer,x*3);
for(j=0; j < x*3 ; j=j+3)
{
c=wr_buffer[j];
wr_buffer[j]=wr_buffer[j+2];
wr_buffer[j+2]=c;
}
if (skip) {
read(fd, buff, skip);
}
wr_buffer -= x*3; // backoff 1 lines - x*3
}
break;
default:
return(FH_ERROR_FORMAT);
}
close(fd);
// dbout("fh_bmp_load }\n");
return(FH_ERROR_OK);
}
int fh_bmp_getsize(const char *name,int *x,int *y, int /*wanted_width*/, int /*wanted_height*/)
{
// dbout("fh_bmp_getsize {\n");
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) {
close(fd);//Resource leak: fd
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);
// dbout("fh_bmp_getsize }\n");
return(FH_ERROR_OK);
}
#endif