- use %u rather tham %d for unsigned ints in string formatting funcs.
[blender.git] / source / blender / imbuf / intern / tiff.c
index 6b94583f17d98304ad227a373b9e59a72c514fe6..7beb853fe62ba0fc58cef0809766f22d2d3ed86a 100644 (file)
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/imbuf/intern/tiff.c
+ *  \ingroup imbuf
+ */
+
+
 /**
  * Provides TIFF file loading and saving for Blender, via libtiff.
  *
 #include <string.h>
 
 #include "imbuf.h"
-#include "BKE_global.h"
-#include "BKE_utildefines.h"
 
 #include "BLI_math.h"
 #include "BLI_string.h"
+#include "BLI_utildefines.h"
+#include "BKE_global.h"
+
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
@@ -93,11 +99,18 @@ typedef struct ImbTIFFMemFile {
 
 static void imb_tiff_DummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
 {
+       (void)fd;
+       (void)base;
+       (void)size;
 }
 
 static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) 
 {
-                       return (0);
+       (void)fd;
+       (void)pbase;
+       (void)psize;
+
+       return (0);
 }
 
 /**
@@ -154,6 +167,10 @@ static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n)
  */
 static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n)
 {
+       (void)handle;
+       (void)data;
+       (void)n;
+       
        printf("imb_tiff_WriteProc: this function should not be called.\n");
        return (-1);
 }
@@ -262,7 +279,7 @@ static toff_t imb_tiff_SizeProc(thandle_t handle)
        return (toff_t)(mfile->size);
 }
 
-static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, unsigned char *mem, int size)
+static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, unsigned char *mem, size_t size)
 {
        /* open the TIFF client layer interface to the in-memory file */
        memFile->mem = mem;
@@ -319,7 +336,7 @@ static void scanline_contig_32bit(float *rectf, float *fbuf, int scanline_w, int
                rectf[i*4 + 0] = fbuf[i*spp + 0];
                rectf[i*4 + 1] = fbuf[i*spp + 1];
                rectf[i*4 + 2] = fbuf[i*spp + 2];
-               rectf[i*4 + 3] = (spp==4)?fbuf[i*spp + 3]:1.0;
+               rectf[i*4 + 3] = (spp==4)?fbuf[i*spp + 3]:1.0f;
        }
 }
 
@@ -337,6 +354,25 @@ static void scanline_separate_32bit(float *rectf, float *fbuf, int scanline_w, i
                rectf[i*4 + chan] = fbuf[i];
 }
 
+static void imb_read_tiff_resolution(ImBuf *ibuf, TIFF *image)
+{
+       uint16 unit;
+       float xres;
+       float yres;
+
+       TIFFGetFieldDefaulted(image, TIFFTAG_RESOLUTIONUNIT, &unit);
+       TIFFGetFieldDefaulted(image, TIFFTAG_XRESOLUTION, &xres);
+       TIFFGetFieldDefaulted(image, TIFFTAG_YRESOLUTION, &yres);
+
+       if(unit == RESUNIT_CENTIMETER) {
+               ibuf->ppm[0]= (double)xres * 100.0;
+               ibuf->ppm[1]= (double)yres * 100.0;
+       }
+       else {
+               ibuf->ppm[0]= (double)xres / 0.0254;
+               ibuf->ppm[1]= (double)yres / 0.0254;
+       }
+}
 
 /* 
  * Use the libTIFF scanline API to read a TIFF image.
@@ -352,10 +388,13 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
        int ib_flag=0, row, chan;
        float *fbuf=NULL;
        unsigned short *sbuf=NULL;
-       
+
        TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample);
        TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp);             /* number of 'channels' */
        TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config);
+
+       imb_read_tiff_resolution(ibuf, image);
+
        scanline = TIFFScanlineSize(image);
        
        if (bitspersample == 32) {
@@ -368,7 +407,7 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
                ib_flag = IB_rect;
        }
        
-       tmpibuf= IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->depth, ib_flag, 0);
+       tmpibuf= IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->depth, ib_flag);
        
        /* simple RGBA image */
        if (!(bitspersample == 32 || bitspersample == 16)) {
@@ -423,9 +462,11 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
 
        if(success) {
                ibuf->profile = (bitspersample==32)?IB_PROFILE_LINEAR_RGB:IB_PROFILE_SRGB;
-                       
-               if(ENDIAN_ORDER == B_ENDIAN)
-                       IMB_convert_rgba_to_abgr(tmpibuf);
+
+//             Code seems to be not needed for 16 bits tif, on PPC G5 OSX (ton)
+               if(bitspersample < 16)
+                       if(ENDIAN_ORDER == B_ENDIAN)
+                               IMB_convert_rgba_to_abgr(tmpibuf);
                if(premul) {
                        IMB_premultiply_alpha(tmpibuf);
                        ibuf->flags |= IB_premul;
@@ -464,7 +505,7 @@ void imb_inittiff(void)
  *
  * @return: A newly allocated ImBuf structure if successful, otherwise NULL.
  */
-ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
+ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags)
 {
        TIFF *image = NULL;
        ImBuf *ibuf = NULL, *hbuf;
@@ -497,7 +538,7 @@ ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
        
        ib_depth = (spp==3)?24:32;
        
-       ibuf = IMB_allocImBuf(width, height, ib_depth, 0, 0);
+       ibuf = IMB_allocImBuf(width, height, ib_depth, 0);
        if(ibuf) {
                ibuf->ftype = TIF;
        }
@@ -533,7 +574,7 @@ ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
                                        width= (width > 1)? width/2: 1;
                                        height= (height > 1)? height/2: 1;
 
-                                       hbuf= IMB_allocImBuf(width, height, 32, 0, 0);
+                                       hbuf= IMB_allocImBuf(width, height, 32, 0);
                                        hbuf->miplevel= level;
                                        hbuf->ftype= ibuf->ftype;
                                        ibuf->mipmap[level-1] = hbuf;
@@ -573,7 +614,7 @@ ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
        return ibuf;
 }
 
-void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, int size, int tx, int ty, unsigned int *rect)
+void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect)
 {
        TIFF *image = NULL;
        uint32 width, height;
@@ -586,8 +627,7 @@ void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, int size, int tx, int ty,
                return;
        }
 
-       if(TIFFSetDirectory(image, ibuf->miplevel)) {
-               /* allocate the image buffer */
+       if(TIFFSetDirectory(image, ibuf->miplevel)) { /* allocate the image buffer */
                TIFFGetField(image, TIFFTAG_IMAGEWIDTH,  &width);
                TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
 
@@ -606,7 +646,7 @@ void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, int size, int tx, int ty,
                        }
                }
                else
-                       printf("imb_loadtiff: mipmap level %d has unexpected size %dx%d instead of %dx%d\n", ibuf->miplevel, width, height, ibuf->x, ibuf->y);
+                       printf("imb_loadtiff: mipmap level %d has unexpected size %ux%u instead of %dx%d\n", ibuf->miplevel, width, height, ibuf->x, ibuf->y);
        }
        else
                printf("imb_loadtiff: could not find mipmap level %d\n", ibuf->miplevel);
@@ -631,7 +671,7 @@ void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, int size, int tx, int ty,
  * @return: 1 if the function is successful, 0 on failure.
  */
 
-int imb_savetiff(ImBuf *ibuf, char *name, int flags)
+int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
 {
        TIFF *image = NULL;
        uint16 samplesperpixel, bitspersample;
@@ -640,6 +680,7 @@ int imb_savetiff(ImBuf *ibuf, char *name, int flags)
        unsigned char *from = NULL, *to = NULL;
        unsigned short *pixels16 = NULL, *to16 = NULL;
        float *fromf = NULL;
+       float xres, yres;
        int x, y, from_i, to_i, i;
        int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA };
        
@@ -748,7 +789,7 @@ int imb_savetiff(ImBuf *ibuf, char *name, int flags)
                                
                                if (samplesperpixel == 4) {
                                        to16[to_i+3] = FTOUSHORT(fromf[from_i+3]);
-                                       to_i++; from_i++;
+                                       /*to_i++; from_i++;*/ /*unused, set on each loop */
                                }
                        }
                        else {
@@ -765,8 +806,18 @@ int imb_savetiff(ImBuf *ibuf, char *name, int flags)
        TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
        TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
        TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
-       TIFFSetField(image, TIFFTAG_XRESOLUTION,     150.0);
-       TIFFSetField(image, TIFFTAG_YRESOLUTION,     150.0);
+
+
+       if(ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
+               xres= (float)(ibuf->ppm[0] * 0.0254);
+               yres= (float)(ibuf->ppm[1] * 0.0254);
+       }
+       else {
+               xres= yres= 150.0f;
+       }
+
+       TIFFSetField(image, TIFFTAG_XRESOLUTION,     xres);
+       TIFFSetField(image, TIFFTAG_YRESOLUTION,     yres);
        TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT,  RESUNIT_INCH);
        if(TIFFWriteEncodedStrip(image, 0,
                        (bitspersample == 16)? (unsigned char*)pixels16: pixels,