diff options
author | Kent Mein <mein@cs.umn.edu> | 2005-11-22 21:50:03 +0300 |
---|---|---|
committer | Kent Mein <mein@cs.umn.edu> | 2005-11-22 21:50:03 +0300 |
commit | 00f266c651a52027b662f725d081af6b51aae343 (patch) | |
tree | 40fd6d4d9a76f1eddcc63e5af6091c1442922dca /source/blender | |
parent | b63e26e109ba8c651ea20f553e3ca8e0604fc73f (diff) |
This is a modified version of patch #2995
To enable dynamic tiff support.
I had to fix some of the logic in the fileselect box for icons,
I also expanded the patch to look in various default locations for
a dynamic libtiff.so/libtiff.dll
and look at the env variable BF_TIFF_LIB if it can't find it automatically.
If unable to load the library it prints a message about setting BF_TIFF_LIB
to the console.
I haven't been able to test it on a lot of platforms but hopefully it
will just work ;) I added the files to scons but have not had a chance to
test that as well.
Kent
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_global.h | 68 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 3 | ||||
-rw-r--r-- | source/blender/imbuf/IMB_imbuf_types.h | 4 | ||||
-rw-r--r-- | source/blender/imbuf/intern/IMB_tiff.h | 48 | ||||
-rw-r--r-- | source/blender/imbuf/intern/Makefile | 1 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dynlibtiff.c | 191 | ||||
-rw-r--r-- | source/blender/imbuf/intern/dynlibtiff.h | 58 | ||||
-rwxr-xr-x | source/blender/imbuf/intern/gen_dynlibtiff.py | 248 | ||||
-rw-r--r-- | source/blender/imbuf/intern/readimage.c | 6 | ||||
-rw-r--r-- | source/blender/imbuf/intern/tiff.c | 528 | ||||
-rw-r--r-- | source/blender/imbuf/intern/util.c | 15 | ||||
-rw-r--r-- | source/blender/imbuf/intern/writeimage.c | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 1 | ||||
-rw-r--r-- | source/blender/src/buttons_scene.c | 7 | ||||
-rw-r--r-- | source/blender/src/filesel.c | 8 | ||||
-rw-r--r-- | source/blender/src/screendump.c | 6 | ||||
-rw-r--r-- | source/blender/src/toets.c | 7 | ||||
-rw-r--r-- | source/blender/src/usiblender.c | 6 | ||||
-rw-r--r-- | source/blender/src/writeimage.c | 3 |
19 files changed, 1164 insertions, 49 deletions
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 2335510ac2d..6ecd3626993 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -66,50 +66,51 @@ struct EditMesh; typedef struct Global { - /* active pointers */ - struct View3D *vd; - struct View2D *v2d; - struct SpaceIpo *sipo; - struct SpaceButs *buts; - struct SpaceImage *sima; - struct SpaceOops *soops; - struct SpaceSound *ssound; - struct SpaceAction *saction; /* __NLA */ + /* active pointers */ + struct View3D *vd; + struct View2D *v2d; + struct SpaceIpo *sipo; + struct SpaceButs *buts; + struct SpaceImage *sima; + struct SpaceOops *soops; + struct SpaceSound *ssound; + struct SpaceAction *saction; /* __NLA */ struct SpaceNla *snla; - struct Main *main; - struct Scene *scene; /* denk aan file.c */ - struct bScreen *curscreen; - struct Object *obedit; + struct Main *main; + struct Scene *scene; /* denk aan file.c */ + struct bScreen *curscreen; + struct Object *obedit; char editModeTitleExtra[64]; - /* fonts, allocated global data */ - struct BMF_Font *font, *fonts, *fontss; + /* fonts, allocated global data */ + struct BMF_Font *font, *fonts, *fontss; - /* strings: lastsaved */ - char ima[160], sce[160], lib[160]; + /* strings: lastsaved */ + char ima[160], sce[160], lib[160]; - /* totals */ - short totobj, totlamp, totobjsel, totcurve, totmesh, totbone, totbonesel; - int totvert, totedge, totface, totvertsel, totedgesel, totfacesel; + /* totals */ + short totobj, totlamp, totobjsel, totcurve, totmesh; + short totbone, totbonesel; + int totvert, totedge, totface, totvertsel, totedgesel, totfacesel; - short afbreek, moving; - short qual, background; + short afbreek, moving; + short qual, background; short winpos, displaymode; /* used to be in Render */ /** * The current version of Blender. */ - short version; + short version; short simulf, order, rt; int f; - /* Editmode lists */ + /* Editmode lists */ struct EditMesh *editMesh; - float textcurs[4][2]; + float textcurs[4][2]; - /* Frank's variables */ - int save_over; + /* Frank's variables */ + int save_over; /* Reevan's __NLA variables */ struct ListBase edbo; /* Armature Editmode bones */ @@ -123,8 +124,11 @@ typedef struct Global { struct VFont *selfont; struct ListBase ttfdata; - /* this variable is written to / read from FileGlobal->fileflags */ - int fileflags; + /* libtiff flag */ + int have_libtiff; + + /* this variable is written to / read from FileGlobal->fileflags */ + int fileflags; /* save the allowed windowstate of blender when using -W or -w */ int windowstate; @@ -132,12 +136,12 @@ typedef struct Global { /* Janco's playing ground */ struct bSoundListener* listener; - /* Test thingy for Nzc */ + /* Test thingy for Nzc */ int compat; /* toggle compatibility mode for edge rendering */ int notonlysolid;/* T-> also edge-render transparent faces */ /* confusing... G.f and G.flags */ - int flags; + int flags; } Global; @@ -185,7 +189,7 @@ typedef struct Global { #define G_FILE_SHOW_PROFILE (1 << 6) #define G_FILE_LOCK (1 << 7) #define G_FILE_SIGN (1 << 8) -#define G_FILE_PUBLISH (1 << 9) +#define G_FIle_PUBLISH (1 << 9) #define G_FILE_NO_UI (1 << 10) #define G_FILE_GAME_TO_IPO (1 << 11) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index d2188ad409e..5be1c0ed48f 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -315,6 +315,9 @@ void addImageExtension(char *string) if(!BLI_testextensie(string, ".bmp")) extension= ".bmp"; } + else if(G.have_libtiff && (G.scene->r.imtype==R_TIFF)) { + extension= ".tif"; + } strcat(string, extension); } diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 413047bcae6..56a28850e71 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -150,7 +150,8 @@ typedef enum { #ifdef WITH_QUICKTIME #define QUICKTIME (1 << 25) #endif -#define RADHDR (1<<24) +#define RADHDR (1<<24) +#define TIF (1<<23) #define RAWTGA (TGA | 1) @@ -188,6 +189,7 @@ typedef enum { #define IS_tga(x) (x->ftype & TGA) #define IS_png(x) (x->ftype & PNG) #define IS_bmp(x) (x->ftype & BMP) +#define IS_tiff(x) (x->ftype & TIF) #define IS_radhdr(x) (x->ftype & RADHDR) #define IMAGIC 0732 diff --git a/source/blender/imbuf/intern/IMB_tiff.h b/source/blender/imbuf/intern/IMB_tiff.h new file mode 100644 index 00000000000..b633fbffd23 --- /dev/null +++ b/source/blender/imbuf/intern/IMB_tiff.h @@ -0,0 +1,48 @@ +/* + * IMB_tiff.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + * + * Contributor(s): Jonathan Merritt. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +/** + * \file IMB_tiff.h + * \ingroup imbuf + * \brief Function declarations for tiff.c + */ + +#ifndef IMB_TIFF_H +#define IMB_TIFF_H + +/* Foward declaration of ImBuf structure. */ +struct ImBuf; + +/* Declarations for tiff.c */ +int imb_is_a_tiff(void *buf); +struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags); +short imb_savetiff(struct ImBuf *ibuf, char *name, int flags); +void* libtiff_findsymbol(char *name); + +#endif /* IMB_TIFF_H */ + diff --git a/source/blender/imbuf/intern/Makefile b/source/blender/imbuf/intern/Makefile index ed79b67af99..859f7c4cd34 100644 --- a/source/blender/imbuf/intern/Makefile +++ b/source/blender/imbuf/intern/Makefile @@ -45,6 +45,7 @@ CFLAGS += $(LEVEL_1_C_WARNINGS) CPPFLAGS += -I$(NAN_JPEG)/include CPPFLAGS += -I$(NAN_PNG)/include CPPFLAGS += -I$(NAN_ZLIB)/include +CPPFLAGS += -I$(NAN_TIFF)/include CPPFLAGS += -I../../include CPPFLAGS += -I../../blenkernel CPPFLAGS += -I../../blenlib diff --git a/source/blender/imbuf/intern/dynlibtiff.c b/source/blender/imbuf/intern/dynlibtiff.c new file mode 100644 index 00000000000..aed73d29fcb --- /dev/null +++ b/source/blender/imbuf/intern/dynlibtiff.c @@ -0,0 +1,191 @@ +/** + * Dynamically loaded libtiff support. + * + * This file is automatically generated by the gen_dynlibtiff.py script. + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + * + * Contributor(s): Jonathan Merritt. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/** + * To use the dynamic libtiff support, you must initialize the library using: + * libtiff_init() + * This attempts to load libtiff dynamically at runtime. G.have_libtiff will + * be set to indicate whether or not libtiff is available. If libtiff is + * not available, Blender can proceed with no ill effects, provided that + * it does not attempt to use any of the libtiff_ functions. When you're + * finished, close the library with: + * libtiff_exit() + * These functions are both declared in IMB_imbuf.h + * + * The functions provided by dyn_libtiff.h are the same as those in the + * normal static / shared libtiff, except that they are prefixed by the + * string "libtiff_" to indicate that they belong to a dynamically-loaded + * version. + */ +#include "dynlibtiff.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include "IMB_imbuf.h" +#include "BKE_global.h" +#include "PIL_dynlib.h" + + +/********************* + * LOCAL DEFINITIONS * + *********************/ +PILdynlib *libtiff = NULL; +void libtiff_loadlibtiff(); +void* libtiff_findsymbol(char*); +int libtiff_load_symbols(); + + +/************************** + * LIBRARY INITIALIZATION * + **************************/ + +void libtiff_loadlibtiff() +{ + char filename[1024]; + libtiff = NULL; + + /* Try to find libtiff in a couple of standard places */ + libtiff = PIL_dynlib_open("libtiff.so"); + if (libtiff != NULL) return; + libtiff = PIL_dynlib_open("libtiff.dll"); + if (libtiff != NULL) return; + libtiff = PIL_dynlib_open("/usr/lib/libtiff.so"); + if (libtiff != NULL) return; + /* OSX has version specific library */ + libtiff = PIL_dynlib_open("/usr/lib/libtiff.so.3"); + if (libtiff != NULL) return; + libtiff = PIL_dynlib_open("/usr/local/lib/libtiff.so"); + if (libtiff != NULL) return; + /* For solaris */ + libtiff = PIL_dynlib_open("/usr/openwin/lib/libtiff.so"); + if (libtiff != NULL) return; + snprintf(filename, 1023, "%s", getenv("BF_TIFF_LIB")); + libtiff = PIL_dynlib_open(filename); + if (libtiff != NULL) return; +} + +void *libtiff_findsymbol(char *name) +{ + void *symbol = NULL; + assert(libtiff != NULL); + symbol = PIL_dynlib_find_symbol(libtiff, name); + if (symbol == NULL) { + printf("libtiff_findsymbol: error %s\n", + PIL_dynlib_get_error_as_string(libtiff)); + libtiff = NULL; + G.have_libtiff = (0); + return NULL; + } + return symbol; +} + +void libtiff_init() +{ + if (libtiff != NULL) { + printf("libtiff_init: Attempted to load libtiff twice!\n"); + return; + } + libtiff_loadlibtiff(); + G.have_libtiff = ((libtiff != NULL) && (libtiff_load_symbols())); +} + +void libtiff_exit() +{ + if (libtiff != NULL) { + PIL_dynlib_close(libtiff); + libtiff = NULL; + } +} + + +int libtiff_load_symbols() +{ + /* Attempt to load TIFFClientOpen */ + libtiff_TIFFClientOpen = libtiff_findsymbol("TIFFClientOpen"); + if (libtiff_TIFFClientOpen == NULL) { + return (0); + } + /* Attempt to load TIFFClose */ + libtiff_TIFFClose = libtiff_findsymbol("TIFFClose"); + if (libtiff_TIFFClose == NULL) { + return (0); + } + /* Attempt to load TIFFGetField */ + libtiff_TIFFGetField = libtiff_findsymbol("TIFFGetField"); + if (libtiff_TIFFGetField == NULL) { + return (0); + } + /* Attempt to load TIFFOpen */ + libtiff_TIFFOpen = libtiff_findsymbol("TIFFOpen"); + if (libtiff_TIFFOpen == NULL) { + return (0); + } + /* Attempt to load TIFFReadRGBAImage */ + libtiff_TIFFReadRGBAImage = libtiff_findsymbol("TIFFReadRGBAImage"); + if (libtiff_TIFFReadRGBAImage == NULL) { + return (0); + } + /* Attempt to load TIFFSetField */ + libtiff_TIFFSetField = libtiff_findsymbol("TIFFSetField"); + if (libtiff_TIFFSetField == NULL) { + return (0); + } + /* Attempt to load TIFFWriteEncodedStrip */ + libtiff_TIFFWriteEncodedStrip = libtiff_findsymbol("TIFFWriteEncodedStrip"); + if (libtiff_TIFFWriteEncodedStrip == NULL) { + return (0); + } + /* Attempt to load _TIFFfree */ + libtiff__TIFFfree = libtiff_findsymbol("_TIFFfree"); + if (libtiff__TIFFfree == NULL) { + return (0); + } + /* Attempt to load _TIFFmalloc */ + libtiff__TIFFmalloc = libtiff_findsymbol("_TIFFmalloc"); + if (libtiff__TIFFmalloc == NULL) { + return (0); + } + return (1); +} + + +/******************* + * SYMBOL POINTERS * + *******************/ + +TIFF* (*libtiff_TIFFClientOpen)(const char*, const char*, thandle_t, TIFFReadWriteProc, TIFFReadWriteProc, TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, TIFFMapFileProc, TIFFUnmapFileProc) = NULL; +void (*libtiff_TIFFClose)(TIFF*) = NULL; +int (*libtiff_TIFFGetField)(TIFF*, ttag_t, ...) = NULL; +TIFF* (*libtiff_TIFFOpen)(const char*, const char*) = NULL; +int (*libtiff_TIFFReadRGBAImage)(TIFF*, uint32, uint32, uint32*, int) = NULL; +int (*libtiff_TIFFSetField)(TIFF*, ttag_t, ...) = NULL; +tsize_t (*libtiff_TIFFWriteEncodedStrip)(TIFF*, tstrip_t, tdata_t, tsize_t) = NULL; +void (*libtiff__TIFFfree)(tdata_t) = NULL; +tdata_t (*libtiff__TIFFmalloc)(tsize_t) = NULL; diff --git a/source/blender/imbuf/intern/dynlibtiff.h b/source/blender/imbuf/intern/dynlibtiff.h new file mode 100644 index 00000000000..8d61ee3ca87 --- /dev/null +++ b/source/blender/imbuf/intern/dynlibtiff.h @@ -0,0 +1,58 @@ +/** + * Dynamically loaded libtiff support. + * + * This file is automatically generated by the gen_dynlibtiff.py script. + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + * + * Contributor(s): Jonathan Merritt. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/** + * To use the dynamic libtiff support, you must initialize the library using: + * libtiff_init() + * This attempts to load libtiff dynamically at runtime. G.have_libtiff will + * be set to indicate whether or not libtiff is available. If libtiff is + * not available, Blender can proceed with no ill effects, provided that + * it does not attempt to use any of the libtiff_ functions. When you're + * finished, close the library with: + * libtiff_exit() + * These functions are both declared in IMB_imbuf.h + * + * The functions provided by dyn_libtiff.h are the same as those in the + * normal static / shared libtiff, except that they are prefixed by the + * string "libtiff_" to indicate that they belong to a dynamically-loaded + * version. + */ +#ifndef DYN_LIBTIFF_H +#include "tiffio.h" +extern TIFF* (*libtiff_TIFFClientOpen)(const char*, const char*, thandle_t, TIFFReadWriteProc, TIFFReadWriteProc, TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, TIFFMapFileProc, TIFFUnmapFileProc); +extern void (*libtiff_TIFFClose)(TIFF*); +extern int (*libtiff_TIFFGetField)(TIFF*, ttag_t, ...); +extern TIFF* (*libtiff_TIFFOpen)(const char*, const char*); +extern int (*libtiff_TIFFReadRGBAImage)(TIFF*, uint32, uint32, uint32*, int); +extern int (*libtiff_TIFFSetField)(TIFF*, ttag_t, ...); +extern tsize_t (*libtiff_TIFFWriteEncodedStrip)(TIFF*, tstrip_t, tdata_t, tsize_t); +extern void (*libtiff__TIFFfree)(tdata_t); +extern tdata_t (*libtiff__TIFFmalloc)(tsize_t); +#endif /* DYN_LIBTIFF_H */ + diff --git a/source/blender/imbuf/intern/gen_dynlibtiff.py b/source/blender/imbuf/intern/gen_dynlibtiff.py new file mode 100755 index 00000000000..cb24ee9431b --- /dev/null +++ b/source/blender/imbuf/intern/gen_dynlibtiff.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python + +# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# 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. +# +# Contributor(s): Jonathan Merritt. +# +# ***** END GPL/BL DUAL LICENSE BLOCK ***** + +# +# This script generates a C source file and a header file that implement +# dynamic loading functionality for libtiff. +# If you need to make more functions from libtiff available, then simply add +# them to the tiff_functions[] list below. +# + + +FILENAME = 'dynlibtiff' +C_FILENAME = '%s.c' % FILENAME +H_FILENAME = '%s.h' % FILENAME + + +COMMENT = \ +"""/** + * Dynamically loaded libtiff support. + * + * This file is automatically generated by the gen_dynlibtiff.py script. + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + * + * Contributor(s): Jonathan Merritt. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/** + * To use the dynamic libtiff support, you must initialize the library using: + * libtiff_init() + * This attempts to load libtiff dynamically at runtime. G.have_libtiff will + * be set to indicate whether or not libtiff is available. If libtiff is + * not available, Blender can proceed with no ill effects, provided that + * it does not attempt to use any of the libtiff_ functions. When you're + * finished, close the library with: + * libtiff_exit() + * These functions are both declared in IMB_imbuf.h + * + * The functions provided by dyn_libtiff.h are the same as those in the + * normal static / shared libtiff, except that they are prefixed by the + * string "libtiff_" to indicate that they belong to a dynamically-loaded + * version. + */ +""" + + +C_EXTRA = \ +""" +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include "IMB_imbuf.h" +#include "BKE_global.h" +#include "PIL_dynlib.h" + + +/********************* + * LOCAL DEFINITIONS * + *********************/ +PILdynlib *libtiff = NULL; +void libtiff_loadlibtiff(); +void* libtiff_findsymbol(char*); +int libtiff_load_symbols(); + + +/************************** + * LIBRARY INITIALIZATION * + **************************/ + +void libtiff_loadlibtiff() +{ + char filename[1024]; + libtiff = NULL; + + /* Try to find libtiff in a couple of standard places */ + libtiff = PIL_dynlib_open("libtiff.so"); + if (libtiff != NULL) return; + libtiff = PIL_dynlib_open("libtiff.dll"); + if (libtiff != NULL) return; + libtiff = PIL_dynlib_open("/usr/lib/libtiff.so"); + if (libtiff != NULL) return; + /* OSX has version specific library */ + libtiff = PIL_dynlib_open("/usr/lib/libtiff.so.3"); + if (libtiff != NULL) return; + libtiff = PIL_dynlib_open("/usr/local/lib/libtiff.so"); + if (libtiff != NULL) return; + /* For solaris */ + libtiff = PIL_dynlib_open("/usr/openwin/lib/libtiff.so"); + if (libtiff != NULL) return; + snprintf(filename, 1023, "%s", getenv("BF_TIFF_LIB")); + libtiff = PIL_dynlib_open(filename); + if (libtiff != NULL) return; +} + +void *libtiff_findsymbol(char *name) +{ + void *symbol = NULL; + assert(libtiff != NULL); + symbol = PIL_dynlib_find_symbol(libtiff, name); + if (symbol == NULL) { + printf("libtiff_findsymbol: error %s\\n", + PIL_dynlib_get_error_as_string(libtiff)); + libtiff = NULL; + G.have_libtiff = (0); + return NULL; + } + return symbol; +} + +void libtiff_init() +{ + if (libtiff != NULL) { + printf("libtiff_init: Attempted to load libtiff twice!\\n"); + return; + } + libtiff_loadlibtiff(); + G.have_libtiff = ((libtiff != NULL) && (libtiff_load_symbols())); +} + +void libtiff_exit() +{ + if (libtiff != NULL) { + PIL_dynlib_close(libtiff); + libtiff = NULL; + } +} + + +""" + + +class CFun: + def __init__(self, name, retType, args): + self.name = name + self.retType = retType + self.args = args + def getDynamicName(self): + return ('libtiff_%s' % self.name) + def getDynamicDecl(self): + argstr = (('%s, '*len(self.args)) % tuple(self.args))[:-2] + return ('%s (*%s)(%s)' % (self.retType, + self.getDynamicName(), argstr)) + def getLoadSymbol(self): + dname = self.getDynamicName() + return ( + """\t/* Attempt to load %s */ + %s = libtiff_findsymbol("%s"); + if (%s == NULL) { + return (0); + }\n""" % (self.name, dname, self.name, dname)) + + +# If you need more functions, add them to the list below, based upon entries +# in either tiffio.h or tiff.h. +tiff_functions = [ + CFun('TIFFClientOpen', 'TIFF*', ['const char*', 'const char*', + 'thandle_t', 'TIFFReadWriteProc', 'TIFFReadWriteProc', + 'TIFFSeekProc', 'TIFFCloseProc', 'TIFFSizeProc', + 'TIFFMapFileProc', 'TIFFUnmapFileProc']), + CFun('TIFFClose', 'void', ['TIFF*']), + CFun('TIFFGetField', 'int', ['TIFF*', 'ttag_t', '...']), + CFun('TIFFOpen', 'TIFF*', ['const char*', 'const char*']), + CFun('TIFFReadRGBAImage', 'int', ['TIFF*', 'uint32', 'uint32', + 'uint32*', 'int']), + CFun('TIFFSetField', 'int', ['TIFF*', 'ttag_t', '...']), + CFun('TIFFWriteEncodedStrip', 'tsize_t', ['TIFF*', 'tstrip_t', + 'tdata_t', 'tsize_t']), + CFun('_TIFFfree', 'void', ['tdata_t']), + CFun('_TIFFmalloc', 'tdata_t', ['tsize_t']), +] + + +def outputDynCFile(outfile, header_file_name): + outfile.write(COMMENT) + outfile.write('#include "%s"\n' % header_file_name) + outfile.write(C_EXTRA) + outfile.write('int libtiff_load_symbols()\n') + outfile.write('{\n') + for function in tiff_functions: + outfile.write(function.getLoadSymbol()) + outfile.write('\treturn (1);\n') + outfile.write('}\n') + outfile.write(""" + +/******************* + * SYMBOL POINTERS * + *******************/\n\n""") + for function in tiff_functions: + outfile.write('%s = NULL;\n' % function.getDynamicDecl()) + + +def outputDynHFile(outfile): + outfile.write(COMMENT) + outfile.write('#ifndef DYN_LIBTIFF_H\n') + outfile.write('#include "tiffio.h"\n') + for function in tiff_functions: + outfile.write('extern %s;\n' % function.getDynamicDecl()) + outfile.write('#endif /* DYN_LIBTIFF_H */\n\n') + + +if __name__ == '__main__': + outfile = file(C_FILENAME, 'w') + outputDynCFile(outfile, H_FILENAME) + outfile.close() + outfile = file(H_FILENAME, 'w') + outputDynHFile(outfile) + outfile.close() diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c index 166b1d6af81..779401c3183 100644 --- a/source/blender/imbuf/intern/readimage.c +++ b/source/blender/imbuf/intern/readimage.c @@ -50,6 +50,7 @@ #include "IMB_hamx.h" #include "IMB_jpeg.h" #include "IMB_bmp.h" +#include "IMB_tiff.h" #include "IMB_radiance_hdr.h" #include "BKE_global.h" @@ -129,6 +130,11 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) { ibuf = imb_loadtarga((uchar *)mem, flags); if (ibuf) return(ibuf); + if (G.have_libtiff) { + ibuf = imb_loadtiff((uchar *)mem, size, flags); + if (ibuf) return(ibuf); + } + ibuf = imb_loadhdr((uchar*)mem, size, flags); if (ibuf) return (ibuf); diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c new file mode 100644 index 00000000000..9f5ecf18dd9 --- /dev/null +++ b/source/blender/imbuf/intern/tiff.c @@ -0,0 +1,528 @@ +/* + * tiff.c + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + * + * Contributor(s): Jonathan Merritt. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/** + * Provides TIFF file loading and saving for Blender, via libtiff. + * + * The task of loading is complicated somewhat by the fact that Blender has + * already loaded the file into a memory buffer. libtiff is not well + * configured to handle files in memory, so a client wrapper is written to + * surround the memory and turn it into a virtual file. Currently, reading + * of TIFF files is done using libtiff's RGBAImage support. This is a + * high-level routine that loads all images as 32-bit RGBA, handling all the + * required conversions between many different TIFF types internally. + * + * Saving supports RGB, RGBA and BW (greyscale) images correctly, with + * 8 bits per channel in all cases. The "deflate" compression algorithm is + * used to compress images. + */ + +#include <assert.h> +#include <string.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_tiff.h" + +#include "dynlibtiff.h" + + + +/*********************** + * Local declarations. * + ***********************/ +/* Reading and writing of an in-memory TIFF file. */ +tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n); +tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n); +toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence); +int imb_tiff_CloseProc(thandle_t handle); +toff_t imb_tiff_SizeProc(thandle_t handle); +/* Structure for in-memory TIFF file. */ +struct ImbTIFFMemFile { + unsigned char *mem; /* Location of first byte of TIFF file. */ + toff_t offset; /* Current offset within the file. */ + tsize_t size; /* Size of the TIFF file. */ +}; +#define IMB_TIFF_GET_MEMFILE(x) ((struct ImbTIFFMemFile*)(x)); + + + +/***************************** + * Function implementations. * + *****************************/ + + + +/** + * Reads data from an in-memory TIFF file. + * + * @param handle: Handle of the TIFF file (pointer to ImbTIFFMemFile). + * @param data: Buffer to contain data (treat as void*). + * @param n: Number of bytes to read. + * + * @return: Number of bytes actually read. + * 0 = EOF. + * -1 = Error (never returned). + */ +tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n) +{ + tsize_t nRemaining, nCopy; + struct ImbTIFFMemFile* mfile; + void *srcAddr; + + /* get the pointer to the in-memory file */ + mfile = IMB_TIFF_GET_MEMFILE(handle); + assert(mfile != NULL); + assert(mfile->mem != NULL); + + /* find the actual number of bytes to read (copy) */ + nCopy = n; + if ((tsize_t)mfile->offset >= mfile->size) + nRemaining = 0; + else + nRemaining = mfile->size - mfile->offset; + + if (nCopy > nRemaining) + nCopy = nRemaining; + + /* on EOF, return immediately and read (copy) nothing */ + if (nCopy <= 0) + return (0); + + /* all set -> do the read (copy) */ + assert(sizeof(unsigned char) == 1); + srcAddr = (void*)(&(mfile->mem[mfile->offset])); + memcpy((void*)data, srcAddr, nCopy); + mfile->offset += nCopy; /* advance file ptr by copied bytes */ + return nCopy; +} + + + +/** + * Writes data to an in-memory TIFF file. + * + * NOTE: The current Blender implementation should not need this function. It + * is simply a stub. + */ +tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n) +{ + printf("imb_tiff_WriteProc: this function should not be called.\n"); + return (-1); +} + + + +/** + * Seeks to a new location in an in-memory TIFF file. + * + * @param handle: Handle of the TIFF file (pointer to ImbTIFFMemFile). + * @param ofs: Offset value (interpreted according to whence below). + * @param whence: This can be one of three values: + * SEEK_SET - The offset is set to ofs bytes. + * SEEK_CUR - The offset is set to its current location plus ofs bytes. + * SEEK_END - (This is unsupported and will return -1, indicating an + * error). + * + * @return: Resulting offset location within the file, measured in bytes from + * the beginning of the file. (-1) indicates an error. + */ +toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence) +{ + struct ImbTIFFMemFile *mfile; + toff_t new_offset; + + /* get the pointer to the in-memory file */ + mfile = IMB_TIFF_GET_MEMFILE(handle); + assert(mfile != NULL); + assert(mfile->mem != NULL); + + /* find the location we plan to seek to */ + switch (whence) { + case SEEK_SET: + new_offset = ofs; + break; + case SEEK_CUR: + new_offset = mfile->offset + ofs; + break; + default: + /* no other types are supported - return an error */ + printf("Unsupported TIFF SEEK type.\n"); + return (-1); + } + + /* set the new location */ + mfile->offset = new_offset; + return mfile->offset; +} + + + +/** + * Closes (virtually) an in-memory TIFF file. + * + * NOTE: All this function actually does is sets the data pointer within the + * TIFF file to NULL. That should trigger assertion errors if attempts + * are made to access the file after that point. However, no such + * attempts should ever be made (in theory). + * + * @param handle: Handle of the TIFF file (pointer to ImbTIFFMemFile). + * + * @return: 0 + */ +int imb_tiff_CloseProc(thandle_t handle) +{ + struct ImbTIFFMemFile *mfile; + + /* get the pointer to the in-memory file */ + mfile = IMB_TIFF_GET_MEMFILE(handle); + assert(mfile != NULL); + assert(mfile->mem != NULL); /* the file has not been closed yet */ + + /* virtually close the file */ + mfile->mem = NULL; + mfile->offset = 0; + mfile->size = 0; + + return (0); +} + + + +/** + * Returns the size of an in-memory TIFF file in bytes. + * + * @return: Size of file (in bytes). + */ +toff_t imb_tiff_SizeProc(thandle_t handle) +{ + struct ImbTIFFMemFile* mfile; + + /* get the pointer to the in-memory file */ + mfile = IMB_TIFF_GET_MEMFILE(handle); + assert(mfile != NULL); + assert(mfile->mem != NULL); + + /* return the size */ + return (toff_t)(mfile->size); +} + + + +/** + * Checks whether a given memory buffer contains a TIFF file. + * + * FIXME: Possible memory leak if mem is less than IMB_TIFF_NCB bytes long. + * However, changing this will require up-stream modifications. + * + * This method uses the format identifiers from: + * http://www.faqs.org/faqs/graphics/fileformats-faq/part4/section-9.html + * The first four bytes of big-endian and little-endian TIFF files + * respectively are (hex): + * 4d 4d 00 2a + * 49 49 2a 00 + * Note that TIFF files on *any* platform can be either big- or little-endian; + * it's not platform-specific. + * + * AFAICT, libtiff doesn't provide a method to do this automatically, and + * hence my manual comparison. - Jonathan Merritt (lancelet) 4th Sept 2005. + */ +#define IMB_TIFF_NCB 4 /* number of comparison bytes used */ +int imb_is_a_tiff(void *mem) +{ + char big_endian[IMB_TIFF_NCB] = { 0x4d, 0x4d, 0x00, 0x2a }; + char lil_endian[IMB_TIFF_NCB] = { 0x49, 0x49, 0x2a, 0x00 }; + + return ( (memcmp(big_endian, mem, IMB_TIFF_NCB) == 0) || + (memcmp(lil_endian, mem, IMB_TIFF_NCB) == 0) ); +} + + + +/** + * Loads a TIFF file. + * + * This function uses the "RGBA Image" support from libtiff, which enables + * it to load most commonly-encountered TIFF formats. libtiff handles format + * conversion, color depth conversion, etc. + * + * @param mem: Memory containing the TIFF file. + * @param size: Size of the mem buffer. + * @param flags: If flags has IB_test set then the file is not actually loaded, + * but all other operations take place. + * + * @return: A newly allocated ImBuf structure if successful, otherwise NULL. + */ +struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags) +{ + TIFF *image = NULL; + struct ImBuf *ibuf = NULL; + struct ImbTIFFMemFile memFile = { mem, 0, size }; + uint32 width, height; + int bytesperpixel; + int success; + unsigned int pixel_i, byte_i; + uint32 *raster = NULL; + uint32 pixel; + unsigned char *to = NULL; + + /* check whether or not we have a TIFF file */ + assert(size >= IMB_TIFF_NCB); + if (imb_is_a_tiff(mem) == 0) + return NULL; + + /* open the TIFF client layer interface to the in-memory file */ + image = libtiff_TIFFClientOpen("(Blender TIFF Interface Layer)", + "r", (thandle_t)(&memFile), + imb_tiff_ReadProc, imb_tiff_WriteProc, + imb_tiff_SeekProc, imb_tiff_CloseProc, + imb_tiff_SizeProc, (TIFFMapFileProc)NULL, + (TIFFUnmapFileProc)NULL); + if (image == NULL) { + printf("imb_loadtiff: could not open TIFF IO layer.\n"); + return NULL; + } + + /* allocate the image buffer */ + bytesperpixel = 4; /* 1 byte per channel, 4 channels */ + libtiff_TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width); + libtiff_TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height); + ibuf = IMB_allocImBuf(width, height, 8*bytesperpixel, 0, 0); + if (ibuf) { + ibuf->ftype = TIF; + } else { + printf("imb_loadtiff: could not allocate memory for TIFF " \ + "image.\n"); + libtiff_TIFFClose(image); + return NULL; + } + + /* read in the image data */ + if (!(flags & IB_test)) { + + /* allocate memory for the ibuf->rect */ + imb_addrectImBuf(ibuf); + + /* perform actual read */ + raster = (uint32*)libtiff__TIFFmalloc( + width*height * sizeof(uint32)); + if (raster == NULL) { + libtiff_TIFFClose(image); + return NULL; + } + success = libtiff_TIFFReadRGBAImage( + image, width, height, raster, 0); + if (!success) { + printf("imb_loadtiff: This TIFF format is not " \ + "currently supported by Blender.\n"); + libtiff__TIFFfree(raster); + libtiff_TIFFClose(image); + return NULL; + } + + /* copy raster to ibuf->rect; we do a fast copy if possible, + * otherwise revert to a slower component-wise copy */ + if (sizeof(unsigned int) == sizeof(uint32)) { + memcpy(ibuf->rect, raster, + width*height*sizeof(uint32)); + } else { + /* this may not be entirely necessary, but is put here + * in case sizeof(unsigned int) is not a 32-bit + * quantity */ + printf("imb_loadtiff: using (slower) component-wise " \ + "buffer copy.\n"); + to = (unsigned char*)ibuf->rect; + for (pixel_i=0; pixel_i < width*height; pixel_i++) + { + byte_i = sizeof(unsigned int)*pixel_i; + pixel = raster[pixel_i]; + + to[byte_i++] = (unsigned char)TIFFGetR(pixel); + to[byte_i++] = (unsigned char)TIFFGetG(pixel); + to[byte_i++] = (unsigned char)TIFFGetB(pixel); + to[byte_i++] = (unsigned char)TIFFGetA(pixel); + } + } + + libtiff__TIFFfree(raster); + } + + /* close the client layer interface to the in-memory file */ + libtiff_TIFFClose(image); + + /* return successfully */ + return (ibuf); +} + + + +/** + * Saves a TIFF file. + * + * ImBuf structures with 1, 3 or 4 bytes per pixel (GRAY, RGB, RGBA + * respectively) are accepted, and interpreted correctly. Note that the TIFF + * convention is to use pre-multiplied alpha, which can be achieved within + * Blender by setting "Premul" alpha handling. Other alpha conventions are + * not strictly correct, but are permitted anyhow. + * + * @param ibuf: Image buffer. + * @param name: Name of the TIFF file to create. + * @param flags: Currently largely ignored. + * + * @return: 1 if the function is successful, 0 on failure. + */ +short imb_savetiff(struct ImBuf *ibuf, char *name, int flags) +{ + TIFF *image = NULL; + uint16 samplesperpixel; + size_t npixels; + unsigned char *pixels = NULL; + unsigned char *from = NULL, *to = NULL; + int x, y, from_i, to_i; + int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA }; + + /* check for a valid number of bytes per pixel. Like the PNG writer, + * the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding + * to gray, RGB, RGBA respectively. */ + samplesperpixel = (uint16)((ibuf->depth + 7) >> 3); + if ((samplesperpixel > 4) || (samplesperpixel == 2)) { + printf("imb_savetiff: unsupported number of bytes per " \ + "pixel: %d\n", samplesperpixel); + return (0); + } + + /* open TIFF file for writing */ + if (flags & IB_mem) { + /* bork at the creation of a TIFF in memory */ + printf("imb_savetiff: creation of in-memory TIFF files is " \ + "not yet supported.\n"); + return (0); + } else { + /* create image as a file */ + image = libtiff_TIFFOpen(name, "w"); + } + if (image == NULL) { + printf("imb_savetiff: could not open TIFF for writing.\n"); + return (0); + } + + /* allocate array for pixel data */ + npixels = ibuf->x * ibuf->y; + pixels = (unsigned char*)libtiff__TIFFmalloc(npixels * + samplesperpixel * sizeof(unsigned char)); + if (pixels == NULL) { + printf("imb_savetiff: could not allocate pixels array.\n"); + libtiff_TIFFClose(image); + return (0); + } + + /* copy pixel data. While copying, we flip the image + * vertically. */ + from = (unsigned char*)ibuf->rect; + to = pixels; + libtiff_TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); + switch (samplesperpixel) { + case 4: /* RGBA images, 8 bits per channel */ + libtiff_TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1, + extraSampleTypes); + libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8); + libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC, + PHOTOMETRIC_RGB); + for (x = 0; x < ibuf->x; x++) { + for (y = 0; y < ibuf->y; y++) { + from_i = 4*(y*ibuf->x+x); + to_i = 4*((ibuf->y-y-1)*ibuf->x+x); + + to[to_i++] = from[from_i++]; + to[to_i++] = from[from_i++]; + to[to_i++] = from[from_i++]; + to[to_i] = from[from_i]; + } + } + break; + case 3: /* RGB images, 8 bits per channel */ + libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8); + libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC, + PHOTOMETRIC_RGB); + for (x = 0; x < ibuf->x; x++) { + for (y = 0; y < ibuf->y; y++) { + from_i = 4*(y*ibuf->x+x); + to_i = 3*((ibuf->y-y-1)*ibuf->x+x); + + to[to_i++] = from[from_i++]; + to[to_i++] = from[from_i++]; + to[to_i] = from[from_i]; + } + } + break; + case 1: /* greyscale images, 1 channel with 8 bits */ + libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8); + libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC, + PHOTOMETRIC_MINISBLACK); + for (x = 0; x < ibuf->x; x++) { + for (y = 0; y < ibuf->y; y++) { + from_i = 4*(y*ibuf->x+x); + to_i = 1*((ibuf->y-y-1)*ibuf->x+x); + + to[to_i] = from[from_i]; + } + } + break; + } + + /* write the actual TIFF file */ + libtiff_TIFFSetField(image, TIFFTAG_IMAGEWIDTH, ibuf->x); + libtiff_TIFFSetField(image, TIFFTAG_IMAGELENGTH, ibuf->y); + libtiff_TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, ibuf->y); + libtiff_TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); + libtiff_TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); + libtiff_TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + libtiff_TIFFSetField(image, TIFFTAG_XRESOLUTION, 150.0); + libtiff_TIFFSetField(image, TIFFTAG_YRESOLUTION, 150.0); + libtiff_TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); + if (libtiff_TIFFWriteEncodedStrip(image, 0, pixels, + ibuf->x*ibuf->y*samplesperpixel) == -1) { + printf("imb_savetiff: Could not write encoded TIFF.\n"); + libtiff_TIFFClose(image); + libtiff__TIFFfree(pixels); + return (1); + } + + /* close the TIFF file */ + libtiff_TIFFClose(image); + libtiff__TIFFfree(pixels); + return (1); +} + diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index bbfa41e9dcc..4cdfa852df1 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -45,6 +45,7 @@ #include "IMB_targa.h" #include "IMB_png.h" #include "IMB_bmp.h" +#include "IMB_tiff.h" #include "IMB_radiance_hdr.h" #include "IMB_anim.h" @@ -97,6 +98,8 @@ static int IMB_ispic_name(char *name) if (imb_is_a_png(buf)) return(PNG); if (imb_is_a_targa(buf)) return(TGA); + if (imb_is_a_tiff(buf)) return(TIF); + /* radhdr: check if hdr format */ if (imb_is_a_hdr(buf)) return(RADHDR); @@ -125,9 +128,15 @@ static int IMB_ispic_name(char *name) int IMB_ispic(char *filename) { if(U.uiflag & USER_FILTERFILEEXTS) { + if (G.have_libtiff && (BLI_testextensie(filename, ".tif") + || BLI_testextensie(filename, ".tiff"))) { + return IMB_ispic_name(filename); + } if (G.have_quicktime){ if( BLI_testextensie(filename, ".jpg") || BLI_testextensie(filename, ".jpeg") + || BLI_testextensie(filename, ".tif") + || BLI_testextensie(filename, ".tiff") || BLI_testextensie(filename, ".hdr") || BLI_testextensie(filename, ".tga") || BLI_testextensie(filename, ".rgb") @@ -137,8 +146,6 @@ int IMB_ispic(char *filename) || BLI_testextensie(filename, ".lbm") || BLI_testextensie(filename, ".gif") || BLI_testextensie(filename, ".psd") - || BLI_testextensie(filename, ".tif") - || BLI_testextensie(filename, ".tiff") || BLI_testextensie(filename, ".pct") || BLI_testextensie(filename, ".pict") || BLI_testextensie(filename, ".pntg") //macpaint @@ -148,7 +155,7 @@ int IMB_ispic(char *filename) } else { return(FALSE); } - } else { // no quicktime + } else { /* no quicktime or libtiff */ if( BLI_testextensie(filename, ".jpg") || BLI_testextensie(filename, ".jpeg") || BLI_testextensie(filename, ".hdr") @@ -165,7 +172,7 @@ int IMB_ispic(char *filename) return(FALSE); } } - } else { // no FILTERFILEEXTS + } else { /* no FILTERFILEEXTS */ return IMB_ispic_name(filename); } } diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c index 148597dda35..340f8ace415 100644 --- a/source/blender/imbuf/intern/writeimage.c +++ b/source/blender/imbuf/intern/writeimage.c @@ -36,6 +36,7 @@ #include <io.h> #endif +#include "BKE_global.h" #include "BLI_blenlib.h" #include "imbuf.h" @@ -54,6 +55,7 @@ #include "IMB_amiga.h" #include "IMB_png.h" #include "IMB_bmp.h" +#include "IMB_tiff.h" #include "IMB_radiance_hdr.h" #include "IMB_iff.h" @@ -87,6 +89,9 @@ short IMB_saveiff(struct ImBuf *ibuf,char *naam,int flags) if (IS_iris(ibuf)) { return imb_saveiris(ibuf,naam,flags); } + if (G.have_libtiff && IS_tiff(ibuf)) { + return imb_savetiff(ibuf,naam,flags); + } file = open(naam, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666); if (file < 0) return (FALSE); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 39827838515..ed038d0d44f 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -395,6 +395,7 @@ typedef struct Scene { #define R_QUICKTIME 19 #define R_BMP 20 #define R_RADHDR 21 +#define R_TIFF 22 /* **************** RENDER ********************* */ /* mode flag is same as for renderdata */ diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 3739a8c2d98..ffa1390c8e0 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -919,6 +919,7 @@ static char *imagetype_pup(void) { static char string[1024]; char formatstring[1024]; + char appendstring[1024]; strcpy(formatstring, "Save image as: %%t|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d"); @@ -986,6 +987,12 @@ static char *imagetype_pup(void) ); } + if (G.have_libtiff) { + strcpy(formatstring, "|%s %%x%d"); + sprintf(appendstring, formatstring, "TIFF", R_TIFF); + strcat(string, appendstring); + } + return (string); } diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index 09cf0d8a42e..3b17f0c2c26 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -34,10 +34,6 @@ #include <string.h> #include <math.h> -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #ifdef WIN32 #include <io.h> #include <direct.h> @@ -589,6 +585,10 @@ void test_flags_file(SpaceFile *sfile) || BLI_testextensie(file->relname, ".otf") || BLI_testextensie(file->relname, ".otc")) { file->flags |= FTFONTFILE; + } else if (G.have_libtiff && + (BLI_testextensie(file->relname, ".tif") + || BLI_testextensie(file->relname, ".tiff"))) { + file->flags |= IMAGEFILE; } else if (G.have_quicktime){ if( BLI_testextensie(file->relname, ".jpg") || BLI_testextensie(file->relname, ".jpeg") diff --git a/source/blender/src/screendump.c b/source/blender/src/screendump.c index 4568eb7f4c5..ebc5bad88c6 100644 --- a/source/blender/src/screendump.c +++ b/source/blender/src/screendump.c @@ -33,10 +33,6 @@ #include <string.h> -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" @@ -89,6 +85,8 @@ void write_screendump(char *name) else if(G.scene->r.imtype==R_TARGA) ibuf->ftype= TGA; else if(G.scene->r.imtype==R_RAWTGA) ibuf->ftype= RAWTGA; else if(G.scene->r.imtype==R_PNG) ibuf->ftype= PNG; + else if((G.have_libtiff) && + (G.scene->r.imtype==R_TIFF)) ibuf->ftype= TIF; else if(G.scene->r.imtype==R_HAMX) ibuf->ftype= AN_hamx; else if(ELEM5(G.scene->r.imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) { ibuf->ftype= JPG|G.scene->r.quality; diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index 721738b8931..0fee06a65d8 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -215,6 +215,9 @@ void schrijfplaatje(char *name) else if(R.r.imtype==R_BMP) { ibuf->ftype= BMP; } + else if((G.have_libtiff) && (R.r.imtype==R_TIFF)) { + ibuf->ftype= TIF; + } else if((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) { ibuf->ftype= TGA; } @@ -491,6 +494,10 @@ int save_image_filesel_str(char *str) strcpy(str, "Save PNG"); return 1; case R_BMP: strcpy(str, "Save BMP"); return 1; + case R_TIFF: + if (G.have_libtiff) { + strcpy(str, "Save TIFF"); return 1; + } case R_TARGA: strcpy(str, "Save Targa"); return 1; case R_RAWTGA: diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 25b46b064a9..a3dfbae7451 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -37,10 +37,6 @@ #include <stdio.h> #include <string.h> -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #ifdef WIN32 #include "BLI_winstuff.h" #include <process.h> /* getpid */ @@ -729,6 +725,8 @@ void exit_usiblender(void) sound_exit_audio(); if(G.listener) MEM_freeN(G.listener); + libtiff_exit(); + #ifdef WITH_QUICKTIME quicktime_exit(); #endif diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c index d7e0fd234ca..40160c42367 100644 --- a/source/blender/src/writeimage.c +++ b/source/blender/src/writeimage.c @@ -60,6 +60,9 @@ int BIF_write_ibuf(ImBuf *ibuf, char *name) else if ((G.scene->r.imtype==R_BMP)) { ibuf->ftype= BMP; } + else if ((G.have_libtiff) && (G.scene->r.imtype==R_TIFF)) { + ibuf->ftype= TIF; + } else if ((G.scene->r.imtype==R_TARGA) || (G.scene->r.imtype==R_PNG)) { // fall back to Targa if PNG writing is not supported ibuf->ftype= TGA; |