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