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