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