Blender V2.61 - r43446

readimage.c

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