Merged changes in the trunk up to revision 50607.
[blender.git] / source / blender / render / intern / source / render_result.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) 2006 Blender Foundation.
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/render/intern/source/render_result.c
29  *  \ingroup render
30  */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BKE_image.h"
39 #include "BKE_global.h"
40 #include "BKE_main.h"
41 #include "BKE_report.h"
42
43 #include "BLI_fileops.h"
44 #include "BLI_listbase.h"
45 #include "BLI_path_util.h"
46 #include "BLI_rect.h"
47 #include "BLI_string.h"
48 #include "BLI_threads.h"
49 #include "BLI_utildefines.h"
50
51 #include "IMB_imbuf.h"
52 #include "IMB_imbuf_types.h"
53
54 #include "intern/openexr/openexr_multi.h"
55
56 #include "render_result.h"
57 #include "render_types.h"
58
59 #include "FRS_freestyle_config.h"
60
61 /********************************** Free *************************************/
62
63 void render_result_free(RenderResult *res)
64 {
65         if (res == NULL) return;
66
67         while (res->layers.first) {
68                 RenderLayer *rl = res->layers.first;
69                 
70                 if (rl->rectf) MEM_freeN(rl->rectf);
71                 /* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */
72                 if (rl->acolrect) MEM_freeN(rl->acolrect);
73                 if (rl->scolrect) MEM_freeN(rl->scolrect);
74                 
75                 while (rl->passes.first) {
76                         RenderPass *rpass = rl->passes.first;
77                         if (rpass->rect) MEM_freeN(rpass->rect);
78                         BLI_remlink(&rl->passes, rpass);
79                         MEM_freeN(rpass);
80                 }
81                 BLI_remlink(&res->layers, rl);
82                 MEM_freeN(rl);
83         }
84         
85         if (res->rect32)
86                 MEM_freeN(res->rect32);
87         if (res->rectz)
88                 MEM_freeN(res->rectz);
89         if (res->rectf)
90                 MEM_freeN(res->rectf);
91         if (res->text)
92                 MEM_freeN(res->text);
93         
94         MEM_freeN(res);
95 }
96
97 /* version that's compatible with fullsample buffers */
98 void render_result_free_list(ListBase *lb, RenderResult *rr)
99 {
100         RenderResult *rrnext;
101         
102         for (; rr; rr = rrnext) {
103                 rrnext = rr->next;
104                 
105                 if (lb && lb->first)
106                         BLI_remlink(lb, rr);
107                 
108                 render_result_free(rr);
109         }
110 }
111
112 /********************************* Names *************************************/
113
114 /* NOTE: OpenEXR only supports 32 chars for layer+pass names
115  * In blender we now use max 10 chars for pass, max 20 for layer */
116 static const char *get_pass_name(int passtype, int channel)
117 {
118         
119         if (passtype == SCE_PASS_COMBINED) {
120                 if (channel == -1) return "Combined";
121                 if (channel == 0) return "Combined.R";
122                 if (channel == 1) return "Combined.G";
123                 if (channel == 2) return "Combined.B";
124                 return "Combined.A";
125         }
126         if (passtype == SCE_PASS_Z) {
127                 if (channel == -1) return "Depth";
128                 return "Depth.Z";
129         }
130         if (passtype == SCE_PASS_VECTOR) {
131                 if (channel == -1) return "Vector";
132                 if (channel == 0) return "Vector.X";
133                 if (channel == 1) return "Vector.Y";
134                 if (channel == 2) return "Vector.Z";
135                 return "Vector.W";
136         }
137         if (passtype == SCE_PASS_NORMAL) {
138                 if (channel == -1) return "Normal";
139                 if (channel == 0) return "Normal.X";
140                 if (channel == 1) return "Normal.Y";
141                 return "Normal.Z";
142         }
143         if (passtype == SCE_PASS_UV) {
144                 if (channel == -1) return "UV";
145                 if (channel == 0) return "UV.U";
146                 if (channel == 1) return "UV.V";
147                 return "UV.A";
148         }
149         if (passtype == SCE_PASS_RGBA) {
150                 if (channel == -1) return "Color";
151                 if (channel == 0) return "Color.R";
152                 if (channel == 1) return "Color.G";
153                 if (channel == 2) return "Color.B";
154                 return "Color.A";
155         }
156         if (passtype == SCE_PASS_EMIT) {
157                 if (channel == -1) return "Emit";
158                 if (channel == 0) return "Emit.R";
159                 if (channel == 1) return "Emit.G";
160                 return "Emit.B";
161         }
162         if (passtype == SCE_PASS_DIFFUSE) {
163                 if (channel == -1) return "Diffuse";
164                 if (channel == 0) return "Diffuse.R";
165                 if (channel == 1) return "Diffuse.G";
166                 return "Diffuse.B";
167         }
168         if (passtype == SCE_PASS_SPEC) {
169                 if (channel == -1) return "Spec";
170                 if (channel == 0) return "Spec.R";
171                 if (channel == 1) return "Spec.G";
172                 return "Spec.B";
173         }
174         if (passtype == SCE_PASS_SHADOW) {
175                 if (channel == -1) return "Shadow";
176                 if (channel == 0) return "Shadow.R";
177                 if (channel == 1) return "Shadow.G";
178                 return "Shadow.B";
179         }
180         if (passtype == SCE_PASS_AO) {
181                 if (channel == -1) return "AO";
182                 if (channel == 0) return "AO.R";
183                 if (channel == 1) return "AO.G";
184                 return "AO.B";
185         }
186         if (passtype == SCE_PASS_ENVIRONMENT) {
187                 if (channel == -1) return "Env";
188                 if (channel == 0) return "Env.R";
189                 if (channel == 1) return "Env.G";
190                 return "Env.B";
191         }
192         if (passtype == SCE_PASS_INDIRECT) {
193                 if (channel == -1) return "Indirect";
194                 if (channel == 0) return "Indirect.R";
195                 if (channel == 1) return "Indirect.G";
196                 return "Indirect.B";
197         }
198         if (passtype == SCE_PASS_REFLECT) {
199                 if (channel == -1) return "Reflect";
200                 if (channel == 0) return "Reflect.R";
201                 if (channel == 1) return "Reflect.G";
202                 return "Reflect.B";
203         }
204         if (passtype == SCE_PASS_REFRACT) {
205                 if (channel == -1) return "Refract";
206                 if (channel == 0) return "Refract.R";
207                 if (channel == 1) return "Refract.G";
208                 return "Refract.B";
209         }
210         if (passtype == SCE_PASS_INDEXOB) {
211                 if (channel == -1) return "IndexOB";
212                 return "IndexOB.X";
213         }
214         if (passtype == SCE_PASS_INDEXMA) {
215                 if (channel == -1) return "IndexMA";
216                 return "IndexMA.X";
217         }
218         if (passtype == SCE_PASS_MIST) {
219                 if (channel == -1) return "Mist";
220                 return "Mist.Z";
221         }
222         if (passtype == SCE_PASS_RAYHITS) {
223                 if (channel == -1) return "Rayhits";
224                 if (channel == 0) return "Rayhits.R";
225                 if (channel == 1) return "Rayhits.G";
226                 return "Rayhits.B";
227         }
228         if (passtype == SCE_PASS_DIFFUSE_DIRECT) {
229                 if (channel == -1) return "DiffDir";
230                 if (channel == 0) return "DiffDir.R";
231                 if (channel == 1) return "DiffDir.G";
232                 return "DiffDir.B";
233         }
234         if (passtype == SCE_PASS_DIFFUSE_INDIRECT) {
235                 if (channel == -1) return "DiffInd";
236                 if (channel == 0) return "DiffInd.R";
237                 if (channel == 1) return "DiffInd.G";
238                 return "DiffInd.B";
239         }
240         if (passtype == SCE_PASS_DIFFUSE_COLOR) {
241                 if (channel == -1) return "DiffCol";
242                 if (channel == 0) return "DiffCol.R";
243                 if (channel == 1) return "DiffCol.G";
244                 return "DiffCol.B";
245         }
246         if (passtype == SCE_PASS_GLOSSY_DIRECT) {
247                 if (channel == -1) return "GlossDir";
248                 if (channel == 0) return "GlossDir.R";
249                 if (channel == 1) return "GlossDir.G";
250                 return "GlossDir.B";
251         }
252         if (passtype == SCE_PASS_GLOSSY_INDIRECT) {
253                 if (channel == -1) return "GlossInd";
254                 if (channel == 0) return "GlossInd.R";
255                 if (channel == 1) return "GlossInd.G";
256                 return "GlossInd.B";
257         }
258         if (passtype == SCE_PASS_GLOSSY_COLOR) {
259                 if (channel == -1) return "GlossCol";
260                 if (channel == 0) return "GlossCol.R";
261                 if (channel == 1) return "GlossCol.G";
262                 return "GlossCol.B";
263         }
264         if (passtype == SCE_PASS_TRANSM_DIRECT) {
265                 if (channel == -1) return "TransDir";
266                 if (channel == 0) return "TransDir.R";
267                 if (channel == 1) return "TransDir.G";
268                 return "TransDir.B";
269         }
270         if (passtype == SCE_PASS_TRANSM_INDIRECT) {
271                 if (channel == -1) return "TransInd";
272                 if (channel == 0) return "TransInd.R";
273                 if (channel == 1) return "TransInd.G";
274                 return "TransInd.B";
275         }
276         if (passtype == SCE_PASS_TRANSM_COLOR) {
277                 if (channel == -1) return "TransCol";
278                 if (channel == 0) return "TransCol.R";
279                 if (channel == 1) return "TransCol.G";
280                 return "TransCol.B";
281         }
282         return "Unknown";
283 }
284
285 static int passtype_from_name(const char *str)
286 {
287         
288         if (strcmp(str, "Combined") == 0)
289                 return SCE_PASS_COMBINED;
290
291         if (strcmp(str, "Depth") == 0)
292                 return SCE_PASS_Z;
293
294         if (strcmp(str, "Vector") == 0)
295                 return SCE_PASS_VECTOR;
296
297         if (strcmp(str, "Normal") == 0)
298                 return SCE_PASS_NORMAL;
299
300         if (strcmp(str, "UV") == 0)
301                 return SCE_PASS_UV;
302
303         if (strcmp(str, "Color") == 0)
304                 return SCE_PASS_RGBA;
305
306         if (strcmp(str, "Emit") == 0)
307                 return SCE_PASS_EMIT;
308
309         if (strcmp(str, "Diffuse") == 0)
310                 return SCE_PASS_DIFFUSE;
311
312         if (strcmp(str, "Spec") == 0)
313                 return SCE_PASS_SPEC;
314
315         if (strcmp(str, "Shadow") == 0)
316                 return SCE_PASS_SHADOW;
317         
318         if (strcmp(str, "AO") == 0)
319                 return SCE_PASS_AO;
320
321         if (strcmp(str, "Env") == 0)
322                 return SCE_PASS_ENVIRONMENT;
323
324         if (strcmp(str, "Indirect") == 0)
325                 return SCE_PASS_INDIRECT;
326
327         if (strcmp(str, "Reflect") == 0)
328                 return SCE_PASS_REFLECT;
329
330         if (strcmp(str, "Refract") == 0)
331                 return SCE_PASS_REFRACT;
332
333         if (strcmp(str, "IndexOB") == 0)
334                 return SCE_PASS_INDEXOB;
335
336         if (strcmp(str, "IndexMA") == 0)
337                 return SCE_PASS_INDEXMA;
338
339         if (strcmp(str, "Mist") == 0)
340                 return SCE_PASS_MIST;
341         
342         if (strcmp(str, "RayHits") == 0)
343                 return SCE_PASS_RAYHITS;
344
345         if (strcmp(str, "DiffDir") == 0)
346                 return SCE_PASS_DIFFUSE_DIRECT;
347
348         if (strcmp(str, "DiffInd") == 0)
349                 return SCE_PASS_DIFFUSE_INDIRECT;
350
351         if (strcmp(str, "DiffCol") == 0)
352                 return SCE_PASS_DIFFUSE_COLOR;
353
354         if (strcmp(str, "GlossDir") == 0)
355                 return SCE_PASS_GLOSSY_DIRECT;
356
357         if (strcmp(str, "GlossInd") == 0)
358                 return SCE_PASS_GLOSSY_INDIRECT;
359
360         if (strcmp(str, "GlossCol") == 0)
361                 return SCE_PASS_GLOSSY_COLOR;
362
363         if (strcmp(str, "TransDir") == 0)
364                 return SCE_PASS_TRANSM_DIRECT;
365
366         if (strcmp(str, "TransInd") == 0)
367                 return SCE_PASS_TRANSM_INDIRECT;
368
369         if (strcmp(str, "TransCol") == 0)
370                 return SCE_PASS_TRANSM_COLOR;
371
372         return 0;
373 }
374
375 /********************************** New **************************************/
376
377 static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
378 {
379         const char *typestr = get_pass_name(passtype, 0);
380         RenderPass *rpass = MEM_callocN(sizeof(RenderPass), typestr);
381         int rectsize = rr->rectx * rr->recty * channels;
382         
383         BLI_addtail(&rl->passes, rpass);
384         rpass->passtype = passtype;
385         rpass->channels = channels;
386         rpass->rectx = rl->rectx;
387         rpass->recty = rl->recty;
388         BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
389         
390         if (rl->exrhandle) {
391                 int a;
392                 for (a = 0; a < channels; a++)
393                         IMB_exr_add_channel(rl->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
394         }
395         else {
396                 float *rect;
397                 int x;
398                 
399                 rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, typestr);
400                 
401                 if (passtype == SCE_PASS_VECTOR) {
402                         /* initialize to max speed */
403                         rect = rpass->rect;
404                         for (x = rectsize - 1; x >= 0; x--)
405                                 rect[x] = PASS_VECTOR_MAX;
406                 }
407                 else if (passtype == SCE_PASS_Z) {
408                         rect = rpass->rect;
409                         for (x = rectsize - 1; x >= 0; x--)
410                                 rect[x] = 10e10;
411                 }
412         }
413 }
414
415 /* called by main render as well for parts */
416 /* will read info from Render *re to define layers */
417 /* called in threads */
418 /* re->winx,winy is coordinate space of entire image, partrct the part within */
419 RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers, const char *layername)
420 {
421         RenderResult *rr;
422         RenderLayer *rl;
423         SceneRenderLayer *srl;
424         int rectx, recty, nr;
425         
426         rectx = BLI_RCT_SIZE_X(partrct);
427         recty = BLI_RCT_SIZE_Y(partrct);
428         
429         if (rectx <= 0 || recty <= 0)
430                 return NULL;
431         
432         rr = MEM_callocN(sizeof(RenderResult), "new render result");
433         rr->rectx = rectx;
434         rr->recty = recty;
435         rr->renrect.xmin = 0; rr->renrect.xmax = rectx - 2 * crop;
436         /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
437         rr->crop = crop;
438         
439         /* tilerect is relative coordinates within render disprect. do not subtract crop yet */
440         rr->tilerect.xmin = partrct->xmin - re->disprect.xmin;
441         rr->tilerect.xmax = partrct->xmax - re->disprect.xmin;
442         rr->tilerect.ymin = partrct->ymin - re->disprect.ymin;
443         rr->tilerect.ymax = partrct->ymax - re->disprect.ymin;
444         
445         if (savebuffers) {
446                 rr->do_exr_tile = TRUE;
447         }
448
449         /* check renderdata for amount of layers */
450         for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) {
451
452                 if (layername && layername[0])
453                         if (strcmp(srl->name, layername) != 0)
454                                 continue;
455
456                 if ((re->r.scemode & R_SINGLE_LAYER) && nr != re->r.actlay)
457                         continue;
458                 if (srl->layflag & SCE_LAY_DISABLE)
459                         continue;
460                 
461                 rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
462                 BLI_addtail(&rr->layers, rl);
463                 
464                 BLI_strncpy(rl->name, srl->name, sizeof(rl->name));
465                 rl->lay = srl->lay;
466                 rl->lay_zmask = srl->lay_zmask;
467                 rl->lay_exclude = srl->lay_exclude;
468                 rl->layflag = srl->layflag;
469                 rl->passflag = srl->passflag; /* for debugging: srl->passflag | SCE_PASS_RAYHITS; */
470                 rl->pass_xor = srl->pass_xor;
471                 rl->light_override = srl->light_override;
472                 rl->mat_override = srl->mat_override;
473                 rl->rectx = rectx;
474                 rl->recty = recty;
475                 
476                 if (rr->do_exr_tile) {
477                         rl->exrhandle = IMB_exr_get_handle();
478
479                         IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
480                         IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
481                         IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
482                         IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
483                 }
484                 else
485                         rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba");
486                 
487                 if (srl->passflag  & SCE_PASS_Z)
488                         render_layer_add_pass(rr, rl, 1, SCE_PASS_Z);
489                 if (srl->passflag  & SCE_PASS_VECTOR)
490                         render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR);
491                 if (srl->passflag  & SCE_PASS_NORMAL)
492                         render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL);
493                 if (srl->passflag  & SCE_PASS_UV) 
494                         render_layer_add_pass(rr, rl, 3, SCE_PASS_UV);
495                 if (srl->passflag  & SCE_PASS_RGBA)
496                         render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA);
497                 if (srl->passflag  & SCE_PASS_EMIT)
498                         render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT);
499                 if (srl->passflag  & SCE_PASS_DIFFUSE)
500                         render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);
501                 if (srl->passflag  & SCE_PASS_SPEC)
502                         render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);
503                 if (srl->passflag  & SCE_PASS_AO)
504                         render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
505                 if (srl->passflag  & SCE_PASS_ENVIRONMENT)
506                         render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT);
507                 if (srl->passflag  & SCE_PASS_INDIRECT)
508                         render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT);
509                 if (srl->passflag  & SCE_PASS_SHADOW)
510                         render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
511                 if (srl->passflag  & SCE_PASS_REFLECT)
512                         render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT);
513                 if (srl->passflag  & SCE_PASS_REFRACT)
514                         render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT);
515                 if (srl->passflag  & SCE_PASS_INDEXOB)
516                         render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB);
517                 if (srl->passflag  & SCE_PASS_INDEXMA)
518                         render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA);
519                 if (srl->passflag  & SCE_PASS_MIST)
520                         render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST);
521                 if (rl->passflag & SCE_PASS_RAYHITS)
522                         render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS);
523                 if (srl->passflag  & SCE_PASS_DIFFUSE_DIRECT)
524                         render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT);
525                 if (srl->passflag  & SCE_PASS_DIFFUSE_INDIRECT)
526                         render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT);
527                 if (srl->passflag  & SCE_PASS_DIFFUSE_COLOR)
528                         render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR);
529                 if (srl->passflag  & SCE_PASS_GLOSSY_DIRECT)
530                         render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT);
531                 if (srl->passflag  & SCE_PASS_GLOSSY_INDIRECT)
532                         render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT);
533                 if (srl->passflag  & SCE_PASS_GLOSSY_COLOR)
534                         render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_COLOR);
535                 if (srl->passflag  & SCE_PASS_TRANSM_DIRECT)
536                         render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_DIRECT);
537                 if (srl->passflag  & SCE_PASS_TRANSM_INDIRECT)
538                         render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT);
539                 if (srl->passflag  & SCE_PASS_TRANSM_COLOR)
540                         render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR);
541                 
542         }
543         /* sss, previewrender and envmap don't do layers, so we make a default one */
544         if (rr->layers.first == NULL && !(layername && layername[0])) {
545                 rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
546                 BLI_addtail(&rr->layers, rl);
547                 
548                 rl->rectx = rectx;
549                 rl->recty = recty;
550
551                 /* duplicate code... */
552                 if (rr->do_exr_tile) {
553                         rl->exrhandle = IMB_exr_get_handle();
554
555                         IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
556                         IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
557                         IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
558                         IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
559                 }
560                 else {
561                         rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba");
562                 }
563                 
564                 /* note, this has to be in sync with scene.c */
565                 rl->lay = (1 << 20) - 1;
566                 rl->layflag = 0x7FFF;    /* solid ztra halo strand */
567                 rl->passflag = SCE_PASS_COMBINED;
568                 FRS_add_freestyle_config( srl );
569                 
570                 re->r.actlay = 0;
571         }
572         
573         /* border render; calculate offset for use in compositor. compo is centralized coords */
574         rr->xof = re->disprect.xmin + BLI_RCT_CENTER_X(&re->disprect) - (re->winx / 2);
575         rr->yof = re->disprect.ymin + BLI_RCT_CENTER_Y(&re->disprect) - (re->winy / 2);
576         
577         return rr;
578 }
579
580 /* allocate osa new results for samples */
581 RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers)
582 {
583         int a;
584         
585         if (re->osa == 0)
586                 return render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS);
587         
588         for (a = 0; a < re->osa; a++) {
589                 RenderResult *rr = render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS);
590                 BLI_addtail(lb, rr);
591                 rr->sample_nr = a;
592         }
593         
594         return lb->first;
595 }
596
597 /* callbacks for render_result_new_from_exr */
598 static void *ml_addlayer_cb(void *base, const char *str)
599 {
600         RenderResult *rr = base;
601         RenderLayer *rl;
602         
603         rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
604         BLI_addtail(&rr->layers, rl);
605         
606         BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME);
607         return rl;
608 }
609
610 static void ml_addpass_cb(void *UNUSED(base), void *lay, const char *str, float *rect, int totchan, const char *chan_id)
611 {
612         RenderLayer *rl = lay;
613         RenderPass *rpass = MEM_callocN(sizeof(RenderPass), "loaded pass");
614         int a;
615         
616         BLI_addtail(&rl->passes, rpass);
617         rpass->channels = totchan;
618
619         rpass->passtype = passtype_from_name(str);
620         if (rpass->passtype == 0) printf("unknown pass %s\n", str);
621         rl->passflag |= rpass->passtype;
622         
623         BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME);
624         /* channel id chars */
625         for (a = 0; a < totchan; a++)
626                 rpass->chan_id[a] = chan_id[a];
627         
628         rpass->rect = rect;
629 }
630
631 /* from imbuf, if a handle was returned we convert this to render result */
632 RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty)
633 {
634         RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
635         RenderLayer *rl;
636         RenderPass *rpass;
637         
638         rr->rectx = rectx;
639         rr->recty = recty;
640         
641         IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb);
642
643         for (rl = rr->layers.first; rl; rl = rl->next) {
644                 rl->rectx = rectx;
645                 rl->recty = recty;
646
647                 for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
648                         rpass->rectx = rectx;
649                         rpass->recty = recty;
650                 }
651         }
652         
653         return rr;
654 }
655
656 /*********************************** Merge ***********************************/
657
658 static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
659 {
660         int y, ofs, copylen, tilex, tiley;
661         
662         copylen = tilex = rrpart->rectx;
663         tiley = rrpart->recty;
664         
665         if (rrpart->crop) { /* filters add pixel extra */
666                 tile += pixsize * (rrpart->crop + rrpart->crop * tilex);
667                 
668                 copylen = tilex - 2 * rrpart->crop;
669                 tiley -= 2 * rrpart->crop;
670                 
671                 ofs = (rrpart->tilerect.ymin + rrpart->crop) * rr->rectx + (rrpart->tilerect.xmin + rrpart->crop);
672                 target += pixsize * ofs;
673         }
674         else {
675                 ofs = (rrpart->tilerect.ymin * rr->rectx + rrpart->tilerect.xmin);
676                 target += pixsize * ofs;
677         }
678
679         copylen *= sizeof(float) * pixsize;
680         tilex *= pixsize;
681         ofs = pixsize * rr->rectx;
682
683         for (y = 0; y < tiley; y++) {
684                 memcpy(target, tile, copylen);
685                 target += ofs;
686                 tile += tilex;
687         }
688 }
689
690 /* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
691 /* no test happens here if it fits... we also assume layers are in sync */
692 /* is used within threads */
693 void render_result_merge(RenderResult *rr, RenderResult *rrpart)
694 {
695         RenderLayer *rl, *rlp;
696         RenderPass *rpass, *rpassp;
697         
698         for (rl = rr->layers.first; rl; rl = rl->next) {
699                 rlp = RE_GetRenderLayer(rrpart, rl->name);
700                 if (rlp) {
701                         /* combined */
702                         if (rl->rectf && rlp->rectf)
703                                 do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
704
705                         /* passes are allocated in sync */
706                         for (rpass = rl->passes.first, rpassp = rlp->passes.first;
707                              rpass && rpassp;
708                              rpass = rpass->next, rpassp = rpassp->next)
709                         {
710                                 do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
711                         }
712                 }
713         }
714 }
715
716 /* for passes read from files, these have names stored */
717 static char *make_pass_name(RenderPass *rpass, int chan)
718 {
719         static char name[16];
720         int len;
721         
722         BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME);
723         len = strlen(name);
724         name[len] = '.';
725         name[len + 1] = rpass->chan_id[chan];
726         name[len + 2] = 0;
727
728         return name;
729 }
730
731 /* filename already made absolute */
732 /* called from within UI, saves both rendered result as a file-read result */
733 int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress)
734 {
735         RenderLayer *rl;
736         RenderPass *rpass;
737         void *exrhandle = IMB_exr_get_handle();
738         int success;
739
740         BLI_make_existing_file(filename);
741         
742         /* composite result */
743         if (rr->rectf) {
744                 IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4 * rr->rectx, rr->rectf);
745                 IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4 * rr->rectx, rr->rectf + 1);
746                 IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4 * rr->rectx, rr->rectf + 2);
747                 IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4 * rr->rectx, rr->rectf + 3);
748         }
749         
750         /* add layers/passes and assign channels */
751         for (rl = rr->layers.first; rl; rl = rl->next) {
752                 
753                 /* combined */
754                 if (rl->rectf) {
755                         int a, xstride = 4;
756                         for (a = 0; a < xstride; a++) {
757                                 IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
758                                                     xstride, xstride * rr->rectx, rl->rectf + a);
759                         }
760                 }
761                 
762                 /* passes are allocated in sync */
763                 for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
764                         int a, xstride = rpass->channels;
765                         for (a = 0; a < xstride; a++) {
766                                 if (rpass->passtype) {
767                                         IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
768                                                             xstride, xstride * rr->rectx, rpass->rect + a);
769                                 }
770                                 else {
771                                         IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a),
772                                                             xstride, xstride * rr->rectx, rpass->rect + a);
773                                 }
774                         }
775                 }
776         }
777
778         /* when the filename has no permissions, this can fail */
779         if (IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) {
780                 IMB_exr_write_channels(exrhandle);
781                 success = TRUE;
782         }
783         else {
784                 /* TODO, get the error from openexr's exception */
785                 BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console");
786                 success = FALSE;
787         }
788         IMB_exr_close(exrhandle);
789
790         return success;
791 }
792
793 /**************************** Single Layer Rendering *************************/
794
795 void render_result_single_layer_begin(Render *re)
796 {
797         /* all layers except the active one get temporally pushed away */
798
799         /* officially pushed result should be NULL... error can happen with do_seq */
800         RE_FreeRenderResult(re->pushedresult);
801         
802         re->pushedresult = re->result;
803         re->result = NULL;
804 }
805
806 /* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */
807 void render_result_single_layer_end(Render *re)
808 {
809         SceneRenderLayer *srl;
810         RenderLayer *rlpush;
811         RenderLayer *rl;
812         int nr;
813
814         if (re->result == NULL) {
815                 printf("pop render result error; no current result!\n");
816                 return;
817         }
818
819         if (!re->pushedresult)
820                 return;
821
822         if (re->pushedresult->rectx == re->result->rectx && re->pushedresult->recty == re->result->recty) {
823                 /* find which layer in re->pushedresult should be replaced */
824                 rl = re->result->layers.first;
825                 
826                 /* render result should be empty after this */
827                 BLI_remlink(&re->result->layers, rl);
828                 
829                 /* reconstruct render result layers */
830                 for (nr = 0, srl = re->scene->r.layers.first; srl; srl = srl->next, nr++) {
831                         if (nr == re->r.actlay) {
832                                 BLI_addtail(&re->result->layers, rl);
833                         }
834                         else {
835                                 rlpush = RE_GetRenderLayer(re->pushedresult, srl->name);
836                                 if (rlpush) {
837                                         BLI_remlink(&re->pushedresult->layers, rlpush);
838                                         BLI_addtail(&re->result->layers, rlpush);
839                                 }
840                         }
841                 }
842         }
843
844         RE_FreeRenderResult(re->pushedresult);
845         re->pushedresult = NULL;
846 }
847
848 /************************* EXR Tile File Rendering ***************************/
849
850 static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
851 {
852         RenderLayer *rlp, *rl;
853         RenderPass *rpassp;
854         int offs, partx, party;
855         
856         BLI_lock_thread(LOCK_IMAGE);
857         
858         for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
859                 rl = RE_GetRenderLayer(rr, rlp->name);
860
861                 /* should never happen but prevents crash if it does */
862                 BLI_assert(rl);
863                 if (UNLIKELY(rl == NULL)) {
864                         continue;
865                 }
866
867                 if (rrpart->crop) { /* filters add pixel extra */
868                         offs = (rrpart->crop + rrpart->crop * rrpart->rectx);
869                 }
870                 else {
871                         offs = 0;
872                 }
873                 
874                 /* combined */
875                 if (rlp->rectf) {
876                         int a, xstride = 4;
877                         for (a = 0; a < xstride; a++) {
878                                 IMB_exr_set_channel(rl->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a), 
879                                                     xstride, xstride * rrpart->rectx, rlp->rectf + a + xstride * offs);
880                         }
881                 }
882                 
883                 /* passes are allocated in sync */
884                 for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) {
885                         int a, xstride = rpassp->channels;
886                         for (a = 0; a < xstride; a++) {
887                                 IMB_exr_set_channel(rl->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a), 
888                                                     xstride, xstride * rrpart->rectx, rpassp->rect + a + xstride * offs);
889                         }
890                 }
891                 
892         }
893
894         party = rrpart->tilerect.ymin + rrpart->crop;
895         partx = rrpart->tilerect.xmin + rrpart->crop;
896
897         for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
898                 rl = RE_GetRenderLayer(rr, rlp->name);
899
900                 /* should never happen but prevents crash if it does */
901                 BLI_assert(rl);
902                 if (UNLIKELY(rl == NULL)) {
903                         continue;
904                 }
905
906                 IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
907         }
908
909         BLI_unlock_thread(LOCK_IMAGE);
910 }
911
912 static void save_empty_result_tiles(Render *re)
913 {
914         RenderPart *pa;
915         RenderResult *rr;
916         RenderLayer *rl;
917         
918         for (rr = re->result; rr; rr = rr->next) {
919                 for (rl = rr->layers.first; rl; rl = rl->next) {
920                         IMB_exrtile_clear_channels(rl->exrhandle);
921                 
922                         for (pa = re->parts.first; pa; pa = pa->next) {
923                                 if (pa->ready == 0) {
924                                         int party = pa->disprect.ymin - re->disprect.ymin + pa->crop;
925                                         int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop;
926                                         IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
927                                 }
928                         }
929                 }
930         }
931 }
932
933 /* begin write of exr tile file */
934 void render_result_exr_file_begin(Render *re)
935 {
936         RenderResult *rr;
937         RenderLayer *rl;
938         char str[FILE_MAX];
939
940         for (rr = re->result; rr; rr = rr->next) {
941                 for (rl = rr->layers.first; rl; rl = rl->next) {
942                         render_result_exr_file_path(re->scene, rl->name, rr->sample_nr, str);
943                         printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
944                         IMB_exrtile_begin_write(rl->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
945                 }
946         }
947 }
948
949 /* end write of exr tile file, read back first sample */
950 void render_result_exr_file_end(Render *re)
951 {
952         RenderResult *rr;
953         RenderLayer *rl;
954
955         save_empty_result_tiles(re);
956         
957         for (rr = re->result; rr; rr = rr->next) {
958                 for (rl = rr->layers.first; rl; rl = rl->next) {
959                         IMB_exr_close(rl->exrhandle);
960                         rl->exrhandle = NULL;
961                 }
962
963                 rr->do_exr_tile = FALSE;
964         }
965         
966         render_result_free_list(&re->fullresult, re->result);
967         re->result = NULL;
968
969         render_result_exr_file_read(re, 0);
970 }
971
972 /* save part into exr file */
973 void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart)
974 {
975         for (; rr && rrpart; rr = rr->next, rrpart = rrpart->next)
976                 save_render_result_tile(rr, rrpart);
977 }
978
979 /* path to temporary exr file */
980 void render_result_exr_file_path(Scene *scene, const char *layname, int sample, char *filepath)
981 {
982         char di[FILE_MAX], name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100], fi[FILE_MAXFILE];
983         
984         BLI_strncpy(di, G.main->name, FILE_MAX);
985         BLI_splitdirstring(di, fi);
986         
987         if (sample == 0)
988                 BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
989         else
990                 BLI_snprintf(name, sizeof(name), "%s_%s_%s%d.exr", fi, scene->id.name + 2, layname, sample);
991
992         BLI_make_file_string("/", filepath, BLI_temporary_dir(), name);
993 }
994
995 /* only for temp buffer files, makes exact copy of render result */
996 int render_result_exr_file_read(Render *re, int sample)
997 {
998         RenderLayer *rl;
999         char str[FILE_MAX];
1000         int success = TRUE;
1001
1002         RE_FreeRenderResult(re->result);
1003         re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
1004
1005         for (rl = re->result->layers.first; rl; rl = rl->next) {
1006
1007                 render_result_exr_file_path(re->scene, rl->name, sample, str);
1008                 printf("read exr tmp file: %s\n", str);
1009
1010                 if (!render_result_exr_file_read_path(re->result, rl, str)) {
1011                         printf("cannot read: %s\n", str);
1012                         success = FALSE;
1013
1014                 }
1015         }
1016
1017         return success;
1018 }
1019
1020 /* called for reading temp files, and for external engines */
1021 int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, const char *filepath)
1022 {
1023         RenderLayer *rl;
1024         RenderPass *rpass;
1025         void *exrhandle = IMB_exr_get_handle();
1026         int rectx, recty;
1027
1028         if (IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty) == 0) {
1029                 printf("failed being read %s\n", filepath);
1030                 IMB_exr_close(exrhandle);
1031                 return 0;
1032         }
1033
1034         if (rr == NULL || rectx != rr->rectx || recty != rr->recty) {
1035                 if (rr)
1036                         printf("error in reading render result: dimensions don't match\n");
1037                 else
1038                         printf("error in reading render result: NULL result pointer\n");
1039                 IMB_exr_close(exrhandle);
1040                 return 0;
1041         }
1042
1043         for (rl = rr->layers.first; rl; rl = rl->next) {
1044                 if (rl_single && rl_single != rl)
1045                         continue;
1046
1047                 /* combined */
1048                 if (rl->rectf) {
1049                         int a, xstride = 4;
1050                         for (a = 0; a < xstride; a++)
1051                                 IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a), 
1052                                                     xstride, xstride * rectx, rl->rectf + a);
1053                 }
1054                 
1055                 /* passes are allocated in sync */
1056                 for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
1057                         int a, xstride = rpass->channels;
1058                         for (a = 0; a < xstride; a++)
1059                                 IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), 
1060                                                     xstride, xstride * rectx, rpass->rect + a);
1061
1062                         BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
1063                 }
1064         }
1065
1066         IMB_exr_read_channels(exrhandle);
1067         IMB_exr_close(exrhandle);
1068
1069         return 1;
1070 }
1071
1072 /*************************** Combined Pixel Rect *****************************/
1073
1074 ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
1075 {
1076         int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) ? IB_cm_predivide : 0;
1077         ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags);
1078         
1079         /* if not exists, BKE_imbuf_write makes one */
1080         ibuf->rect = (unsigned int *)rr->rect32;
1081         ibuf->rect_float = rr->rectf;
1082         ibuf->zbuf_float = rr->rectz;
1083         
1084         /* float factor for random dither, imbuf takes care of it */
1085         ibuf->dither = rd->dither_intensity;
1086         
1087         /* prepare to gamma correct to sRGB color space */
1088         if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
1089                 /* sequence editor can generate 8bpc render buffers */
1090                 if (ibuf->rect) {
1091                         ibuf->profile = IB_PROFILE_SRGB;
1092                         if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32))
1093                                 IMB_float_from_rect(ibuf);
1094                 }
1095                 else {
1096                         ibuf->profile = IB_PROFILE_LINEAR_RGB;
1097                 }
1098         }
1099
1100         /* color -> grayscale */
1101         /* editing directly would alter the render view */
1102         if (rd->im_format.planes == R_IMF_PLANES_BW) {
1103                 ImBuf *ibuf_bw = IMB_dupImBuf(ibuf);
1104                 IMB_color_to_bw(ibuf_bw);
1105                 IMB_freeImBuf(ibuf);
1106                 ibuf = ibuf_bw;
1107         }
1108
1109         return ibuf;
1110 }
1111
1112 void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf)
1113 {
1114         if (ibuf->rect_float) {
1115                 /* color management: when off ensure rectf is non-lin, since thats what the internal
1116                  * render engine delivers */
1117                 int profile_to = (rd->color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB;
1118                 int profile_from = (ibuf->profile == IB_PROFILE_LINEAR_RGB) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB;
1119                 int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
1120
1121                 if (!rr->rectf)
1122                         rr->rectf = MEM_mallocN(4 * sizeof(float) * rr->rectx * rr->recty, "render_seq rectf");
1123                 
1124                 IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float,
1125                                             4, profile_to, profile_from, predivide,
1126                                             rr->rectx, rr->recty, rr->rectx, rr->rectx);
1127                 
1128                 /* TSK! Since sequence render doesn't free the *rr render result, the old rect32
1129                  * can hang around when sequence render has rendered a 32 bits one before */
1130                 if (rr->rect32) {
1131                         MEM_freeN(rr->rect32);
1132                         rr->rect32 = NULL;
1133                 }
1134         }
1135         else if (ibuf->rect) {
1136                 if (!rr->rect32)
1137                         rr->rect32 = MEM_mallocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
1138
1139                 memcpy(rr->rect32, ibuf->rect, 4 * rr->rectx * rr->recty);
1140
1141                 /* Same things as above, old rectf can hang around from previous render. */
1142                 if (rr->rectf) {
1143                         MEM_freeN(rr->rectf);
1144                         rr->rectf = NULL;
1145                 }
1146         }
1147 }
1148
1149 void render_result_rect_fill_zero(RenderResult *rr)
1150 {
1151         if (rr->rectf)
1152                 memset(rr->rectf, 0, 4 * sizeof(float) * rr->rectx * rr->recty);
1153         else if (rr->rect32)
1154                 memset(rr->rect32, 0, 4 * rr->rectx * rr->recty);
1155         else
1156                 rr->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
1157 }
1158
1159 void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty)
1160 {
1161         if (rr->rect32) {
1162                 memcpy(rect, rr->rect32, sizeof(int) * rr->rectx * rr->recty);
1163         }
1164         else if (rr->rectf) {
1165                 int profile_from = (rd->color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB;
1166                 int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
1167                 int dither = 0;
1168
1169                 IMB_buffer_byte_from_float((unsigned char *)rect, rr->rectf,
1170                                            4, dither, IB_PROFILE_SRGB, profile_from, predivide,
1171                                            rr->rectx, rr->recty, rr->rectx, rr->rectx);
1172         }
1173         else
1174                 /* else fill with black */
1175                 memset(rect, 0, sizeof(int) * rectx * recty);
1176 }
1177