Blender V2.61 - r43446
|
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 */ 00027 00033 /* It's become a bit messy... Basically, only the IMB_ prefixed files 00034 * should remain. */ 00035 00036 #include <stddef.h> 00037 00038 #include "IMB_imbuf.h" 00039 #include "IMB_imbuf_types.h" 00040 00041 #include "IMB_allocimbuf.h" 00042 #include "IMB_filetype.h" 00043 #include "IMB_metadata.h" 00044 00045 #include "imbuf.h" 00046 00047 #include "MEM_guardedalloc.h" 00048 #include "MEM_CacheLimiterC-Api.h" 00049 00050 void imb_freemipmapImBuf(ImBuf *ibuf) 00051 { 00052 int a; 00053 00054 for(a=1; a<ibuf->miptot; a++) { 00055 if(ibuf->mipmap[a-1]) 00056 IMB_freeImBuf(ibuf->mipmap[a-1]); 00057 ibuf->mipmap[a-1]= NULL; 00058 } 00059 00060 ibuf->miptot= 0; 00061 } 00062 00063 /* any free rect frees mipmaps to be sure, creation is in render on first request */ 00064 void imb_freerectfloatImBuf(ImBuf *ibuf) 00065 { 00066 if(ibuf==NULL) return; 00067 00068 if(ibuf->rect_float && (ibuf->mall & IB_rectfloat)) { 00069 MEM_freeN(ibuf->rect_float); 00070 ibuf->rect_float=NULL; 00071 } 00072 00073 imb_freemipmapImBuf(ibuf); 00074 00075 ibuf->rect_float= NULL; 00076 ibuf->mall &= ~IB_rectfloat; 00077 } 00078 00079 /* any free rect frees mipmaps to be sure, creation is in render on first request */ 00080 void imb_freerectImBuf(ImBuf *ibuf) 00081 { 00082 if(ibuf==NULL) return; 00083 00084 if(ibuf->rect && (ibuf->mall & IB_rect)) 00085 MEM_freeN(ibuf->rect); 00086 ibuf->rect= NULL; 00087 00088 imb_freemipmapImBuf(ibuf); 00089 00090 ibuf->mall &= ~IB_rect; 00091 } 00092 00093 void imb_freetilesImBuf(ImBuf *ibuf) 00094 { 00095 int tx, ty; 00096 00097 if(ibuf==NULL) return; 00098 00099 if(ibuf->tiles && (ibuf->mall & IB_tiles)) { 00100 for(ty=0; ty<ibuf->ytiles; ty++) { 00101 for(tx=0; tx<ibuf->xtiles; tx++) { 00102 if(ibuf->tiles[ibuf->xtiles*ty + tx]) { 00103 imb_tile_cache_tile_free(ibuf, tx, ty); 00104 MEM_freeN(ibuf->tiles[ibuf->xtiles*ty + tx]); 00105 } 00106 } 00107 } 00108 00109 MEM_freeN(ibuf->tiles); 00110 } 00111 00112 ibuf->tiles= NULL; 00113 ibuf->mall &= ~IB_tiles; 00114 } 00115 00116 static void freeencodedbufferImBuf(ImBuf *ibuf) 00117 { 00118 if(ibuf==NULL) return; 00119 00120 if(ibuf->encodedbuffer && (ibuf->mall & IB_mem)) 00121 MEM_freeN(ibuf->encodedbuffer); 00122 00123 ibuf->encodedbuffer = NULL; 00124 ibuf->encodedbuffersize = 0; 00125 ibuf->encodedsize = 0; 00126 ibuf->mall &= ~IB_mem; 00127 } 00128 00129 void IMB_freezbufImBuf(ImBuf *ibuf) 00130 { 00131 if(ibuf==NULL) return; 00132 00133 if(ibuf->zbuf && (ibuf->mall & IB_zbuf)) 00134 MEM_freeN(ibuf->zbuf); 00135 00136 ibuf->zbuf= NULL; 00137 ibuf->mall &= ~IB_zbuf; 00138 } 00139 00140 void IMB_freezbuffloatImBuf(ImBuf *ibuf) 00141 { 00142 if(ibuf==NULL) return; 00143 00144 if(ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat)) 00145 MEM_freeN(ibuf->zbuf_float); 00146 00147 ibuf->zbuf_float= NULL; 00148 ibuf->mall &= ~IB_zbuffloat; 00149 } 00150 00151 void IMB_freeImBuf(ImBuf *ibuf) 00152 { 00153 if(ibuf) { 00154 if(ibuf->refcounter > 0) { 00155 ibuf->refcounter--; 00156 } 00157 else { 00158 imb_freerectImBuf(ibuf); 00159 imb_freerectfloatImBuf(ibuf); 00160 imb_freetilesImBuf(ibuf); 00161 IMB_freezbufImBuf(ibuf); 00162 IMB_freezbuffloatImBuf(ibuf); 00163 freeencodedbufferImBuf(ibuf); 00164 IMB_metadata_free(ibuf); 00165 MEM_freeN(ibuf); 00166 } 00167 } 00168 } 00169 00170 void IMB_refImBuf(ImBuf *ibuf) 00171 { 00172 ibuf->refcounter++; 00173 } 00174 00175 ImBuf * IMB_makeSingleUser(ImBuf *ibuf) 00176 { 00177 ImBuf * rval; 00178 00179 if (!ibuf || ibuf->refcounter == 0) { return ibuf; } 00180 00181 rval = IMB_dupImBuf(ibuf); 00182 00183 IMB_freeImBuf(ibuf); 00184 00185 return rval; 00186 } 00187 00188 short addzbufImBuf(ImBuf *ibuf) 00189 { 00190 int size; 00191 00192 if(ibuf==NULL) return FALSE; 00193 00194 IMB_freezbufImBuf(ibuf); 00195 00196 size = ibuf->x *ibuf->y *sizeof(unsigned int); 00197 if((ibuf->zbuf = MEM_mapallocN(size, "addzbufImBuf"))) { 00198 ibuf->mall |= IB_zbuf; 00199 ibuf->flags |= IB_zbuf; 00200 return TRUE; 00201 } 00202 00203 return FALSE; 00204 } 00205 00206 short addzbuffloatImBuf(ImBuf *ibuf) 00207 { 00208 int size; 00209 00210 if(ibuf==NULL) return FALSE; 00211 00212 IMB_freezbuffloatImBuf(ibuf); 00213 00214 size = ibuf->x *ibuf->y *sizeof(float); 00215 if((ibuf->zbuf_float = MEM_mapallocN(size, "addzbuffloatImBuf"))) { 00216 ibuf->mall |= IB_zbuffloat; 00217 ibuf->flags |= IB_zbuffloat; 00218 return TRUE; 00219 } 00220 00221 return FALSE; 00222 } 00223 00224 00225 short imb_addencodedbufferImBuf(ImBuf *ibuf) 00226 { 00227 if(ibuf==NULL) return FALSE; 00228 00229 freeencodedbufferImBuf(ibuf); 00230 00231 if(ibuf->encodedbuffersize == 0) 00232 ibuf->encodedbuffersize = 10000; 00233 00234 ibuf->encodedsize = 0; 00235 00236 if((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, "addencodedbufferImBuf"))) { 00237 ibuf->mall |= IB_mem; 00238 ibuf->flags |= IB_mem; 00239 return TRUE; 00240 } 00241 00242 return FALSE; 00243 } 00244 00245 00246 short imb_enlargeencodedbufferImBuf(ImBuf *ibuf) 00247 { 00248 unsigned int newsize, encodedsize; 00249 void *newbuffer; 00250 00251 if(ibuf==NULL) return FALSE; 00252 00253 if(ibuf->encodedbuffersize < ibuf->encodedsize) { 00254 printf("imb_enlargeencodedbufferImBuf: error in parameters\n"); 00255 return FALSE; 00256 } 00257 00258 newsize = 2 *ibuf->encodedbuffersize; 00259 if(newsize < 10000) newsize = 10000; 00260 00261 newbuffer = MEM_mallocN(newsize, "enlargeencodedbufferImBuf"); 00262 if(newbuffer == NULL) return FALSE; 00263 00264 if(ibuf->encodedbuffer) { 00265 memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize); 00266 } else { 00267 ibuf->encodedsize = 0; 00268 } 00269 00270 encodedsize = ibuf->encodedsize; 00271 00272 freeencodedbufferImBuf(ibuf); 00273 00274 ibuf->encodedbuffersize = newsize; 00275 ibuf->encodedsize = encodedsize; 00276 ibuf->encodedbuffer = newbuffer; 00277 ibuf->mall |= IB_mem; 00278 ibuf->flags |= IB_mem; 00279 00280 return TRUE; 00281 } 00282 00283 short imb_addrectfloatImBuf(ImBuf *ibuf) 00284 { 00285 int size; 00286 00287 if(ibuf==NULL) return FALSE; 00288 00289 if(ibuf->rect_float) 00290 imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */ 00291 00292 size = ibuf->x *ibuf->y; 00293 size = size *4 *sizeof(float); 00294 ibuf->channels= 4; 00295 00296 if((ibuf->rect_float = MEM_mapallocN(size, "imb_addrectfloatImBuf"))) { 00297 ibuf->mall |= IB_rectfloat; 00298 ibuf->flags |= IB_rectfloat; 00299 return TRUE; 00300 } 00301 00302 return FALSE; 00303 } 00304 00305 /* question; why also add zbuf? */ 00306 short imb_addrectImBuf(ImBuf *ibuf) 00307 { 00308 int size; 00309 00310 if(ibuf==NULL) return FALSE; 00311 00312 /* don't call imb_freerectImBuf, it frees mipmaps, this call is used only too give float buffers display */ 00313 if(ibuf->rect && (ibuf->mall & IB_rect)) 00314 MEM_freeN(ibuf->rect); 00315 ibuf->rect= NULL; 00316 00317 size = ibuf->x*ibuf->y; 00318 size = size*sizeof(unsigned int); 00319 00320 if((ibuf->rect = MEM_mapallocN(size, "imb_addrectImBuf"))) { 00321 ibuf->mall |= IB_rect; 00322 ibuf->flags |= IB_rect; 00323 if(ibuf->planes > 32) return (addzbufImBuf(ibuf)); 00324 else return TRUE; 00325 } 00326 00327 return FALSE; 00328 } 00329 00330 short imb_addtilesImBuf(ImBuf *ibuf) 00331 { 00332 if(ibuf==NULL) return FALSE; 00333 00334 if(!ibuf->tiles) 00335 if((ibuf->tiles = MEM_callocN(sizeof(unsigned int*)*ibuf->xtiles*ibuf->ytiles, "imb_tiles"))) 00336 ibuf->mall |= IB_tiles; 00337 00338 return (ibuf->tiles != NULL); 00339 } 00340 00341 ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int flags) 00342 { 00343 ImBuf *ibuf; 00344 00345 ibuf = MEM_callocN(sizeof(ImBuf), "ImBuf_struct"); 00346 00347 if(ibuf) { 00348 ibuf->x= x; 00349 ibuf->y= y; 00350 ibuf->planes= planes; 00351 ibuf->ftype= TGA; 00352 ibuf->channels= 4; /* float option, is set to other values when buffers get assigned */ 00353 ibuf->ppm[0]= ibuf->ppm[1]= 150.0 / 0.0254; /* 150dpi -> pixels-per-meter */ 00354 00355 if(flags & IB_rect) { 00356 if(imb_addrectImBuf(ibuf)==FALSE) { 00357 IMB_freeImBuf(ibuf); 00358 return NULL; 00359 } 00360 } 00361 00362 if(flags & IB_rectfloat) { 00363 if(imb_addrectfloatImBuf(ibuf)==FALSE) { 00364 IMB_freeImBuf(ibuf); 00365 return NULL; 00366 } 00367 } 00368 00369 if(flags & IB_zbuf) { 00370 if(addzbufImBuf(ibuf)==FALSE) { 00371 IMB_freeImBuf(ibuf); 00372 return NULL; 00373 } 00374 } 00375 00376 if(flags & IB_zbuffloat) { 00377 if(addzbuffloatImBuf(ibuf)==FALSE) { 00378 IMB_freeImBuf(ibuf); 00379 return NULL; 00380 } 00381 } 00382 } 00383 return (ibuf); 00384 } 00385 00386 /* does no zbuffers? */ 00387 ImBuf *IMB_dupImBuf(ImBuf *ibuf1) 00388 { 00389 ImBuf *ibuf2, tbuf; 00390 int flags = 0; 00391 int a, x, y; 00392 00393 if(ibuf1 == NULL) return NULL; 00394 00395 if(ibuf1->rect) flags |= IB_rect; 00396 if(ibuf1->rect_float) flags |= IB_rectfloat; 00397 00398 x = ibuf1->x; 00399 y = ibuf1->y; 00400 if(ibuf1->flags & IB_fields) y *= 2; 00401 00402 ibuf2 = IMB_allocImBuf(x, y, ibuf1->planes, flags); 00403 if(ibuf2 == NULL) return NULL; 00404 00405 if(flags & IB_rect) 00406 memcpy(ibuf2->rect, ibuf1->rect, x *y *sizeof(int)); 00407 00408 if(flags & IB_rectfloat) 00409 memcpy(ibuf2->rect_float, ibuf1->rect_float, ibuf1->channels *x *y *sizeof(float)); 00410 00411 if(ibuf1->encodedbuffer) { 00412 ibuf2->encodedbuffersize = ibuf1->encodedbuffersize; 00413 if(imb_addencodedbufferImBuf(ibuf2) == FALSE) { 00414 IMB_freeImBuf(ibuf2); 00415 return NULL; 00416 } 00417 00418 memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize); 00419 } 00420 00421 /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */ 00422 tbuf = *ibuf1; 00423 00424 // fix pointers 00425 tbuf.rect = ibuf2->rect; 00426 tbuf.rect_float = ibuf2->rect_float; 00427 tbuf.encodedbuffer = ibuf2->encodedbuffer; 00428 tbuf.zbuf= NULL; 00429 tbuf.zbuf_float= NULL; 00430 for(a=0; a<IB_MIPMAP_LEVELS; a++) 00431 tbuf.mipmap[a]= NULL; 00432 00433 // set malloc flag 00434 tbuf.mall = ibuf2->mall; 00435 tbuf.c_handle = NULL; 00436 tbuf.refcounter = 0; 00437 00438 // for now don't duplicate metadata 00439 tbuf.metadata = NULL; 00440 00441 *ibuf2 = tbuf; 00442 00443 return(ibuf2); 00444 } 00445 00446 #if 0 /* remove? - campbell */ 00447 /* support for cache limiting */ 00448 00449 static void imbuf_cache_destructor(void *data) 00450 { 00451 ImBuf *ibuf = (ImBuf*) data; 00452 00453 imb_freerectImBuf(ibuf); 00454 imb_freerectfloatImBuf(ibuf); 00455 IMB_freezbufImBuf(ibuf); 00456 IMB_freezbuffloatImBuf(ibuf); 00457 freeencodedbufferImBuf(ibuf); 00458 00459 ibuf->c_handle = NULL; 00460 } 00461 00462 00463 static MEM_CacheLimiterC **get_imbuf_cache_limiter(void) 00464 { 00465 static MEM_CacheLimiterC *c = NULL; 00466 00467 if(!c) 00468 c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL); 00469 00470 return &c; 00471 } 00472 #endif