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