Add BLI_utildefines.h for __func__ (necessary for MSVC).
[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 #include "IMB_colormanagement_intern.h"
45
46 #include "imbuf.h"
47
48 #include "MEM_guardedalloc.h"
49 #include "MEM_CacheLimiterC-Api.h"
50
51 #include "BLI_utildefines.h"
52
53 void imb_freemipmapImBuf(ImBuf *ibuf)
54 {
55         int a;
56         
57         for (a = 1; a < ibuf->miptot; a++) {
58                 if (ibuf->mipmap[a - 1])
59                         IMB_freeImBuf(ibuf->mipmap[a - 1]);
60                 ibuf->mipmap[a - 1] = NULL;
61         }
62
63         ibuf->miptot = 0;
64 }
65
66 /* any free rect frees mipmaps to be sure, creation is in render on first request */
67 void imb_freerectfloatImBuf(ImBuf *ibuf)
68 {
69         if (ibuf == NULL) return;
70         
71         if (ibuf->rect_float && (ibuf->mall & IB_rectfloat)) {
72                 MEM_freeN(ibuf->rect_float);
73                 ibuf->rect_float = NULL;
74         }
75
76         imb_freemipmapImBuf(ibuf);
77         
78         ibuf->rect_float = NULL;
79         ibuf->mall &= ~IB_rectfloat;
80 }
81
82 /* any free rect frees mipmaps to be sure, creation is in render on first request */
83 void imb_freerectImBuf(ImBuf *ibuf)
84 {
85         if (ibuf == NULL) return;
86
87         if (ibuf->rect && (ibuf->mall & IB_rect))
88                 MEM_freeN(ibuf->rect);
89         ibuf->rect = NULL;
90         
91         imb_freemipmapImBuf(ibuf);
92
93         ibuf->mall &= ~IB_rect;
94 }
95
96 void imb_freetilesImBuf(ImBuf *ibuf)
97 {
98         int tx, ty;
99
100         if (ibuf == NULL) return;
101
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]);
108                                 }
109                         }
110                 }
111
112                 MEM_freeN(ibuf->tiles);
113         }
114
115         ibuf->tiles = NULL;
116         ibuf->mall &= ~IB_tiles;
117 }
118
119 static void freeencodedbufferImBuf(ImBuf *ibuf)
120 {
121         if (ibuf == NULL) return;
122
123         if (ibuf->encodedbuffer && (ibuf->mall & IB_mem))
124                 MEM_freeN(ibuf->encodedbuffer);
125
126         ibuf->encodedbuffer = NULL;
127         ibuf->encodedbuffersize = 0;
128         ibuf->encodedsize = 0;
129         ibuf->mall &= ~IB_mem;
130 }
131
132 void IMB_freezbufImBuf(ImBuf *ibuf)
133 {
134         if (ibuf == NULL) return;
135
136         if (ibuf->zbuf && (ibuf->mall & IB_zbuf))
137                 MEM_freeN(ibuf->zbuf);
138
139         ibuf->zbuf = NULL;
140         ibuf->mall &= ~IB_zbuf;
141 }
142
143 void IMB_freezbuffloatImBuf(ImBuf *ibuf)
144 {
145         if (ibuf == NULL) return;
146
147         if (ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat))
148                 MEM_freeN(ibuf->zbuf_float);
149
150         ibuf->zbuf_float = NULL;
151         ibuf->mall &= ~IB_zbuffloat;
152 }
153
154 void IMB_freeImBuf(ImBuf *ibuf)
155 {
156         if (ibuf) {
157                 if (ibuf->refcounter > 0) {
158                         ibuf->refcounter--;
159                 }
160                 else {
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_metadata_free(ibuf);
168                         colormanage_cache_free(ibuf);
169
170                         if (ibuf->dds_data.data != NULL) {
171                                 free(ibuf->dds_data.data); /* dds_data.data is allocated by DirectDrawSurface::readData(), so don't use MEM_freeN! */
172                         }
173                         MEM_freeN(ibuf);
174                 }
175         }
176 }
177
178 void IMB_refImBuf(ImBuf *ibuf)
179 {
180         ibuf->refcounter++;
181 }
182
183 ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
184 {
185         ImBuf *rval;
186
187         if (!ibuf || ibuf->refcounter == 0) { return ibuf; }
188
189         rval = IMB_dupImBuf(ibuf);
190
191         IMB_freeImBuf(ibuf);
192
193         return rval;
194 }
195
196 bool addzbufImBuf(ImBuf *ibuf)
197 {
198         size_t size;
199         
200         if (ibuf == NULL) return false;
201         
202         IMB_freezbufImBuf(ibuf);
203         
204         size = (size_t)(ibuf->x * ibuf->y) * sizeof(unsigned int);
205
206         if ((ibuf->zbuf = MEM_mapallocN(size, __func__))) {
207                 ibuf->mall |= IB_zbuf;
208                 ibuf->flags |= IB_zbuf;
209                 return true;
210         }
211         
212         return false;
213 }
214
215 bool addzbuffloatImBuf(ImBuf *ibuf)
216 {
217         size_t size;
218         
219         if (ibuf == NULL) return false;
220         
221         IMB_freezbuffloatImBuf(ibuf);
222         
223         size = (size_t)(ibuf->x * ibuf->y) * sizeof(float);
224
225         if ((ibuf->zbuf_float = MEM_mapallocN(size, __func__))) {
226                 ibuf->mall |= IB_zbuffloat;
227                 ibuf->flags |= IB_zbuffloat;
228                 return true;
229         }
230         
231         return false;
232 }
233
234
235 bool imb_addencodedbufferImBuf(ImBuf *ibuf)
236 {
237         if (ibuf == NULL) return false;
238
239         freeencodedbufferImBuf(ibuf);
240
241         if (ibuf->encodedbuffersize == 0)
242                 ibuf->encodedbuffersize = 10000;
243
244         ibuf->encodedsize = 0;
245
246         if ((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, __func__))) {
247                 ibuf->mall |= IB_mem;
248                 ibuf->flags |= IB_mem;
249                 return true;
250         }
251
252         return false;
253 }
254
255
256 bool imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
257 {
258         unsigned int newsize, encodedsize;
259         void *newbuffer;
260
261         if (ibuf == NULL) return false;
262
263         if (ibuf->encodedbuffersize < ibuf->encodedsize) {
264                 printf("%s: error in parameters\n", __func__);
265                 return false;
266         }
267
268         newsize = 2 * ibuf->encodedbuffersize;
269         if (newsize < 10000) newsize = 10000;
270
271         newbuffer = MEM_mallocN(newsize, __func__);
272         if (newbuffer == NULL) return false;
273
274         if (ibuf->encodedbuffer) {
275                 memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
276         }
277         else {
278                 ibuf->encodedsize = 0;
279         }
280
281         encodedsize = ibuf->encodedsize;
282
283         freeencodedbufferImBuf(ibuf);
284
285         ibuf->encodedbuffersize = newsize;
286         ibuf->encodedsize = encodedsize;
287         ibuf->encodedbuffer = newbuffer;
288         ibuf->mall |= IB_mem;
289         ibuf->flags |= IB_mem;
290
291         return true;
292 }
293
294 bool imb_addrectfloatImBuf(ImBuf *ibuf)
295 {
296         size_t size;
297         
298         if (ibuf == NULL) return false;
299         
300         if (ibuf->rect_float)
301                 imb_freerectfloatImBuf(ibuf);  /* frees mipmap too, hrm */
302         
303         size = (size_t)(ibuf->x * ibuf->y) * sizeof(float[4]);
304
305         ibuf->channels = 4;
306         if ((ibuf->rect_float = MEM_mapallocN(size, __func__))) {
307                 ibuf->mall |= IB_rectfloat;
308                 ibuf->flags |= IB_rectfloat;
309                 return true;
310         }
311         
312         return false;
313 }
314
315 /* question; why also add zbuf? */
316 bool imb_addrectImBuf(ImBuf *ibuf)
317 {
318         size_t size;
319
320         if (ibuf == NULL) return false;
321         
322         /* don't call imb_freerectImBuf, it frees mipmaps, this call is used only too give float buffers display */
323         if (ibuf->rect && (ibuf->mall & IB_rect))
324                 MEM_freeN(ibuf->rect);
325         ibuf->rect = NULL;
326         
327         size = (size_t)(ibuf->x * ibuf->y) * sizeof(unsigned int);
328
329         if ((ibuf->rect = MEM_mapallocN(size, __func__))) {
330                 ibuf->mall |= IB_rect;
331                 ibuf->flags |= IB_rect;
332                 if (ibuf->planes > 32) {
333                         return (addzbufImBuf(ibuf));
334                 }
335                 else {
336                         return true;
337                 }
338         }
339
340         return false;
341 }
342
343 bool imb_addtilesImBuf(ImBuf *ibuf)
344 {
345         if (ibuf == NULL) return false;
346
347         if (!ibuf->tiles)
348                 if ((ibuf->tiles = MEM_callocN(sizeof(unsigned int *) * ibuf->xtiles * ibuf->ytiles, "imb_tiles")))
349                         ibuf->mall |= IB_tiles;
350
351         return (ibuf->tiles != NULL);
352 }
353
354 ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int flags)
355 {
356         ImBuf *ibuf;
357
358         ibuf = MEM_callocN(sizeof(ImBuf), "ImBuf_struct");
359
360         if (ibuf) {
361                 ibuf->x = x;
362                 ibuf->y = y;
363                 ibuf->planes = planes;
364                 ibuf->ftype = PNG | 90; /* the 90 means, set compression to nearly the maximum */
365                 ibuf->channels = 4;  /* float option, is set to other values when buffers get assigned */
366                 ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254f; /* IMB_DPI_DEFAULT -> pixels-per-meter */
367
368                 if (flags & IB_rect) {
369                         if (imb_addrectImBuf(ibuf) == false) {
370                                 IMB_freeImBuf(ibuf);
371                                 return NULL;
372                         }
373                 }
374                 
375                 if (flags & IB_rectfloat) {
376                         if (imb_addrectfloatImBuf(ibuf) == false) {
377                                 IMB_freeImBuf(ibuf);
378                                 return NULL;
379                         }
380                 }
381                 
382                 if (flags & IB_zbuf) {
383                         if (addzbufImBuf(ibuf) == false) {
384                                 IMB_freeImBuf(ibuf);
385                                 return NULL;
386                         }
387                 }
388                 
389                 if (flags & IB_zbuffloat) {
390                         if (addzbuffloatImBuf(ibuf) == false) {
391                                 IMB_freeImBuf(ibuf);
392                                 return NULL;
393                         }
394                 }
395
396                 /* assign default spaces */
397                 colormanage_imbuf_set_default_spaces(ibuf);
398         }
399         return (ibuf);
400 }
401
402 /* does no zbuffers? */
403 ImBuf *IMB_dupImBuf(ImBuf *ibuf1)
404 {
405         ImBuf *ibuf2, tbuf;
406         int flags = 0;
407         int a, x, y;
408         
409         if (ibuf1 == NULL) return NULL;
410
411         if (ibuf1->rect) flags |= IB_rect;
412         if (ibuf1->rect_float) flags |= IB_rectfloat;
413
414         x = ibuf1->x;
415         y = ibuf1->y;
416         if (ibuf1->flags & IB_fields) y *= 2;
417         
418         ibuf2 = IMB_allocImBuf(x, y, ibuf1->planes, flags);
419         if (ibuf2 == NULL) return NULL;
420
421         if (flags & IB_rect)
422                 memcpy(ibuf2->rect, ibuf1->rect, x * y * sizeof(int));
423         
424         if (flags & IB_rectfloat)
425                 memcpy(ibuf2->rect_float, ibuf1->rect_float, ibuf1->channels * x * y * sizeof(float));
426
427         if (ibuf1->encodedbuffer) {
428                 ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
429                 if (imb_addencodedbufferImBuf(ibuf2) == false) {
430                         IMB_freeImBuf(ibuf2);
431                         return NULL;
432                 }
433
434                 memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
435         }
436
437         /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
438         tbuf = *ibuf1;
439         
440         /* fix pointers */
441         tbuf.rect          = ibuf2->rect;
442         tbuf.rect_float    = ibuf2->rect_float;
443         tbuf.encodedbuffer = ibuf2->encodedbuffer;
444         tbuf.zbuf          = NULL;
445         tbuf.zbuf_float    = NULL;
446         for (a = 0; a < IB_MIPMAP_LEVELS; a++)
447                 tbuf.mipmap[a] = NULL;
448         tbuf.dds_data.data = NULL;
449         
450         /* set malloc flag */
451         tbuf.mall               = ibuf2->mall;
452         tbuf.c_handle           = NULL;
453         tbuf.refcounter         = 0;
454
455         /* for now don't duplicate metadata */
456         tbuf.metadata = NULL;
457
458         tbuf.display_buffer_flags = NULL;
459         tbuf.colormanage_cache = NULL;
460
461         *ibuf2 = tbuf;
462
463         return(ibuf2);
464 }
465
466 #if 0 /* remove? - campbell */
467 /* support for cache limiting */
468
469 static void imbuf_cache_destructor(void *data)
470 {
471         ImBuf *ibuf = (ImBuf *) data;
472
473         imb_freerectImBuf(ibuf);
474         imb_freerectfloatImBuf(ibuf);
475         IMB_freezbufImBuf(ibuf);
476         IMB_freezbuffloatImBuf(ibuf);
477         freeencodedbufferImBuf(ibuf);
478
479         ibuf->c_handle = NULL;
480 }
481
482
483 static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
484 {
485         static MEM_CacheLimiterC *c = NULL;
486
487         if (!c)
488                 c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
489
490         return &c;
491 }
492 #endif