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