Added new render pass: "Mist".
[blender.git] / source / blender / imbuf / intern / allocimbuf.c
1 /*
2  * allocimbuf.c
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL/BL DUAL 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. The Blender
12  * Foundation also sells licenses for use in proprietary software under
13  * the Blender License.  See http://www.blender.org/BL/ for information
14  * about this.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL/BL DUAL LICENSE BLOCK *****
33  */
34
35 /* It's become a bit messy... Basically, only the IMB_ prefixed files
36  * should remain. */
37
38 #include "IMB_imbuf_types.h"
39
40 #include "imbuf.h"
41 #include "imbuf_patch.h"
42 #include "IMB_imbuf.h"
43
44 #include "IMB_divers.h"
45 #include "IMB_allocimbuf.h"
46 #include "IMB_imginfo.h"
47 #include "MEM_CacheLimiterC-Api.h"
48
49 static unsigned int dfltcmap[16] = {
50         0x00000000, 0xffffffff, 0x777777ff, 0xccccccff, 
51         0xcc3344ff, 0xdd8844ff, 0xccdd44ff, 0x888833ff, 
52         0x338844ff, 0x44dd44ff, 0x44ddccff, 0x3388ccff, 
53         0x8888ddff, 0x4433ccff, 0xcc33ccff, 0xcc88ddff
54 };
55
56 void imb_freeplanesImBuf(struct ImBuf * ibuf)
57 {
58         if (ibuf==NULL) return;
59         if (ibuf->planes){
60                 if (ibuf->mall & IB_planes) MEM_freeN(ibuf->planes);
61         }
62         ibuf->planes = 0;
63         ibuf->mall &= ~IB_planes;
64 }
65
66 void imb_freemipmapImBuf(struct ImBuf * ibuf)
67 {
68         int a;
69         
70         for(a=0; a<IB_MIPMAP_LEVELS; a++) {
71                 if(ibuf->mipmap[a]) IMB_freeImBuf(ibuf->mipmap[a]);
72                 ibuf->mipmap[a]= NULL;
73         }
74 }
75
76 /* any free rect frees mipmaps to be sure, creation is in render on first request */
77 void imb_freerectfloatImBuf(struct ImBuf * ibuf)
78 {
79         if (ibuf==NULL) return;
80         
81         if (ibuf->rect_float) {
82                 if (ibuf->mall & IB_rectfloat) {
83                         MEM_freeN(ibuf->rect_float);
84                         ibuf->rect_float=NULL;
85                 }
86         }
87
88         imb_freemipmapImBuf(ibuf);
89         
90         ibuf->rect_float= NULL;
91         ibuf->mall &= ~IB_rectfloat;
92 }
93
94 /* any free rect frees mipmaps to be sure, creation is in render on first request */
95 void imb_freerectImBuf(struct ImBuf * ibuf)
96 {
97         if (ibuf==NULL) return;
98         
99         if (ibuf->rect) {
100                 if (ibuf->mall & IB_rect) {
101                         MEM_freeN(ibuf->rect);
102                 }
103         }
104         
105         imb_freemipmapImBuf(ibuf);
106         
107         ibuf->rect= NULL;
108         ibuf->mall &= ~IB_rect;
109 }
110
111 static void freeencodedbufferImBuf(struct ImBuf * ibuf)
112 {
113         if (ibuf==NULL) return;
114         if (ibuf->encodedbuffer){
115                 if (ibuf->mall & IB_mem) MEM_freeN(ibuf->encodedbuffer);
116         }
117         ibuf->encodedbuffer = 0;
118         ibuf->encodedbuffersize = 0;
119         ibuf->encodedsize = 0;
120         ibuf->mall &= ~IB_mem;
121 }
122
123 void IMB_freezbufImBuf(struct ImBuf * ibuf)
124 {
125         if (ibuf==NULL) return;
126         if (ibuf->zbuf){
127                 if (ibuf->mall & IB_zbuf) MEM_freeN(ibuf->zbuf);
128         }
129         ibuf->zbuf= NULL;
130         ibuf->mall &= ~IB_zbuf;
131 }
132
133 void IMB_freezbuffloatImBuf(struct ImBuf * ibuf)
134 {
135         if (ibuf==NULL) return;
136         if (ibuf->zbuf_float){
137                 if (ibuf->mall & IB_zbuffloat) MEM_freeN(ibuf->zbuf_float);
138         }
139         ibuf->zbuf_float= NULL;
140         ibuf->mall &= ~IB_zbuffloat;
141 }
142
143 void IMB_freecmapImBuf(struct ImBuf * ibuf)
144 {
145         if (ibuf==NULL) return;
146         if (ibuf->cmap){
147                 if (ibuf->mall & IB_cmap) MEM_freeN(ibuf->cmap);
148         }
149         ibuf->cmap = 0;
150         ibuf->mall &= ~IB_cmap;
151 }
152
153 void IMB_freeImBuf(struct ImBuf * ibuf)
154 {
155         if (ibuf){
156                 if (ibuf->refcounter > 0) {
157                         ibuf->refcounter--;
158                 } else {
159                         imb_freeplanesImBuf(ibuf);
160                         imb_freerectImBuf(ibuf);
161                         imb_freerectfloatImBuf(ibuf);
162                         IMB_freezbufImBuf(ibuf);
163                         IMB_freezbuffloatImBuf(ibuf);
164                         IMB_freecmapImBuf(ibuf);
165                         freeencodedbufferImBuf(ibuf);
166                         IMB_cache_limiter_unmanage(ibuf);
167                         IMB_imginfo_free(ibuf);
168                         MEM_freeN(ibuf);
169                 }
170         }
171 }
172
173 void IMB_refImBuf(struct ImBuf * ibuf)
174 {
175         ibuf->refcounter++;
176 }
177
178 short addzbufImBuf(struct ImBuf * ibuf)
179 {
180         int size;
181         
182         if (ibuf==NULL) return(FALSE);
183         
184         IMB_freezbufImBuf(ibuf);
185         
186         size = ibuf->x * ibuf->y * sizeof(unsigned int);
187         if ( (ibuf->zbuf = MEM_mapallocN(size, "addzbufImBuf")) ){
188                 ibuf->mall |= IB_zbuf;
189                 ibuf->flags |= IB_zbuf;
190                 return (TRUE);
191         }
192         
193         return (FALSE);
194 }
195
196 short addzbuffloatImBuf(struct ImBuf * ibuf)
197 {
198         int size;
199         
200         if (ibuf==NULL) return(FALSE);
201         
202         IMB_freezbuffloatImBuf(ibuf);
203         
204         size = ibuf->x * ibuf->y * sizeof(float);
205         if ( (ibuf->zbuf_float = MEM_mapallocN(size, "addzbuffloatImBuf")) ){
206                 ibuf->mall |= IB_zbuffloat;
207                 ibuf->flags |= IB_zbuffloat;
208                 return (TRUE);
209         }
210         
211         return (FALSE);
212 }
213
214
215 short imb_addencodedbufferImBuf(struct ImBuf * ibuf)
216 {
217         if (ibuf==NULL) return(FALSE);
218
219         freeencodedbufferImBuf(ibuf);
220
221         if (ibuf->encodedbuffersize == 0) 
222                 ibuf->encodedbuffersize = 10000;
223
224         ibuf->encodedsize = 0;
225
226         if ( (ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, "addencodedbufferImBuf") )){
227                 ibuf->mall |= IB_mem;
228                 ibuf->flags |= IB_mem;
229                 return (TRUE);
230         }
231
232         return (FALSE);
233 }
234
235
236 short imb_enlargeencodedbufferImBuf(struct ImBuf * ibuf)
237 {
238         unsigned int newsize, encodedsize;
239         void *newbuffer;
240
241         if (ibuf==NULL) return(FALSE);
242
243         if (ibuf->encodedbuffersize < ibuf->encodedsize) {
244                 printf("imb_enlargeencodedbufferImBuf: error in parameters\n");
245                 return(FALSE);
246         }
247
248         newsize = 2 * ibuf->encodedbuffersize;
249         if (newsize < 10000) newsize = 10000;
250
251         newbuffer = MEM_mallocN(newsize, "enlargeencodedbufferImBuf");
252         if (newbuffer == NULL) return(FALSE);
253
254         if (ibuf->encodedbuffer) {
255                 memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
256         } else {
257                 ibuf->encodedsize = 0;
258         }
259
260         encodedsize = ibuf->encodedsize;
261
262         freeencodedbufferImBuf(ibuf);
263
264         ibuf->encodedbuffersize = newsize;
265         ibuf->encodedsize = encodedsize;
266         ibuf->encodedbuffer = newbuffer;
267         ibuf->mall |= IB_mem;
268         ibuf->flags |= IB_mem;
269
270         return (TRUE);
271 }
272
273 short imb_addrectfloatImBuf(struct ImBuf * ibuf)
274 {
275         int size;
276         
277         if (ibuf==NULL) return(FALSE);
278         
279         imb_freerectfloatImBuf(ibuf);
280         
281         size = ibuf->x * ibuf->y;
282         size = size * 4 * sizeof(float);
283         ibuf->channels= 4;
284         
285         if ( (ibuf->rect_float = MEM_mapallocN(size, "imb_addrectfloatImBuf")) ){
286                 ibuf->mall |= IB_rectfloat;
287                 ibuf->flags |= IB_rectfloat;
288                 return (TRUE);
289         }
290         
291         return (FALSE);
292 }
293
294 /* question; why also add zbuf? */
295 short imb_addrectImBuf(struct ImBuf * ibuf)
296 {
297         int size;
298
299         if (ibuf==NULL) return(FALSE);
300         imb_freerectImBuf(ibuf);
301
302         size = ibuf->x * ibuf->y;
303         size = size * sizeof(unsigned int);
304
305         if ( (ibuf->rect = MEM_mapallocN(size, "imb_addrectImBuf")) ){
306                 ibuf->mall |= IB_rect;
307                 ibuf->flags |= IB_rect;
308                 if (ibuf->depth > 32) return (addzbufImBuf(ibuf));
309                 else return (TRUE);
310         }
311
312         return (FALSE);
313 }
314
315
316 short imb_addcmapImBuf(struct ImBuf *ibuf)
317 {
318         int min;
319         
320         if (ibuf==NULL) return(FALSE);
321         IMB_freecmapImBuf(ibuf);
322
323         imb_checkncols(ibuf);
324         if (ibuf->maxcol == 0) return (TRUE);
325
326         if ( (ibuf->cmap = MEM_callocN(sizeof(unsigned int) * ibuf->maxcol, "imb_addcmapImBuf") ) ){
327                 min = ibuf->maxcol * sizeof(unsigned int);
328                 if (min > sizeof(dfltcmap)) min = sizeof(dfltcmap);
329                 memcpy(ibuf->cmap, dfltcmap, min);
330                 ibuf->mall |= IB_cmap;
331                 ibuf->flags |= IB_cmap;
332                 return (TRUE);
333         }
334
335         return (FALSE);
336 }
337
338
339 short imb_addplanesImBuf(struct ImBuf *ibuf)
340 {
341         int size;
342         short skipx,d,y;
343         unsigned int **planes;
344         unsigned int *point2;
345
346         if (ibuf==NULL) return(FALSE);
347         imb_freeplanesImBuf(ibuf);
348
349         skipx = ((ibuf->x+31) >> 5);
350         ibuf->skipx=skipx;
351         y=ibuf->y;
352         d=ibuf->depth;
353
354         planes = MEM_mallocN( (d*skipx*y)*sizeof(int) + d*sizeof(int *), "imb_addplanesImBuf");
355         
356         ibuf->planes = planes;
357         if (planes==0) return (FALSE);
358
359         point2 = (unsigned int *)(planes+d);
360         size = skipx*y;
361
362         for (;d>0;d--){
363                 *(planes++) = point2;
364                 point2 += size;
365         }
366         ibuf->mall |= IB_planes;
367         ibuf->flags |= IB_planes;
368
369         return (TRUE);
370 }
371
372
373 struct ImBuf *IMB_allocImBuf(short x, short y, uchar d, unsigned int flags, uchar bitmap)
374 {
375         struct ImBuf *ibuf;
376
377         ibuf = MEM_callocN(sizeof(struct ImBuf), "ImBuf_struct");
378         if (bitmap) flags |= IB_planes;
379
380         if (ibuf){
381                 ibuf->x= x;
382                 ibuf->y= y;
383                 ibuf->depth= d;
384                 ibuf->ftype= TGA;
385                 ibuf->channels= 4;      /* float option, is set to other values when buffers get assigned */
386                 
387                 if (flags & IB_rect){
388                         if (imb_addrectImBuf(ibuf)==FALSE){
389                                 IMB_freeImBuf(ibuf);
390                                 return NULL;
391                         }
392                 }
393                 
394                 if (flags & IB_rectfloat){
395                         if (imb_addrectfloatImBuf(ibuf)==FALSE){
396                                 IMB_freeImBuf(ibuf);
397                                 return NULL;
398                         }
399                 }
400                 
401                 if (flags & IB_zbuf){
402                         if (addzbufImBuf(ibuf)==FALSE){
403                                 IMB_freeImBuf(ibuf);
404                                 return NULL;
405                         }
406                 }
407                 
408                 if (flags & IB_zbuffloat){
409                         if (addzbuffloatImBuf(ibuf)==FALSE){
410                                 IMB_freeImBuf(ibuf);
411                                 return NULL;
412                         }
413                 }
414                 
415                 if (flags & IB_planes){
416                         if (imb_addplanesImBuf(ibuf)==FALSE){
417                                 IMB_freeImBuf(ibuf);
418                                 return NULL;
419                         }
420                 }
421         }
422         return (ibuf);
423 }
424
425 /* does no zbuffers? */
426 struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
427 {
428         struct ImBuf *ibuf2, tbuf;
429         int flags = 0;
430         int a, x, y;
431         
432         if (ibuf1 == NULL) return NULL;
433
434         if (ibuf1->rect) flags |= IB_rect;
435         if (ibuf1->rect_float) flags |= IB_rectfloat;
436         if (ibuf1->planes) flags |= IB_planes;
437
438         x = ibuf1->x;
439         y = ibuf1->y;
440         if (ibuf1->flags & IB_fields) y *= 2;
441         
442         ibuf2 = IMB_allocImBuf(x, y, ibuf1->depth, flags, 0);
443         if (ibuf2 == NULL) return NULL;
444
445         if (flags & IB_rect)
446                 memcpy(ibuf2->rect, ibuf1->rect, x * y * sizeof(int));
447         
448         if (flags & IB_rectfloat)
449                 memcpy(ibuf2->rect_float, ibuf1->rect_float, ibuf1->channels * x * y * sizeof(float));
450
451         if (flags & IB_planes) 
452                 memcpy(*(ibuf2->planes),*(ibuf1->planes),ibuf1->depth * ibuf1->skipx * y * sizeof(int));
453
454         if (ibuf1->encodedbuffer) {
455                 ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
456                 if (imb_addencodedbufferImBuf(ibuf2) == FALSE) {
457                         IMB_freeImBuf(ibuf2);
458                         return NULL;
459                 }
460
461                 memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
462         }
463
464         /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
465         tbuf = *ibuf1;
466         
467         // fix pointers 
468         tbuf.rect               = ibuf2->rect;
469         tbuf.rect_float = ibuf2->rect_float;
470         tbuf.planes             = ibuf2->planes;
471         tbuf.cmap               = ibuf2->cmap;
472         tbuf.encodedbuffer = ibuf2->encodedbuffer;
473         tbuf.zbuf= NULL;
474         tbuf.zbuf_float= NULL;
475         for(a=0; a<IB_MIPMAP_LEVELS; a++)
476                 tbuf.mipmap[a]= NULL;
477         
478         // set malloc flag
479         tbuf.mall               = ibuf2->mall;
480         tbuf.c_handle           = 0;
481
482         // for now don't duplicate image info
483         tbuf.img_info = 0;
484
485         *ibuf2 = tbuf;
486         
487         if (ibuf1->cmap){
488                 imb_addcmapImBuf(ibuf2);
489                 if (ibuf2->cmap) memcpy(ibuf2->cmap,ibuf1->cmap,ibuf2->maxcol * sizeof(int));
490         }
491
492         return(ibuf2);
493 }
494
495 /* support for cache limiting */
496
497 static void imbuf_cache_destructor(void * data)
498 {
499         struct ImBuf * ibuf = (struct ImBuf*) data;
500
501         imb_freeplanesImBuf(ibuf);
502         imb_freerectImBuf(ibuf);
503         imb_freerectfloatImBuf(ibuf);
504         IMB_freezbufImBuf(ibuf);
505         IMB_freezbuffloatImBuf(ibuf);
506         IMB_freecmapImBuf(ibuf);
507         freeencodedbufferImBuf(ibuf);
508
509         ibuf->c_handle = 0;
510 }
511
512 static MEM_CacheLimiterC ** get_imbuf_cache_limiter()
513 {
514         static MEM_CacheLimiterC * c = 0;
515         if (!c) {
516                 c = new_MEM_CacheLimiter(imbuf_cache_destructor);
517         }
518         return &c;
519 }
520
521 void IMB_free_cache_limiter()
522 {
523         delete_MEM_CacheLimiter(*get_imbuf_cache_limiter());
524         *get_imbuf_cache_limiter() = 0;
525 }
526
527 void IMB_cache_limiter_insert(struct ImBuf * i)
528 {
529         if (!i->c_handle) {
530                 i->c_handle = MEM_CacheLimiter_insert(
531                         *get_imbuf_cache_limiter(), i);
532                 MEM_CacheLimiter_ref(i->c_handle);
533                 MEM_CacheLimiter_enforce_limits(
534                         *get_imbuf_cache_limiter());
535                 MEM_CacheLimiter_unref(i->c_handle);
536         }
537 }
538
539 void IMB_cache_limiter_unmanage(struct ImBuf * i)
540 {
541         if (i->c_handle) {
542                 MEM_CacheLimiter_unmanage(i->c_handle);
543                 i->c_handle = 0;
544         }
545 }
546
547 void IMB_cache_limiter_touch(struct ImBuf * i)
548 {
549         if (i->c_handle) {
550                 MEM_CacheLimiter_touch(i->c_handle);
551         }
552 }
553
554 void IMB_cache_limiter_ref(struct ImBuf * i)
555 {
556         if (i->c_handle) {
557                 MEM_CacheLimiter_ref(i->c_handle);
558         }
559 }
560
561 void IMB_cache_limiter_unref(struct ImBuf * i)
562 {
563         if (i->c_handle) {
564                 MEM_CacheLimiter_unref(i->c_handle);
565         }
566 }
567
568 int IMB_cache_limiter_get_refcount(struct ImBuf * i)
569 {
570         if (i->c_handle) {
571                 return MEM_CacheLimiter_get_refcount(i->c_handle);
572         }
573         return 0;
574 }