Blender  V2.59
readimage.c
Go to the documentation of this file.
00001 /*
00002  *
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Contributor(s): none yet.
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  * allocimbuf.c
00028  *
00029  * $Id: readimage.c 35336 2011-03-03 17:58:06Z campbellbarton $
00030  */
00031 
00037 #ifdef _WIN32
00038 #include <io.h>
00039 #include <stddef.h>
00040 #include <sys/types.h>
00041 #include "mmap_win.h"
00042 #define open _open
00043 #define read _read
00044 #define close _close
00045 #endif
00046 
00047 #include "BLI_blenlib.h"
00048 
00049 #include "imbuf.h"
00050 #include "IMB_imbuf_types.h"
00051 #include "IMB_imbuf.h"
00052 #include "IMB_filetype.h"
00053 
00054 ImBuf *IMB_ibImageFromMemory(unsigned char *mem, size_t size, int flags)
00055 {
00056         ImBuf *ibuf;
00057         ImFileType *type;
00058 
00059         if(mem == NULL) {
00060                 printf("Error in ibImageFromMemory: NULL pointer\n");
00061                 return NULL;
00062         }
00063 
00064         for(type=IMB_FILE_TYPES; type->is_a; type++) {
00065                 if(type->load) {
00066                         ibuf= type->load(mem, size, flags);
00067                         if(ibuf) {
00068                                 if(flags & IB_premul) {
00069                                         IMB_premultiply_alpha(ibuf);
00070                                         ibuf->flags |= IB_premul;
00071                                 }
00072 
00073                                 return ibuf;
00074                         }
00075                 }
00076         }
00077 
00078         fprintf(stderr, "Unknown fileformat\n");
00079         
00080         return NULL;
00081 }
00082 
00083 ImBuf *IMB_loadifffile(int file, int flags)
00084 {
00085         ImBuf *ibuf;
00086         unsigned char *mem;
00087         size_t size;
00088 
00089         if(file == -1) return NULL;
00090 
00091         size= BLI_filesize(file);
00092 
00093         mem= mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
00094         if(mem==(unsigned char*)-1) {
00095                 fprintf(stderr, "Couldn't get mapping\n");
00096                 return NULL;
00097         }
00098 
00099         ibuf= IMB_ibImageFromMemory(mem, size, flags);
00100 
00101         if(munmap(mem, size))
00102                 fprintf(stderr, "Couldn't unmap file.\n");
00103 
00104         return ibuf;
00105 }
00106 
00107 static void imb_cache_filename(char *filename, const char *name, int flags)
00108 {
00109         /* read .tx instead if it exists and is not older */
00110         if(flags & IB_tilecache) {
00111                 BLI_strncpy(filename, name, IB_FILENAME_SIZE);
00112                 if(!BLI_replace_extension(filename, IB_FILENAME_SIZE, ".tx"))
00113                         return;
00114 
00115                 if(BLI_file_older(name, filename))
00116                         return;
00117         }
00118 
00119         BLI_strncpy(filename, name, IB_FILENAME_SIZE);
00120 }
00121 
00122 ImBuf *IMB_loadiffname(const char *name, int flags)
00123 {
00124         ImBuf *ibuf;
00125         int file, a;
00126         char filename[IB_FILENAME_SIZE];
00127 
00128         imb_cache_filename(filename, name, flags);
00129 
00130         file = open(filename, O_BINARY|O_RDONLY);
00131         if(file < 0) return NULL;
00132 
00133         ibuf= IMB_loadifffile(file, flags);
00134 
00135         if(ibuf) {
00136                 BLI_strncpy(ibuf->name, name, sizeof(ibuf->name));
00137                 BLI_strncpy(ibuf->cachename, filename, sizeof(ibuf->cachename));
00138                 for(a=1; a<ibuf->miptot; a++)
00139                         BLI_strncpy(ibuf->mipmap[a-1]->cachename, filename, sizeof(ibuf->cachename));
00140                 if(flags & IB_fields) IMB_de_interlace(ibuf);
00141         }
00142 
00143         close(file);
00144 
00145         return ibuf;
00146 }
00147 
00148 ImBuf *IMB_testiffname(char *name, int flags)
00149 {
00150         ImBuf *ibuf;
00151         int file;
00152         char filename[IB_FILENAME_SIZE];
00153 
00154         imb_cache_filename(filename, name, flags);
00155 
00156         file = open(filename,O_BINARY|O_RDONLY);
00157         if(file < 0) return NULL;
00158 
00159         ibuf=IMB_loadifffile(file, flags|IB_test|IB_multilayer);
00160         if(ibuf) {
00161                 BLI_strncpy(ibuf->name, name, sizeof(ibuf->name));
00162                 BLI_strncpy(ibuf->cachename, filename, sizeof(ibuf->cachename));
00163         }
00164 
00165         close(file);
00166 
00167         return ibuf;
00168 }
00169 
00170 static void imb_loadtilefile(ImBuf *ibuf, int file, int tx, int ty, unsigned int *rect)
00171 {
00172         ImFileType *type;
00173         unsigned char *mem;
00174         size_t size;
00175 
00176         if(file == -1) return;
00177 
00178         size= BLI_filesize(file);
00179 
00180         mem= mmap(NULL, size, PROT_READ, MAP_SHARED, file, 0);
00181         if(mem==(unsigned char*)-1) {
00182                 fprintf(stderr, "Couldn't get memory mapping for %s\n", ibuf->cachename);
00183                 return;
00184         }
00185 
00186         for(type=IMB_FILE_TYPES; type->is_a; type++)
00187                 if(type->load_tile && type->ftype(type, ibuf))
00188                         type->load_tile(ibuf, mem, size, tx, ty, rect);
00189 
00190         if(munmap(mem, size))
00191                 fprintf(stderr, "Couldn't unmap memory for %s.\n", ibuf->cachename);
00192 }
00193 
00194 void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect)
00195 {
00196         int file;
00197 
00198         file = open(ibuf->cachename, O_BINARY|O_RDONLY);
00199         if(file < 0) return;
00200 
00201         imb_loadtilefile(ibuf, file, tx, ty, rect);
00202 
00203         close(file);
00204 }
00205