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