replace ImBuf.depth with ImBuf.planes to match ImageFormatData.planes & to avoid...
[blender.git] / source / blender / imbuf / intern / targa.c
index acc3e06448f81ef7a4dedcdf1fe4373b37ed282f..895f922a0da9e94f777ed0e62f606cb3df2eba21 100644 (file)
@@ -1,5 +1,4 @@
-/**
- *
+/*
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -14,7 +13,7 @@
  *
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
  * Contributor(s): none yet.
  *
  * ***** END GPL LICENSE BLOCK *****
- * $Id$
  */
 
+/** \file blender/imbuf/intern/targa.c
+ *  \ingroup imbuf
+ */
+
+
 #ifdef WIN32
 #include <io.h>
 #endif
 #include "BLI_blenlib.h"
+#include "MEM_guardedalloc.h"
 
 #include "imbuf.h"
-#include "imbuf_patch.h"
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
 
 #include "IMB_allocimbuf.h"
-#include "IMB_cmap.h"
-#include "IMB_targa.h"
+#include "IMB_filetype.h"
 
 
 /* this one is only def-ed once, strangely... related to GS? */
@@ -192,26 +194,26 @@ static int dumptarga(struct ImBuf * ibuf, FILE * file)
        int size;
        uchar *rect;
 
-       if (ibuf == 0) return (0);
-       if (ibuf->rect == 0) return (0);
+       if (ibuf == NULL) return (0);
+       if (ibuf->rect == NULL) return (0);
 
        size = ibuf->x * ibuf->y;
        rect = (uchar *) ibuf->rect;
 
-       if (ibuf->depth <= 8) {
+       if (ibuf->planes <= 8) {
                while(size > 0){
                        if (putc(*rect, file) == EOF) return (0);
                        size--;
                        rect += 4;
                }
-       } else if (ibuf->depth <= 16) {
+       } else if (ibuf->planes <= 16) {
                while(size > 0){
                        putc(rect[0], file);
                        if (putc(rect[1], file) == EOF) return (0);
                        size--;
                        rect += 4;
                }
-       } else if (ibuf->depth <= 24) {
+       } else if (ibuf->planes <= 24) {
                while(size > 0){
                        putc(rect[2], file);
                        putc(rect[1], file);
@@ -219,7 +221,7 @@ static int dumptarga(struct ImBuf * ibuf, FILE * file)
                        size--;
                        rect += 4;
                }
-       } else if (ibuf->depth <= 32) {
+       } else if (ibuf->planes <= 32) {
                while(size > 0){
                        putc(rect[2], file);
                        putc(rect[1], file);
@@ -234,34 +236,16 @@ static int dumptarga(struct ImBuf * ibuf, FILE * file)
 }
 
 
-short imb_savetarga(struct ImBuf * ibuf, char *name, int flags)
+int imb_savetarga(struct ImBuf * ibuf, const char *name, int flags)
 {
-       char buf[20];
+       char buf[20]= {0};
        FILE *fildes;
-       int i;
        short ok = 0;
+       
+       (void)flags; /* unused */
 
-       if (ibuf == 0) return (0);
-       if (ibuf->rect == 0) return (0);
-
-       memset(buf,0,sizeof(buf));
-
-       /* buf[0] = 0;  length string */
-
-       buf[16] = (ibuf->depth + 0x7 ) & ~0x7;
-       if (ibuf->cmap) {
-               buf[1] = 1;
-               buf[2] = 9;
-               buf[3] = ibuf->mincol & 0xff;
-               buf[4] = ibuf->mincol >> 8;
-               buf[5] = ibuf->maxcol & 0xff;
-               buf[6] = ibuf->maxcol >> 8;
-               buf[7] = 24;
-               if ((flags & IB_ttob) == 0) {
-                       IMB_flipy(ibuf);
-                       buf[17] = 0x20;
-               }
-       } else if (ibuf->depth > 8 ){
+       buf[16] = (ibuf->planes + 0x7 ) & ~0x7;
+       if (ibuf->planes > 8 ){
                buf[2] = 10;
        } else{
                buf[2] = 11;
@@ -269,46 +253,33 @@ short imb_savetarga(struct ImBuf * ibuf, char *name, int flags)
 
        if (ibuf->ftype == RAWTGA) buf[2] &= ~8;
        
-       buf[8] = ibuf->xorig & 0xff;
-       buf[9] = ibuf->xorig >> 8;
-       buf[10] = ibuf->yorig & 0xff;
-       buf[11] = ibuf->yorig >> 8;
+       buf[8] = 0;
+       buf[9] = 0;
+       buf[10] = 0;
+       buf[11] = 0;
 
        buf[12] = ibuf->x & 0xff;
        buf[13] = ibuf->x >> 8;
        buf[14] = ibuf->y & 0xff;
        buf[15] = ibuf->y >> 8;
 
-       if (flags & IB_ttob) buf[17] ^= 0x20;
-
        /* Don't forget to indicate that your 32 bit
         * targa uses 8 bits for the alpha channel! */
-       if (ibuf->depth==32) {
+       if (ibuf->planes==32) {
                buf[17] |= 0x08;
        }
        fildes = fopen(name,"wb");
-        if (!fildes) return 0;
+               if (!fildes) return 0;
 
        if (fwrite(buf, 1, 18,fildes) != 18) {
                fclose(fildes);
                return (0);
        }
 
-       if (ibuf->cmap){
-               for (i = 0 ; i<ibuf->maxcol ; i++){
-                       if (fwrite(((uchar *)(ibuf->cmap + i)) + 1,1,3,fildes) != 3) {
-                fclose(fildes);
-                return (0);
-            }
-               }
-       }
-       
-       if (ibuf->cmap && (flags & IB_cmap) == 0) IMB_converttocmap(ibuf);
-       
        if (ibuf->ftype == RAWTGA) {
                ok = dumptarga(ibuf, fildes);
        } else {                
-               switch((ibuf->depth + 7) >> 3){
+               switch((ibuf->planes + 7) >> 3){
                case 1:
                        ok = makebody_tga(ibuf, fildes, tga_out1);
                        break;
@@ -365,7 +336,8 @@ static int checktarga(TARGA *tga, unsigned char *mem)
        return(1);
 }
 
-int imb_is_a_targa(void *buf) {
+int imb_is_a_targa(unsigned char *buf)
+{
        TARGA tga;
        
        return checktarga(&tga, buf);
@@ -386,15 +358,15 @@ static void complete_partial_load(struct ImBuf *ibuf, unsigned int *rect)
        }
 }
 
-static void decodetarga(struct ImBuf *ibuf, unsigned char *mem, int mem_size, int psize)
+static void decodetarga(struct ImBuf *ibuf, unsigned char *mem, size_t mem_size, int psize)
 {
        unsigned char *mem_end = mem+mem_size;
        int count, col, size;
        unsigned int *rect;
        uchar * cp = (uchar *) &col;
        
-       if (ibuf == 0) return;
-       if (ibuf->rect == 0) return;
+       if (ibuf == NULL) return;
+       if (ibuf->rect == NULL) return;
 
        size = ibuf->x * ibuf->y;
        rect = ibuf->rect;
@@ -497,15 +469,15 @@ partial_load:
        complete_partial_load(ibuf, rect);
 }
 
-static void ldtarga(struct ImBuf * ibuf,unsigned char * mem, int mem_size, int psize)
+static void ldtarga(struct ImBuf * ibuf,unsigned char * mem, size_t mem_size, int psize)
 {
        unsigned char *mem_end = mem+mem_size;
        int col,size;
        unsigned int *rect;
        uchar * cp = (uchar *) &col;
 
-       if (ibuf == 0) return;
-       if (ibuf->rect == 0) return;
+       if (ibuf == NULL) return;
+       if (ibuf->rect == NULL) return;
 
        size = ibuf->x * ibuf->y;
        rect = ibuf->rect;
@@ -554,34 +526,34 @@ partial_load:
 }
 
 
-struct ImBuf *imb_loadtarga(unsigned char *mem, int mem_size, int flags)
+struct ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags)
 {
        TARGA tga;
        struct ImBuf * ibuf;
        int col, count, size;
-       unsigned int * rect;
+       unsigned int *rect, *cmap= NULL /*, mincol= 0*/, maxcol= 0;
        uchar * cp = (uchar *) &col;
        
-       if (checktarga(&tga,mem) == 0) return(0);
+       if (checktarga(&tga,mem) == 0) return(NULL);
 
-       if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,tga.pixsize, 0, 0);
-       else ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,(tga.pixsize + 0x7) & ~0x7, IB_rect, 0);
+       if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,tga.pixsize, 0);
+       else ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,(tga.pixsize + 0x7) & ~0x7, IB_rect);
 
-       if (ibuf == 0) return(0);
+       if (ibuf == NULL) return(NULL);
        ibuf->ftype = TGA;
-       ibuf->xorig = tga.xorig;
-       ibuf->yorig = tga.yorig;
+       ibuf->profile = IB_PROFILE_SRGB;
        mem = mem + 18 + tga.numid;
        
        cp[0] = 0xff;
        cp[1] = cp[2] = 0;
        
        if (tga.mapsize){
-               ibuf->mincol = tga.maporig;
-               ibuf->maxcol = tga.mapsize;
-               imb_addcmapImBuf(ibuf);
-               ibuf->cbits = 8;
-               for (count = 0 ; count < ibuf->maxcol ; count ++) {
+               /* load color map */
+               /*mincol = tga.maporig;*/ /*UNUSED*/
+               maxcol = tga.mapsize;
+               cmap = MEM_callocN(sizeof(unsigned int)*maxcol, "targa cmap");
+
+               for (count = 0 ; count < maxcol ; count ++) {
                        switch (tga.mapbits >> 3) {
                                case 4:
                                        cp[0] = mem[3];
@@ -605,21 +577,26 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, int mem_size, int flags)
                                        col = *mem++;
                                        break;
                        }
-                       ibuf->cmap[count] = col;
+                       cmap[count] = col;
                }
                
                size = 0;
-               for (col = ibuf->maxcol - 1; col > 0; col >>= 1) size++;
-               ibuf->depth = size;
+               for (col = maxcol - 1; col > 0; col >>= 1) size++;
+               ibuf->planes = size;
 
                if (tga.mapbits != 32) {        /* set alpha bits  */
-                       ibuf->cmap[0] &= BIG_LONG(0x00ffffff);
+                       cmap[0] &= BIG_LONG(0x00ffffffl);
                }
        }
        
        if (flags & IB_test) return (ibuf);
 
-       if (tga.imgtyp != 1 && tga.imgtyp != 9) IMB_freecmapImBuf(ibuf); /* happens sometimes (beuh) */
+       if (tga.imgtyp != 1 && tga.imgtyp != 9) { /* happens sometimes (beuh) */
+               if(cmap) {
+                       MEM_freeN(cmap); 
+                       cmap= NULL;
+               }
+       }
 
        switch(tga.imgtyp){
        case 1:
@@ -640,11 +617,18 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, int mem_size, int flags)
                break;
        }
        
-       if (ibuf->cmap){
-               if ((flags & IB_cmap) == 0) IMB_applycmap(ibuf);
+       if(cmap) {
+               /* apply color map */
+               rect = ibuf->rect;
+               for(size = ibuf->x * ibuf->y; size>0; --size, ++rect) {
+                       col = *rect;
+                       if (col >= 0 && col < maxcol) *rect = cmap[col];
+               }
+
+               MEM_freeN(cmap);
        }
        
-       if (tga.pixsize == 16 && ibuf->cmap == 0){
+       if (tga.pixsize == 16{
                rect = ibuf->rect;
                for (size = ibuf->x * ibuf->y; size > 0; --size, ++rect){
                        col = *rect;
@@ -659,7 +643,7 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, int mem_size, int flags)
                        cp[3] += cp[3] >> 5;
                        cp[0] = 0xff;
                }
-               ibuf->depth = 24;
+               ibuf->planes = 24;
        }
        
        if (tga.imgtyp == 3 || tga.imgtyp == 11){
@@ -678,13 +662,10 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, int mem_size, int flags)
                }
        }
        
-       if (flags & IB_ttob) tga.imgdes ^= 0x20;
        if (tga.imgdes & 0x20) IMB_flipy(ibuf);
 
-       if (ibuf) {
-               if (ibuf->rect && (flags & IB_cmap)==0) 
-                       IMB_convert_rgba_to_abgr(ibuf);
-       }
+       if (ibuf && ibuf->rect)
+               IMB_convert_rgba_to_abgr(ibuf);
        
        return(ibuf);
 }