style cleanup: follow style guide for formatting of if/for/while loops, and else...
[blender.git] / source / blender / render / intern / source / render_result.c
1 /*  
2  *
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. 
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * The Original Code is Copyright (C) 2006 Blender Foundation.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file blender/render/intern/source/render_result.c
30  *  \ingroup render
31  */
32
33 #include <stdio.h>
34 #include <string.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BKE_image.h"
39 #include "BKE_global.h"
40 #include "BKE_main.h"
41 #include "BKE_report.h"
42 #include "BKE_utildefines.h"
43
44 #include "BLI_fileops.h"
45 #include "BLI_listbase.h"
46 #include "BLI_path_util.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 (rr->exrhandle) {
389                 int a;
390                 for (a=0; a<channels; a++)
391                         IMB_exr_add_channel(rr->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)
418 {
419         RenderResult *rr;
420         RenderLayer *rl;
421         SceneRenderLayer *srl;
422         int rectx, recty, nr;
423         
424         rectx= partrct->xmax - partrct->xmin;
425         recty= partrct->ymax - partrct->ymin;
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.xmax;
440         rr->tilerect.ymin = partrct->ymin - re->disprect.ymin;
441         rr->tilerect.ymax = partrct->ymax - re->disprect.ymax;
442         
443         if (savebuffers) {
444                 rr->exrhandle= IMB_exr_get_handle();
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 ((re->r.scemode & R_SINGLE_LAYER) && nr!=re->r.actlay)
451                         continue;
452                 if (srl->layflag & SCE_LAY_DISABLE)
453                         continue;
454                 
455                 rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
456                 BLI_addtail(&rr->layers, rl);
457                 
458                 BLI_strncpy(rl->name, srl->name, sizeof(rl->name));
459                 rl->lay= srl->lay;
460                 rl->lay_zmask= srl->lay_zmask;
461                 rl->layflag= srl->layflag;
462                 rl->passflag= srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS;
463                 rl->pass_xor= srl->pass_xor;
464                 rl->light_override= srl->light_override;
465                 rl->mat_override= srl->mat_override;
466                 rl->rectx= rectx;
467                 rl->recty= recty;
468                 
469                 if (rr->exrhandle) {
470                         IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
471                         IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
472                         IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
473                         IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
474                 }
475                 else
476                         rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");
477                 
478                 if (srl->passflag  & SCE_PASS_Z)
479                         render_layer_add_pass(rr, rl, 1, SCE_PASS_Z);
480                 if (srl->passflag  & SCE_PASS_VECTOR)
481                         render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR);
482                 if (srl->passflag  & SCE_PASS_NORMAL)
483                         render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL);
484                 if (srl->passflag  & SCE_PASS_UV) 
485                         render_layer_add_pass(rr, rl, 3, SCE_PASS_UV);
486                 if (srl->passflag  & SCE_PASS_RGBA)
487                         render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA);
488                 if (srl->passflag  & SCE_PASS_EMIT)
489                         render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT);
490                 if (srl->passflag  & SCE_PASS_DIFFUSE)
491                         render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);
492                 if (srl->passflag  & SCE_PASS_SPEC)
493                         render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);
494                 if (srl->passflag  & SCE_PASS_AO)
495                         render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
496                 if (srl->passflag  & SCE_PASS_ENVIRONMENT)
497                         render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT);
498                 if (srl->passflag  & SCE_PASS_INDIRECT)
499                         render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT);
500                 if (srl->passflag  & SCE_PASS_SHADOW)
501                         render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
502                 if (srl->passflag  & SCE_PASS_REFLECT)
503                         render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT);
504                 if (srl->passflag  & SCE_PASS_REFRACT)
505                         render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT);
506                 if (srl->passflag  & SCE_PASS_INDEXOB)
507                         render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB);
508                 if (srl->passflag  & SCE_PASS_INDEXMA)
509                         render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA);
510                 if (srl->passflag  & SCE_PASS_MIST)
511                         render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST);
512                 if (rl->passflag & SCE_PASS_RAYHITS)
513                         render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS);
514                 if (srl->passflag  & SCE_PASS_DIFFUSE_DIRECT)
515                         render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT);
516                 if (srl->passflag  & SCE_PASS_DIFFUSE_INDIRECT)
517                         render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT);
518                 if (srl->passflag  & SCE_PASS_DIFFUSE_COLOR)
519                         render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR);
520                 if (srl->passflag  & SCE_PASS_GLOSSY_DIRECT)
521                         render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT);
522                 if (srl->passflag  & SCE_PASS_GLOSSY_INDIRECT)
523                         render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT);
524                 if (srl->passflag  & SCE_PASS_GLOSSY_COLOR)
525                         render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_COLOR);
526                 if (srl->passflag  & SCE_PASS_TRANSM_DIRECT)
527                         render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_DIRECT);
528                 if (srl->passflag  & SCE_PASS_TRANSM_INDIRECT)
529                         render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT);
530                 if (srl->passflag  & SCE_PASS_TRANSM_COLOR)
531                         render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR);
532                 
533         }
534         /* sss, previewrender and envmap don't do layers, so we make a default one */
535         if (rr->layers.first==NULL) {
536                 rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
537                 BLI_addtail(&rr->layers, rl);
538                 
539                 rl->rectx= rectx;
540                 rl->recty= recty;
541
542                 /* duplicate code... */
543                 if (rr->exrhandle) {
544                         IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
545                         IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
546                         IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
547                         IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
548                 }
549                 else
550                         rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");
551                 
552                 /* note, this has to be in sync with scene.c */
553                 rl->lay= (1<<20) -1;
554                 rl->layflag= 0x7FFF;    /* solid ztra halo strand */
555                 rl->passflag= SCE_PASS_COMBINED;
556                 
557                 re->r.actlay= 0;
558         }
559         
560         /* border render; calculate offset for use in compositor. compo is centralized coords */
561         rr->xof= re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin)/2 - re->winx/2;
562         rr->yof= re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin)/2 - re->winy/2;
563         
564         return rr;
565 }
566
567 /* allocate osa new results for samples */
568 RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers)
569 {
570         int a;
571         
572         if (re->osa==0)
573                 return render_result_new(re, partrct, crop, savebuffers);
574         
575         for (a=0; a<re->osa; a++) {
576                 RenderResult *rr= render_result_new(re, partrct, crop, savebuffers);
577                 BLI_addtail(lb, rr);
578                 rr->sample_nr= a;
579         }
580         
581         return lb->first;
582 }
583
584 /* callbacks for render_result_new_from_exr */
585 static void *ml_addlayer_cb(void *base, char *str)
586 {
587         RenderResult *rr= base;
588         RenderLayer *rl;
589         
590         rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
591         BLI_addtail(&rr->layers, rl);
592         
593         BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME);
594         return rl;
595 }
596
597 static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id)
598 {
599         RenderLayer *rl= lay;   
600         RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass");
601         int a;
602         
603         BLI_addtail(&rl->passes, rpass);
604         rpass->channels= totchan;
605
606         rpass->passtype= passtype_from_name(str);
607         if (rpass->passtype==0) printf("unknown pass %s\n", str);
608         rl->passflag |= rpass->passtype;
609         
610         BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME);
611         /* channel id chars */
612         for (a=0; a<totchan; a++)
613                 rpass->chan_id[a]= chan_id[a];
614         
615         rpass->rect= rect;
616 }
617
618 /* from imbuf, if a handle was returned we convert this to render result */
619 RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty)
620 {
621         RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result");
622         RenderLayer *rl;
623         RenderPass *rpass;
624         
625         rr->rectx= rectx;
626         rr->recty= recty;
627         
628         IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb);
629
630         for (rl=rr->layers.first; rl; rl=rl->next) {
631                 rl->rectx= rectx;
632                 rl->recty= recty;
633
634                 for (rpass=rl->passes.first; rpass; rpass=rpass->next) {
635                         rpass->rectx= rectx;
636                         rpass->recty= recty;
637                 }
638         }
639         
640         return rr;
641 }
642
643 /*********************************** Merge ***********************************/
644
645 static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
646 {
647         int y, ofs, copylen, tilex, tiley;
648         
649         copylen= tilex= rrpart->rectx;
650         tiley= rrpart->recty;
651         
652         if (rrpart->crop) {     /* filters add pixel extra */
653                 tile+= pixsize*(rrpart->crop + rrpart->crop*tilex);
654                 
655                 copylen= tilex - 2*rrpart->crop;
656                 tiley -= 2*rrpart->crop;
657                 
658                 ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
659                 target+= pixsize*ofs;
660         }
661         else {
662                 ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
663                 target+= pixsize*ofs;
664         }
665
666         copylen *= sizeof(float)*pixsize;
667         tilex *= pixsize;
668         ofs= pixsize*rr->rectx;
669
670         for (y=0; y<tiley; y++) {
671                 memcpy(target, tile, copylen);
672                 target+= ofs;
673                 tile+= tilex;
674         }
675 }
676
677 /* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
678 /* no test happens here if it fits... we also assume layers are in sync */
679 /* is used within threads */
680 void render_result_merge(RenderResult *rr, RenderResult *rrpart)
681 {
682         RenderLayer *rl, *rlp;
683         RenderPass *rpass, *rpassp;
684         
685         for (rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
686                 
687                 /* combined */
688                 if (rl->rectf && rlp->rectf)
689                         do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
690                 
691                 /* passes are allocated in sync */
692                 for (rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) {
693                         do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
694                 }
695         }
696 }
697
698 /* for passes read from files, these have names stored */
699 static char *make_pass_name(RenderPass *rpass, int chan)
700 {
701         static char name[16];
702         int len;
703         
704         BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME);
705         len= strlen(name);
706         name[len]= '.';
707         name[len+1]= rpass->chan_id[chan];
708         name[len+2]= 0;
709
710         return name;
711 }
712
713 /* filename already made absolute */
714 /* called from within UI, saves both rendered result as a file-read result */
715 int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress)
716 {
717         RenderLayer *rl;
718         RenderPass *rpass;
719         void *exrhandle= IMB_exr_get_handle();
720         int success;
721
722         BLI_make_existing_file(filename);
723         
724         /* composite result */
725         if (rr->rectf) {
726                 IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4*rr->rectx, rr->rectf);
727                 IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4*rr->rectx, rr->rectf+1);
728                 IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4*rr->rectx, rr->rectf+2);
729                 IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4*rr->rectx, rr->rectf+3);
730         }
731         
732         /* add layers/passes and assign channels */
733         for (rl= rr->layers.first; rl; rl= rl->next) {
734                 
735                 /* combined */
736                 if (rl->rectf) {
737                         int a, xstride= 4;
738                         for (a=0; a<xstride; a++)
739                                 IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a), 
740                                                                         xstride, xstride*rr->rectx, rl->rectf+a);
741                 }
742                 
743                 /* passes are allocated in sync */
744                 for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
745                         int a, xstride= rpass->channels;
746                         for (a=0; a<xstride; a++) {
747                                 if (rpass->passtype)
748                                         IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), 
749                                                                                 xstride, xstride*rr->rectx, rpass->rect+a);
750                                 else
751                                         IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), 
752                                                                                 xstride, xstride*rr->rectx, rpass->rect+a);
753                         }
754                 }
755         }
756
757         /* when the filename has no permissions, this can fail */
758         if (IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) {
759                 IMB_exr_write_channels(exrhandle);
760                 success= TRUE;
761         }
762         else {
763                 /* TODO, get the error from openexr's exception */
764                 BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console");
765                 success= FALSE;
766         }
767         IMB_exr_close(exrhandle);
768
769         return success;
770 }
771
772 /**************************** Single Layer Rendering *************************/
773
774 void render_result_single_layer_begin(Render *re)
775 {
776         /* all layers except the active one get temporally pushed away */
777
778         /* officially pushed result should be NULL... error can happen with do_seq */
779         RE_FreeRenderResult(re->pushedresult);
780         
781         re->pushedresult= re->result;
782         re->result= NULL;
783 }
784
785 /* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */
786 void render_result_single_layer_end(Render *re)
787 {
788         SceneRenderLayer *srl;
789         RenderLayer *rlpush;
790         RenderLayer *rl;
791         int nr;
792
793         if (re->result==NULL) {
794                 printf("pop render result error; no current result!\n");
795                 return;
796         }
797
798         if (!re->pushedresult)
799                 return;
800
801         if (re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) {
802                 /* find which layer in re->pushedresult should be replaced */
803                 rl= re->result->layers.first;
804                 
805                 /* render result should be empty after this */
806                 BLI_remlink(&re->result->layers, rl);
807                 
808                 /* reconstruct render result layers */
809                 for (nr=0, srl= re->scene->r.layers.first; srl; srl= srl->next, nr++) {
810                         if (nr==re->r.actlay)
811                                 BLI_addtail(&re->result->layers, rl);
812                         else {
813                                 rlpush= RE_GetRenderLayer(re->pushedresult, srl->name);
814                                 if (rlpush) {
815                                         BLI_remlink(&re->pushedresult->layers, rlpush);
816                                         BLI_addtail(&re->result->layers, rlpush);
817                                 }
818                         }
819                 }
820         }
821
822         RE_FreeRenderResult(re->pushedresult);
823         re->pushedresult= NULL;
824 }
825
826 /************************* EXR Tile File Rendering ***************************/
827
828 static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
829 {
830         RenderLayer *rlp;
831         RenderPass *rpassp;
832         int offs, partx, party;
833         
834         BLI_lock_thread(LOCK_IMAGE);
835         
836         for (rlp= rrpart->layers.first; rlp; rlp= rlp->next) {
837                 
838                 if (rrpart->crop) {     /* filters add pixel extra */
839                         offs= (rrpart->crop + rrpart->crop*rrpart->rectx);
840                 }
841                 else {
842                         offs= 0;
843                 }
844                 
845                 /* combined */
846                 if (rlp->rectf) {
847                         int a, xstride= 4;
848                         for (a=0; a<xstride; a++)
849                                 IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a), 
850                                                                 xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs);
851                 }
852                 
853                 /* passes are allocated in sync */
854                 for (rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) {
855                         int a, xstride= rpassp->channels;
856                         for (a=0; a<xstride; a++)
857                                 IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a), 
858                                                                         xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs);
859                 }
860                 
861         }
862
863         party= rrpart->tilerect.ymin + rrpart->crop;
864         partx= rrpart->tilerect.xmin + rrpart->crop;
865         IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
866
867         BLI_unlock_thread(LOCK_IMAGE);
868 }
869
870 static void save_empty_result_tiles(Render *re)
871 {
872         RenderPart *pa;
873         RenderResult *rr;
874         
875         for (rr= re->result; rr; rr= rr->next) {
876                 IMB_exrtile_clear_channels(rr->exrhandle);
877                 
878                 for (pa= re->parts.first; pa; pa= pa->next) {
879                         if (pa->ready==0) {
880                                 int party= pa->disprect.ymin - re->disprect.ymin + pa->crop;
881                                 int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop;
882                                 IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
883                         }
884                 }
885         }
886 }
887
888 /* begin write of exr tile file */
889 void render_result_exr_file_begin(Render *re)
890 {
891         RenderResult *rr;
892         char str[FILE_MAX];
893         
894         for (rr= re->result; rr; rr= rr->next) {
895                 render_result_exr_file_path(re->scene, rr->sample_nr, str);
896         
897                 printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
898                 IMB_exrtile_begin_write(rr->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
899         }
900 }
901
902 /* end write of exr tile file, read back first sample */
903 void render_result_exr_file_end(Render *re)
904 {
905         RenderResult *rr;
906
907         save_empty_result_tiles(re);
908         
909         for (rr= re->result; rr; rr= rr->next) {
910                 IMB_exr_close(rr->exrhandle);
911                 rr->exrhandle= NULL;
912         }
913         
914         render_result_free_list(&re->fullresult, re->result);
915         re->result= NULL;
916
917         render_result_exr_file_read(re, 0);
918 }
919
920 /* save part into exr file */
921 void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart)
922 {
923         for (; rr && rrpart; rr= rr->next, rrpart= rrpart->next)
924                 save_render_result_tile(rr, rrpart);
925 }
926
927 /* path to temporary exr file */
928 void render_result_exr_file_path(Scene *scene, int sample, char *filepath)
929 {
930         char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE];
931         
932         BLI_strncpy(di, G.main->name, FILE_MAX);
933         BLI_splitdirstring(di, fi);
934         
935         if (sample==0)
936                 BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name+2);
937         else
938                 BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name+2, sample);
939
940         BLI_make_file_string("/", filepath, BLI_temporary_dir(), name);
941 }
942
943 /* only for temp buffer files, makes exact copy of render result */
944 int render_result_exr_file_read(Render *re, int sample)
945 {
946         char str[FILE_MAX];
947         int success;
948
949         RE_FreeRenderResult(re->result);
950         re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM);
951
952         render_result_exr_file_path(re->scene, sample, str);
953         printf("read exr tmp file: %s\n", str);
954
955         if (render_result_exr_file_read_path(re->result, str)) {
956                 success= TRUE;
957         }
958         else {
959                 printf("cannot read: %s\n", str);
960                 success= FALSE;
961
962         }
963
964         return success;
965 }
966
967 /* called for reading temp files, and for external engines */
968 int render_result_exr_file_read_path(RenderResult *rr, const char *filepath)
969 {
970         RenderLayer *rl;
971         RenderPass *rpass;
972         void *exrhandle= IMB_exr_get_handle();
973         int rectx, recty;
974
975         if (IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty)==0) {
976                 printf("failed being read %s\n", filepath);
977                 IMB_exr_close(exrhandle);
978                 return 0;
979         }
980
981         if (rr == NULL || rectx!=rr->rectx || recty!=rr->recty) {
982                 if (rr)
983                         printf("error in reading render result: dimensions don't match\n");
984                 else
985                         printf("error in reading render result: NULL result pointer\n");
986                 IMB_exr_close(exrhandle);
987                 return 0;
988         }
989
990         for (rl= rr->layers.first; rl; rl= rl->next) {
991                 /* combined */
992                 if (rl->rectf) {
993                         int a, xstride= 4;
994                         for (a=0; a<xstride; a++)
995                                 IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a), 
996                                                                         xstride, xstride*rectx, rl->rectf+a);
997                 }
998                 
999                 /* passes are allocated in sync */
1000                 for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
1001                         int a, xstride= rpass->channels;
1002                         for (a=0; a<xstride; a++)
1003                                 IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a), 
1004                                                                         xstride, xstride*rectx, rpass->rect+a);
1005
1006                         BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
1007                 }
1008         }
1009
1010         IMB_exr_read_channels(exrhandle);
1011         IMB_exr_close(exrhandle);
1012
1013         return 1;
1014 }
1015
1016 /*************************** Combined Pixel Rect *****************************/
1017
1018 ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
1019 {
1020         int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE)? IB_cm_predivide: 0;
1021         ImBuf *ibuf= IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags);
1022         
1023         /* if not exists, BKE_write_ibuf makes one */
1024         ibuf->rect= (unsigned int *)rr->rect32;    
1025         ibuf->rect_float= rr->rectf;
1026         ibuf->zbuf_float= rr->rectz;
1027         
1028         /* float factor for random dither, imbuf takes care of it */
1029         ibuf->dither= rd->dither_intensity;
1030         
1031         /* prepare to gamma correct to sRGB color space */
1032         if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
1033                 /* sequence editor can generate 8bpc render buffers */
1034                 if (ibuf->rect) {
1035                         ibuf->profile = IB_PROFILE_SRGB;
1036                         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))
1037                                 IMB_float_from_rect(ibuf);
1038                 }
1039                 else {
1040                         ibuf->profile = IB_PROFILE_LINEAR_RGB;
1041                 }
1042         }
1043
1044         /* color -> greyscale */
1045         /* editing directly would alter the render view */
1046         if (rd->im_format.planes == R_IMF_PLANES_BW) {
1047                 ImBuf *ibuf_bw= IMB_dupImBuf(ibuf);
1048                 IMB_color_to_bw(ibuf_bw);
1049                 IMB_freeImBuf(ibuf);
1050                 ibuf= ibuf_bw;
1051         }
1052
1053         return ibuf;
1054 }
1055
1056 void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf)
1057 {
1058         if (ibuf->rect_float) {
1059                 /* color management: when off ensure rectf is non-lin, since thats what the internal
1060                  * render engine delivers */
1061                 int profile_to= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
1062                 int profile_from= (ibuf->profile == IB_PROFILE_LINEAR_RGB)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
1063                 int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
1064
1065                 if (!rr->rectf)
1066                         rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
1067                 
1068                 IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float,
1069                         4, profile_to, profile_from, predivide,
1070                         rr->rectx, rr->recty, rr->rectx, rr->rectx);
1071                 
1072                 /* TSK! Since sequence render doesn't free the *rr render result, the old rect32
1073                  * can hang around when sequence render has rendered a 32 bits one before */
1074                 if (rr->rect32) {
1075                         MEM_freeN(rr->rect32);
1076                         rr->rect32= NULL;
1077                 }
1078         }
1079         else if (ibuf->rect) {
1080                 if (!rr->rect32)
1081                         rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
1082
1083                 memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty);
1084
1085                 /* Same things as above, old rectf can hang around from previous render. */
1086                 if (rr->rectf) {
1087                         MEM_freeN(rr->rectf);
1088                         rr->rectf= NULL;
1089                 }
1090         }
1091 }
1092
1093 void render_result_rect_fill_zero(RenderResult *rr)
1094 {
1095         if (rr->rectf)
1096                 memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty);
1097         else if (rr->rect32)
1098                 memset(rr->rect32, 0, 4*rr->rectx*rr->recty);
1099         else
1100                 rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
1101 }
1102
1103 void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty)
1104 {
1105         if (rr->rect32) {
1106                 memcpy(rect, rr->rect32, sizeof(int)*rr->rectx*rr->recty);
1107         }
1108         else if (rr->rectf) {
1109                 int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
1110                 int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
1111                 int dither= 0;
1112
1113                 IMB_buffer_byte_from_float((unsigned char*)rect, rr->rectf,
1114                         4, dither, IB_PROFILE_SRGB, profile_from, predivide,
1115                         rr->rectx, rr->recty, rr->rectx, rr->rectx);
1116         }
1117         else
1118                 /* else fill with black */
1119                 memset(rect, 0, sizeof(int)*rectx*recty);
1120 }
1121