Cleanup: add trailing commas
[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
50 #include "BLI_utildefines.h"
51 #include "BLI_threads.h"
52
53 static SpinLock refcounter_spin;
54
55 void imb_refcounter_lock_init(void)
56 {
57         BLI_spin_init(&refcounter_spin);
58 }
59
60 void imb_refcounter_lock_exit(void)
61 {
62         BLI_spin_end(&refcounter_spin);
63 }
64
65 #ifdef WIN32
66 static SpinLock mmap_spin;
67
68 void imb_mmap_lock_init(void)
69 {
70         BLI_spin_init(&mmap_spin);
71 }
72
73 void imb_mmap_lock_exit(void)
74 {
75         BLI_spin_end(&mmap_spin);
76 }
77
78 void imb_mmap_lock(void)
79 {
80         BLI_spin_lock(&mmap_spin);
81 }
82
83 void imb_mmap_unlock(void)
84 {
85         BLI_spin_unlock(&mmap_spin);
86 }
87 #endif
88
89 void imb_freemipmapImBuf(ImBuf *ibuf)
90 {
91         int a;
92
93         /* Do not trust ibuf->miptot, in some cases IMB_remakemipmap can leave unfreed unused levels,
94          * leading to memory leaks... */
95         for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
96                 if (ibuf->mipmap[a] != NULL) {
97                         IMB_freeImBuf(ibuf->mipmap[a]);
98                         ibuf->mipmap[a] = NULL;
99                 }
100         }
101
102         ibuf->miptot = 0;
103 }
104
105 /* any free rect frees mipmaps to be sure, creation is in render on first request */
106 void imb_freerectfloatImBuf(ImBuf *ibuf)
107 {
108         if (ibuf == NULL) return;
109
110         if (ibuf->rect_float && (ibuf->mall & IB_rectfloat)) {
111                 MEM_freeN(ibuf->rect_float);
112                 ibuf->rect_float = NULL;
113         }
114
115         imb_freemipmapImBuf(ibuf);
116
117         ibuf->rect_float = NULL;
118         ibuf->mall &= ~IB_rectfloat;
119 }
120
121 /* any free rect frees mipmaps to be sure, creation is in render on first request */
122 void imb_freerectImBuf(ImBuf *ibuf)
123 {
124         if (ibuf == NULL) return;
125
126         if (ibuf->rect && (ibuf->mall & IB_rect))
127                 MEM_freeN(ibuf->rect);
128         ibuf->rect = NULL;
129
130         imb_freemipmapImBuf(ibuf);
131
132         ibuf->mall &= ~IB_rect;
133 }
134
135 void imb_freetilesImBuf(ImBuf *ibuf)
136 {
137         int tx, ty;
138
139         if (ibuf == NULL) return;
140
141         if (ibuf->tiles && (ibuf->mall & IB_tiles)) {
142                 for (ty = 0; ty < ibuf->ytiles; ty++) {
143                         for (tx = 0; tx < ibuf->xtiles; tx++) {
144                                 if (ibuf->tiles[ibuf->xtiles * ty + tx]) {
145                                         imb_tile_cache_tile_free(ibuf, tx, ty);
146                                         MEM_freeN(ibuf->tiles[ibuf->xtiles * ty + tx]);
147                                 }
148                         }
149                 }
150
151                 MEM_freeN(ibuf->tiles);
152         }
153
154         ibuf->tiles = NULL;
155         ibuf->mall &= ~IB_tiles;
156 }
157
158 static void freeencodedbufferImBuf(ImBuf *ibuf)
159 {
160         if (ibuf == NULL) return;
161
162         if (ibuf->encodedbuffer && (ibuf->mall & IB_mem))
163                 MEM_freeN(ibuf->encodedbuffer);
164
165         ibuf->encodedbuffer = NULL;
166         ibuf->encodedbuffersize = 0;
167         ibuf->encodedsize = 0;
168         ibuf->mall &= ~IB_mem;
169 }
170
171 void IMB_freezbufImBuf(ImBuf *ibuf)
172 {
173         if (ibuf == NULL) return;
174
175         if (ibuf->zbuf && (ibuf->mall & IB_zbuf))
176                 MEM_freeN(ibuf->zbuf);
177
178         ibuf->zbuf = NULL;
179         ibuf->mall &= ~IB_zbuf;
180 }
181
182 void IMB_freezbuffloatImBuf(ImBuf *ibuf)
183 {
184         if (ibuf == NULL) return;
185
186         if (ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat))
187                 MEM_freeN(ibuf->zbuf_float);
188
189         ibuf->zbuf_float = NULL;
190         ibuf->mall &= ~IB_zbuffloat;
191 }
192
193 void IMB_freeImBuf(ImBuf *ibuf)
194 {
195         if (ibuf) {
196                 bool needs_free = false;
197
198                 BLI_spin_lock(&refcounter_spin);
199                 if (ibuf->refcounter > 0) {
200                         ibuf->refcounter--;
201                 }
202                 else {
203                         needs_free = true;
204                 }
205                 BLI_spin_unlock(&refcounter_spin);
206
207                 if (needs_free) {
208                         imb_freerectImBuf(ibuf);
209                         imb_freerectfloatImBuf(ibuf);
210                         imb_freetilesImBuf(ibuf);
211                         IMB_freezbufImBuf(ibuf);
212                         IMB_freezbuffloatImBuf(ibuf);
213                         freeencodedbufferImBuf(ibuf);
214                         IMB_metadata_free(ibuf->metadata);
215                         colormanage_cache_free(ibuf);
216
217                         if (ibuf->dds_data.data != NULL) {
218                                 free(ibuf->dds_data.data); /* dds_data.data is allocated by DirectDrawSurface::readData(), so don't use MEM_freeN! */
219                         }
220                         MEM_freeN(ibuf);
221                 }
222         }
223 }
224
225 void IMB_refImBuf(ImBuf *ibuf)
226 {
227         BLI_spin_lock(&refcounter_spin);
228         ibuf->refcounter++;
229         BLI_spin_unlock(&refcounter_spin);
230 }
231
232 ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
233 {
234         ImBuf *rval;
235
236         if (ibuf) {
237                 bool is_single;
238                 BLI_spin_lock(&refcounter_spin);
239                 is_single = (ibuf->refcounter == 0);
240                 BLI_spin_unlock(&refcounter_spin);
241                 if (is_single) {
242                         return ibuf;
243                 }
244         }
245         else {
246                 return NULL;
247         }
248
249         rval = IMB_dupImBuf(ibuf);
250
251         IMB_metadata_copy(rval, ibuf);
252
253         IMB_freeImBuf(ibuf);
254
255         return rval;
256 }
257
258 bool addzbufImBuf(ImBuf *ibuf)
259 {
260         if (ibuf == NULL) return false;
261
262         IMB_freezbufImBuf(ibuf);
263
264         if ((ibuf->zbuf = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(unsigned int), __func__))) {
265                 ibuf->mall |= IB_zbuf;
266                 ibuf->flags |= IB_zbuf;
267                 return true;
268         }
269
270         return false;
271 }
272
273 bool addzbuffloatImBuf(ImBuf *ibuf)
274 {
275         if (ibuf == NULL) return false;
276
277         IMB_freezbuffloatImBuf(ibuf);
278
279         if ((ibuf->zbuf_float = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(float), __func__))) {
280                 ibuf->mall |= IB_zbuffloat;
281                 ibuf->flags |= IB_zbuffloat;
282                 return true;
283         }
284
285         return false;
286 }
287
288
289 bool imb_addencodedbufferImBuf(ImBuf *ibuf)
290 {
291         if (ibuf == NULL) return false;
292
293         freeencodedbufferImBuf(ibuf);
294
295         if (ibuf->encodedbuffersize == 0)
296                 ibuf->encodedbuffersize = 10000;
297
298         ibuf->encodedsize = 0;
299
300         if ((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, __func__))) {
301                 ibuf->mall |= IB_mem;
302                 ibuf->flags |= IB_mem;
303                 return true;
304         }
305
306         return false;
307 }
308
309
310 bool imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
311 {
312         unsigned int newsize, encodedsize;
313         void *newbuffer;
314
315         if (ibuf == NULL) return false;
316
317         if (ibuf->encodedbuffersize < ibuf->encodedsize) {
318                 printf("%s: error in parameters\n", __func__);
319                 return false;
320         }
321
322         newsize = 2 * ibuf->encodedbuffersize;
323         if (newsize < 10000) newsize = 10000;
324
325         newbuffer = MEM_mallocN(newsize, __func__);
326         if (newbuffer == NULL) return false;
327
328         if (ibuf->encodedbuffer) {
329                 memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
330         }
331         else {
332                 ibuf->encodedsize = 0;
333         }
334
335         encodedsize = ibuf->encodedsize;
336
337         freeencodedbufferImBuf(ibuf);
338
339         ibuf->encodedbuffersize = newsize;
340         ibuf->encodedsize = encodedsize;
341         ibuf->encodedbuffer = newbuffer;
342         ibuf->mall |= IB_mem;
343         ibuf->flags |= IB_mem;
344
345         return true;
346 }
347
348 void *imb_alloc_pixels(unsigned int x,
349                        unsigned int y,
350                        unsigned int channels,
351                        size_t typesize,
352                        const char *name)
353 {
354         /* Protect against buffer overflow vulnerabilities from files specifying
355          * a width and height that overflow and alloc too little memory. */
356         if (!((uint64_t)x * (uint64_t)y < (SIZE_MAX / (channels * typesize)))) {
357                 return NULL;
358         }
359
360         size_t size = (size_t)x * (size_t)y * (size_t)channels * typesize;
361         return MEM_mapallocN(size, name);
362 }
363
364 bool imb_addrectfloatImBuf(ImBuf *ibuf)
365 {
366         if (ibuf == NULL) return false;
367
368         if (ibuf->rect_float)
369                 imb_freerectfloatImBuf(ibuf);  /* frees mipmap too, hrm */
370
371         ibuf->channels = 4;
372         if ((ibuf->rect_float = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(float), __func__))) {
373                 ibuf->mall |= IB_rectfloat;
374                 ibuf->flags |= IB_rectfloat;
375                 return true;
376         }
377
378         return false;
379 }
380
381 /* question; why also add zbuf? */
382 bool imb_addrectImBuf(ImBuf *ibuf)
383 {
384         if (ibuf == NULL) return false;
385
386         /* don't call imb_freerectImBuf, it frees mipmaps, this call is used only too give float buffers display */
387         if (ibuf->rect && (ibuf->mall & IB_rect))
388                 MEM_freeN(ibuf->rect);
389         ibuf->rect = NULL;
390
391         if ((ibuf->rect = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(unsigned char), __func__))) {
392                 ibuf->mall |= IB_rect;
393                 ibuf->flags |= IB_rect;
394                 if (ibuf->planes > 32) {
395                         return (addzbufImBuf(ibuf));
396                 }
397                 else {
398                         return true;
399                 }
400         }
401
402         return false;
403 }
404
405 struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect, const float *rectf,
406                                   unsigned int w, unsigned int h)
407 {
408         ImBuf *ibuf = NULL;
409
410         if (!(rect || rectf))
411                 return NULL;
412
413         ibuf = IMB_allocImBuf(w, h, 32, 0);
414
415         if (rectf) {
416                 ibuf->rect_float = MEM_dupallocN(rectf);
417                 ibuf->flags |= IB_rectfloat;
418                 ibuf->mall |= IB_rectfloat;
419         }
420         if (rect) {
421                 ibuf->rect = MEM_dupallocN(rect);
422                 ibuf->flags |= IB_rect;
423                 ibuf->mall |= IB_rect;
424         }
425
426         return ibuf;
427 }
428
429 bool imb_addtilesImBuf(ImBuf *ibuf)
430 {
431         if (ibuf == NULL) return false;
432
433         if (!ibuf->tiles)
434                 if ((ibuf->tiles = MEM_callocN(sizeof(unsigned int *) * ibuf->xtiles * ibuf->ytiles, "imb_tiles")))
435                         ibuf->mall |= IB_tiles;
436
437         return (ibuf->tiles != NULL);
438 }
439
440 ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int flags)
441 {
442         ImBuf *ibuf;
443
444         ibuf = MEM_mallocN(sizeof(ImBuf), "ImBuf_struct");
445
446         if (ibuf) {
447                 if (!IMB_initImBuf(ibuf, x, y, planes, flags)) {
448                         IMB_freeImBuf(ibuf);
449                         return NULL;
450                 }
451         }
452
453         return (ibuf);
454 }
455
456 bool IMB_initImBuf(struct ImBuf *ibuf,
457                    unsigned int x, unsigned int y,
458                    unsigned char planes, unsigned int flags)
459 {
460         memset(ibuf, 0, sizeof(ImBuf));
461
462         ibuf->x = x;
463         ibuf->y = y;
464         ibuf->planes = planes;
465         ibuf->ftype = IMB_FTYPE_PNG;
466         ibuf->foptions.quality = 15; /* the 15 means, set compression to low ratio but not time consuming */
467         ibuf->channels = 4;  /* float option, is set to other values when buffers get assigned */
468         ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254f; /* IMB_DPI_DEFAULT -> pixels-per-meter */
469
470         if (flags & IB_rect) {
471                 if (imb_addrectImBuf(ibuf) == false) {
472                         return false;
473                 }
474         }
475
476         if (flags & IB_rectfloat) {
477                 if (imb_addrectfloatImBuf(ibuf) == false) {
478                         return false;
479                 }
480         }
481
482         if (flags & IB_zbuf) {
483                 if (addzbufImBuf(ibuf) == false) {
484                         return false;
485                 }
486         }
487
488         if (flags & IB_zbuffloat) {
489                 if (addzbuffloatImBuf(ibuf) == false) {
490                         return false;
491                 }
492         }
493
494         /* assign default spaces */
495         colormanage_imbuf_set_default_spaces(ibuf);
496
497         return true;
498 }
499
500 /* does no zbuffers? */
501 ImBuf *IMB_dupImBuf(const ImBuf *ibuf1)
502 {
503         ImBuf *ibuf2, tbuf;
504         int flags = 0;
505         int a, x, y;
506
507         if (ibuf1 == NULL) return NULL;
508
509         if (ibuf1->rect) flags |= IB_rect;
510         if (ibuf1->rect_float) flags |= IB_rectfloat;
511         if (ibuf1->zbuf) flags |= IB_zbuf;
512         if (ibuf1->zbuf_float) flags |= IB_zbuffloat;
513
514         x = ibuf1->x;
515         y = ibuf1->y;
516
517         ibuf2 = IMB_allocImBuf(x, y, ibuf1->planes, flags);
518         if (ibuf2 == NULL) return NULL;
519
520         if (flags & IB_rect)
521                 memcpy(ibuf2->rect, ibuf1->rect, ((size_t)x) * y * sizeof(int));
522
523         if (flags & IB_rectfloat)
524                 memcpy(ibuf2->rect_float, ibuf1->rect_float, ((size_t)ibuf1->channels) * x * y * sizeof(float));
525
526         if (flags & IB_zbuf)
527                 memcpy(ibuf2->zbuf, ibuf1->zbuf, ((size_t)x) * y * sizeof(int));
528
529         if (flags & IB_zbuffloat)
530                 memcpy(ibuf2->zbuf_float, ibuf1->zbuf_float, ((size_t)x) * y * sizeof(float));
531
532         if (ibuf1->encodedbuffer) {
533                 ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
534                 if (imb_addencodedbufferImBuf(ibuf2) == false) {
535                         IMB_freeImBuf(ibuf2);
536                         return NULL;
537                 }
538
539                 memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
540         }
541
542         /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
543         tbuf = *ibuf1;
544
545         /* fix pointers */
546         tbuf.rect          = ibuf2->rect;
547         tbuf.rect_float    = ibuf2->rect_float;
548         tbuf.encodedbuffer = ibuf2->encodedbuffer;
549         tbuf.zbuf          = ibuf2->zbuf;
550         tbuf.zbuf_float    = ibuf2->zbuf_float;
551         for (a = 0; a < IMB_MIPMAP_LEVELS; a++)
552                 tbuf.mipmap[a] = NULL;
553         tbuf.dds_data.data = NULL;
554
555         /* set malloc flag */
556         tbuf.mall               = ibuf2->mall;
557         tbuf.c_handle           = NULL;
558         tbuf.refcounter         = 0;
559
560         /* for now don't duplicate metadata */
561         tbuf.metadata = NULL;
562
563         tbuf.display_buffer_flags = NULL;
564         tbuf.colormanage_cache = NULL;
565
566         *ibuf2 = tbuf;
567
568         return(ibuf2);
569 }
570
571 #if 0 /* remove? - campbell */
572 /* support for cache limiting */
573
574 static void imbuf_cache_destructor(void *data)
575 {
576         ImBuf *ibuf = (ImBuf *) data;
577
578         imb_freerectImBuf(ibuf);
579         imb_freerectfloatImBuf(ibuf);
580         IMB_freezbufImBuf(ibuf);
581         IMB_freezbuffloatImBuf(ibuf);
582         freeencodedbufferImBuf(ibuf);
583
584         ibuf->c_handle = NULL;
585 }
586
587
588 static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
589 {
590         static MEM_CacheLimiterC *c = NULL;
591
592         if (!c)
593                 c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
594
595         return &c;
596 }
597 #endif