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:
@@ -163,7 +163,7 @@ SOURCE=..\..\..\source\blender\imbuf\intern\bitplanes.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\..\source\blender\imbuf\intern\bmp_decode.c
|
SOURCE=..\..\..\source\blender\imbuf\intern\bmp.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ source_files = ['intern/allocimbuf.c',
|
|||||||
'intern/anim5.c',
|
'intern/anim5.c',
|
||||||
'intern/antialias.c',
|
'intern/antialias.c',
|
||||||
'intern/bitplanes.c',
|
'intern/bitplanes.c',
|
||||||
'intern/bmp_decode.c',
|
'intern/bmp.c',
|
||||||
'intern/cmap.c',
|
'intern/cmap.c',
|
||||||
'intern/cspace.c',
|
'intern/cspace.c',
|
||||||
'intern/data.c',
|
'intern/data.c',
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ struct ImBuf;
|
|||||||
|
|
||||||
int imb_is_a_bmp(void *buf);
|
int imb_is_a_bmp(void *buf);
|
||||||
struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags);
|
struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags);
|
||||||
|
int bmp_savebmp(struct ImBuf *ibuf, int file, int flags);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -48,43 +48,33 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// some code copied from article on microsoft.com, copied
|
/* some code copied from article on microsoft.com, copied
|
||||||
// here for enhanced BMP support in the future
|
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
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct BMPINFOHEADER{
|
typedef struct BMPINFOHEADER{
|
||||||
unsigned int biSize;
|
unsigned int biSize;
|
||||||
int biWidth;
|
unsigned int biWidth;
|
||||||
int biHeight;
|
unsigned int biHeight;
|
||||||
unsigned short biPlanes;
|
unsigned short biPlanes;
|
||||||
unsigned short biBitCount;
|
unsigned short biBitCount;
|
||||||
unsigned int biCompression;
|
unsigned int biCompression;
|
||||||
unsigned int biSizeImage;
|
unsigned int biSizeImage;
|
||||||
int biXPelsPerMeter;
|
unsigned int biXPelsPerMeter;
|
||||||
int biYPelsPerMeter;
|
unsigned int biYPelsPerMeter;
|
||||||
unsigned int biClrUsed;
|
unsigned int biClrUsed;
|
||||||
unsigned int biClrImportant;
|
unsigned int biClrImportant;
|
||||||
} BMPINFOHEADER;
|
} 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
|
#define BMP_FILEHEADER_SIZE 14
|
||||||
|
|
||||||
static int checkbmp(unsigned char *mem)
|
static int checkbmp(unsigned char *mem)
|
||||||
@@ -95,15 +85,16 @@ static int checkbmp(unsigned char *mem)
|
|||||||
|
|
||||||
if (mem) {
|
if (mem) {
|
||||||
if ((mem[0] == 'B') && (mem[1] == 'M')) {
|
if ((mem[0] == 'B') && (mem[1] == 'M')) {
|
||||||
// skip fileheader
|
/* skip fileheader */
|
||||||
mem += BMP_FILEHEADER_SIZE;
|
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));
|
memcpy(&bmi, mem, sizeof(bmi));
|
||||||
|
|
||||||
u = LITTLE_LONG(bmi.biSize);
|
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 (u >= sizeof(BMPINFOHEADER)) {
|
||||||
if ((bmi.biCompression == 0) && (bmi.biClrUsed == 0)) {
|
if ((bmi.biCompression == 0) && (bmi.biClrUsed == 0)) {
|
||||||
u = LITTLE_SHORT(bmi.biBitCount);
|
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 (checkbmp(mem) == 0) return(0);
|
||||||
|
|
||||||
if ((mem[0] == 'B') && (mem[1] == 'M')) {
|
if ((mem[0] == 'B') && (mem[1] == 'M')) {
|
||||||
// skip fileheader
|
/* skip fileheader */
|
||||||
mem += BMP_FILEHEADER_SIZE;
|
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));
|
memcpy(&bmi, mem, sizeof(bmi));
|
||||||
|
|
||||||
skip = LITTLE_LONG(bmi.biSize);
|
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);
|
y = LITTLE_LONG(bmi.biHeight);
|
||||||
depth = LITTLE_SHORT(bmi.biBitCount);
|
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) {
|
if (flags & IB_test) {
|
||||||
ibuf = IMB_allocImBuf(x, y, depth, 0, 0);
|
ibuf = IMB_allocImBuf(x, y, depth, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
@@ -191,3 +185,65 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags)
|
|||||||
return(ibuf);
|
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)) {
|
if (IS_tga(ibuf)) {
|
||||||
ok = imb_savetarga(ibuf,file,flags);
|
ok = imb_savetarga(ibuf,file,flags);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
|||||||
@@ -21,7 +21,20 @@ Add your hooks to read and write the image format these go in
|
|||||||
|
|
||||||
Step 3:
|
Step 3:
|
||||||
Add in IS_openexr to blender/source/blender/imbuf/IMB_imbuf_types.h
|
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:
|
Step 4:
|
||||||
Add any external library info to the build process.
|
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_AVIJPEG 16
|
||||||
#define R_PNG 17
|
#define R_PNG 17
|
||||||
#define R_AVICODEC 18
|
#define R_AVICODEC 18
|
||||||
#define R_QUICKTIME 19
|
#define R_QUICKTIME 19
|
||||||
|
#define R_BMP 20
|
||||||
|
|
||||||
|
|
||||||
/* **************** RENDER ********************* */
|
/* **************** RENDER ********************* */
|
||||||
|
|||||||
@@ -877,6 +877,7 @@ static char *imagetype_pup(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
strcat(formatstring, "|%s %%x%d"); // add space for PNG
|
strcat(formatstring, "|%s %%x%d"); // add space for PNG
|
||||||
|
strcat(formatstring, "|%s %%x%d"); // add space for BMP
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
strcat(formatstring, "|%s %%x%d"); // add space for AVI Codec
|
strcat(formatstring, "|%s %%x%d"); // add space for AVI Codec
|
||||||
@@ -900,6 +901,7 @@ static char *imagetype_pup(void)
|
|||||||
"Targa", R_TARGA,
|
"Targa", R_TARGA,
|
||||||
"Targa Raw", R_RAWTGA,
|
"Targa Raw", R_RAWTGA,
|
||||||
"PNG", R_PNG,
|
"PNG", R_PNG,
|
||||||
|
"BMP", R_BMP,
|
||||||
"Jpeg", R_JPEG90,
|
"Jpeg", R_JPEG90,
|
||||||
"HamX", R_HAMX,
|
"HamX", R_HAMX,
|
||||||
"Iris", R_IRIS,
|
"Iris", R_IRIS,
|
||||||
@@ -917,6 +919,7 @@ static char *imagetype_pup(void)
|
|||||||
"Targa", R_TARGA,
|
"Targa", R_TARGA,
|
||||||
"Targa Raw", R_RAWTGA,
|
"Targa Raw", R_RAWTGA,
|
||||||
"PNG", R_PNG,
|
"PNG", R_PNG,
|
||||||
|
"BMP", R_BMP,
|
||||||
"Jpeg", R_JPEG90,
|
"Jpeg", R_JPEG90,
|
||||||
"HamX", R_HAMX,
|
"HamX", R_HAMX,
|
||||||
"Iris", R_IRIS,
|
"Iris", R_IRIS,
|
||||||
|
|||||||
@@ -191,6 +191,9 @@ void schrijfplaatje(char *name)
|
|||||||
else if(R.r.imtype==R_PNG) {
|
else if(R.r.imtype==R_PNG) {
|
||||||
ibuf->ftype= 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)) {
|
else if((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) {
|
||||||
ibuf->ftype= TGA;
|
ibuf->ftype= TGA;
|
||||||
}
|
}
|
||||||
@@ -460,6 +463,8 @@ int save_image_filesel_str(char *str)
|
|||||||
switch(G.scene->r.imtype) {
|
switch(G.scene->r.imtype) {
|
||||||
case R_PNG:
|
case R_PNG:
|
||||||
strcpy(str, "SAVE PNG"); return 1;
|
strcpy(str, "SAVE PNG"); return 1;
|
||||||
|
case R_BMP:
|
||||||
|
strcpy(str, "SAVE BMP"); return 1;
|
||||||
case R_TARGA:
|
case R_TARGA:
|
||||||
strcpy(str, "SAVE TARGA"); return 1;
|
strcpy(str, "SAVE TARGA"); return 1;
|
||||||
case R_RAWTGA:
|
case R_RAWTGA:
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ int BIF_write_ibuf(ImBuf *ibuf, char *name)
|
|||||||
else if ((R.r.imtype==R_PNG)) {
|
else if ((R.r.imtype==R_PNG)) {
|
||||||
ibuf->ftype= 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)) {
|
else if ((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) {
|
||||||
// fall back to Targa if PNG writing is not supported
|
// fall back to Targa if PNG writing is not supported
|
||||||
ibuf->ftype= TGA;
|
ibuf->ftype= TGA;
|
||||||
|
|||||||
Reference in New Issue
Block a user