Fix buffer overflows in TIFF, PNG, IRIS, DPX, HDR and AVI loading.
[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 imb_free_bitmap_font(ImBuf *ibuf)
159 {
160         if (ibuf->userdata && (ibuf->userflags & IB_BITMAPFONT)) {
161                 MEM_freeN(ibuf->userdata);
162         }
163 }
164
165 static void freeencodedbufferImBuf(ImBuf *ibuf)
166 {
167         if (ibuf == NULL) return;
168
169         if (ibuf->encodedbuffer && (ibuf->mall & IB_mem))
170                 MEM_freeN(ibuf->encodedbuffer);
171
172         ibuf->encodedbuffer = NULL;
173         ibuf->encodedbuffersize = 0;
174         ibuf->encodedsize = 0;
175         ibuf->mall &= ~IB_mem;
176 }
177
178 void IMB_freezbufImBuf(ImBuf *ibuf)
179 {
180         if (ibuf == NULL) return;
181
182         if (ibuf->zbuf && (ibuf->mall & IB_zbuf))
183                 MEM_freeN(ibuf->zbuf);
184
185         ibuf->zbuf = NULL;
186         ibuf->mall &= ~IB_zbuf;
187 }
188
189 void IMB_freezbuffloatImBuf(ImBuf *ibuf)
190 {
191         if (ibuf == NULL) return;
192
193         if (ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat))
194                 MEM_freeN(ibuf->zbuf_float);
195
196         ibuf->zbuf_float = NULL;
197         ibuf->mall &= ~IB_zbuffloat;
198 }
199
200 void IMB_freeImBuf(ImBuf *ibuf)
201 {
202         if (ibuf) {
203                 bool needs_free = false;
204
205                 BLI_spin_lock(&refcounter_spin);
206                 if (ibuf->refcounter > 0) {
207                         ibuf->refcounter--;
208                 }
209                 else {
210                         needs_free = true;
211                 }
212                 BLI_spin_unlock(&refcounter_spin);
213
214                 if (needs_free) {
215                         imb_freerectImBuf(ibuf);
216                         imb_freerectfloatImBuf(ibuf);
217                         imb_freetilesImBuf(ibuf);
218                         imb_free_bitmap_font(ibuf);
219                         IMB_freezbufImBuf(ibuf);
220                         IMB_freezbuffloatImBuf(ibuf);
221                         freeencodedbufferImBuf(ibuf);
222                         IMB_metadata_free(ibuf);
223                         colormanage_cache_free(ibuf);
224
225                         if (ibuf->dds_data.data != NULL) {
226                                 free(ibuf->dds_data.data); /* dds_data.data is allocated by DirectDrawSurface::readData(), so don't use MEM_freeN! */
227                         }
228                         MEM_freeN(ibuf);
229                 }
230         }
231 }
232
233 void IMB_refImBuf(ImBuf *ibuf)
234 {
235         BLI_spin_lock(&refcounter_spin);
236         ibuf->refcounter++;
237         BLI_spin_unlock(&refcounter_spin);
238 }
239
240 ImBuf *IMB_makeSingleUser(ImBuf *ibuf)
241 {
242         ImBuf *rval;
243
244         if (ibuf) {
245                 bool is_single;
246                 BLI_spin_lock(&refcounter_spin);
247                 is_single = (ibuf->refcounter == 0);
248                 BLI_spin_unlock(&refcounter_spin);
249                 if (is_single) {
250                         return ibuf;
251                 }
252         }
253         else {
254                 return NULL;
255         }
256
257         rval = IMB_dupImBuf(ibuf);
258
259         IMB_metadata_copy(rval, ibuf);
260
261         IMB_freeImBuf(ibuf);
262
263         return rval;
264 }
265
266 bool addzbufImBuf(ImBuf *ibuf)
267 {
268         if (ibuf == NULL) return false;
269         
270         IMB_freezbufImBuf(ibuf);
271         
272         if ((ibuf->zbuf = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(unsigned int), __func__))) {
273                 ibuf->mall |= IB_zbuf;
274                 ibuf->flags |= IB_zbuf;
275                 return true;
276         }
277         
278         return false;
279 }
280
281 bool addzbuffloatImBuf(ImBuf *ibuf)
282 {
283         if (ibuf == NULL) return false;
284         
285         IMB_freezbuffloatImBuf(ibuf);
286         
287         if ((ibuf->zbuf_float = imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(float), __func__))) {
288                 ibuf->mall |= IB_zbuffloat;
289                 ibuf->flags |= IB_zbuffloat;
290                 return true;
291         }
292         
293         return false;
294 }
295
296
297 bool imb_addencodedbufferImBuf(ImBuf *ibuf)
298 {
299         if (ibuf == NULL) return false;
300
301         freeencodedbufferImBuf(ibuf);
302
303         if (ibuf->encodedbuffersize == 0)
304                 ibuf->encodedbuffersize = 10000;
305
306         ibuf->encodedsize = 0;
307
308         if ((ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, __func__))) {
309                 ibuf->mall |= IB_mem;
310                 ibuf->flags |= IB_mem;
311                 return true;
312         }
313
314         return false;
315 }
316
317
318 bool imb_enlargeencodedbufferImBuf(ImBuf *ibuf)
319 {
320         unsigned int newsize, encodedsize;
321         void *newbuffer;
322
323         if (ibuf == NULL) return false;
324
325         if (ibuf->encodedbuffersize < ibuf->encodedsize) {
326                 printf("%s: error in parameters\n", __func__);
327                 return false;
328         }
329
330         newsize = 2 * ibuf->encodedbuffersize;
331         if (newsize < 10000) newsize = 10000;
332
333         newbuffer = MEM_mallocN(newsize, __func__);
334         if (newbuffer == NULL) return false;
335
336         if (ibuf->encodedbuffer) {
337                 memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize);
338         }
339         else {
340                 ibuf->encodedsize = 0;
341         }
342
343         encodedsize = ibuf->encodedsize;
344
345         freeencodedbufferImBuf(ibuf);
346
347         ibuf->encodedbuffersize = newsize;
348         ibuf->encodedsize = encodedsize;
349         ibuf->encodedbuffer = newbuffer;
350         ibuf->mall |= IB_mem;
351         ibuf->flags |= IB_mem;
352
353         return true;
354 }
355
356 void *imb_alloc_pixels(unsigned int x,
357                        unsigned int y,
358                        unsigned int channels,
359                        size_t typesize,
360                        const char *name)
361 {
362         /* Protect against buffer overflow vulnerabilities from files specifying
363          * a width and height that overflow and alloc too little memory. */
364         if (!((uint64_t)x * (uint64_t)y < (SIZE_MAX / (channels * typesize)))) {
365                 return NULL;
366         }
367
368         size_t size = (size_t)x * (size_t)y * (size_t)channels * typesize;
369         return MEM_mapallocN(size, name);
370 }
371
372 bool imb_addrectfloatImBuf(ImBuf *ibuf)
373 {
374         if (ibuf == NULL) return false;
375         
376         if (ibuf->rect_float)
377                 imb_freerectfloatImBuf(ibuf);  /* frees mipmap too, hrm */
378         
379         ibuf->channels = 4;
380         if ((ibuf->rect_float = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(float), __func__))) {
381                 ibuf->mall |= IB_rectfloat;
382                 ibuf->flags |= IB_rectfloat;
383                 return true;
384         }
385         
386         return false;
387 }
388
389 /* question; why also add zbuf? */
390 bool imb_addrectImBuf(ImBuf *ibuf)
391 {
392         if (ibuf == NULL) return false;
393         
394         /* don't call imb_freerectImBuf, it frees mipmaps, this call is used only too give float buffers display */
395         if (ibuf->rect && (ibuf->mall & IB_rect))
396                 MEM_freeN(ibuf->rect);
397         ibuf->rect = NULL;
398         
399         if ((ibuf->rect = imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(unsigned char), __func__))) {
400                 ibuf->mall |= IB_rect;
401                 ibuf->flags |= IB_rect;
402                 if (ibuf->planes > 32) {
403                         return (addzbufImBuf(ibuf));
404                 }
405                 else {
406                         return true;
407                 }
408         }
409
410         return false;
411 }
412
413 struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect, const float *rectf,
414                                   unsigned int w, unsigned int h)
415 {
416         ImBuf *ibuf = NULL;
417
418         if (!(rect || rectf))
419                 return NULL;
420
421         ibuf = IMB_allocImBuf(w, h, 32, 0);
422
423         if (rectf) {
424                 ibuf->rect_float = MEM_dupallocN(rectf);
425                 ibuf->flags |= IB_rectfloat;
426                 ibuf->mall |= IB_rectfloat;
427         }
428         if (rect) {
429                 ibuf->rect = MEM_dupallocN(rect);
430                 ibuf->flags |= IB_rect;
431                 ibuf->mall |= IB_rect;
432         }
433
434         return ibuf;
435 }
436
437 bool imb_addtilesImBuf(ImBuf *ibuf)
438 {
439         if (ibuf == NULL) return false;
440
441         if (!ibuf->tiles)
442                 if ((ibuf->tiles = MEM_callocN(sizeof(unsigned int *) * ibuf->xtiles * ibuf->ytiles, "imb_tiles")))
443                         ibuf->mall |= IB_tiles;
444
445         return (ibuf->tiles != NULL);
446 }
447
448 ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar planes, unsigned int flags)
449 {
450         ImBuf *ibuf;
451
452         ibuf = MEM_mallocN(sizeof(ImBuf), "ImBuf_struct");
453
454         if (ibuf) {
455                 if (!IMB_initImBuf(ibuf, x, y, planes, flags)) {
456                         IMB_freeImBuf(ibuf);
457                         return NULL;
458                 }
459         }
460
461         return (ibuf);
462 }
463
464 bool IMB_initImBuf(struct ImBuf *ibuf,
465                    unsigned int x, unsigned int y,
466                    unsigned char planes, unsigned int flags)
467 {
468         memset(ibuf, 0, sizeof(ImBuf));
469
470         ibuf->x = x;
471         ibuf->y = y;
472         ibuf->planes = planes;
473         ibuf->ftype = IMB_FTYPE_PNG;
474         ibuf->foptions.quality = 15; /* the 15 means, set compression to low ratio but not time consuming */
475         ibuf->channels = 4;  /* float option, is set to other values when buffers get assigned */
476         ibuf->ppm[0] = ibuf->ppm[1] = IMB_DPI_DEFAULT / 0.0254f; /* IMB_DPI_DEFAULT -> pixels-per-meter */
477
478         if (flags & IB_rect) {
479                 if (imb_addrectImBuf(ibuf) == false) {
480                         return false;
481                 }
482         }
483
484         if (flags & IB_rectfloat) {
485                 if (imb_addrectfloatImBuf(ibuf) == false) {
486                         return false;
487                 }
488         }
489
490         if (flags & IB_zbuf) {
491                 if (addzbufImBuf(ibuf) == false) {
492                         return false;
493                 }
494         }
495
496         if (flags & IB_zbuffloat) {
497                 if (addzbuffloatImBuf(ibuf) == false) {
498                         return false;
499                 }
500         }
501
502         /* assign default spaces */
503         colormanage_imbuf_set_default_spaces(ibuf);
504
505         return true;
506 }
507
508 /* does no zbuffers? */
509 ImBuf *IMB_dupImBuf(const ImBuf *ibuf1)
510 {
511         ImBuf *ibuf2, tbuf;
512         int flags = 0;
513         int a, x, y;
514         
515         if (ibuf1 == NULL) return NULL;
516
517         if (ibuf1->rect) flags |= IB_rect;
518         if (ibuf1->rect_float) flags |= IB_rectfloat;
519         if (ibuf1->zbuf) flags |= IB_zbuf;
520         if (ibuf1->zbuf_float) flags |= IB_zbuffloat;
521
522         x = ibuf1->x;
523         y = ibuf1->y;
524         if (ibuf1->flags & IB_fields) y *= 2;
525         
526         ibuf2 = IMB_allocImBuf(x, y, ibuf1->planes, flags);
527         if (ibuf2 == NULL) return NULL;
528
529         if (flags & IB_rect)
530                 memcpy(ibuf2->rect, ibuf1->rect, ((size_t)x) * y * sizeof(int));
531         
532         if (flags & IB_rectfloat)
533                 memcpy(ibuf2->rect_float, ibuf1->rect_float, ((size_t)ibuf1->channels) * x * y * sizeof(float));
534
535         if (flags & IB_zbuf)
536                 memcpy(ibuf2->zbuf, ibuf1->zbuf, ((size_t)x) * y * sizeof(int));
537
538         if (flags & IB_zbuffloat)
539                 memcpy(ibuf2->zbuf_float, ibuf1->zbuf_float, ((size_t)x) * y * sizeof(float));
540
541         if (ibuf1->encodedbuffer) {
542                 ibuf2->encodedbuffersize = ibuf1->encodedbuffersize;
543                 if (imb_addencodedbufferImBuf(ibuf2) == false) {
544                         IMB_freeImBuf(ibuf2);
545                         return NULL;
546                 }
547
548                 memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize);
549         }
550
551         /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */
552         tbuf = *ibuf1;
553         
554         /* fix pointers */
555         tbuf.rect          = ibuf2->rect;
556         tbuf.rect_float    = ibuf2->rect_float;
557         tbuf.encodedbuffer = ibuf2->encodedbuffer;
558         tbuf.zbuf          = ibuf2->zbuf;
559         tbuf.zbuf_float    = ibuf2->zbuf_float;
560         for (a = 0; a < IMB_MIPMAP_LEVELS; a++)
561                 tbuf.mipmap[a] = NULL;
562         tbuf.dds_data.data = NULL;
563         
564         /* set malloc flag */
565         tbuf.mall               = ibuf2->mall;
566         tbuf.c_handle           = NULL;
567         tbuf.refcounter         = 0;
568
569         /* for now don't duplicate metadata */
570         tbuf.metadata = NULL;
571
572         tbuf.display_buffer_flags = NULL;
573         tbuf.colormanage_cache = NULL;
574
575         *ibuf2 = tbuf;
576
577         return(ibuf2);
578 }
579
580 #if 0 /* remove? - campbell */
581 /* support for cache limiting */
582
583 static void imbuf_cache_destructor(void *data)
584 {
585         ImBuf *ibuf = (ImBuf *) data;
586
587         imb_freerectImBuf(ibuf);
588         imb_freerectfloatImBuf(ibuf);
589         IMB_freezbufImBuf(ibuf);
590         IMB_freezbuffloatImBuf(ibuf);
591         freeencodedbufferImBuf(ibuf);
592
593         ibuf->c_handle = NULL;
594 }
595
596
597 static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
598 {
599         static MEM_CacheLimiterC *c = NULL;
600
601         if (!c)
602                 c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
603
604         return &c;
605 }
606 #endif