Added support for outputting bmp's

The padding is slightly messed up, so it produces somewhat trunkcated images
however it works.  I'll try and fix it later but I have to go home now.
Its atleast usable at this stage.

I moved bmp_decode.c to bmp.c and cleaned it up a little bit.

Kent
This commit is contained in:
Kent Mein 2004-01-09 22:04:08 +00:00
parent b430cd167f
commit e3080c9580
10 changed files with 126 additions and 36 deletions

@ -163,7 +163,7 @@ SOURCE=..\..\..\source\blender\imbuf\intern\bitplanes.c
# End Source File
# Begin Source File
SOURCE=..\..\..\source\blender\imbuf\intern\bmp_decode.c
SOURCE=..\..\..\source\blender\imbuf\intern\bmp.c
# End Source File
# Begin Source File

@ -15,7 +15,7 @@ source_files = ['intern/allocimbuf.c',
'intern/anim5.c',
'intern/antialias.c',
'intern/bitplanes.c',
'intern/bmp_decode.c',
'intern/bmp.c',
'intern/cmap.c',
'intern/cspace.c',
'intern/data.c',

@ -44,6 +44,7 @@ struct ImBuf;
int imb_is_a_bmp(void *buf);
struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags);
int bmp_savebmp(struct ImBuf *ibuf, int file, int flags);
#endif

@ -48,43 +48,33 @@
#include <config.h>
#endif
// some code copied from article on microsoft.com, copied
// here for enhanced BMP support in the future
// http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0197/mfcp1/mfcp1.htm&nav=/msj/0197/newnav.htm
/*
LPBYTE CDib::GetBits()
{
return (LPBYTE)m_pbmih + // start of bitmap +
m_pbmih->biSize + // size of header +
GetNumPaletteColors() // (num colors *
*sizeof(RGBQUAD); // size each entry)
}
UINT CDib::GetNumPaletteColors()
{
UINT nColors=m_pbmih->biClrUsed;
if (nColors==0 && m_pbmih->biBitCount<=8)
nColors = 1<<m_pbmih->biBitCount;
return nColors;
}
/* some code copied from article on microsoft.com, copied
here for enhanced BMP support in the future
http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0197/mfcp1/mfcp1.htm&nav=/msj/0197/newnav.htm
*/
typedef struct BMPINFOHEADER{
unsigned int biSize;
int biWidth;
int biHeight;
unsigned int biWidth;
unsigned int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biXPelsPerMeter;
unsigned int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} BMPINFOHEADER;
typedef struct BMPHEADER {
unsigned short biType;
unsigned int biSize;
unsigned short biRes1;
unsigned short biRes2;
unsigned int biOffBits;
} BMPHEADER;
#define BMP_FILEHEADER_SIZE 14
static int checkbmp(unsigned char *mem)
@ -95,15 +85,16 @@ static int checkbmp(unsigned char *mem)
if (mem) {
if ((mem[0] == 'B') && (mem[1] == 'M')) {
// skip fileheader
/* skip fileheader */
mem += BMP_FILEHEADER_SIZE;
} else {
}
// for systems where an int needs to be 4 bytes aligned
/* for systems where an int needs to be 4 bytes aligned */
memcpy(&bmi, mem, sizeof(bmi));
u = LITTLE_LONG(bmi.biSize);
// we only support uncompressed 24 or 32 bits images for now
/* we only support uncompressed 24 or 32 bits images for now */
if (u >= sizeof(BMPINFOHEADER)) {
if ((bmi.biCompression == 0) && (bmi.biClrUsed == 0)) {
u = LITTLE_SHORT(bmi.biBitCount);
@ -133,11 +124,11 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags)
if (checkbmp(mem) == 0) return(0);
if ((mem[0] == 'B') && (mem[1] == 'M')) {
// skip fileheader
/* skip fileheader */
mem += BMP_FILEHEADER_SIZE;
}
// for systems where an int needs to be 4 bytes aligned
/* for systems where an int needs to be 4 bytes aligned */
memcpy(&bmi, mem, sizeof(bmi));
skip = LITTLE_LONG(bmi.biSize);
@ -145,7 +136,10 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags)
y = LITTLE_LONG(bmi.biHeight);
depth = LITTLE_SHORT(bmi.biBitCount);
// printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y, depth, bmi.biBitCount);
/* printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y,
depth, bmi.biBitCount); */
printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y,
depth, bmi.biBitCount);
if (flags & IB_test) {
ibuf = IMB_allocImBuf(x, y, depth, 0, 0);
} else {
@ -191,3 +185,65 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags)
return(ibuf);
}
/* Couple of helper functions for writing our data */
int putIntLSB(unsigned int ui,FILE *ofile) {
putc((ui>>0)&0xFF,ofile);
putc((ui>>8)&0xFF,ofile);
putc((ui>>16)&0xFF,ofile);
return putc((ui>>24)&0xFF,ofile);
}
int putShortLSB(unsigned short us,FILE *ofile) {
putc((us>>0)&0xFF,ofile);
return putc((us>>8)&0xFF,ofile);
}
/* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */
short imb_savebmp(struct ImBuf *ibuf, int outfile, int flags) {
BMPINFOHEADER infoheader;
int bytesize, extrabytes, x, y, t, ptr;
uchar *data;
FILE *ofile;
extrabytes = (4 - ibuf->x % 4) % 4;
printf("extrabytes = %d\n",extrabytes);
bytesize = (ibuf->x + extrabytes) * ibuf->y;
data = (uchar *) ibuf->rect;
ofile = fdopen(outfile,"ab");
putShortLSB(19778,ofile); /* "BM" */
putIntLSB(0,ofile); /* This can be 0 for BI_RGB bitmaps */
putShortLSB(0,ofile); /* Res1 */
putShortLSB(0,ofile); /* Res2 */
putIntLSB(BMP_FILEHEADER_SIZE + sizeof(infoheader),ofile);
putIntLSB(sizeof(infoheader),ofile);
putIntLSB(ibuf->x,ofile);
putIntLSB(ibuf->y,ofile);
putShortLSB(1,ofile);
putShortLSB(24,ofile);
putIntLSB(0,ofile);
putIntLSB(bytesize,ofile);
putIntLSB(0,ofile);
putIntLSB(0,ofile);
putIntLSB(0,ofile);
putIntLSB(0,ofile);
/* Need to write out padded image data in bgr format */
for (y=0;y<ibuf->y;y++) {
for (x=0;x<ibuf->x;x++) {
ptr=(x + y * ibuf->x) * 4;
if (putc(data[ptr+2],ofile) == EOF) return 0;
if (putc(data[ptr+1],ofile) == EOF) return 0;
if (putc(data[ptr],ofile) == EOF) return 0;
}
/* add padding here */
for (t=0;t<extrabytes;t++) if (putc(0,ofile) == EOF) return 0;
}
printf("x = %d y = %d\n",x,y);
return 1;
}

@ -91,6 +91,14 @@ short IMB_saveiff(struct ImBuf *ibuf,char *naam,int flags)
}
}
if (IS_bmp(ibuf)) {
ok = imb_savebmp(ibuf,file,flags);
if (ok) {
close (file);
return (ok);
}
}
if (IS_tga(ibuf)) {
ok = imb_savetarga(ibuf,file,flags);
if (ok) {

@ -21,7 +21,20 @@ Add your hooks to read and write the image format these go in
Step 3:
Add in IS_openexr to blender/source/blender/imbuf/IMB_imbuf_types.h
Add in R_openexr to source/blender/makesdna/DNA_scene_types.h
Step 4:
Add any external library info to the build process.
Step 4:
Add your hooks to the gui.
source/blender/src/buttons_scene.c
source/blender/src/toets.c
source/blender/src/writeimage.c
Step 5:
Alter the build process:
For autoconf you need to edit blender/source/blender/imbuf/Makefile.am
and add in your additional files.
For msvp you need to edit blender/projectfiles/blender/imbuf/BL_imbuf.dsp
and add in your additional files.
If you have any external library info you will also need to add that
to the various build processes.

@ -323,7 +323,8 @@ typedef struct Scene {
#define R_AVIJPEG 16
#define R_PNG 17
#define R_AVICODEC 18
#define R_QUICKTIME 19
#define R_QUICKTIME 19
#define R_BMP 20
/* **************** RENDER ********************* */

@ -877,6 +877,7 @@ static char *imagetype_pup(void)
#endif
strcat(formatstring, "|%s %%x%d"); // add space for PNG
strcat(formatstring, "|%s %%x%d"); // add space for BMP
#ifdef _WIN32
strcat(formatstring, "|%s %%x%d"); // add space for AVI Codec
@ -900,6 +901,7 @@ static char *imagetype_pup(void)
"Targa", R_TARGA,
"Targa Raw", R_RAWTGA,
"PNG", R_PNG,
"BMP", R_BMP,
"Jpeg", R_JPEG90,
"HamX", R_HAMX,
"Iris", R_IRIS,
@ -917,6 +919,7 @@ static char *imagetype_pup(void)
"Targa", R_TARGA,
"Targa Raw", R_RAWTGA,
"PNG", R_PNG,
"BMP", R_BMP,
"Jpeg", R_JPEG90,
"HamX", R_HAMX,
"Iris", R_IRIS,

@ -191,6 +191,9 @@ void schrijfplaatje(char *name)
else if(R.r.imtype==R_PNG) {
ibuf->ftype= PNG;
}
else if(R.r.imtype==R_BMP) {
ibuf->ftype= BMP;
}
else if((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) {
ibuf->ftype= TGA;
}
@ -460,6 +463,8 @@ int save_image_filesel_str(char *str)
switch(G.scene->r.imtype) {
case R_PNG:
strcpy(str, "SAVE PNG"); return 1;
case R_BMP:
strcpy(str, "SAVE BMP"); return 1;
case R_TARGA:
strcpy(str, "SAVE TARGA"); return 1;
case R_RAWTGA:

@ -53,6 +53,9 @@ int BIF_write_ibuf(ImBuf *ibuf, char *name)
else if ((R.r.imtype==R_PNG)) {
ibuf->ftype= PNG;
}
else if ((R.r.imtype==R_BMP)) {
ibuf->ftype= BMP;
}
else if ((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) {
// fall back to Targa if PNG writing is not supported
ibuf->ftype= TGA;