- use %u rather tham %d for unsigned ints in string formatting funcs.
[blender.git] / source / blender / imbuf / intern / tiff.c
index 4e5dc5923fe5e0f5ff9b2389900b870351465835..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.
  *
@@ -331,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;
        }
 }
 
@@ -349,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.
@@ -364,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) {
@@ -435,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;
@@ -598,8 +627,7 @@ void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, size_t size, int tx, int
                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);
 
@@ -618,7 +646,7 @@ void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, size_t size, int tx, int
                        }
                }
                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);
@@ -652,6 +680,7 @@ int imb_savetiff(ImBuf *ibuf, const 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 };
        
@@ -760,7 +789,7 @@ int imb_savetiff(ImBuf *ibuf, const 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 {
@@ -777,8 +806,18 @@ int imb_savetiff(ImBuf *ibuf, const 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,