doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / blender / imbuf / intern / iris.c
index aa30158..f29f68b 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -14,7 +14,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.
  */
 
 #include <string.h>
+
 #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_iris.h"
+#include "IMB_filetype.h"
 
 typedef struct {
        unsigned short  imagic;         /* stuff saved on disk . . */
@@ -104,7 +106,9 @@ static int writetab(FILE *outf, unsigned int *tab, int len);
 static void readtab(FILE *inf, unsigned int *tab, int len);
 
 static void expandrow(unsigned char *optr, unsigned char *iptr, int z);
+static void expandrow2(float *optr, unsigned char *iptr, int z);
 static void interleaverow(unsigned char *lptr, unsigned char *cptr, int z, int n);
+static void interleaverow2(float *lptr, unsigned char *cptr, int z, int n);
 static int compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cnt);
 static void lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n);
 
@@ -119,7 +123,8 @@ static int file_offset;
 static unsigned short getshort(FILE *inf)
 {
        unsigned char * buf;
-       
+       (void)inf; /* unused */
+
        buf = file_data + file_offset;
        file_offset += 2;
        
@@ -129,6 +134,7 @@ static unsigned short getshort(FILE *inf)
 static unsigned int getlong(FILE *inf)
 {
        unsigned char * buf;
+       (void)inf; /* unused */
        
        buf = file_data + file_offset;
        file_offset += 4;
@@ -169,9 +175,8 @@ static void readheader(FILE *inf, IMAGE *image)
 
 static int writeheader(FILE *outf, IMAGE *image)
 {
-       IMAGE t;
+       IMAGE t= {0};
 
-       memset(&t, 0, sizeof(IMAGE));
        fwrite(&t,sizeof(IMAGE),1,outf);
        fseek(outf,0,SEEK_SET);
        putshort(outf,image->imagic);
@@ -222,6 +227,16 @@ static void test_endian_zbuf(struct ImBuf *ibuf)
        }
 }
 
+/* from misc_util: flip the bytes from x  */
+#define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1])
+
+/* this one is only def-ed once, strangely... */
+#define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0])
+
+int imb_is_a_iris(unsigned char *mem)
+{
+       return ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC));
+}
 
 /*
  *     longimagedata - 
@@ -230,9 +245,10 @@ static void test_endian_zbuf(struct ImBuf *ibuf)
  *
  */
 
-struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
+struct ImBuf *imb_loadiris(unsigned char *mem, size_t size, int flags)
 {
        unsigned int *base, *lptr = NULL;
+       float *fbase, *fptr = NULL;
        unsigned int *zbase, *zptr;
        unsigned char *rledat;
        unsigned int *starttab, *lengthtab;
@@ -242,8 +258,11 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
        int xsize, ysize, zsize;
        int bpp, rle, cur, badorder;
        ImBuf * ibuf;
-       uchar * rect;
+
+       (void)size; /* unused */
        
+       if(!imb_is_a_iris(mem)) return NULL;
+
        /*printf("new iris\n");*/
        
        file_data = mem;
@@ -257,8 +276,8 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
        
        rle = ISRLE(image.type);
        bpp = BPP(image.type);
-       if(bpp != 1 ) {
-               fprintf(stderr,"longimagedata: image must have 1 byte per pix chan\n");
+       if(bpp != 1 && bpp != 2) {
+               fprintf(stderr,"longimagedata: image must have 1 or 2 byte per pix chan\n");
                return(0);
        }
        
@@ -267,20 +286,21 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
        zsize = image.zsize;
        
        if (flags & IB_test) {
-               ibuf = IMB_allocImBuf(image.xsize, image.ysize, 8 * image.zsize, 0, 0);
+               ibuf = IMB_allocImBuf(image.xsize, image.ysize, 8 * image.zsize, 0);
                if (ibuf) ibuf->ftype = IMAGIC;
                return(ibuf);
        }
        
        if (rle) {
+               
                tablen = ysize*zsize*sizeof(int);
-               starttab = (unsigned int *)malloc(tablen);
-               lengthtab = (unsigned int *)malloc(tablen);
+               starttab = (unsigned int *)MEM_mallocN(tablen, "iris starttab");
+               lengthtab = (unsigned int *)MEM_mallocN(tablen, "iris endtab");
                file_offset = 512;
                
                readtab(inf,starttab,tablen);
                readtab(inf,lengthtab,tablen);
-
+       
                /* check data order */
                cur = 0;
                badorder = 0;
@@ -295,101 +315,203 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags)
                        if(badorder)
                                break;
                }
-
-               ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect, 0);
-               if (ibuf->depth > 32) ibuf->depth = 32;
-               base = ibuf->rect;
-               zbase = (unsigned int *)ibuf->zbuf;
-               
-               if (badorder) {
-                       for(z=0; z<zsize; z++) {
+       
+               if (bpp == 1) {
+                       
+                       ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect);
+                       if (ibuf->depth > 32) ibuf->depth = 32;
+                       base = ibuf->rect;
+                       zbase = (unsigned int *)ibuf->zbuf;
+                       
+                       if (badorder) {
+                               for(z=0; z<zsize; z++) {
+                                       lptr = base;
+                                       for(y=0; y<ysize; y++) {
+                                               file_offset = starttab[y+z*ysize];
+                                               
+                                               rledat = file_data + file_offset;
+                                               file_offset += lengthtab[y+z*ysize];
+                                               
+                                               expandrow((uchar *)lptr, rledat, 3-z);
+                                               lptr += xsize;
+                                       }
+                               }
+                       } else {
                                lptr = base;
+                               zptr = zbase;
                                for(y=0; y<ysize; y++) {
-                                       file_offset = starttab[y+z*ysize];
-                                       
-                                       rledat = file_data + file_offset;
-                                       file_offset += lengthtab[y+z*ysize];
-                                       
-                                       expandrow((uchar *)lptr, rledat, 3-z);
+                               
+                                       for(z=0; z<zsize; z++) {
+                                               
+                                               file_offset = starttab[y+z*ysize];
+
+                                               rledat = file_data + file_offset;
+                                               file_offset += lengthtab[y+z*ysize];
+                                               
+                                               if(z<4) expandrow((uchar *)lptr, rledat, 3-z);
+                                               else if(z<8) expandrow((uchar *)zptr, rledat, 7-z);
+                                       }
                                        lptr += xsize;
+                                       zptr += xsize;
                                }
                        }
-               }
-               else {
-                       lptr = base;
-                       zptr = zbase;
-                       for(y=0; y<ysize; y++) {
                        
+
+               } else {        /* bpp == 2 */
+                       
+                       ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect)|IB_rectfloat);
+                       
+                       fbase = ibuf->rect_float;
+                       
+                       if (badorder) {
                                for(z=0; z<zsize; z++) {
-                                       
-                                       file_offset = starttab[y+z*ysize];
+                                       fptr = fbase;
+                                       for(y=0; y<ysize; y++) {
+                                               file_offset = starttab[y+z*ysize];
+                                               
+                                               rledat = file_data + file_offset;
+                                               file_offset += lengthtab[y+z*ysize];
+                                               
+                                               expandrow2(fptr, rledat, 3-z);
+                                               fptr += xsize * 4;
+                                       }
+                               }
+                       } else {
+                               fptr = fbase;
 
-                                       rledat = file_data + file_offset;
-                                       file_offset += lengthtab[y+z*ysize];
-                                       
-                                       if(z<4) expandrow((uchar *)lptr, rledat, 3-z);
-                                       else if(z<8) expandrow((uchar *)zptr, rledat, 7-z);
+                               for(y=0; y<ysize; y++) {
+                               
+                                       for(z=0; z<zsize; z++) {
+                                               
+                                               file_offset = starttab[y+z*ysize];
+
+                                               rledat = file_data + file_offset;
+                                               file_offset += lengthtab[y+z*ysize];
+                                               
+                                               expandrow2(fptr, rledat, 3-z);
+                                               
+                                       }
+                                       fptr += xsize * 4;
                                }
-                               lptr += xsize;
-                               zptr += xsize;
                        }
                }
                
-               free(starttab);
-               free(lengthtab);
-       } 
-       else {
-       
-               ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect, 0);
-               if (ibuf->depth > 32) ibuf->depth = 32;
+               MEM_freeN(starttab);
+               MEM_freeN(lengthtab);   
 
-               base = ibuf->rect;
-               zbase = (unsigned int *)ibuf->zbuf;
-               
-               file_offset = 512;
-               rledat = file_data + file_offset;
-               
-               for(z = 0; z < zsize; z++) {
+       } else {
+               if (bpp == 1) {
+                       
+                       ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect);
+                       if (ibuf->depth > 32) ibuf->depth = 32;
+
+                       base = ibuf->rect;
+                       zbase = (unsigned int *)ibuf->zbuf;
                        
-                       if(z<4) lptr = base;
-                       else if(z<8) lptr= zbase;
+                       file_offset = 512;
+                       rledat = file_data + file_offset;
                        
-                       for(y = 0; y < ysize; y++) {
+                       for(z = 0; z < zsize; z++) {
+                               
+                               if(z<4) lptr = base;
+                               else if(z<8) lptr= zbase;
+                               
+                               for(y = 0; y < ysize; y++) {
 
-                               interleaverow((uchar *)lptr, rledat, 3-z, xsize);
-                               rledat += xsize;
+                                       interleaverow((uchar *)lptr, rledat, 3-z, xsize);
+                                       rledat += xsize;
+                                       
+                                       lptr += xsize;
+                               }
+                       }
+                       
+               } else {        /* bpp == 2 */
+                       
+                       ibuf = IMB_allocImBuf(xsize, ysize, 32, (flags & IB_rect)|IB_rectfloat);
+
+                       fbase = ibuf->rect_float;
+
+                       file_offset = 512;
+                       rledat = file_data + file_offset;
+                       
+                       for(z = 0; z < zsize; z++) {
+                               
+                               fptr = fbase;
                                
-                               lptr += xsize;
+                               for(y = 0; y < ysize; y++) {
+
+                                       interleaverow2(fptr, rledat, 3-z, xsize);
+                                       rledat += xsize * 2;
+                                       
+                                       fptr += xsize * 4;
+                               }
                        }
+                       
                }
        }
        
-       if (image.zsize == 1){
-               rect = (uchar *) ibuf->rect;
-               for (x = ibuf->x * ibuf->y; x > 0; x--) {
-                       rect[0] = 255;
-                       rect[1] = rect[2] = rect[3];
-                       rect += 4;
+       
+       if (bpp == 1) {
+               uchar * rect;
+               
+               if (image.zsize == 1){
+                       rect = (uchar *) ibuf->rect;
+                       for (x = ibuf->x * ibuf->y; x > 0; x--) {
+                               rect[0] = 255;
+                               rect[1] = rect[2] = rect[3];
+                               rect += 4;
+                       }
+               } else if (image.zsize == 2){
+                       /* grayscale with alpha */
+                       rect = (uchar *) ibuf->rect;
+                       for (x = ibuf->x * ibuf->y; x > 0; x--) {
+                               rect[0] = rect[2];
+                               rect[1] = rect[2] = rect[3];
+                               rect += 4;
+                       }
+               } else if (image.zsize == 3){
+                       /* add alpha */
+                       rect = (uchar *) ibuf->rect;
+                       for (x = ibuf->x * ibuf->y; x > 0; x--) {
+                               rect[0] = 255;
+                               rect += 4;
+                       }
                }
-       } else if (image.zsize == 2){
-               /* grayscale with alpha */
-               rect = (uchar *) ibuf->rect;
-               for (x = ibuf->x * ibuf->y; x > 0; x--) {
-                       rect[0] = rect[2];
-                       rect[1] = rect[2] = rect[3];
-                       rect += 4;
+               
+       } else {        /* bpp == 2 */
+               
+               if (image.zsize == 1){
+                       fbase = ibuf->rect_float;
+                       for (x = ibuf->x * ibuf->y; x > 0; x--) {
+                               fbase[0] = 1;
+                               fbase[1] = fbase[2] = fbase[3];
+                               fbase += 4;
+                       }
+               } else if (image.zsize == 2){
+                       /* grayscale with alpha */
+                       fbase = ibuf->rect_float;
+                       for (x = ibuf->x * ibuf->y; x > 0; x--) {
+                               fbase[0] = fbase[2];
+                               fbase[1] = fbase[2] = fbase[3];
+                               fbase += 4;
+                       }
+               } else if (image.zsize == 3){
+                       /* add alpha */
+                       fbase = ibuf->rect_float;
+                       for (x = ibuf->x * ibuf->y; x > 0; x--) {
+                               fbase[0] = 1;
+                               fbase += 4;
+                       }
                }
-       } else if (image.zsize == 3){
-               /* add alpha */
-               rect = (uchar *) ibuf->rect;
-               for (x = ibuf->x * ibuf->y; x > 0; x--) {
-                       rect[0] = 255;
-                       rect += 4;
+               
+               if (flags & IB_rect) {
+                       IMB_rect_from_float(ibuf);
                }
+               
        }
-       
+
        ibuf->ftype = IMAGIC;
-       if (flags & IB_ttob) IMB_flipy(ibuf);
+       ibuf->profile = IB_PROFILE_SRGB;
        
        test_endian_zbuf(ibuf);
        
@@ -412,6 +534,71 @@ static void interleaverow(unsigned char *lptr, unsigned char *cptr, int z, int n
        }
 }
 
+static void interleaverow2(float *lptr, unsigned char *cptr, int z, int n)
+{
+       lptr += z;
+       while(n--) {
+               *lptr = ((cptr[0]<<8) | (cptr[1]<<0)) / (float)0xFFFF;          
+               cptr += 2;
+               lptr += 4;
+       }
+}
+
+static void expandrow2(float *optr, unsigned char *iptr, int z)
+{
+       unsigned short pixel, count;
+       float pixel_f;
+
+       optr += z;
+       while(1) {
+               pixel = (iptr[0]<<8) | (iptr[1]<<0);
+               iptr += 2;
+               
+               if ( !(count = (pixel & 0x7f)) )
+                       return;
+               if(pixel & 0x80) {
+                       while(count>=8) {
+                               optr[0*4] = ((iptr[0]<<8) | (iptr[1]<<0))/(float)0xFFFF;
+                               optr[1*4] = ((iptr[2]<<8) | (iptr[3]<<0))/(float)0xFFFF;
+                               optr[2*4] = ((iptr[4]<<8) | (iptr[5]<<0))/(float)0xFFFF;
+                               optr[3*4] = ((iptr[6]<<8) | (iptr[7]<<0))/(float)0xFFFF;
+                               optr[4*4] = ((iptr[8]<<8) | (iptr[9]<<0))/(float)0xFFFF;
+                               optr[5*4] = ((iptr[10]<<8) | (iptr[11]<<0))/(float)0xFFFF;
+                               optr[6*4] = ((iptr[12]<<8) | (iptr[13]<<0))/(float)0xFFFF;
+                               optr[7*4] = ((iptr[14]<<8) | (iptr[15]<<0))/(float)0xFFFF;
+                               optr += 8*4;
+                               iptr += 8*2;
+                               count -= 8;
+                       }
+                       while(count--) {
+                               *optr = ((iptr[0]<<8) | (iptr[1]<<0))/(float)0xFFFF;
+                               iptr+=2;
+                               optr+=4;
+                       }
+               } else {
+                       pixel_f = ((iptr[0]<<8) | (iptr[1]<<0))/(float)0xFFFF;
+                       iptr += 2;
+
+                       while(count>=8) {
+                               optr[0*4] = pixel_f;
+                               optr[1*4] = pixel_f;
+                               optr[2*4] = pixel_f;
+                               optr[3*4] = pixel_f;
+                               optr[4*4] = pixel_f;
+                               optr[5*4] = pixel_f;
+                               optr[6*4] = pixel_f;
+                               optr[7*4] = pixel_f;
+                               optr += 8*4;
+                               count -= 8;
+                       }
+                       while(count--) {
+                               *optr = pixel_f;
+                               optr+=4;
+                       }
+               }
+       }       
+}
+
 static void expandrow(unsigned char *optr, unsigned char *iptr, int z)
 {
        unsigned char pixel, count;
@@ -474,7 +661,7 @@ static void expandrow(unsigned char *optr, unsigned char *iptr, int z)
  *  Added: zbuf write
  */
 
-static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, char *name, int *zptr)
+static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, const char *name, int *zptr)
 {
        FILE *outf;
        IMAGE *image;
@@ -490,12 +677,12 @@ static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, char
 
        tablen = ysize*zsize*sizeof(int);
 
-       image = (IMAGE *)malloc(sizeof(IMAGE));
-       starttab = (unsigned int *)malloc(tablen);
-       lengthtab = (unsigned int *)malloc(tablen);
+       image = (IMAGE *)MEM_mallocN(sizeof(IMAGE), "iris image");
+       starttab = (unsigned int *)MEM_mallocN(tablen, "iris starttab");
+       lengthtab = (unsigned int *)MEM_mallocN(tablen, "iris lengthtab");
        rlebuflen = 1.05*xsize+10;
-       rlebuf = (unsigned char *)malloc(rlebuflen);
-       lumbuf = (unsigned int *)malloc(xsize*sizeof(int));
+       rlebuf = (unsigned char *)MEM_mallocN(rlebuflen, "iris rlebuf");
+       lumbuf = (unsigned int *)MEM_mallocN(xsize*sizeof(int), "iris lumbuf");
 
        memset(image, 0, sizeof(IMAGE));
        image->imagic = IMAGIC;
@@ -544,11 +731,11 @@ static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, char
        fseek(outf,512,SEEK_SET);
        goodwrite *= writetab(outf,starttab,tablen);
        goodwrite *= writetab(outf,lengthtab,tablen);
-       free(image);
-       free(starttab);
-       free(lengthtab);
-       free(rlebuf);
-       free(lumbuf);
+       MEM_freeN(image);
+       MEM_freeN(starttab);
+       MEM_freeN(lengthtab);
+       MEM_freeN(rlebuf);
+       MEM_freeN(lumbuf);
        fclose(outf);
        if(goodwrite)
                return 1;
@@ -628,7 +815,7 @@ static int compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cn
        return optr - (unsigned char *)rlebuf;
 }
 
-short imb_saveiris(struct ImBuf * ibuf, char *name, int flags)
+int imb_saveiris(struct ImBuf * ibuf, const char *name, int flags)
 {
        short zsize;
        int ret;