remove unused vars
[blender.git] / source / blender / imbuf / intern / allocimbuf.c
1 /*
2  * allocimbuf.c
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
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.
12  *
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.
17  *
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.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30  */
31
32 /** \file blender/imbuf/intern/allocimbuf.c
33  *  \ingroup imbuf
34  */
35
36
37 /* It's become a bit messy... Basically, only the IMB_ prefixed files
38  * should remain. */
39
40 #include <stddef.h>
41
42 #include "IMB_imbuf.h"
43 #include "IMB_imbuf_types.h"
44
45 #include "IMB_allocimbuf.h"
46 #include "IMB_filetype.h"
47 #include "IMB_metadata.h"
48
49 #include "imbuf.h"
50
51 #include "MEM_CacheLimiterC-Api.h"
52 #include "MEM_guardedalloc.h"
53
54 void imb_freemipmapImBuf(ImBuf *ibuf)
55 {
56         int a;
57         
58         for(a=1; a<ibuf->miptot; a++) {
59                 if(ibuf->mipmap[a-1])
60                         IMB_freeImBuf(ibuf->mipmap[a-1]);
61                 ibuf->mipmap[a-1]= NULL;
62         }
63
64         ibuf->miptot= 0;
65 }
66
67 /* any free rect frees mipmaps to be sure, creation is in render on first request */
68 void imb_freerectfloatImBuf(ImBuf *ibuf)
69 {
70         if(ibuf==NULL) return;
71         
72         if(ibuf->rect_float && (ibuf->mall & IB_rectfloat)) {
73                 MEM_freeN(ibuf->rect_float);
74                 ibuf->rect_float=NULL;
75         }
76
77         imb_freemipmapImBuf(ibuf);
78         
79         ibuf->rect_float= NULL;
80         ibuf->mall &= ~IB_rectfloat;
81 }
82
83 /* any free rect frees mipmaps to be sure, creation is in render on first request */
84 void imb_freerectImBuf(ImBuf *ibuf)
85 {
86         if(ibuf==NULL) return;
87         
88         if(ibuf->crect)
89                 MEM_freeN(ibuf->crect);
90
91         if(ibuf->rect && (ibuf->mall & IB_rect))
92                 MEM_freeN(ibuf->rect);
93         
94         imb_freemipmapImBuf(ibuf);
95         
96         ibuf->rect= NULL;
97         ibuf->crect= NULL;
98         ibuf->mall &= ~IB_rect;
99 }
100
101 void imb_freetilesImBuf(ImBuf *ibuf)
102 {
103         int tx, ty;
104
105         if(ibuf==NULL) return;
106
107         if(ibuf->tiles && (ibuf->mall & IB_tiles)) {
108                 for(ty=0; ty<ibuf->ytiles; ty++) {
109                         for(tx=0; tx<ibuf->xtiles; tx++) {
110                                 if(ibuf->tiles[ibuf->xtiles*ty + tx]) {
111                                         imb_tile_cache_tile_free(ibuf, tx, ty);
112                                         MEM_freeN(ibuf->tiles[ibuf->xtiles*ty + tx]);
113                                 }
114                         }
115                 }
116
117                 MEM_freeN(ibuf->tiles);
118         }
119
120         ibuf->tiles= NULL;
121         ibuf->mall &= ~IB_tiles;
122 }
123
124 static void freeencodedbufferImBuf(ImBuf *ibuf)
125 {
126         if(ibuf==NULL) return;
127
128         if(ibuf->encodedbuffer && (ibuf->mall & IB_mem))
129                 MEM_freeN(ibuf->encodedbuffer);
130
131         ibuf->encodedbuffer = NULL;
132         ibuf->encodedbuffersize = 0;
133         ibuf->encodedsize = 0;
134         ibuf->mall &= ~IB_mem;
135 }
136
137 void IMB_freezbufImBuf(ImBuf *ibuf)
138 {
139         if(ibuf==NULL) return;
140
141         if(ibuf->zbuf && (ibuf->mall & IB_zbuf))
142                 MEM_freeN(ibuf->zbuf);
143
144         ibuf->zbuf= NULL;
145         ibuf->mall &= ~IB_zbuf;
146 }
147
148 void IMB_freezbuffloatImBuf(ImBuf *ibuf)
149 {
150         if(ibuf==NULL) return;
151
152         if(ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat))
153                 MEM_freeN(ibuf->zbuf_float);
154
155         ibuf->zbuf_float= NULL;
156         ibuf->mall &= ~IB_zbuffloat;
157 }
158
159 void IMB_freeImBuf(ImBuf *ibuf)
160 {
161         if(ibuf) {
162                 if(ibuf->refcounter > 0) {
163                         ibuf->refcounter--;
164                 }
165                 else {
166                         imb_freerectImBuf(ibuf);
167                         imb_freerectfloatImBuf(ibuf);
168                         imb_freetilesImBuf(ibuf);
169                         IMB_freezbufImBuf(ibuf);
170                         IMB_freezbuffloatImBuf(ibuf);
171                         freeencodedbufferImBuf(ibuf);
172                         IMB_cache_limiter_unmanage(ibuf);
173                         IMB_metadata_free(ibuf);
174                         MEM_freeN(ibuf);
175                 }
176         }
177 }
178
179 void IMB_refImBuf(ImBuf *ibuf)
180 {
181         ibuf->refcounter++;
182 }
183
184 short addzbufImBuf(ImBuf *ibuf)
185 {
186         int size;
187         
188         if(ibuf==NULL) return FALSE;
189         
190         IMB_freezbufImBuf(ibuf);
191         
192         size = ibuf->x *ibuf->y *sizeof(unsigned int);
193         if((ibuf->zbuf = MEM_mapallocN(size, "addzbufImBuf"))) {
194                 ibuf->mall |= IB_zbuf;
195                 ibuf->flags |= IB_zbuf;
196                 return TRUE;
197         }
198         
199         return FALSE;
200 }
201
202 short addzbuffloatImBuf(ImBuf *ibuf)
203 {
204         int size;
205         
206         if(ibuf==NULL) return FALSE;
207         
208         IMB_freezbuffloatImBuf(ibuf);
209         
210         size = ibuf->x *ibuf->y *sizeof(float);
211         if((ibuf->zbuf_float = MEM_mapallocN(size, "addzbuffloatImBuf"))) {
212                 ibuf->mall |= IB_zbuffloat;
213                 ibuf->flags |= IB_zbuffloat;
214                 return TRUE;
215         }
216         
217         return FALSE;
218 }
219
220
221 short imb_addencodedbufferImBuf(ImBuf *ibuf)
222 {
223         if(ibuf==NULL) return FALSE;
224
225         freeencodedbufferImBuf(ibuf);
226
227         if(ibuf->encodedbuffersize == 0) 
228                 ibuf->encodedbuffersize = 10000;
229
230         ibuf->encodedsize = 0;
231
232         if((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, "addencodedbufferImBuf"))) {
233                 ibuf->mall |= IB_mem;
234                 ibuf->flags |= IB_mem;
235                 return TRUE;
236         }
237
238         return FALSE;
239 }
240
241
242 short imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
243 {
244         unsigned int newsize, encodedsize;
245         void *newbuffer;
246
247         if(ibuf==NULL) return FALSE;
248
249         if(ibuf->encodedbuffersize < ibuf->encodedsize) {
250                 printf("imb_enlargeencodedbufferImBuf: error in parameters\n");
251                 return FALSE;
252         }
253
254         newsize = 2 *ibuf->encodedbuffersize;
255         if(newsize < 10000) newsize = 10000;
256
257         newbuffer = MEM_mallocN(newsize, "enlargeencodedbufferImBuf");
258         if(newbuffer == NULL) return FALSE;
259
260         if(ibuf->encodedbuffer) {
261                 memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
262         } else {
263                 ibuf->encodedsize = 0;
264         }
265
266         encodedsize = ibuf->encodedsize;
267
268         freeencodedbufferImBuf(ibuf);
269
270         ibuf->encodedbuffersize = newsize;
271         ibuf->encodedsize = encodedsize;
272         ibuf->encodedbuffer = newbuffer;
273         ibuf->mall |= IB_mem;
274         ibuf->flags |= IB_mem;
275
276         return TRUE;
277 }
278
279 short imb_addrectfloatImBuf(ImBuf *ibuf)
280 {
281         int size;
282         
283         if(ibuf==NULL) return FALSE;
284         
285         if(ibuf->rect_float)
286                 imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */
287         
288         size = ibuf->x *ibuf->y;
289         size = size *4 *sizeof(float);
290         ibuf->channels= 4;
291         
292         if((ibuf->rect_float = MEM_mapallocN(size, "imb_addrectfloatImBuf"))) {
293                 ibuf->mall |= IB_rectfloat;
294                 ibuf->flags |= IB_rectfloat;
295                 return TRUE;
296         }
297         
298         return FALSE;
299 }
300
301 /* question; why also add zbuf? */
302 short imb_addrectImBuf(ImBuf *ibuf)
303 {
304         int size;
305
306         if(ibuf==NULL) return FALSE;
307         
308         /* don't call imb_freerectImBuf, it frees mipmaps, this call is used only too give float buffers display */
309         if(ibuf->rect && (ibuf->mall & IB_rect))
310                 MEM_freeN(ibuf->rect);
311         ibuf->rect= NULL;
312         
313         size = ibuf->x*ibuf->y;
314         size = size*sizeof(unsigned int);
315
316         if((ibuf->rect = MEM_mapallocN(size, "imb_addrectImBuf"))) {
317                 ibuf->mall |= IB_rect;
318                 ibuf->flags |= IB_rect;
319                 if(ibuf->depth > 32) return (addzbufImBuf(ibuf));
320                 else return TRUE;
321         }
322
323         return FALSE;
324 }
325
326 short imb_addtilesImBuf(ImBuf *ibuf)
327 {
328         if(ibuf==NULL) return FALSE;
329
330         if(!ibuf->tiles)
331                 if((ibuf->tiles = MEM_callocN(sizeof(unsigned int*)*ibuf->xtiles*ibuf->ytiles, "imb_tiles")))
332                         ibuf->mall |= IB_tiles;
333
334         return (ibuf->tiles != NULL);
335 }
336
337 ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar d, unsigned int flags)
338 {
339         ImBuf *ibuf;
340
341         ibuf = MEM_callocN(sizeof(ImBuf), "ImBuf_struct");
342
343         if(ibuf) {
344                 ibuf->x= x;
345                 ibuf->y= y;
346                 ibuf->depth= d;
347                 ibuf->ftype= TGA;
348                 ibuf->channels= 4;      /* float option, is set to other values when buffers get assigned */
349                 
350                 if(flags & IB_rect) {
351                         if(imb_addrectImBuf(ibuf)==FALSE) {
352                                 IMB_freeImBuf(ibuf);
353                                 return NULL;
354                         }
355                 }
356                 
357                 if(flags & IB_rectfloat) {
358                         if(imb_addrectfloatImBuf(ibuf)==FALSE) {
359                                 IMB_freeImBuf(ibuf);
360                                 return NULL;
361                         }
362                 }
363                 
364                 if(flags & IB_zbuf) {
365                         if(addzbufImBuf(ibuf)==FALSE) {
366                                 IMB_freeImBuf(ibuf);
367                                 return NULL;
368                         }
369                 }
370                 
371                 if(flags & IB_zbuffloat) {
372                         if(addzbuffloatImBuf(ibuf)==FALSE) {
373                                 IMB_freeImBuf(ibuf);
374                                 return NULL;
375                         }
376                 }
377         }
378         return (ibuf);
379 }
380
381 /* does no zbuffers? */
382 ImBuf *IMB_dupImBuf(ImBuf *ibuf1)
383 {
384         ImBuf *ibuf2, tbuf;
385         int flags = 0;
386         int a, x, y;
387         
388         if(ibuf1 == NULL) return NULL;
389
390         if(ibuf1->rect) flags |= IB_rect;
391         if(ibuf1->rect_float) flags |= IB_rectfloat;
392
393         x = ibuf1->x;
394         y = ibuf1->y;
395         if(ibuf1->flags & IB_fields) y *= 2;
396         
397         ibuf2 = IMB_allocImBuf(x, y, ibuf1->depth, flags);
398         if(ibuf2 == NULL) return NULL;
399
400         if(flags & IB_rect)
401                 memcpy(ibuf2->rect, ibuf1->rect, x *y *sizeof(int));
402         
403         if(flags & IB_rectfloat)
404                 memcpy(ibuf2->rect_float, ibuf1->rect_float, ibuf1->channels *x *y *sizeof(float));
405
406         if(ibuf1->encodedbuffer) {
407                 ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
408                 if(imb_addencodedbufferImBuf(ibuf2) == FALSE) {
409                         IMB_freeImBuf(ibuf2);
410                         return NULL;
411                 }
412
413                 memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
414         }
415
416         /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
417         tbuf = *ibuf1;
418         
419         // fix pointers 
420         tbuf.rect               = ibuf2->rect;
421         tbuf.rect_float = ibuf2->rect_float;
422         tbuf.encodedbuffer = ibuf2->encodedbuffer;
423         tbuf.zbuf= NULL;
424         tbuf.zbuf_float= NULL;
425         for(a=0; a<IB_MIPMAP_LEVELS; a++)
426                 tbuf.mipmap[a]= NULL;
427         
428         // set malloc flag
429         tbuf.mall               = ibuf2->mall;
430         tbuf.c_handle           = NULL;
431         tbuf.refcounter         = 0;
432
433         // for now don't duplicate metadata
434         tbuf.metadata = NULL;
435
436         *ibuf2 = tbuf;
437         
438         return(ibuf2);
439 }
440
441 /* support for cache limiting */
442
443 static void imbuf_cache_destructor(void *data)
444 {
445         ImBuf *ibuf = (ImBuf*) data;
446
447         imb_freerectImBuf(ibuf);
448         imb_freerectfloatImBuf(ibuf);
449         IMB_freezbufImBuf(ibuf);
450         IMB_freezbuffloatImBuf(ibuf);
451         freeencodedbufferImBuf(ibuf);
452
453         ibuf->c_handle = NULL;
454 }
455
456 static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
457 {
458         static MEM_CacheLimiterC *c = NULL;
459
460         if(!c)
461                 c = new_MEM_CacheLimiter(imbuf_cache_destructor);
462
463         return &c;
464 }
465
466 void IMB_free_cache_limiter(void)
467 {
468         delete_MEM_CacheLimiter(*get_imbuf_cache_limiter());
469         *get_imbuf_cache_limiter() = NULL;
470 }
471
472 void IMB_cache_limiter_insert(ImBuf *i)
473 {
474         if(!i->c_handle) {
475                 i->c_handle = MEM_CacheLimiter_insert(
476                         *get_imbuf_cache_limiter(), i);
477                 MEM_CacheLimiter_ref(i->c_handle);
478                 MEM_CacheLimiter_enforce_limits(
479                         *get_imbuf_cache_limiter());
480                 MEM_CacheLimiter_unref(i->c_handle);
481         }
482 }
483
484 void IMB_cache_limiter_unmanage(ImBuf *i)
485 {
486         if(i->c_handle) {
487                 MEM_CacheLimiter_unmanage(i->c_handle);
488                 i->c_handle = NULL;
489         }
490 }
491
492 void IMB_cache_limiter_touch(ImBuf *i)
493 {
494         if(i->c_handle)
495                 MEM_CacheLimiter_touch(i->c_handle);
496 }
497
498 void IMB_cache_limiter_ref(ImBuf *i)
499 {
500         if(i->c_handle)
501                 MEM_CacheLimiter_ref(i->c_handle);
502 }
503
504 void IMB_cache_limiter_unref(ImBuf *i)
505 {
506         if(i->c_handle)
507                 MEM_CacheLimiter_unref(i->c_handle);
508 }
509
510 int IMB_cache_limiter_get_refcount(ImBuf *i)
511 {
512         if(i->c_handle)
513                 return MEM_CacheLimiter_get_refcount(i->c_handle);
514
515         return 0;
516 }
517