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