Added support for outputting bmp's
authorKent Mein <mein@cs.umn.edu>
Fri, 9 Jan 2004 22:04:08 +0000 (22:04 +0000)
committerKent Mein <mein@cs.umn.edu>
Fri, 9 Jan 2004 22:04:08 +0000 (22:04 +0000)
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

projectfiles/blender/imbuf/BL_imbuf.dsp
source/blender/imbuf/SConscript
source/blender/imbuf/intern/IMB_bmp.h
source/blender/imbuf/intern/bmp.c [moved from source/blender/imbuf/intern/bmp_decode.c with 57% similarity]
source/blender/imbuf/intern/writeimage.c
source/blender/imbuf/readme.txt
source/blender/makesdna/DNA_scene_types.h
source/blender/src/buttons_scene.c
source/blender/src/toets.c
source/blender/src/writeimage.c

index 34ec90e4a8af5c3cd88805a03352097578e91b8f..510d1fdc924d688d6d25aa44026bf6cf72c2b739 100644 (file)
@@ -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
 
index 7461a89b7095d3e1b967c94325f8e7f5f8c11c64..52a1795d66636229f163a463afcee9c44ebc591c 100644 (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',
index fe279849bd072e43f447cf031166e469de73ba77..b0fde577b00f94b9c3add19dbf07dc1bd416fc3c 100644 (file)
@@ -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
 
similarity index 57%
rename from source/blender/imbuf/intern/bmp_decode.c
rename to source/blender/imbuf/intern/bmp.c
index 79a249c6b812aa2b478fa412ce55bf2efafc589e..cb8a1e22711f39cd2ac6d0e23ebd82bfd5498b7d 100644 (file)
 #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;
+}
index 64df437679ab66c84a4d2c732a548abf27a4e29e..d6133a1919311abd1a0e2fbd6db950cc8ec87086 100644 (file)
@@ -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) {
index d50cf82af89229284fb32726086548b38b4682d4..4edc625013f04e3f01d4931c48e826785d855187 100644 (file)
@@ -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.
 
index c8219bdc1d12d86888aee0ea5a736295a1d6fdcb..5d03de842e55c969a326a97b333693fedb1b9dfd 100644 (file)
@@ -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 ********************* */
index c3697b1f40c47298d9ca9849ffa859ada7d75e5e..dbb1734dc2b149d89954bf15521948f99586dc69 100644 (file)
@@ -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,
index 87f2654e8c6d4bccbb88f5718cf45c3eda597f8a..fa220f3da2b733795f8ec1609572a39db8f7770b 100644 (file)
@@ -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:
index 2b49a0f6fda57136a2f3270d00b17e3631712f56..23ead94c22d7ccdaa222e268c3e96f669e461e86 100644 (file)
@@ -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;