6 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
22 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23 * All rights reserved.
25 * The Original Code is: all of this file.
27 * Contributor(s): none yet.
29 * ***** END GPL LICENSE BLOCK *****
32 /* It's become a bit messy... Basically, only the IMB_ prefixed files
37 #include "IMB_imbuf.h"
38 #include "IMB_imbuf_types.h"
40 #include "IMB_allocimbuf.h"
41 #include "IMB_filetype.h"
42 #include "IMB_metadata.h"
46 #include "MEM_CacheLimiterC-Api.h"
47 #include "MEM_guardedalloc.h"
49 void imb_freemipmapImBuf(ImBuf *ibuf)
53 for(a=1; a<ibuf->miptot; a++) {
55 IMB_freeImBuf(ibuf->mipmap[a-1]);
56 ibuf->mipmap[a-1]= NULL;
62 /* any free rect frees mipmaps to be sure, creation is in render on first request */
63 void imb_freerectfloatImBuf(ImBuf *ibuf)
65 if(ibuf==NULL) return;
67 if(ibuf->rect_float && (ibuf->mall & IB_rectfloat)) {
68 MEM_freeN(ibuf->rect_float);
69 ibuf->rect_float=NULL;
72 imb_freemipmapImBuf(ibuf);
74 ibuf->rect_float= NULL;
75 ibuf->mall &= ~IB_rectfloat;
78 /* any free rect frees mipmaps to be sure, creation is in render on first request */
79 void imb_freerectImBuf(ImBuf *ibuf)
81 if(ibuf==NULL) return;
84 MEM_freeN(ibuf->crect);
86 if(ibuf->rect && (ibuf->mall & IB_rect))
87 MEM_freeN(ibuf->rect);
89 imb_freemipmapImBuf(ibuf);
93 ibuf->mall &= ~IB_rect;
96 void imb_freetilesImBuf(ImBuf *ibuf)
100 if(ibuf==NULL) return;
102 if(ibuf->tiles && (ibuf->mall & IB_tiles)) {
103 for(ty=0; ty<ibuf->ytiles; ty++) {
104 for(tx=0; tx<ibuf->xtiles; tx++) {
105 if(ibuf->tiles[ibuf->xtiles*ty + tx]) {
106 imb_tile_cache_tile_free(ibuf, tx, ty);
107 MEM_freeN(ibuf->tiles[ibuf->xtiles*ty + tx]);
112 MEM_freeN(ibuf->tiles);
116 ibuf->mall &= ~IB_tiles;
119 static void freeencodedbufferImBuf(ImBuf *ibuf)
121 if(ibuf==NULL) return;
123 if(ibuf->encodedbuffer && (ibuf->mall & IB_mem))
124 MEM_freeN(ibuf->encodedbuffer);
126 ibuf->encodedbuffer = 0;
127 ibuf->encodedbuffersize = 0;
128 ibuf->encodedsize = 0;
129 ibuf->mall &= ~IB_mem;
132 void IMB_freezbufImBuf(ImBuf *ibuf)
134 if(ibuf==NULL) return;
136 if(ibuf->zbuf && (ibuf->mall & IB_zbuf))
137 MEM_freeN(ibuf->zbuf);
140 ibuf->mall &= ~IB_zbuf;
143 void IMB_freezbuffloatImBuf(ImBuf *ibuf)
145 if(ibuf==NULL) return;
147 if(ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat))
148 MEM_freeN(ibuf->zbuf_float);
150 ibuf->zbuf_float= NULL;
151 ibuf->mall &= ~IB_zbuffloat;
154 void IMB_freeImBuf(ImBuf *ibuf)
157 if(ibuf->refcounter > 0) {
161 imb_freerectImBuf(ibuf);
162 imb_freerectfloatImBuf(ibuf);
163 imb_freetilesImBuf(ibuf);
164 IMB_freezbufImBuf(ibuf);
165 IMB_freezbuffloatImBuf(ibuf);
166 freeencodedbufferImBuf(ibuf);
167 IMB_cache_limiter_unmanage(ibuf);
168 IMB_metadata_free(ibuf);
174 void IMB_refImBuf(ImBuf *ibuf)
179 short addzbufImBuf(ImBuf *ibuf)
183 if(ibuf==NULL) return FALSE;
185 IMB_freezbufImBuf(ibuf);
187 size = ibuf->x *ibuf->y *sizeof(unsigned int);
188 if((ibuf->zbuf = MEM_mapallocN(size, "addzbufImBuf"))) {
189 ibuf->mall |= IB_zbuf;
190 ibuf->flags |= IB_zbuf;
197 short addzbuffloatImBuf(ImBuf *ibuf)
201 if(ibuf==NULL) return FALSE;
203 IMB_freezbuffloatImBuf(ibuf);
205 size = ibuf->x *ibuf->y *sizeof(float);
206 if((ibuf->zbuf_float = MEM_mapallocN(size, "addzbuffloatImBuf"))) {
207 ibuf->mall |= IB_zbuffloat;
208 ibuf->flags |= IB_zbuffloat;
216 short imb_addencodedbufferImBuf(ImBuf *ibuf)
218 if(ibuf==NULL) return FALSE;
220 freeencodedbufferImBuf(ibuf);
222 if(ibuf->encodedbuffersize == 0)
223 ibuf->encodedbuffersize = 10000;
225 ibuf->encodedsize = 0;
227 if((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, "addencodedbufferImBuf"))) {
228 ibuf->mall |= IB_mem;
229 ibuf->flags |= IB_mem;
237 short imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
239 unsigned int newsize, encodedsize;
242 if(ibuf==NULL) return FALSE;
244 if(ibuf->encodedbuffersize < ibuf->encodedsize) {
245 printf("imb_enlargeencodedbufferImBuf: error in parameters\n");
249 newsize = 2 *ibuf->encodedbuffersize;
250 if(newsize < 10000) newsize = 10000;
252 newbuffer = MEM_mallocN(newsize, "enlargeencodedbufferImBuf");
253 if(newbuffer == NULL) return FALSE;
255 if(ibuf->encodedbuffer) {
256 memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
258 ibuf->encodedsize = 0;
261 encodedsize = ibuf->encodedsize;
263 freeencodedbufferImBuf(ibuf);
265 ibuf->encodedbuffersize = newsize;
266 ibuf->encodedsize = encodedsize;
267 ibuf->encodedbuffer = newbuffer;
268 ibuf->mall |= IB_mem;
269 ibuf->flags |= IB_mem;
274 short imb_addrectfloatImBuf(ImBuf *ibuf)
278 if(ibuf==NULL) return FALSE;
281 imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */
283 size = ibuf->x *ibuf->y;
284 size = size *4 *sizeof(float);
287 if((ibuf->rect_float = MEM_mapallocN(size, "imb_addrectfloatImBuf"))) {
288 ibuf->mall |= IB_rectfloat;
289 ibuf->flags |= IB_rectfloat;
296 /* question; why also add zbuf? */
297 short imb_addrectImBuf(ImBuf *ibuf)
301 if(ibuf==NULL) return FALSE;
302 imb_freerectImBuf(ibuf);
304 size = ibuf->x*ibuf->y;
305 size = size*sizeof(unsigned int);
307 if((ibuf->rect = MEM_mapallocN(size, "imb_addrectImBuf"))) {
308 ibuf->mall |= IB_rect;
309 ibuf->flags |= IB_rect;
310 if(ibuf->depth > 32) return (addzbufImBuf(ibuf));
317 short imb_addtilesImBuf(ImBuf *ibuf)
319 if(ibuf==NULL) return FALSE;
322 if((ibuf->tiles = MEM_callocN(sizeof(unsigned int*)*ibuf->xtiles*ibuf->ytiles, "imb_tiles")))
323 ibuf->mall |= IB_tiles;
325 return (ibuf->tiles != NULL);
328 ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar d, unsigned int flags)
332 ibuf = MEM_callocN(sizeof(ImBuf), "ImBuf_struct");
339 ibuf->channels= 4; /* float option, is set to other values when buffers get assigned */
341 if(flags & IB_rect) {
342 if(imb_addrectImBuf(ibuf)==FALSE) {
348 if(flags & IB_rectfloat) {
349 if(imb_addrectfloatImBuf(ibuf)==FALSE) {
355 if(flags & IB_zbuf) {
356 if(addzbufImBuf(ibuf)==FALSE) {
362 if(flags & IB_zbuffloat) {
363 if(addzbuffloatImBuf(ibuf)==FALSE) {
372 /* does no zbuffers? */
373 ImBuf *IMB_dupImBuf(ImBuf *ibuf1)
379 if(ibuf1 == NULL) return NULL;
381 if(ibuf1->rect) flags |= IB_rect;
382 if(ibuf1->rect_float) flags |= IB_rectfloat;
386 if(ibuf1->flags & IB_fields) y *= 2;
388 ibuf2 = IMB_allocImBuf(x, y, ibuf1->depth, flags);
389 if(ibuf2 == NULL) return NULL;
392 memcpy(ibuf2->rect, ibuf1->rect, x *y *sizeof(int));
394 if(flags & IB_rectfloat)
395 memcpy(ibuf2->rect_float, ibuf1->rect_float, ibuf1->channels *x *y *sizeof(float));
397 if(ibuf1->encodedbuffer) {
398 ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
399 if(imb_addencodedbufferImBuf(ibuf2) == FALSE) {
400 IMB_freeImBuf(ibuf2);
404 memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
407 /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
411 tbuf.rect = ibuf2->rect;
412 tbuf.rect_float = ibuf2->rect_float;
413 tbuf.encodedbuffer = ibuf2->encodedbuffer;
415 tbuf.zbuf_float= NULL;
416 for(a=0; a<IB_MIPMAP_LEVELS; a++)
417 tbuf.mipmap[a]= NULL;
420 tbuf.mall = ibuf2->mall;
424 // for now don't duplicate metadata
432 /* support for cache limiting */
434 static void imbuf_cache_destructor(void *data)
436 ImBuf *ibuf = (ImBuf*) data;
438 imb_freerectImBuf(ibuf);
439 imb_freerectfloatImBuf(ibuf);
440 IMB_freezbufImBuf(ibuf);
441 IMB_freezbuffloatImBuf(ibuf);
442 freeencodedbufferImBuf(ibuf);
447 static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
449 static MEM_CacheLimiterC *c = 0;
452 c = new_MEM_CacheLimiter(imbuf_cache_destructor);
457 void IMB_free_cache_limiter()
459 delete_MEM_CacheLimiter(*get_imbuf_cache_limiter());
460 *get_imbuf_cache_limiter() = 0;
463 void IMB_cache_limiter_insert(ImBuf *i)
466 i->c_handle = MEM_CacheLimiter_insert(
467 *get_imbuf_cache_limiter(), i);
468 MEM_CacheLimiter_ref(i->c_handle);
469 MEM_CacheLimiter_enforce_limits(
470 *get_imbuf_cache_limiter());
471 MEM_CacheLimiter_unref(i->c_handle);
475 void IMB_cache_limiter_unmanage(ImBuf *i)
478 MEM_CacheLimiter_unmanage(i->c_handle);
483 void IMB_cache_limiter_touch(ImBuf *i)
486 MEM_CacheLimiter_touch(i->c_handle);
489 void IMB_cache_limiter_ref(ImBuf *i)
492 MEM_CacheLimiter_ref(i->c_handle);
495 void IMB_cache_limiter_unref(ImBuf *i)
498 MEM_CacheLimiter_unref(i->c_handle);
501 int IMB_cache_limiter_get_refcount(ImBuf *i)
504 return MEM_CacheLimiter_get_refcount(i->c_handle);