1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup imbuf
22 */
23
24 /* It's become a bit messy... Basically, only the IMB_ prefixed files
25 * should remain. */
26
27 #include <stddef.h>
28
29 #include "IMB_imbuf.h"
30 #include "IMB_imbuf_types.h"
31
32 #include "IMB_allocimbuf.h"
33 #include "IMB_colormanagement_intern.h"
34 #include "IMB_filetype.h"
35 #include "IMB_metadata.h"
36
37 #include "imbuf.h"
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLI_threads.h"
42 #include "BLI_utildefines.h"
43
44 static SpinLock refcounter_spin;
45
imb_refcounter_lock_init(void)46 void imb_refcounter_lock_init(void)
47 {
48 BLI_spin_init(&refcounter_spin);
49 }
50
imb_refcounter_lock_exit(void)51 void imb_refcounter_lock_exit(void)
52 {
53 BLI_spin_end(&refcounter_spin);
54 }
55
56 #ifdef WIN32
57 static SpinLock mmap_spin;
58
imb_mmap_lock_init(void)59 void imb_mmap_lock_init(void)
60 {
61 BLI_spin_init(&mmap_spin);
62 }
63
imb_mmap_lock_exit(void)64 void imb_mmap_lock_exit(void)
65 {
66 BLI_spin_end(&mmap_spin);
67 }
68
imb_mmap_lock(void)69 void imb_mmap_lock(void)
70 {
71 BLI_spin_lock(&mmap_spin);
72 }
73
imb_mmap_unlock(void)74 void imb_mmap_unlock(void)
75 {
76 BLI_spin_unlock(&mmap_spin);
77 }
78 #endif
79
imb_freemipmapImBuf(ImBuf * ibuf)80 void imb_freemipmapImBuf(ImBuf *ibuf)
81 {
82 int a;
83
84 /* Do not trust ibuf->miptot, in some cases IMB_remakemipmap can leave unfreed unused levels,
85 * leading to memory leaks... */
86 for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
87 if (ibuf->mipmap[a] != NULL) {
88 IMB_freeImBuf(ibuf->mipmap[a]);
89 ibuf->mipmap[a] = NULL;
90 }
91 }
92
93 ibuf->miptot = 0;
94 }
95
96 /* any free rect frees mipmaps to be sure, creation is in render on first request */
imb_freerectfloatImBuf(ImBuf * ibuf)97 void imb_freerectfloatImBuf(ImBuf *ibuf)
98 {
99 if (ibuf == NULL) {
100 return;
101 }
102
103 if (ibuf->rect_float && (ibuf->mall & IB_rectfloat)) {
104 MEM_freeN(ibuf->rect_float);
105 ibuf->rect_float = NULL;
106 }
107
108 imb_freemipmapImBuf(ibuf);
109
110 ibuf->rect_float = NULL;
111 ibuf->mall &= ~IB_rectfloat;
112 }
113
114 /* any free rect frees mipmaps to be sure, creation is in render on first request */
imb_freerectImBuf(ImBuf * ibuf)115 void imb_freerectImBuf(ImBuf *ibuf)
116 {
117 if (ibuf == NULL) {
118 return;
119 }
120
121 if (ibuf->rect && (ibuf->mall & IB_rect)) {
122 MEM_freeN(ibuf->rect);
123 }
124 ibuf->rect = NULL;
125
126 imb_freemipmapImBuf(ibuf);
127
128 ibuf->mall &= ~IB_rect;
129 }
130
imb_freetilesImBuf(ImBuf * ibuf)131 void imb_freetilesImBuf(ImBuf *ibuf)
132 {
133 int tx, ty;
134
135 if (ibuf == NULL) {
136 return;
137 }
138
139 if (ibuf->tiles && (ibuf->mall & IB_tiles)) {
140 for (ty = 0; ty < ibuf->ytiles; ty++) {
141 for (tx = 0; tx < ibuf->xtiles; tx++) {
142 if (ibuf->tiles[ibuf->xtiles * ty + tx]) {
143 imb_tile_cache_tile_free(ibuf, tx, ty);
144 MEM_freeN(ibuf->tiles[ibuf->xtiles * ty + tx]);
145 }
146 }
147 }
148
149 MEM_freeN(ibuf->tiles);
150 }
151
152 ibuf->tiles = NULL;
153 ibuf->mall &= ~IB_tiles;
154 }
155
freeencodedbufferImBuf(ImBuf * ibuf)156 static void freeencodedbufferImBuf(ImBuf *ibuf)
157 {
158 if (ibuf == NULL) {
159 return;
160 }
161
162 if (ibuf->encodedbuffer && (ibuf->mall & IB_mem)) {
163 MEM_freeN(ibuf->encodedbuffer);
164 }
165
166 ibuf->encodedbuffer = NULL;
167 ibuf->encodedbuffersize = 0;
168 ibuf->encodedsize = 0;
169 ibuf->mall &= ~IB_mem;
170 }
171
IMB_freezbufImBuf(ImBuf * ibuf)172 void IMB_freezbufImBuf(ImBuf *ibuf)
173 {
174 if (ibuf == NULL) {
175 return;
176 }
177
178 if (ibuf->zbuf && (ibuf->mall & IB_zbuf)) {
179 MEM_freeN(ibuf->zbuf);
180 }
181
182 ibuf->zbuf = NULL;
183 ibuf->mall &= ~IB_zbuf;
184 }
185
IMB_freezbuffloatImBuf(ImBuf * ibuf)186 void IMB_freezbuffloatImBuf(ImBuf *ibuf)
187 {
188 if (ibuf == NULL) {
189 return;
190 }
191
192 if (ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat)) {
193 MEM_freeN(ibuf->zbuf_float);
194 }
195
196 ibuf->zbuf_float = NULL;
197 ibuf->mall &= ~IB_zbuffloat;
198 }
199
200 /** Free all pixel data (assosiated with image size). */
imb_freerectImbuf_all(ImBuf * ibuf)201 void imb_freerectImbuf_all(ImBuf *ibuf)
202 {
203 imb_freerectImBuf(ibuf);
204 imb_freerectfloatImBuf(ibuf);
205 imb_freetilesImBuf(ibuf);
206 IMB_freezbufImBuf(ibuf);
207 IMB_freezbuffloatImBuf(ibuf);
208 freeencodedbufferImBuf(ibuf);
209 }
210
IMB_freeImBuf(ImBuf * ibuf)211 void IMB_freeImBuf(ImBuf *ibuf)
212 {
213 if (ibuf) {
214 bool needs_free = false;
215
216 BLI_spin_lock(&refcounter_spin);
217 if (ibuf->refcounter > 0) {
218 ibuf->refcounter--;
219 }
220 else {
221 needs_free = true;
222 }
223 BLI_spin_unlock(&refcounter_spin);
224
225 if (needs_free) {
226 imb_freerectImbuf_all(ibuf);
227 IMB_metadata_free(ibuf->metadata);
228 colormanage_cache_free(ibuf);
229
230 if (ibuf->dds_data.data != NULL) {
231 /* dds_data.data is allocated by DirectDrawSurface::readData(), so don't use MEM_freeN! */
232 free(ibuf->dds_data.data);
233 }
234 MEM_freeN(ibuf);
235 }
236 }
237 }
238
IMB_refImBuf(ImBuf * ibuf)239 void IMB_refImBuf(ImBuf *ibuf)
240 {
241 BLI_spin_lock(&refcounter_spin);
242 ibuf->refcounter++;
243 BLI_spin_unlock(&refcounter_spin);
244 }
245
IMB_makeSingleUser(ImBuf * ibuf)246 ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
247 {
248 ImBuf *rval;
249
250 if (ibuf) {
251 bool is_single;
252 BLI_spin_lock(&refcounter_spin);
253 is_single = (ibuf->refcounter == 0);
254 BLI_spin_unlock(&refcounter_spin);
255 if (is_single) {
256 return ibuf;
257 }
258 }
259 else {
260 return NULL;
261 }
262
263 rval = IMB_dupImBuf(ibuf);
264
265 IMB_metadata_copy(rval, ibuf);
266
267 IMB_freeImBuf(ibuf);
268
269 return rval;
270 }
271
addzbufImBuf(ImBuf * ibuf)272 bool addzbufImBuf(ImBuf *ibuf)
273 {
274 if (ibuf == NULL) {
275 return false;
276 }
277
278 IMB_freezbufImBuf(ibuf);
279
280 if ((ibuf->zbuf = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(unsigned int), __func__))) {
281 ibuf->mall |= IB_zbuf;
282 ibuf->flags |= IB_zbuf;
283 return true;
284 }
285
286 return false;
287 }
288
addzbuffloatImBuf(ImBuf * ibuf)289 bool addzbuffloatImBuf(ImBuf *ibuf)
290 {
291 if (ibuf == NULL) {
292 return false;
293 }
294
295 IMB_freezbuffloatImBuf(ibuf);
296
297 if ((ibuf->zbuf_float = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(float), __func__))) {
298 ibuf->mall |= IB_zbuffloat;
299 ibuf->flags |= IB_zbuffloat;
300 return true;
301 }
302
303 return false;
304 }
305
imb_addencodedbufferImBuf(ImBuf * ibuf)306 bool imb_addencodedbufferImBuf(ImBuf *ibuf)
307 {
308 if (ibuf == NULL) {
309 return false;
310 }
311
312 freeencodedbufferImBuf(ibuf);
313
314 if (ibuf->encodedbuffersize == 0) {
315 ibuf->encodedbuffersize = 10000;
316 }
317
318 ibuf->encodedsize = 0;
319
320 if ((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, __func__))) {
321 ibuf->mall |= IB_mem;
322 ibuf->flags |= IB_mem;
323 return true;
324 }
325
326 return false;
327 }
328
imb_enlargeencodedbufferImBuf(ImBuf * ibuf)329 bool imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
330 {
331 unsigned int newsize, encodedsize;
332 void *newbuffer;
333
334 if (ibuf == NULL) {
335 return false;
336 }
337
338 if (ibuf->encodedbuffersize < ibuf->encodedsize) {
339 printf("%s: error in parameters\n", __func__);
340 return false;
341 }
342
343 newsize = 2 * ibuf->encodedbuffersize;
344 if (newsize < 10000) {
345 newsize = 10000;
346 }
347
348 newbuffer = MEM_mallocN(newsize, __func__);
349 if (newbuffer == NULL) {
350 return false;
351 }
352
353 if (ibuf->encodedbuffer) {
354 memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
355 }
356 else {
357 ibuf->encodedsize = 0;
358 }
359
360 encodedsize = ibuf->encodedsize;
361
362 freeencodedbufferImBuf(ibuf);
363
364 ibuf->encodedbuffersize = newsize;
365 ibuf->encodedsize = encodedsize;
366 ibuf->encodedbuffer = newbuffer;
367 ibuf->mall |= IB_mem;
368 ibuf->flags |= IB_mem;
369
370 return true;
371 }
372
imb_alloc_pixels(unsigned int x,unsigned int y,unsigned int channels,size_t typesize,const char * name)373 void *imb_alloc_pixels(
374 unsigned int x, unsigned int y, unsigned int channels, size_t typesize, const char *name)
375 {
376 /* Protect against buffer overflow vulnerabilities from files specifying
377 * a width and height that overflow and alloc too little memory. */
378 if (!((uint64_t)x * (uint64_t)y < (SIZE_MAX / (channels * typesize)))) {
379 return NULL;
380 }
381
382 size_t size = (size_t)x * (size_t)y * (size_t)channels * typesize;
383 return MEM_callocN(size, name);
384 }
385
imb_addrectfloatImBuf(ImBuf * ibuf)386 bool imb_addrectfloatImBuf(ImBuf *ibuf)
387 {
388 if (ibuf == NULL) {
389 return false;
390 }
391
392 if (ibuf->rect_float) {
393 imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */
394 }
395
396 ibuf->channels = 4;
397 if ((ibuf->rect_float = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(float), __func__))) {
398 ibuf->mall |= IB_rectfloat;
399 ibuf->flags |= IB_rectfloat;
400 return true;
401 }
402
403 return false;
404 }
405
406 /* question; why also add zbuf? */
imb_addrectImBuf(ImBuf * ibuf)407 bool imb_addrectImBuf(ImBuf *ibuf)
408 {
409 if (ibuf == NULL) {
410 return false;
411 }
412
413 /* Don't call imb_freerectImBuf, it frees mipmaps,
414 * this call is used only too give float buffers display. */
415 if (ibuf->rect && (ibuf->mall & IB_rect)) {
416 MEM_freeN(ibuf->rect);
417 }
418 ibuf->rect = NULL;
419
420 if ((ibuf->rect = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(unsigned char), __func__))) {
421 ibuf->mall |= IB_rect;
422 ibuf->flags |= IB_rect;
423 if (ibuf->planes > 32) {
424 return (addzbufImBuf(ibuf));
425 }
426
427 return true;
428 }
429
430 return false;
431 }
432
IMB_allocFromBuffer(const unsigned int * rect,const float * rectf,unsigned int w,unsigned int h,unsigned int channels)433 struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect,
434 const float *rectf,
435 unsigned int w,
436 unsigned int h,
437 unsigned int channels)
438 {
439 ImBuf *ibuf = NULL;
440
441 if (!(rect || rectf)) {
442 return NULL;
443 }
444
445 ibuf = IMB_allocImBuf(w, h, 32, 0);
446
447 ibuf->channels = channels;
448 if (rectf) {
449 ibuf->rect_float = MEM_dupallocN(rectf);
450 ibuf->flags |= IB_rectfloat;
451 ibuf->mall |= IB_rectfloat;
452 }
453 if (rect) {
454 ibuf->rect = MEM_dupallocN(rect);
455 ibuf->flags |= IB_rect;
456 ibuf->mall |= IB_rect;
457 }
458
459 return ibuf;
460 }
461
imb_addtilesImBuf(ImBuf * ibuf)462 bool imb_addtilesImBuf(ImBuf *ibuf)
463 {
464 if (ibuf == NULL) {
465 return false;
466 }
467
468 if (!ibuf->tiles) {
469 if ((ibuf->tiles = MEM_callocN(sizeof(unsigned int *) * ibuf->xtiles * ibuf->ytiles,
470 "imb_tiles"))) {
471 ibuf->mall |= IB_tiles;
472 }
473 }
474
475 return (ibuf->tiles != NULL);
476 }
477
IMB_allocImBuf(unsigned int x,unsigned int y,uchar planes,unsigned int flags)478 ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int flags)
479 {
480 ImBuf *ibuf;
481
482 ibuf = MEM_mallocN(sizeof(ImBuf), "ImBuf_struct");
483
484 if (ibuf) {
485 if (!IMB_initImBuf(ibuf, x, y, planes, flags)) {
486 IMB_freeImBuf(ibuf);
487 return NULL;
488 }
489 }
490
491 return ibuf;
492 }
493
IMB_initImBuf(struct ImBuf * ibuf,unsigned int x,unsigned int y,unsigned char planes,unsigned int flags)494 bool IMB_initImBuf(
495 struct ImBuf *ibuf, unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
496 {
497 memset(ibuf, 0, sizeof(ImBuf));
498
499 ibuf->x = x;
500 ibuf->y = y;
501 ibuf->planes = planes;
502 ibuf->ftype = IMB_FTYPE_PNG;
503 /* The '15' means, set compression to low ratio but not time consuming. */
504 ibuf->foptions.quality = 15;
505 /* float option, is set to other values when buffers get assigned. */
506 ibuf->channels = 4;
507 /* IMB_DPI_DEFAULT -> pixels-per-meter. */
508 ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254f;
509
510 if (flags & IB_rect) {
511 if (imb_addrectImBuf(ibuf) == false) {
512 return false;
513 }
514 }
515
516 if (flags & IB_rectfloat) {
517 if (imb_addrectfloatImBuf(ibuf) == false) {
518 return false;
519 }
520 }
521
522 if (flags & IB_zbuf) {
523 if (addzbufImBuf(ibuf) == false) {
524 return false;
525 }
526 }
527
528 if (flags & IB_zbuffloat) {
529 if (addzbuffloatImBuf(ibuf) == false) {
530 return false;
531 }
532 }
533
534 /* assign default spaces */
535 colormanage_imbuf_set_default_spaces(ibuf);
536
537 return true;
538 }
539
540 /* does no zbuffers? */
IMB_dupImBuf(const ImBuf * ibuf1)541 ImBuf *IMB_dupImBuf(const ImBuf *ibuf1)
542 {
543 ImBuf *ibuf2, tbuf;
544 int flags = 0;
545 int a, x, y;
546
547 if (ibuf1 == NULL) {
548 return NULL;
549 }
550
551 if (ibuf1->rect) {
552 flags |= IB_rect;
553 }
554 if (ibuf1->rect_float) {
555 flags |= IB_rectfloat;
556 }
557 if (ibuf1->zbuf) {
558 flags |= IB_zbuf;
559 }
560 if (ibuf1->zbuf_float) {
561 flags |= IB_zbuffloat;
562 }
563
564 x = ibuf1->x;
565 y = ibuf1->y;
566
567 ibuf2 = IMB_allocImBuf(x, y, ibuf1->planes, flags);
568 if (ibuf2 == NULL) {
569 return NULL;
570 }
571
572 if (flags & IB_rect) {
573 memcpy(ibuf2->rect, ibuf1->rect, ((size_t)x) * y * sizeof(int));
574 }
575
576 if (flags & IB_rectfloat) {
577 memcpy(
578 ibuf2->rect_float, ibuf1->rect_float, ((size_t)ibuf1->channels) * x * y * sizeof(float));
579 }
580
581 if (flags & IB_zbuf) {
582 memcpy(ibuf2->zbuf, ibuf1->zbuf, ((size_t)x) * y * sizeof(int));
583 }
584
585 if (flags & IB_zbuffloat) {
586 memcpy(ibuf2->zbuf_float, ibuf1->zbuf_float, ((size_t)x) * y * sizeof(float));
587 }
588
589 if (ibuf1->encodedbuffer) {
590 ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
591 if (imb_addencodedbufferImBuf(ibuf2) == false) {
592 IMB_freeImBuf(ibuf2);
593 return NULL;
594 }
595
596 memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
597 }
598
599 /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
600 tbuf = *ibuf1;
601
602 /* fix pointers */
603 tbuf.rect = ibuf2->rect;
604 tbuf.rect_float = ibuf2->rect_float;
605 tbuf.encodedbuffer = ibuf2->encodedbuffer;
606 tbuf.zbuf = ibuf2->zbuf;
607 tbuf.zbuf_float = ibuf2->zbuf_float;
608 for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
609 tbuf.mipmap[a] = NULL;
610 }
611 tbuf.dds_data.data = NULL;
612
613 /* set malloc flag */
614 tbuf.mall = ibuf2->mall;
615 tbuf.c_handle = NULL;
616 tbuf.refcounter = 0;
617
618 /* for now don't duplicate metadata */
619 tbuf.metadata = NULL;
620
621 tbuf.display_buffer_flags = NULL;
622 tbuf.colormanage_cache = NULL;
623
624 *ibuf2 = tbuf;
625
626 return ibuf2;
627 }
628
IMB_get_size_in_memory(ImBuf * ibuf)629 size_t IMB_get_size_in_memory(ImBuf *ibuf)
630 {
631 int a;
632 size_t size = 0, channel_size = 0;
633
634 size += sizeof(ImBuf);
635
636 if (ibuf->rect) {
637 channel_size += sizeof(char);
638 }
639
640 if (ibuf->rect_float) {
641 channel_size += sizeof(float);
642 }
643
644 size += channel_size * ibuf->x * ibuf->y * ibuf->channels;
645
646 if (ibuf->miptot) {
647 for (a = 0; a < ibuf->miptot; a++) {
648 if (ibuf->mipmap[a]) {
649 size += IMB_get_size_in_memory(ibuf->mipmap[a]);
650 }
651 }
652 }
653
654 if (ibuf->tiles) {
655 size += sizeof(unsigned int) * ibuf->ytiles * ibuf->xtiles;
656 }
657
658 return size;
659 }
660
661 #if 0 /* remove? - campbell */
662 /* support for cache limiting */
663
664 static void imbuf_cache_destructor(void *data)
665 {
666 ImBuf *ibuf = (ImBuf *)data;
667
668 imb_freerectImBuf(ibuf);
669 imb_freerectfloatImBuf(ibuf);
670 IMB_freezbufImBuf(ibuf);
671 IMB_freezbuffloatImBuf(ibuf);
672 freeencodedbufferImBuf(ibuf);
673
674 ibuf->c_handle = NULL;
675 }
676
677 static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
678 {
679 static MEM_CacheLimiterC *c = NULL;
680
681 if (!c) {
682 c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
683 }
684
685 return &c;
686 }
687 #endif
688