Merge image related changes from the render branch. This includes the image
[blender.git] / source / blender / imbuf / intern / tiff.c
1 /*
2  * tiff.c
3  *
4  * $Id$
5  * 
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  * Contributor(s): Jonathan Merritt.
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /**
28  * Provides TIFF file loading and saving for Blender, via libtiff.
29  *
30  * The task of loading is complicated somewhat by the fact that Blender has
31  * already loaded the file into a memory buffer.  libtiff is not well
32  * configured to handle files in memory, so a client wrapper is written to
33  * surround the memory and turn it into a virtual file.  Currently, reading
34  * of TIFF files is done using libtiff's RGBAImage support.  This is a 
35  * high-level routine that loads all images as 32-bit RGBA, handling all the
36  * required conversions between many different TIFF types internally.
37  * 
38  * Saving supports RGB, RGBA and BW (greyscale) images correctly, with
39  * 8 bits per channel in all cases.  The "deflate" compression algorithm is
40  * used to compress images.
41  */
42
43 #include <string.h>
44
45 #include "imbuf.h"
46
47 #include "BKE_global.h"
48
49 #include "BLI_string.h"
50
51 #include "IMB_imbuf_types.h"
52 #include "IMB_imbuf.h"
53
54 #include "IMB_allocimbuf.h"
55 #include "IMB_filetype.h"
56 #include "IMB_filter.h"
57
58 #include "dynlibtiff.h"
59
60
61
62 /***********************
63  * Local declarations. *
64  ***********************/
65 /* Reading and writing of an in-memory TIFF file. */
66 static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n);
67 static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n);
68 static toff_t  imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence);
69 static int     imb_tiff_CloseProc(thandle_t handle);
70 static toff_t  imb_tiff_SizeProc(thandle_t handle);
71 static int     imb_tiff_DummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize);
72 static void    imb_tiff_DummyUnmapProc(thandle_t fd, tdata_t base, toff_t size);
73
74
75 /* Structure for in-memory TIFF file. */
76 typedef struct ImbTIFFMemFile {
77         unsigned char *mem;     /* Location of first byte of TIFF file. */
78         toff_t offset;          /* Current offset within the file.      */
79         tsize_t size;           /* Size of the TIFF file.               */
80 } ImbTIFFMemFile;
81 #define IMB_TIFF_GET_MEMFILE(x) ((ImbTIFFMemFile*)(x));
82
83
84
85 /*****************************
86  * Function implementations. *
87  *****************************/
88
89
90 static void imb_tiff_DummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
91 {
92 }
93
94 static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) 
95 {
96                         return (0);
97 }
98
99 /**
100  * Reads data from an in-memory TIFF file.
101  *
102  * @param handle: Handle of the TIFF file (pointer to ImbTIFFMemFile).
103  * @param data:   Buffer to contain data (treat as void*).
104  * @param n:      Number of bytes to read.
105  *
106  * @return: Number of bytes actually read.
107  *       0 = EOF.
108  */
109 static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n)
110 {
111         tsize_t nRemaining, nCopy;
112         ImbTIFFMemFile* mfile;
113         void *srcAddr;
114
115         /* get the pointer to the in-memory file */
116         mfile = IMB_TIFF_GET_MEMFILE(handle);
117         if(!mfile || !mfile->mem) {
118                 fprintf(stderr, "imb_tiff_ReadProc: !mfile || !mfile->mem!\n");
119                 return 0;
120         }
121
122         /* find the actual number of bytes to read (copy) */
123         nCopy = n;
124         if((tsize_t)mfile->offset >= mfile->size)
125                 nRemaining = 0;
126         else
127                 nRemaining = mfile->size - mfile->offset;
128         
129         if(nCopy > nRemaining)
130                 nCopy = nRemaining;
131         
132         /* on EOF, return immediately and read (copy) nothing */
133         if(nCopy <= 0)
134                 return (0);
135
136         /* all set -> do the read (copy) */
137         srcAddr = (void*)(&(mfile->mem[mfile->offset]));
138         memcpy((void*)data, srcAddr, nCopy);
139         mfile->offset += nCopy;         /* advance file ptr by copied bytes */
140         return nCopy;
141 }
142
143
144
145 /**
146  * Writes data to an in-memory TIFF file.
147  *
148  * NOTE: The current Blender implementation should not need this function.  It
149  *       is simply a stub.
150  */
151 static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n)
152 {
153         printf("imb_tiff_WriteProc: this function should not be called.\n");
154         return (-1);
155 }
156
157
158
159 /**
160  * Seeks to a new location in an in-memory TIFF file.
161  *
162  * @param handle: Handle of the TIFF file (pointer to ImbTIFFMemFile).
163  * @param ofs:    Offset value (interpreted according to whence below).
164  * @param whence: This can be one of three values:
165  *      SEEK_SET - The offset is set to ofs bytes.
166  *      SEEK_CUR - The offset is set to its current location plus ofs bytes.
167  *      SEEK_END - (This is unsupported and will return -1, indicating an
168  *                  error).
169  *
170  * @return: Resulting offset location within the file, measured in bytes from
171  *          the beginning of the file.  (-1) indicates an error.
172  */
173 static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence)
174 {
175         ImbTIFFMemFile *mfile;
176         toff_t new_offset;
177
178         /* get the pointer to the in-memory file */
179         mfile = IMB_TIFF_GET_MEMFILE(handle);
180         if(!mfile || !mfile->mem) {
181                 fprintf(stderr, "imb_tiff_SeekProc: !mfile || !mfile->mem!\n");
182                 return (-1);
183         }
184
185         /* find the location we plan to seek to */
186         switch (whence) {
187                 case SEEK_SET:
188                         new_offset = ofs;
189                         break;
190                 case SEEK_CUR:
191                         new_offset = mfile->offset + ofs;
192                         break;
193                 default:
194                         /* no other types are supported - return an error */
195                         fprintf(stderr, 
196                                 "imb_tiff_SeekProc: "
197                                 "Unsupported TIFF SEEK type.\n");
198                         return (-1);
199         }
200
201         /* set the new location */
202         mfile->offset = new_offset;
203         return mfile->offset;
204 }
205
206
207
208 /**
209  * Closes (virtually) an in-memory TIFF file.
210  *
211  * NOTE: All this function actually does is sets the data pointer within the
212  *       TIFF file to NULL.  That should trigger assertion errors if attempts
213  *       are made to access the file after that point.  However, no such
214  *       attempts should ever be made (in theory).
215  *
216  * @param handle: Handle of the TIFF file (pointer to ImbTIFFMemFile).
217  *
218  * @return: 0
219  */
220 static int imb_tiff_CloseProc(thandle_t handle)
221 {
222         ImbTIFFMemFile *mfile;
223
224         /* get the pointer to the in-memory file */
225         mfile = IMB_TIFF_GET_MEMFILE(handle);
226         if(!mfile || !mfile->mem) {
227                 fprintf(stderr,"imb_tiff_CloseProc: !mfile || !mfile->mem!\n");
228                 return (0);
229         }
230         
231         /* virtually close the file */
232         mfile->mem    = NULL;
233         mfile->offset = 0;
234         mfile->size   = 0;
235         
236         return (0);
237 }
238
239
240
241 /**
242  * Returns the size of an in-memory TIFF file in bytes.
243  *
244  * @return: Size of file (in bytes).
245  */
246 static toff_t imb_tiff_SizeProc(thandle_t handle)
247 {
248         ImbTIFFMemFile* mfile;
249
250         /* get the pointer to the in-memory file */
251         mfile = IMB_TIFF_GET_MEMFILE(handle);
252         if(!mfile || !mfile->mem) {
253                 fprintf(stderr,"imb_tiff_SizeProc: !mfile || !mfile->mem!\n");
254                 return (0);
255         }
256
257         /* return the size */
258         return (toff_t)(mfile->size);
259 }
260
261 static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, unsigned char *mem, int size)
262 {
263         /* open the TIFF client layer interface to the in-memory file */
264         memFile->mem = mem;
265         memFile->offset = 0;
266         memFile->size = size;
267
268         return libtiff_TIFFClientOpen("(Blender TIFF Interface Layer)", 
269                 "r", (thandle_t)(memFile),
270                 imb_tiff_ReadProc, imb_tiff_WriteProc,
271                 imb_tiff_SeekProc, imb_tiff_CloseProc,
272                 imb_tiff_SizeProc, imb_tiff_DummyMapProc, imb_tiff_DummyUnmapProc);
273 }
274
275 /**
276  * Checks whether a given memory buffer contains a TIFF file.
277  *
278  * This method uses the format identifiers from:
279  *     http://www.faqs.org/faqs/graphics/fileformats-faq/part4/section-9.html
280  * The first four bytes of big-endian and little-endian TIFF files
281  * respectively are (hex):
282  *      4d 4d 00 2a
283  *      49 49 2a 00
284  * Note that TIFF files on *any* platform can be either big- or little-endian;
285  * it's not platform-specific.
286  *
287  * AFAICT, libtiff doesn't provide a method to do this automatically, and
288  * hence my manual comparison. - Jonathan Merritt (lancelet) 4th Sept 2005.
289  */
290 #define IMB_TIFF_NCB 4          /* number of comparison bytes used */
291 int imb_is_a_tiff(unsigned char *mem)
292 {
293         char big_endian[IMB_TIFF_NCB] = { 0x4d, 0x4d, 0x00, 0x2a };
294         char lil_endian[IMB_TIFF_NCB] = { 0x49, 0x49, 0x2a, 0x00 };
295
296         return ( (memcmp(big_endian, mem, IMB_TIFF_NCB) == 0) ||
297                  (memcmp(lil_endian, mem, IMB_TIFF_NCB) == 0) );
298 }
299
300 static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul)
301 {
302         ImBuf *tmpibuf;
303         int success;
304
305         tmpibuf= IMB_allocImBuf(ibuf->x, ibuf->y, 32, IB_rect, 0);
306         success= libtiff_TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0);
307
308         if(ENDIAN_ORDER == B_ENDIAN)
309                 IMB_convert_rgba_to_abgr(tmpibuf);
310         if(premul) {
311                 IMB_premultiply_alpha(tmpibuf);
312                 ibuf->flags |= IB_premul;
313         }
314
315         /* assign rect last */
316         ibuf->rect= tmpibuf->rect;
317         ibuf->mall |= IB_rect;
318         ibuf->flags |= IB_rect;
319
320         tmpibuf->mall &= ~IB_rect;
321         IMB_freeImBuf(tmpibuf);
322
323         return success;
324 }
325
326 /**
327  * Loads a TIFF file.
328  *
329  * This function uses the "RGBA Image" support from libtiff, which enables
330  * it to load most commonly-encountered TIFF formats.  libtiff handles format
331  * conversion, color depth conversion, etc.
332  *
333  * @param mem:   Memory containing the TIFF file.
334  * @param size:  Size of the mem buffer.
335  * @param flags: If flags has IB_test set then the file is not actually loaded,
336  *                but all other operations take place.
337  *
338  * @return: A newly allocated ImBuf structure if successful, otherwise NULL.
339  */
340 ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
341 {
342         TIFF *image = NULL;
343         ImBuf *ibuf = NULL, *hbuf;
344         ImbTIFFMemFile memFile;
345         uint32 width, height;
346         char *format = NULL;
347         int level;
348
349         if(!G.have_libtiff)
350                 return NULL;
351
352         /* check whether or not we have a TIFF file */
353         if(size < IMB_TIFF_NCB) {
354                 fprintf(stderr, "imb_loadtiff: size < IMB_TIFF_NCB\n");
355                 return NULL;
356         }
357         if(imb_is_a_tiff(mem) == 0)
358                 return NULL;
359
360         image = imb_tiff_client_open(&memFile, mem, size);
361
362         if(image == NULL) {
363                 printf("imb_loadtiff: could not open TIFF IO layer.\n");
364                 return NULL;
365         }
366
367         /* allocate the image buffer */
368         libtiff_TIFFGetField(image, TIFFTAG_IMAGEWIDTH,  &width);
369         libtiff_TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
370         ibuf = IMB_allocImBuf(width, height, 32, 0, 0);
371         if(ibuf) {
372                 ibuf->ftype = TIF;
373                 ibuf->profile = IB_PROFILE_SRGB;
374         }
375         else {
376                 fprintf(stderr, 
377                         "imb_loadtiff: could not allocate memory for TIFF " \
378                         "image.\n");
379                 libtiff_TIFFClose(image);
380                 return NULL;
381         }
382
383         /* if testing, we're done */
384         if(flags & IB_test) {
385                 libtiff_TIFFClose(image);
386                 return ibuf;
387         }
388
389         /* detect if we are reading a tiled/mipmapped texture, in that case
390            we don't read pixels but leave it to the cache to load tiles */
391         if(flags & IB_tilecache) {
392                 format= NULL;
393                 libtiff_TIFFGetField(image, TIFFTAG_PIXAR_TEXTUREFORMAT, &format);
394
395                 if(format && strcmp(format, "Plain Texture")==0 && libtiff_TIFFIsTiled(image)) {
396                         int numlevel = libtiff_TIFFNumberOfDirectories(image);
397
398                         /* create empty mipmap levels in advance */
399                         for(level=0; level<numlevel; level++) {
400                                 if(!libtiff_TIFFSetDirectory(image, level))
401                                         break;
402
403                                 if(level > 0) {
404                                         width= (width > 1)? width/2: 1;
405                                         height= (height > 1)? height/2: 1;
406
407                                         hbuf= IMB_allocImBuf(width, height, 32, 0, 0);
408                                         hbuf->miplevel= level;
409                                         hbuf->flags |= IB_tilecache;
410                                         hbuf->ftype= ibuf->ftype;
411                                         ibuf->mipmap[level-1] = hbuf;
412
413                                         if(flags & IB_premul)
414                                                 hbuf->flags |= IB_premul;
415                                 }
416                                 else
417                                         hbuf= ibuf;
418
419                                 libtiff_TIFFGetField(image, TIFFTAG_TILEWIDTH, &hbuf->tilex);
420                                 libtiff_TIFFGetField(image, TIFFTAG_TILELENGTH, &hbuf->tiley);
421
422                                 hbuf->xtiles= ceil(hbuf->x/(float)hbuf->tilex);
423                                 hbuf->ytiles= ceil(hbuf->y/(float)hbuf->tiley);
424
425                                 imb_addtilesImBuf(hbuf);
426
427                                 ibuf->miptot++;
428                         }
429                 }
430         }
431
432         /* read pixels */
433         if(!(ibuf->flags & IB_tilecache) && !imb_read_tiff_pixels(ibuf, image, 0)) {
434                 fprintf(stderr, "imb_loadtiff: Failed to read tiff image.\n");
435                 libtiff_TIFFClose(image);
436                 return NULL;
437         }
438
439         /* close the client layer interface to the in-memory file */
440         libtiff_TIFFClose(image);
441
442         /* return successfully */
443         return ibuf;
444 }
445
446 void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, int size, int tx, int ty, unsigned int *rect)
447 {
448         TIFF *image = NULL;
449         uint32 width, height;
450         ImbTIFFMemFile memFile;
451
452         image = imb_tiff_client_open(&memFile, mem, size);
453
454         if(image == NULL) {
455                 printf("imb_loadtiff: could not open TIFF IO layer for loading mipmap level.\n");
456                 return;
457         }
458
459         if(libtiff_TIFFSetDirectory(image, ibuf->miplevel)) {
460                 /* allocate the image buffer */
461                 libtiff_TIFFGetField(image, TIFFTAG_IMAGEWIDTH,  &width);
462                 libtiff_TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
463
464                 if(width == ibuf->x && height == ibuf->y) {
465                         if(rect) {
466                                 /* tiff pixels are bottom to top, tiles are top to bottom */
467                                 if(libtiff_TIFFReadRGBATile(image, tx*ibuf->tilex, (ibuf->ytiles - 1 - ty)*ibuf->tiley, rect) == 1) {
468                                         if(ibuf->tiley > ibuf->y)
469                                                 memmove(rect, rect+ibuf->tilex*(ibuf->tiley - ibuf->y), sizeof(int)*ibuf->tilex*ibuf->y);
470
471                                         if(ibuf->flags & IB_premul)
472                                                 IMB_premultiply_rect(rect, 32, ibuf->tilex, ibuf->tiley);
473                                 }
474                                 else
475                                         printf("imb_loadtiff: failed to read tiff tile at mipmap level %d\n", ibuf->miplevel);
476                         }
477                 }
478                 else
479                         printf("imb_loadtiff: mipmap level %d has unexpected size %dx%d instead of %dx%d\n", ibuf->miplevel, width, height, ibuf->x, ibuf->y);
480         }
481         else
482                 printf("imb_loadtiff: could not find mipmap level %d\n", ibuf->miplevel);
483
484         /* close the client layer interface to the in-memory file */
485         libtiff_TIFFClose(image);
486 }
487
488 /**
489  * Saves a TIFF file.
490  *
491  * ImBuf structures with 1, 3 or 4 bytes per pixel (GRAY, RGB, RGBA 
492  * respectively) are accepted, and interpreted correctly.  Note that the TIFF
493  * convention is to use pre-multiplied alpha, which can be achieved within
494  * Blender by setting "Premul" alpha handling.  Other alpha conventions are
495  * not strictly correct, but are permitted anyhow.
496  *
497  * @param ibuf:  Image buffer.
498  * @param name:  Name of the TIFF file to create.
499  * @param flags: Currently largely ignored.
500  *
501  * @return: 1 if the function is successful, 0 on failure.
502  */
503
504 #define FTOUSHORT(val) ((val >= 1.0f-0.5f/65535)? 65535: (val <= 0.0f)? 0: (unsigned short)(val*65535.0f + 0.5f))
505
506 int imb_savetiff(ImBuf *ibuf, char *name, int flags)
507 {
508         TIFF *image = NULL;
509         uint16 samplesperpixel, bitspersample;
510         size_t npixels;
511         unsigned char *pixels = NULL;
512         unsigned char *from = NULL, *to = NULL;
513         unsigned short *pixels16 = NULL, *to16 = NULL;
514         float *fromf = NULL;
515         int x, y, from_i, to_i, i;
516         int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA };
517         
518         if(!G.have_libtiff) {
519                 fprintf(stderr, "imb_savetiff: no tiff library available.\n");
520                 return (0);
521         }
522
523         /* check for a valid number of bytes per pixel.  Like the PNG writer,
524          * the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding
525          * to gray, RGB, RGBA respectively. */
526         samplesperpixel = (uint16)((ibuf->depth + 7) >> 3);
527         if((samplesperpixel > 4) || (samplesperpixel == 2)) {
528                 fprintf(stderr,
529                         "imb_savetiff: unsupported number of bytes per " 
530                         "pixel: %d\n", samplesperpixel);
531                 return (0);
532         }
533
534         if((ibuf->ftype & TIF_16BIT) && ibuf->rect_float)
535                 bitspersample = 16;
536         else
537                 bitspersample = 8;
538
539         /* open TIFF file for writing */
540         if(flags & IB_mem) {
541                 /* bork at the creation of a TIFF in memory */
542                 fprintf(stderr,
543                         "imb_savetiff: creation of in-memory TIFF files is " 
544                         "not yet supported.\n");
545                 return (0);
546         }
547         else {
548                 /* create image as a file */
549                 image = libtiff_TIFFOpen(name, "w");
550         }
551         if(image == NULL) {
552                 fprintf(stderr,
553                         "imb_savetiff: could not open TIFF for writing.\n");
554                 return (0);
555         }
556
557         /* allocate array for pixel data */
558         npixels = ibuf->x * ibuf->y;
559         if(bitspersample == 16)
560                 pixels16 = (unsigned short*)libtiff__TIFFmalloc(npixels *
561                         samplesperpixel * sizeof(unsigned short));
562         else
563                 pixels = (unsigned char*)libtiff__TIFFmalloc(npixels *
564                         samplesperpixel * sizeof(unsigned char));
565
566         if(pixels == NULL && pixels16 == NULL) {
567                 fprintf(stderr,
568                         "imb_savetiff: could not allocate pixels array.\n");
569                 libtiff_TIFFClose(image);
570                 return (0);
571         }
572
573         /* setup pointers */
574         if(bitspersample == 16) {
575                 fromf = ibuf->rect_float;
576                 to16   = pixels16;
577         }
578         else {
579                 from = (unsigned char*)ibuf->rect;
580                 to   = pixels;
581         }
582
583         /* setup samples per pixel */
584         libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, bitspersample);
585         libtiff_TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
586
587         if(samplesperpixel == 4) {
588                 /* RGBA images */
589                 libtiff_TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1,
590                                 extraSampleTypes);
591                 libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC, 
592                                 PHOTOMETRIC_RGB);
593         }
594         else if(samplesperpixel == 3) {
595                 /* RGB images */
596                 libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
597                                 PHOTOMETRIC_RGB);
598         }
599         else if(samplesperpixel == 1) {
600                 /* greyscale images, 1 channel */
601                 libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
602                                 PHOTOMETRIC_MINISBLACK);
603         }
604
605         /* copy pixel data.  While copying, we flip the image vertically. */
606         for(x = 0; x < ibuf->x; x++) {
607                 for(y = 0; y < ibuf->y; y++) {
608                         from_i = 4*(y*ibuf->x+x);
609                         to_i   = samplesperpixel*((ibuf->y-y-1)*ibuf->x+x);
610
611                         if(pixels16) {
612                                 for(i = 0; i < samplesperpixel; i++, to_i++, from_i++)
613                                         to16[to_i] = FTOUSHORT(fromf[from_i]);
614                         }
615                         else {
616                                 for(i = 0; i < samplesperpixel; i++, to_i++, from_i++)
617                                         to[to_i] = from[from_i];
618                         }
619                 }
620         }
621
622         /* write the actual TIFF file */
623         libtiff_TIFFSetField(image, TIFFTAG_IMAGEWIDTH,      ibuf->x);
624         libtiff_TIFFSetField(image, TIFFTAG_IMAGELENGTH,     ibuf->y);
625         libtiff_TIFFSetField(image, TIFFTAG_ROWSPERSTRIP,    ibuf->y);
626         libtiff_TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
627         libtiff_TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
628         libtiff_TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
629         libtiff_TIFFSetField(image, TIFFTAG_XRESOLUTION,     150.0);
630         libtiff_TIFFSetField(image, TIFFTAG_YRESOLUTION,     150.0);
631         libtiff_TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT,  RESUNIT_INCH);
632         if(libtiff_TIFFWriteEncodedStrip(image, 0,
633                         (bitspersample == 16)? (unsigned char*)pixels16: pixels,
634                         ibuf->x*ibuf->y*samplesperpixel*bitspersample/8) == -1) {
635                 fprintf(stderr,
636                         "imb_savetiff: Could not write encoded TIFF.\n");
637                 libtiff_TIFFClose(image);
638                 if(pixels) libtiff__TIFFfree(pixels);
639                 if(pixels16) libtiff__TIFFfree(pixels16);
640                 return (1);
641         }
642
643         /* close the TIFF file */
644         libtiff_TIFFClose(image);
645         if(pixels) libtiff__TIFFfree(pixels);
646         if(pixels16) libtiff__TIFFfree(pixels16);
647         return (1);
648 }
649