ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/evalglare.c
Revision: 2.12
Committed: Tue Jun 3 21:31:51 2025 UTC (51 minutes, 2 seconds ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.11: +2 -4 lines
Log Message:
refactor: More consistent use of global char * progname and fixargv0()

File Contents

# User Rev Content
1 greg 2.2 #ifndef lint
2 greg 2.12 static const char RCSid[] = "$Id: evalglare.c,v 2.11 2020/06/30 15:57:30 greg Exp $";
3 greg 2.2 #endif
4 greg 2.11 /* EVALGLARE V2.10
5 greg 2.3 * Evalglare Software License, Version 2.0
6 greg 2.1 *
7 greg 2.11 * Copyright (c) 1995 - 2020 Fraunhofer ISE, EPFL.
8 greg 2.1 * All rights reserved.
9     *
10     *
11     * Redistribution and use in source and binary forms, WITHOUT
12     * modification, are permitted provided that the following all conditions
13     * are met:
14     *
15     * 1. Redistributions of source code must retain the above copyright
16     * notice, this list of conditions and the following disclaimer.
17     *
18     * 2. Redistributions in binary form must reproduce the above copyright
19     * notice, this list of conditions and the following disclaimer in
20     * the documentation and/or other materials provided with the
21     * distribution.
22     *
23     * 3. The end-user documentation included with the redistribution,
24     * if any, must include the following acknowledgments:
25     * "This product includes the evalglare software,
26 greg 2.3 developed at Fraunhofer ISE and EPFL by J. Wienold" and
27 greg 2.1 * "This product includes Radiance software
28     * (http://radsite.lbl.gov/)
29     * developed by the Lawrence Berkeley National Laboratory
30     * (http://www.lbl.gov/)."
31     * Alternately, this acknowledgment may appear in the software itself,
32     * if and wherever such third-party acknowledgments normally appear.
33     *
34 greg 2.3 * 4. The names "Evalglare," "EPFL" and "Fraunhofer ISE" must
35 greg 2.1 * not be used to endorse or promote products derived from this
36     * software without prior written permission. For written
37     * permission, please contact [email protected]
38     *
39     * 5. Products derived from this software may not be called "evalglare",
40     * nor may "evalglare" appear in their name, without prior written
41 greg 2.3 * permission of EPFL.
42 greg 2.1 *
43     * Redistribution and use in source and binary forms, WITH
44     * modification, are permitted provided that the following conditions
45     * are met:
46     *
47     *
48     * conditions 1.-5. apply
49     *
50     * 6. In order to ensure scientific correctness, any modification in source code imply fulfilling all following comditions:
51 greg 2.3 * a) A written permission from EPFL. For written permission, please contact [email protected].
52 greg 2.1 * b) The permission can be applied via email and must contain the applied changes in source code and at least two example calculations,
53     * comparing the results of the modified version and the current version of evalglare.
54     * b) Any redistribution of a modified version of evalglare must contain following note:
55     * "This software uses a modified version of the source code of evalglare."
56     *
57     *
58     *
59     *
60     * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
61     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
62     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63     * DISCLAIMED. IN NO EVENT SHALL Fraunhofer ISE OR
64     * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
65     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
66     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
67     * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
68     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
69     * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
70     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71     * SUCH DAMAGE.
72     * ====================================================================
73     *
74     * This product includes Radiance software
75     * (http://radsite.lbl.gov/)
76     * developed by the Lawrence Berkeley National Laboratory
77     * (http://www.lbl.gov/).
78     *
79     * The Radiance Software License, Version 1.0
80     *
81     * Copyright (c) 1990 - 2009 The Regents of the University of California,
82     * through Lawrence Berkeley National Laboratory. All rights reserved.
83     *
84     * Redistribution and use in source and binary forms, with or without
85     * modification, are permitted provided that the following conditions
86     * are met:
87     *
88     * 1. Redistributions of source code must retain the above copyright
89     * notice, this list of conditions and the following disclaimer.
90     *
91     * 2. Redistributions in binary form must reproduce the above copyright
92     * notice, this list of conditions and the following disclaimer in
93     * the documentation and/or other materials provided with the
94     * distribution.
95     *
96     * 3. The end-user documentation included with the redistribution,
97     * if any, must include the following acknowledgment:
98     * "This product includes Radiance software
99     * (http://radsite.lbl.gov/)
100     * developed by the Lawrence Berkeley National Laboratory
101     * (http://www.lbl.gov/)."
102     * Alternately, this acknowledgment may appear in the software itself,
103     * if and wherever such third-party acknowledgments normally appear.
104     *
105     * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
106     * and "The Regents of the University of California" must
107     * not be used to endorse or promote products derived from this
108     * software without prior written permission. For written
109     * permission, please contact [email protected].
110     *
111     * 5. Products derived from this software may not be called "Radiance",
112     * nor may "Radiance" appear in their name, without prior written
113     * permission of Lawrence Berkeley National Laboratory.
114     *
115     * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
116     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
117     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118     * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
119     * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
120     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
121     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
122     * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
123     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
124     * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
125     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
126     * SUCH DAMAGE.
127     */
128    
129     /* evalglare.c, v0.2 2005/08/21 18:00:00 wienold */
130     /* evalglare.c, v0.3 2006/06/01 16:20:00 wienold
131     changes to the v02 version:
132     -fix problem with non-square pictures
133     -set luminance values in the hemisphere behind the line of sight to 0
134     -fix error in vcp calculation */
135     /* evalglare.c, v0.4 2006/11/13 15:10:00 wienold
136     changes to the v03 version:
137     -fix problem with tabulator in picture header "cannot read view"
138     -fix missing pixels in task area
139     evalglare.c, v0.5 2006/11/29 9:30 wienold
140     changes to the v04 version:
141     - fix problem with glare sources at the edge of the picture
142     */
143     /* evalglare.c, v0.6 2006/11/29 9:30 wienold
144     changes to the v05 version:
145     - add luminance restriction parameters in order to take into account restrictions of measuring systems
146     */
147    
148     /* evalglare.c, v0.7 2007/07/11 18:00 wienold
149     changes to the v06 version:
150     - add external provision of vertical illuminance
151     */
152    
153     /* evalglare.c, v0.8 2007/12/04 1:35 wienold
154     changes to the v07 version:
155     - limit dgp to max 1.0
156     - fill up cutted pictures with last known values
157     - add second detailed output
158     */
159    
160     /* evalglare.c, v0.9 2008/07/02 wienold
161     changes to the v08 version:
162     - add version number in picheader
163     - add option for showing version numer
164     */
165     /* evalglare.c, v0.9a 2008/09/20 wienold
166     changes to the v09 version:
167     - reduce fix value threshold from 500 to 100
168     */
169    
170     /* evalglare.c, v0.9b 2008/11/12 wienold
171     changes to the v09a version:
172     - check view type vta, if wrong than exit
173     */
174     /* evalglare.c, v0.9c 2009/03/31 wienold
175     changes to the v09b version:
176     - peak extraction is default now (-y) , for deactivation use -x
177     */
178    
179     /* evalglare.c, v0.9d 2009/06/24 wienold
180     changes to the v09c version:
181     - fixed memory problem while using strcat
182     */
183     /* evalglare.c, v0.9e 2009/10/10 wienold
184     changes to the v09d version:
185     - fixed problem while reading .pic of windows version
186     */
187     /* evalglare.c, v0.9f 2009/10/21 wienold
188     changes to the v09e version:
189     - piping of input pictures possible, allow also vtv and vtc viewtyps
190     */
191    
192     /* evalglare.c, v0.9g 2009/10/21 wienold
193     changes to the v09f version:
194     - modified pictool.c
195     - added -V (calc only vertical illuminance)
196     */
197     /* evalglare.c, v0.9h 2011/10/10 wienold
198     changes to the v09g version:
199     - include disability glare for age factor of 1
200     -
201     */
202     /* evalglare.c, v0.9i 2011/10/17 wienold
203     changes to the v09h version:
204     - M option: Correct wrong (measured) luminance images by feeding Ev and a luminance value, which should be replaced
205    
206     */
207     /* evalglare.c, v1.0 2012/02/08 wienold
208     changes to the v09h version:
209     - include all view types
210     - check view option in header
211     - add view options in command line
212     - option for cutting out GUTH field of view
213    
214     */
215    
216     /* evalglare.c, v1.02 2012/03/01 wienold,reetz,grobe
217     changes to the v1.0 version:
218     - fixed buffer overflow for string variable version[40]
219     - replaced various strings to handle release by #define
220     - removed most unused variables
221     - initialized variables
222     - removed nested functions
223     - compiles now with -ansi -pedantic
224    
225     */
226    
227     /* evalglare.c, v1.03 2012/04/17 wienold
228     - include low light correction
229     */
230    
231    
232     /* evalglare.c, v1.04 2012/04/23 wienold
233     - remove bug for gen_dgp_profile output
234     */
235    
236     /* evalglare.c, v1.05 2012/05/29 wienold
237     - remove variable overflow of low-light-correction for large Ev
238     */
239     /* evalglare.c, v1.06 2012/05/29 wienold
240     - initiate low-light-correction-variable
241     */
242     /* evalglare.c, v1.07 2012/05/29 wienold
243     - remove edge pixels from evaluation, when center of pixel is behind view (stability)
244     */
245    
246     /* evalglare.c, v1.08 2012/09/09 wienold
247     - add direction vector in detailed output for each glare source
248     - include age correction
249     */
250     /* evalglare.c, v1.09 2012/09/09 wienold
251     - faster calculation for the use of gen_dgp_profile: no vertical illuminance calculation, only dgp is calculated, second scan + split is deactivated, when no pixel >15000 is found
252     */
253     /* evalglare.c, v1.10 2012/09/09 wienold
254     - faster calculation for the use of gen_dgp_profile: no vertical illuminance calculation, only dgp is calculated, second scan + split is deactivated, when no pixel >15000 is found
255     */
256     /* evalglare.c, v1.11 2013/01/17 wienold
257     - fix output bug of dgp, when using -i or -I
258     */
259    
260     /* evalglare.c, v1.12 2013/10/31 wienold
261     - include CIE equation for disability glare, Stiles-Holladay
262     */
263     /* evalglare.c, v1.13 2014/04/06 wienold
264     - remove bug: initialize Lveil_cie_sum
265     used for the CIE equation for disability glare
266     */
267    
268     /* evalglare.c, v1.14 buggy changes... removed...
269     */
270     /* evalglare.c, v1.15 add option for uniform colored glare sources
271     */
272     /* evalglare.c, v1.16 2015/05/05 remove bugs: background luminance is now calculated not cos-weighted any more, to switch on cos-weighting use -n option
273     calculation of the background luminance is now based on the real solid angle and not hard coded 2*PI any more
274     fast calculation mode: total solid angle =2*PI (before PI)
275     */
276    
277     /* evalglare.c, v1.17 2015/07/15 add option for calculating band luminance -B angle_of_band
278     remove of age factor due to non proven statistical evidence
279     */
280    
281 greg 2.3 /* evalglare.c, v1.18 2015/11/10 add masking, UDP, PSGV, DGI_mod, UGR_exp and zoning. For zoning and band luminance, a statistical package from C. Reetz was added in order to derive median, std_dev, percentiles.
282     memory leakage was checked and is o.k.
283     */
284    
285     /* evalglare.c, v1.19 2015/12/04 sorting subroutines in statistical package changed by. C. Reetz, adding Position index weighted Luminance evaluation (mean and median of entire image, only in detailed output available)
286     */
287     /* evalglare.c, v1.20 2015/12/21 removing -ansi gcc-option in makefile for the standalone version, adding DGR as output since VCP equation seems not to match with original publication
288     */
289     /* evalglare.c, v1.21 2016/03/15 add a new pixel-overflow-correction option -N
290     */
291     /* evalglare.c, v1.22 2016/03/22 fixed problem using -N option and angular distance calculation, when actual pixel equals disk-center (arccos returned nan)
292     */
293     /* evalglare.c, v1.23 2016/04/18 fixed problem making black corners for -vth fish-eye images
294     */
295     /* evalglare.c, v1.24 2016/04/26 significant speed improvement for 2nd glare source scan: for other glare sources will not be searched any more, when the 8 surrounding pixels have the same glare source number! Smaller speed improvement in the first glare source scan: remembering if pixel before was also a glare source, then no search for surrounding glare sources is applied.
296     changed masking threshold to 0.05 cd/m2
297     */
298     /* evalglare.c, v1.25 2016/04/27 removed the change on the first glare source scan: in few cases glare sources are not merged together in the same way as before. Although the difference is marginal, this algorithm was removed in order to be consistent to the existing results.
299     */
300     /* evalglare.c, v1.26 2016/04/28 removed the bug Lb getting nan in case all glare source pixels are above the peak extraction limit.
301     The calculation of the average source lumiance and solid angle was adapted to be more robust for extreme cases.
302     In case no glare source is found, the values of the glare metrics, relying only on glare sources, is set to zero (100 for VCP) to avoid nan and -inf in the output.
303     Changed glare section output when 0 glare source are found to have the same amount of columns than when glare sources are found
304     */
305     /* evalglare.c, v1.27 2016/06/13 include a warning, if -vtv is in the header. Check, if the corners are black AND -vtv is used ->stopping (stopping can be avoided by using the forcing option -f ). Check, if an invalid exposure is in the header -> stopping in any case.
306     */
307     /* evalglare.c, v1.28 2016/07/08 small code changes in the section of calculating the E_glare (disability) for each glare source.
308     */
309     /* evalglare.c, v1.29 2016/07/12 change threshold for the black corner to 2cd/m2.
310     */
311 greg 2.4 /* evalglare.c, v1.30 2016/07/28 change zonal output: If just one zone is specified, only one zone shows up in the output (bug removal).
312     */
313 greg 2.5 /* evalglare.c, v1.31 2016/08/02 bug removal: default output did not calculate the amout of glare sources before and therefore no_glaresources was set to zero causing dgi,ugr being set to zero as well. Now renumbering of the glare sources and calculation of the amount of glare sources is done for all output versions.
314     */
315 greg 2.6 /* evalglare.c, v2.00 2016/11/15 add of a second fast calculation mode for annual calculations, activted by -2. Output: dgp,ugr
316     */
317     /* evalglare.c, v2.01 2016/11/16 change of -2 option (now -2 dir_illum). External provision of the direct illuminance necessary, since the sun interpolation of daysim is causing problems in calculation of the background luminance.
318     */
319     /* evalglare.c, v2.02 2017/02/28 change of warning message, when invalid exposure setting is found. Reason: tab removal is not in all cases the right measure - it depends which tool caused the invalid exposure entry */
320 greg 2.7
321 greg 2.8 /* evalglare.c, v2.03 2017/08/04 ad of -O option - disk replacement by providing luminance, not documented
322 greg 2.7 */
323    
324 greg 2.8 /* evalglare.c, v2.04 2017/08/04 adding -q option: use of Ev/pi as background luminance. not documented. no combination with -n option!!!
325     */
326    
327     /* evalglare.c, v2.05 2018/08/28 change of the -q option for the choice of the background luminance calculation mode: 0: CIE method (Ev-Edir)/pi, 1: mathematical correct average background luminance, 2: Ev/pi.
328     change of default options:
329     - cosinus weighted calculation of the background luminance (according to CIE) is now default.
330     - absolute threshold for the glare source detection is now default (2000cd/m2), based on study of C. Pierson
331     */
332    
333     /* evalglare.c, v2.06 2018/08/29
334     change of default value of multiplier b to 5.0, if task options (-t or -T ) are activated AND -b NOT used. To be downward compatible when using the task method.
335     */
336 greg 2.7
337 greg 2.10 /* evalglare.c, v2.07 2018/11/17
338 greg 2.9 bugfix: correction of error in the equations of PGSV_con and PGSV_sat
339     all three PGSV equations are calculated now
340     illuminance from the masking area (E_v_mask) is also printed
341     bugfix: in VCPs error fuction equation, value of 6.347 replaced by 6.374
342     */
343 greg 2.10
344     /* evalglare.c, v2.08 2018/11/27
345     bugfix: checkroutine for same image size for the masking corrected
346     */
347    
348 greg 2.11 /* evalglare.c, v2.09 2019/01/18
349     calculate "illuminance-contribution of zones"
350     -switch to turn off low-light correction: 4
351     */
352 greg 2.10
353 greg 2.11 /* evalglare.c, v2.10 2019/07/30, 2020/06/25
354     -add multiimage-mode for annual glare evaluation -Q
355     -extra output for multiimage mode
356     2020/06/22 - added Ev contribution from each glare source as output to the multiimage mode
357     -switch for correction modes (-C), value of 0 switches off all corrections
358     */
359    
360 greg 2.1 #define EVALGLARE
361     #define PROGNAME "evalglare"
362 greg 2.11 #define VERSION "2.10 release 25.06.2020 by EPFL, J.Wienold"
363 greg 2.1 #define RELEASENAME PROGNAME " " VERSION
364    
365 greg 2.3
366     #include "pictool.h"
367 greg 2.1 #include "rtio.h"
368     #include <math.h>
369     #include <string.h>
370 greg 2.3 #include "platform.h"
371     #include "muc_randvar.h"
372    
373 greg 2.1 /* subroutine to add a pixel to a glare source */
374     void add_pixel_to_gs(pict * p, int x, int y, int gsn)
375     {
376     double old_av_posx, old_av_posy, old_av_lum, old_omega, act_omega,
377     new_omega, act_lum;
378    
379    
380     pict_get_npix(p, gsn) = pict_get_npix(p, gsn) + 1;
381     old_av_posx = pict_get_av_posx(p, gsn);
382     old_av_posy = pict_get_av_posy(p, gsn);
383     old_av_lum = pict_get_av_lum(p, gsn);
384     old_omega = pict_get_av_omega(p, gsn);
385    
386     act_omega = pict_get_omega(p, x, y);
387     act_lum = luminance(pict_get_color(p, x, y));
388     new_omega = old_omega + act_omega;
389     pict_get_av_posx(p, gsn) =
390     (old_av_posx * old_omega + x * act_omega) / new_omega;
391     pict_get_av_posy(p, gsn) =
392     (old_av_posy * old_omega + y * act_omega) / new_omega;
393     if (isnan((pict_get_av_posx(p, gsn))))
394     fprintf(stderr,"error in add_pixel_to_gs %d %d %f %f %f %f\n", x, y, old_av_posy, old_omega, act_omega, new_omega);
395    
396     pict_get_av_lum(p, gsn) =
397     (old_av_lum * old_omega + act_lum * act_omega) / new_omega;
398     pict_get_av_omega(p, gsn) = new_omega;
399     pict_get_gsn(p, x, y) = gsn;
400     if (act_lum < pict_get_lum_min(p, gsn)) {
401     pict_get_lum_min(p, gsn) = act_lum;
402     }
403     if (act_lum > pict_get_lum_max(p, gsn)) {
404     pict_get_lum_max(p, gsn) = act_lum;
405     }
406    
407     /* printf("gsn,x,y,av_posx,av_posy,av_lum %i %f %f %f %f %f\n",gsn,x,y,pict_get_av_posx(p, gsn),pict_get_av_posy(p, gsn),pict_get_av_lum(p, gsn)); */
408    
409     }
410    
411     /* subroutine for peak extraction */
412     int
413     find_split(pict * p, int x, int y, double r, int i_split_start,
414     int i_split_end)
415     {
416     int i_find_split, x_min, x_max, y_min, y_max, ix, iy, iix, iiy, dx, dy,
417     out_r;
418     double r_actual;
419    
420     i_find_split = 0;
421    
422     x_min = 0;
423     y_min = 0;
424     x_max = pict_get_ysize(p) - 1;
425    
426     y_max = pict_get_ysize(p) - 1;
427    
428     for (iiy = 1; iiy <= 2; iiy++) {
429     dy = iiy * 2 - 3;
430     if (dy == -1) {
431     iy = y;
432     } else {
433     iy = y + 1;
434     }
435     while (iy <= y_max && iy >= y_min) {
436     out_r = 0;
437     for (iix = 1; iix <= 2; iix++) {
438     dx = iix * 2 - 3;
439     if (dx == -1) {
440     ix = x;
441     } else {
442     ix = x + 1;
443     }
444     while (ix <= x_max && ix >= x_min && iy >= y_min) {
445    
446     r_actual =
447     acos(DOT(pict_get_cached_dir(p, x, y),
448     pict_get_cached_dir(p, ix, iy))) * 2;
449     if (r_actual <= r) {
450     out_r = 1;
451     if (pict_get_gsn(p, ix, iy) >= i_split_start
452     && pict_get_gsn(p, ix, iy) <= i_split_end) {
453     i_find_split = pict_get_gsn(p, ix, iy);
454     }
455     } else {
456     ix = -99;
457     }
458     ix = ix + dx;
459     }
460     }
461     if (out_r == 0) {
462     iy = -99;
463     }
464     iy = iy + dy;
465    
466     }
467     }
468    
469    
470    
471     return i_find_split;
472     }
473    
474     /*
475     static int icomp(int* a,int* b)
476     {
477     if (*a < *b)
478     return -1;
479     if (*a > *b)
480     return 1;
481     return 0;
482     }
483    
484     */
485    
486     /* subroutine to find nearby glare source pixels */
487    
488     int
489     find_near_pgs(pict * p, int x, int y, float r, int act_gsn, int max_gsn,
490     int min_gsn)
491     {
492     int dx, dy, i_near_gs, xx, yy, x_min, x_max, y_min, y_max, ix, iy, iix,
493     iiy, old_gsn, new_gsn, find_gsn, change, stop_y_search,
494     stop_x_search;
495     double r_actual;
496     int ixm[3];
497    
498     i_near_gs = 0;
499     stop_y_search = 0;
500     stop_x_search = 0;
501     x_min = 0;
502     y_min = 0;
503     if (act_gsn == 0) {
504     x_max = x;
505     } else {
506     x_max = pict_get_xsize(p) - 1;
507     }
508    
509     y_max = pict_get_ysize(p) - 1;
510    
511     old_gsn = pict_get_gsn(p, x, y);
512     new_gsn = old_gsn;
513     change = 0;
514     if (act_gsn > 0) {
515     i_near_gs = pict_get_gsn(p, x, y);
516     }
517     for (iiy = 1; iiy <= 2; iiy++) {
518     dy = iiy * 2 - 3;
519     if (dy == -1) {
520     iy = y;
521     } else {
522     iy = y + 1;
523     }
524     ixm[1] = x;
525     ixm[2] = x;
526     stop_y_search = 0;
527    
528    
529     while (iy <= y_max && iy >= y_min) {
530     for (iix = 1; iix <= 2; iix++) {
531     dx = iix * 2 - 3;
532     ix = (ixm[1] + ixm[2]) / 2;
533     stop_x_search = 0;
534     while (ix <= x_max && ix >= x_min && stop_x_search == 0
535     && stop_y_search == 0) {
536     /* printf(" dx,act_gsn, x,y,x_max, x_min, ix ,iy , ymax,ymin %i %i %i %i %i %i %i %i %i %i\n",dx,act_gsn,x,y,x_max,x_min,ix,iy,y_max,y_min);*/
537     r_actual =
538     acos(DOT(pict_get_cached_dir(p, x, y),
539     pict_get_cached_dir(p, ix, iy))) * 2;
540     if (r_actual <= r) {
541     if (pict_get_gsn(p, ix, iy) > 0) {
542     if (act_gsn == 0) {
543     i_near_gs = pict_get_gsn(p, ix, iy);
544     stop_x_search = 1;
545     stop_y_search = 1;
546     } else {
547     find_gsn = pict_get_gsn(p, ix, iy);
548     if (pict_get_av_omega(p, old_gsn) <
549     pict_get_av_omega(p, find_gsn)
550     && pict_get_av_omega(p,
551     find_gsn) >
552     pict_get_av_omega(p, new_gsn)
553     && find_gsn >= min_gsn
554     && find_gsn <= max_gsn) {
555     /* other primary glare source found with larger solid angle -> add together all */
556     new_gsn = find_gsn;
557     change = 1;
558     stop_x_search = 1;
559     stop_y_search = 1;
560     }
561     }
562     }
563     } else {
564     ixm[iix] = ix - dx;
565     stop_x_search = 1;
566     }
567     ix = ix + dx;
568     }
569     }
570     iy = iy + dy;
571     }
572     }
573     if (change > 0) {
574     pict_get_av_lum(p, old_gsn) = 0.;
575     pict_get_av_omega(p, old_gsn) = 0.;
576     pict_get_npix(p, old_gsn) = 0.;
577     pict_get_lum_max(p, old_gsn) = 0.;
578    
579    
580     i_near_gs = new_gsn;
581     /* printf(" changing gs no %i",old_gsn);
582     printf(" to %i\n",new_gsn);
583     */
584     for (xx = 0; xx < pict_get_xsize(p); xx++)
585     for (yy = 0; yy < pict_get_ysize(p); yy++) {
586     if (pict_is_validpixel(p, x, y)) {
587     if (pict_get_gsn(p, xx, yy) == old_gsn) {
588     add_pixel_to_gs(p, xx, yy, new_gsn);
589     }
590     }
591     }
592     }
593    
594     return i_near_gs;
595    
596    
597     }
598    
599     /* subroutine for calculation of task luminance */
600     double get_task_lum(pict * p, int x, int y, float r, int task_color)
601     {
602     int x_min, x_max, y_min, y_max, ix, iy;
603     double r_actual, av_lum, omega_sum, act_lum;
604    
605    
606     x_max = pict_get_xsize(p) - 1;
607     y_max = pict_get_ysize(p) - 1;
608     x_min = 0;
609     y_min = 0;
610    
611    
612    
613     av_lum = 0.0;
614     omega_sum = 0.0;
615    
616     for (iy = y_min; iy <= y_max; iy++) {
617     for (ix = x_min; ix <= x_max; ix++) {
618    
619     /* if (DOT(pict_get_cached_dir(p,ix,iy),p->view.vdir) < 0.0)
620     continue;*/
621     r_actual =
622     acos(DOT(pict_get_cached_dir(p, x, y),
623     pict_get_cached_dir(p, ix, iy))) * 2;
624     act_lum = luminance(pict_get_color(p, ix, iy));
625    
626     if (r_actual <= r) {
627     act_lum = luminance(pict_get_color(p, ix, iy));
628     av_lum += pict_get_omega(p, ix, iy) * act_lum;
629     omega_sum += pict_get_omega(p, ix, iy);
630     if (task_color == 1) {
631     pict_get_color(p, ix, iy)[RED] = 0.0;
632     pict_get_color(p, ix, iy)[GRN] = 0.0;
633     pict_get_color(p, ix, iy)[BLU] =
634     act_lum / WHTEFFICACY / CIE_bf;
635     }
636     }
637     }
638     }
639    
640     av_lum = av_lum / omega_sum;
641     /* printf("average luminance of task %f \n",av_lum);
642     printf("solid angle of task %f \n",omega_sum);*/
643     return av_lum;
644     }
645    
646    
647    
648    
649    
650     /* subroutine for coloring the glare sources
651     red is used only for explicit call of the subroutine with acol=0 , e.g. for disability glare
652     -1: set to grey*/
653     int setglcolor(pict * p, int x, int y, int acol, int uniform_gs, double u_r, double u_g ,double u_b)
654     {
655     int icol;
656     double pcol[3][1000], act_lum, l;
657    
658     l=u_r+u_g+u_b ;
659    
660     pcol[RED][0] = 1.0 / CIE_rf;
661 greg 2.3 pcol[GRN][0] = 0.0 / CIE_gf;
662     pcol[BLU][0] = 0.0 / CIE_bf;
663 greg 2.1
664 greg 2.3 pcol[RED][1] = 0.0 / CIE_rf;
665 greg 2.1 pcol[GRN][1] = 1.0 / CIE_gf;
666 greg 2.3 pcol[BLU][1] = 0.0 / CIE_bf;
667 greg 2.1
668 greg 2.3 pcol[RED][2] = 0.15 / CIE_rf;
669     pcol[GRN][2] = 0.15 / CIE_gf;
670     pcol[BLU][2] = 0.7 / CIE_bf;
671    
672     pcol[RED][3] = .5 / CIE_rf;
673     pcol[GRN][3] = .5 / CIE_gf;
674     pcol[BLU][3] = 0.0 / CIE_bf;
675    
676     pcol[RED][4] = .5 / CIE_rf;
677     pcol[GRN][4] = .0 / CIE_gf;
678     pcol[BLU][4] = .5 / CIE_bf ;
679    
680     pcol[RED][5] = .0 / CIE_rf;
681     pcol[GRN][5] = .5 / CIE_gf;
682     pcol[BLU][5] = .5 / CIE_bf;
683    
684     pcol[RED][6] = 0.333 / CIE_rf;
685     pcol[GRN][6] = 0.333 / CIE_gf;
686     pcol[BLU][6] = 0.333 / CIE_bf;
687 greg 2.1
688    
689     pcol[RED][999] = 1.0 / WHTEFFICACY;
690     pcol[GRN][999] = 1.0 / WHTEFFICACY;
691     pcol[BLU][999] = 1.0 / WHTEFFICACY;
692    
693    
694     pcol[RED][998] = u_r /(l* CIE_rf) ;
695     pcol[GRN][998] = u_g /(l* CIE_gf);
696     pcol[BLU][998] = u_b /(l* CIE_bf);
697 greg 2.3 /* printf("CIE_rf,CIE_gf,CIE_bf,l=%f %f %f %f %f\n",CIE_rf,CIE_gf,CIE_bf,l,WHTEFFICACY); */
698 greg 2.1 icol = acol ;
699     if ( acol == -1) {icol=999;
700     }else{if (acol>0){icol = acol % 5 +1;
701     }};
702     if ( uniform_gs == 1) {icol=998;
703     } ;
704    
705     act_lum = luminance(pict_get_color(p, x, y));
706    
707     pict_get_color(p, x, y)[RED] = pcol[RED][icol] * act_lum / WHTEFFICACY;
708     pict_get_color(p, x, y)[GRN] = pcol[GRN][icol] * act_lum / WHTEFFICACY;
709     pict_get_color(p, x, y)[BLU] = pcol[BLU][icol] * act_lum / WHTEFFICACY;
710 greg 2.3 /* printf("x,y,lum_before,lum_after,diff %i %i %f %f %f\n",x,y, act_lum,luminance(pict_get_color(p, x, y)), act_lum-luminance(pict_get_color(p, x, y))); */
711 greg 2.1 return icol;
712     }
713    
714     /* this is the smooting subroutine */
715     void add_secondary_gs(pict * p, int x, int y, float r, int act_gs, int uniform_gs, double u_r, double u_g ,double u_b)
716     {
717     int x_min, x_max, y_min, y_max, ix, iy, icol;
718     double r_actual, omega_gs, omega_total, om;
719    
720    
721    
722     omega_gs = 0.0;
723     omega_total = 0.0;
724     x_min = x - r;
725     if (x_min < 0) {
726     x_min = 0;
727     }
728     x_max = x + r;
729     if (x_max > pict_get_xsize(p) - 1) {
730     x_max = pict_get_xsize(p) - 2;
731     }
732     y_min = y - r;
733     if (y_min < 0) {
734     y_min = 0;
735     }
736     y_max = y + r;
737     if (y_max > pict_get_ysize(p) - 1) {
738     y_max = pict_get_ysize(p) - 2;
739     }
740    
741     for (ix = x_min; ix <= x_max; ix++)
742     for (iy = y_min; iy <= y_max; iy++) {
743     r_actual = sqrt((x - ix) * (x - ix) + (y - iy) * (y - iy));
744     if (r_actual <= r) {
745     om = pict_get_omega(p, ix, iy);
746     omega_total += om;
747     if (pict_get_gsn(p, ix, iy) == act_gs
748     && pict_get_pgs(p, ix, iy) == 1) {
749     omega_gs = omega_gs + 1 * om;
750     }
751     }
752     }
753    
754    
755     if (omega_gs / omega_total > 0.2) {
756     /* add pixel to gs */
757    
758     add_pixel_to_gs(p, x, y, act_gs);
759    
760     /* color pixel of gs */
761    
762 greg 2.3 /* icol = setglcolor(p, x, y, act_gs, uniform_gs, u_r, u_g , u_b); */
763 greg 2.1
764     }
765     }
766    
767     /* subroutine for removing a pixel from a glare source */
768     void split_pixel_from_gs(pict * p, int x, int y, int new_gsn, int uniform_gs, double u_r, double u_g , double u_b)
769     {
770     int old_gsn, icol;
771 greg 2.11 double old_av_posx, old_av_posy, old_av_lum, old_omega, act_omega, delta_E,
772 greg 2.1 new_omega, act_lum;
773    
774    
775     /* change existing gs */
776     old_gsn = pict_get_gsn(p, x, y);
777     pict_get_npix(p, old_gsn) = pict_get_npix(p, old_gsn) - 1;
778    
779     act_omega = pict_get_omega(p, x, y);
780     old_av_posx = pict_get_av_posx(p, old_gsn);
781     old_av_posy = pict_get_av_posy(p, old_gsn);
782     old_omega = pict_get_av_omega(p, old_gsn);
783 greg 2.11
784    
785    
786 greg 2.1
787     new_omega = old_omega - act_omega;
788     pict_get_av_omega(p, old_gsn) = new_omega;
789     pict_get_av_posx(p, old_gsn) =
790     (old_av_posx * old_omega - x * act_omega) / new_omega;
791     pict_get_av_posy(p, old_gsn) =
792     (old_av_posy * old_omega - y * act_omega) / new_omega;
793    
794    
795     act_lum = luminance(pict_get_color(p, x, y));
796     old_av_lum = pict_get_av_lum(p, old_gsn);
797     pict_get_av_lum(p, old_gsn) =
798     (old_av_lum * old_omega - act_lum * act_omega) / new_omega;
799     /* add pixel to new gs */
800    
801     add_pixel_to_gs(p, x, y, new_gsn);
802    
803 greg 2.11
804    
805    
806 greg 2.1 /* color pixel of new gs */
807    
808 greg 2.3 /* icol = setglcolor(p, x, y, new_gsn, uniform_gs, u_r, u_g , u_b); */
809    
810 greg 2.1
811     }
812    
813     /* subroutine for the calculation of the position index */
814     float get_posindex(pict * p, float x, float y, int postype)
815     {
816     float posindex;
817     double teta, phi, sigma, tau, deg, d, s, r, fact;
818    
819    
820     pict_get_vangle(p, x, y, p->view.vdir, p->view.vup, &phi);
821     pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &teta);
822     pict_get_sigma(p, x, y, p->view.vdir, p->view.vup, &sigma);
823     pict_get_tau(p, x, y, p->view.vdir, p->view.vup, &tau);
824    
825     /* return (phi+teta+2*3.1415927); */
826    
827     deg = 180 / 3.1415927;
828     fact = 0.8;
829     if (phi == 0) {
830     phi = 0.00001;
831     }
832     if (sigma <= 0) {
833     sigma = -sigma;
834     }
835     if (teta == 0) {
836     teta = 0.0001;
837     }
838     tau = tau * deg;
839     sigma = sigma * deg;
840    
841 greg 2.3 if (postype == 1) {
842     /* KIM model */
843     posindex = exp ((sigma-(-0.000009*tau*tau*tau+0.0014*tau*tau+0.0866*tau+21.633))/(-0.000009*tau*tau*tau+0.0013*tau*tau+0.0853*tau+8.772));
844     }else{
845     /* Guth model, equation from IES lighting handbook */
846 greg 2.1 posindex =
847     exp((35.2 - 0.31889 * tau -
848     1.22 * exp(-2 * tau / 9)) / 1000 * sigma + (21 +
849     0.26667 * tau -
850     0.002963 * tau *
851     tau) / 100000 *
852     sigma * sigma);
853     /* below line of sight, using Iwata model */
854     if (phi < 0) {
855     d = 1 / tan(phi);
856     s = tan(teta) / tan(phi);
857     r = sqrt(1 / d * 1 / d + s * s / d / d);
858     if (r > 0.6)
859     fact = 1.2;
860     if (r > 3) {
861     fact = 1.2;
862     r = 3;
863     }
864    
865     posindex = 1 + fact * r;
866     }
867 greg 2.3 if (posindex > 16)
868 greg 2.1 posindex = 16;
869 greg 2.3 }
870 greg 2.1
871     return posindex;
872    
873     }
874    
875    
876    
877     double get_upper_cut_2eyes(float teta)
878     {
879     double phi;
880    
881     phi=pow(7.7458218+0.00057407915*teta-0.00021746318*teta*teta+8.5572726e-6*teta*teta*teta,2);
882    
883     return phi;
884     }
885     double get_lower_cut_2eyes(float teta)
886     {
887     double phi;
888    
889     phi=1/(-0.014699242-1.5541106e-5*teta+4.6898068e-6*teta*teta-5.1539687e-8*teta*teta*teta);
890    
891     return phi;
892     }
893    
894     double get_lower_cut_central(float teta)
895     {
896     double phi;
897    
898     phi=(68.227109-2.9524084*teta+0.046674262*teta*teta)/(1-0.042317294*teta+0.00075698419*teta*teta-6.5364285e-7*teta*teta*teta);
899    
900     if (teta>73) {
901     phi=60;
902     }
903    
904     return phi;
905     }
906    
907     /* subroutine for the cutting the total field of view */
908     void cut_view_1(pict*p)
909     {
910     int x,y;
911     double border,ang,teta,phi,phi2;
912     for(x=0;x<pict_get_xsize(p)-1;x++)
913     for(y=0;y<pict_get_ysize(p)-1;y++) {
914     if (pict_get_hangle(p,x,y,p->view.vdir,p->view.vup,&ang)) {
915     if (pict_is_validpixel(p, x, y)) {
916     pict_get_vangle(p,x,y,p->view.vdir,p->view.vup,&phi2);
917     pict_get_sigma(p,x,y,p->view.vdir,p->view.vup,&phi);
918     pict_get_tau(p,x,y,p->view.vdir,p->view.vup,&teta);
919     phi=phi*180/3.1415927;
920     phi2=phi2*180/3.1415927;
921     teta=teta*180/3.1415927;
922     if (teta<0) {
923     teta=-teta;
924     }
925     if(phi2>0){
926     border=get_upper_cut_2eyes(teta);
927    
928     if (phi>border) {
929     pict_get_color(p,x,y)[RED]=0;
930     pict_get_color(p,x,y)[GRN]=0;
931     pict_get_color(p,x,y)[BLU]=0;
932     }
933     }else{
934     border=get_lower_cut_2eyes(180-teta);
935     if (-phi<border && teta>135) {
936     pict_get_color(p,x,y)[RED]=0;
937     pict_get_color(p,x,y)[GRN]=0;
938     pict_get_color(p,x,y)[BLU]=0;
939     }
940     }
941    
942    
943    
944     }else{
945     pict_get_color(p,x,y)[RED]=0;
946     pict_get_color(p,x,y)[GRN]=0;
947     pict_get_color(p,x,y)[BLU]=0;
948    
949    
950     }
951    
952     /* printf("teta,phi,border=%f %f %f\n",teta,phi,border);*/
953     }
954     }
955    
956    
957     return;
958    
959     }
960     /* subroutine for the cutting the field of view seen by both eyes*/
961     void cut_view_2(pict*p)
962     {
963    
964     int x,y;
965     double border,ang,teta,phi,phi2;
966     for(x=0;x<pict_get_xsize(p)-1;x++)
967     for(y=0;y<pict_get_ysize(p)-1;y++) {
968     if (pict_get_hangle(p,x,y,p->view.vdir,p->view.vup,&ang)) {
969     if (pict_is_validpixel(p, x, y)) {
970     pict_get_vangle(p,x,y,p->view.vdir,p->view.vup,&phi2);
971     pict_get_hangle(p,x,y,p->view.vdir,p->view.vup,&teta);
972     pict_get_sigma(p,x,y,p->view.vdir,p->view.vup,&phi);
973     pict_get_tau(p,x,y,p->view.vdir,p->view.vup,&teta);
974     phi=phi*180/3.1415927;
975     phi2=phi2*180/3.1415927;
976     teta=teta*180/3.1415927;
977     /* printf("x,y,teta,phi,border=%i %i %f %f %f\n",x,y,teta,phi,border);*/
978     if (teta<0) {
979     teta=-teta;
980     }
981     if(phi2>0){
982     border=60;
983    
984     if (phi>border) {
985     pict_get_color(p,x,y)[RED]=0;
986     pict_get_color(p,x,y)[GRN]=0;
987     pict_get_color(p,x,y)[BLU]=0;
988     }
989     }else{
990     border=get_lower_cut_central(180-teta);
991     if (phi>border) {
992     pict_get_color(p,x,y)[RED]=0;
993     pict_get_color(p,x,y)[GRN]=0;
994     pict_get_color(p,x,y)[BLU]=0;
995     }
996     }
997    
998    
999    
1000     }else{
1001     pict_get_color(p,x,y)[RED]=0;
1002     pict_get_color(p,x,y)[GRN]=0;
1003     pict_get_color(p,x,y)[BLU]=0;
1004    
1005    
1006     }
1007     }
1008     }
1009    
1010    
1011     return;
1012    
1013     }
1014    
1015     /* subroutine for the cutting the field of view seen by both eyes
1016     luminance is modified by position index - just for experiments - undocumented */
1017     void cut_view_3(pict*p)
1018     {
1019    
1020     int x,y;
1021     double border,ang,teta,phi,phi2,lum,newlum;
1022     for(x=0;x<pict_get_xsize(p)-1;x++)
1023     for(y=0;y<pict_get_ysize(p)-1;y++) {
1024     if (pict_get_hangle(p,x,y,p->view.vdir,p->view.vup,&ang)) {
1025     if (DOT(pict_get_cached_dir(p,x,y),p->view.vdir) >= 0.0) {
1026     pict_get_vangle(p,x,y,p->view.vdir,p->view.vup,&phi2);
1027     pict_get_hangle(p,x,y,p->view.vdir,p->view.vup,&teta);
1028     pict_get_sigma(p,x,y,p->view.vdir,p->view.vup,&phi);
1029     pict_get_tau(p,x,y,p->view.vdir,p->view.vup,&teta);
1030     phi=phi*180/3.1415927;
1031     phi2=phi2*180/3.1415927;
1032     teta=teta*180/3.1415927;
1033     lum=luminance(pict_get_color(p,x,y));
1034    
1035     newlum=lum/get_posindex(p,x,y,0);
1036    
1037     pict_get_color(p,x,y)[RED]=newlum/WHTEFFICACY;
1038     pict_get_color(p,x,y)[GRN]=newlum/WHTEFFICACY;
1039     pict_get_color(p,x,y)[BLU]=newlum/WHTEFFICACY;
1040    
1041    
1042    
1043    
1044     /* printf("x,y,teta,phi,border=%i %i %f %f %f\n",x,y,teta,phi,border);*/
1045     if (teta<0) {
1046     teta=-teta;
1047     }
1048     if(phi2>0){
1049     border=60;
1050    
1051     if (phi>border) {
1052     pict_get_color(p,x,y)[RED]=0;
1053     pict_get_color(p,x,y)[GRN]=0;
1054     pict_get_color(p,x,y)[BLU]=0;
1055     }
1056     }else{
1057     border=get_lower_cut_central(180-teta);
1058     if (phi>border) {
1059     pict_get_color(p,x,y)[RED]=0;
1060     pict_get_color(p,x,y)[GRN]=0;
1061     pict_get_color(p,x,y)[BLU]=0;
1062     }
1063     }
1064    
1065    
1066    
1067     }else{
1068     pict_get_color(p,x,y)[RED]=0;
1069     pict_get_color(p,x,y)[GRN]=0;
1070     pict_get_color(p,x,y)[BLU]=0;
1071    
1072    
1073     }
1074     }
1075     }
1076    
1077    
1078     return;
1079    
1080     }
1081    
1082 greg 2.3 /* subroutine for the calculation of the daylight glare index DGI*/
1083 greg 2.1
1084    
1085     float get_dgi(pict * p, float lum_backg, int igs, int posindex_2)
1086     {
1087     float dgi, sum_glare, omega_s;
1088     int i;
1089    
1090    
1091     sum_glare = 0;
1092     omega_s = 0;
1093    
1094     for (i = 0; i <= igs; i++) {
1095    
1096     if (pict_get_npix(p, i) > 0) {
1097     omega_s =
1098     pict_get_av_omega(p, i) / get_posindex(p,pict_get_av_posx(p,i), pict_get_av_posy(p,i),posindex_2) /
1099     get_posindex(p, pict_get_av_posx(p, i), pict_get_av_posy(p, i), posindex_2);
1100     sum_glare += 0.478 * pow(pict_get_av_lum(p, i), 1.6) * pow(omega_s,0.8) / (lum_backg + 0.07 * pow(pict_get_av_omega(p, i),0.5) * pict_get_av_lum(p, i));
1101     /* printf("i,sum_glare %i %f\n",i,sum_glare); */
1102     }
1103     }
1104     dgi = 10 * log10(sum_glare);
1105    
1106     return dgi;
1107    
1108     }
1109 greg 2.3 /* subroutine for the calculation of the modified daylight glare index DGI_mod (Fisekis2003)
1110     several glare sources are taken into account and summed up, original equation has no summary
1111     */
1112    
1113    
1114     float get_dgi_mod(pict * p, float lum_a, int igs, int posindex_2)
1115     {
1116     float dgi_mod, sum_glare, omega_s;
1117     int i;
1118    
1119    
1120     sum_glare = 0;
1121     omega_s = 0;
1122    
1123     for (i = 0; i <= igs; i++) {
1124    
1125     if (pict_get_npix(p, i) > 0) {
1126     omega_s =
1127     pict_get_av_omega(p, i) / get_posindex(p,pict_get_av_posx(p,i), pict_get_av_posy(p,i),posindex_2) /
1128     get_posindex(p, pict_get_av_posx(p, i), pict_get_av_posy(p, i), posindex_2);
1129     sum_glare += 0.478 * pow(pict_get_av_lum(p, i), 1.6) * pow(omega_s,0.8) / (pow(lum_a,0.85) + 0.07 * pow(pict_get_av_omega(p, i),0.5) * pict_get_av_lum(p, i));
1130     /* printf("i,sum_glare %i %f\n",i,sum_glare); */
1131     }
1132     }
1133     dgi_mod = 10 * log10(sum_glare);
1134    
1135     return dgi_mod;
1136    
1137     }
1138 greg 2.1
1139     /* subroutine for the calculation of the daylight glare probability */
1140     double
1141     get_dgp(pict * p, double E_v, int igs, double a1, double a2, double a3,
1142     double a4, double a5, double c1, double c2, double c3,
1143     int posindex_2)
1144     {
1145     double dgp;
1146     double sum_glare;
1147     int i;
1148    
1149     sum_glare = 0;
1150     if (igs > 0) {
1151     for (i = 0; i <= igs; i++) {
1152    
1153     if (pict_get_npix(p, i) > 0) {
1154     sum_glare +=
1155     pow(pict_get_av_lum(p, i),
1156     a1) / pow(get_posindex(p, pict_get_av_posx(p, i),
1157     pict_get_av_posy(p, i),
1158     posindex_2),
1159     a4) * pow(pict_get_av_omega(p, i), a2);
1160     /* printf("i,sum_glare %i %f\n",i,sum_glare);*/
1161     }
1162     }
1163     dgp =
1164     c1 * pow(E_v,
1165     a5) + c3 + c2 * log10(1 + sum_glare / pow(E_v, a3));
1166     } else {
1167     dgp = c3 + c1 * pow(E_v, a5);
1168     }
1169    
1170     if (dgp > 1) {
1171     dgp = 1;
1172     }
1173     /* printf("dgp %f\n",dgp);*/
1174     return dgp;
1175    
1176     }
1177    
1178     /* subroutine for the calculation of the visual comfort probability */
1179 greg 2.3 float get_dgr(pict * p, double lum_a, int igs, int posindex_2)
1180 greg 2.1 {
1181 greg 2.3 float dgr;
1182     double sum_glare;
1183 greg 2.1 int i, i_glare;
1184    
1185    
1186     sum_glare = 0;
1187     i_glare = 0;
1188     for (i = 0; i <= igs; i++) {
1189    
1190     if (pict_get_npix(p, i) > 0) {
1191     i_glare = i_glare + 1;
1192     sum_glare +=
1193     (0.5 * pict_get_av_lum(p, i) *
1194     (20.4 * pict_get_av_omega(p, i) +
1195     1.52 * pow(pict_get_av_omega(p, i),
1196     0.2) - 0.075)) / (get_posindex(p,
1197     pict_get_av_posx
1198     (p, i),
1199     pict_get_av_posy
1200     (p, i),
1201     posindex_2) *
1202     pow(lum_a, 0.44));
1203    
1204     }
1205     }
1206     dgr = pow(sum_glare, pow(i_glare, -0.0914));
1207    
1208 greg 2.3
1209    
1210     return dgr;
1211    
1212     }
1213    
1214     float get_vcp(float dgr )
1215     {
1216     float vcp;
1217    
1218 greg 2.9 vcp = 50 * erf((6.374 - 1.3227 * log(dgr)) / 1.414213562373) + 50;
1219 greg 2.1 if (dgr > 750) {
1220     vcp = 0;
1221     }
1222     if (dgr < 20) {
1223     vcp = 100;
1224     }
1225     return vcp;
1226    
1227     }
1228    
1229 greg 2.3
1230 greg 2.1 /* subroutine for the calculation of the unified glare rating */
1231     float get_ugr(pict * p, double lum_backg, int igs, int posindex_2)
1232     {
1233     float ugr;
1234     double sum_glare;
1235     int i, i_glare;
1236    
1237    
1238     sum_glare = 0;
1239     i_glare = 0;
1240     for (i = 0; i <= igs; i++) {
1241    
1242     if (pict_get_npix(p, i) > 0) {
1243     i_glare = i_glare + 1;
1244     sum_glare +=
1245     pow(pict_get_av_lum(p, i) /
1246     get_posindex(p, pict_get_av_posx(p, i),
1247     pict_get_av_posy(p, i), posindex_2),
1248     2) * pict_get_av_omega(p, i);
1249    
1250     }
1251     }
1252     ugr = 8 * log10(0.25 / lum_backg * sum_glare);
1253 greg 2.6 if (sum_glare==0) {
1254     ugr=0.0;
1255     }
1256     if (lum_backg<=0) {
1257     ugr=-99.0;
1258     }
1259    
1260 greg 2.1 return ugr;
1261    
1262     }
1263 greg 2.3 /* subroutine for the calculation of the experimental unified glare rating (Fisekis 2003)*/
1264     float get_ugr_exp(pict * p, double lum_backg, double lum_a, int igs, int posindex_2)
1265     {
1266     float ugr_exp;
1267     double sum_glare;
1268     int i, i_glare;
1269    
1270    
1271     sum_glare = 0;
1272     i_glare = 0;
1273     for (i = 0; i <= igs; i++) {
1274    
1275     if (pict_get_npix(p, i) > 0) {
1276     i_glare = i_glare + 1;
1277     sum_glare +=
1278     pow(1 /get_posindex(p, pict_get_av_posx(p, i), pict_get_av_posy(p, i), posindex_2),2) *pict_get_av_lum(p, i)* pict_get_av_omega(p, i);
1279    
1280     }
1281     }
1282     ugr_exp =8 * log10(lum_a) + 8 * log10(sum_glare/lum_backg);
1283    
1284     return ugr_exp;
1285    
1286     }
1287     /* subroutine for the calculation of the unified glare probability (Hirning 2014)*/
1288     float get_ugp(pict * p, double lum_backg, int igs, int posindex_2)
1289     {
1290     float ugp;
1291     double sum_glare;
1292     int i, i_glare;
1293    
1294    
1295     sum_glare = 0;
1296     i_glare = 0;
1297     for (i = 0; i <= igs; i++) {
1298    
1299     if (pict_get_npix(p, i) > 0) {
1300     i_glare = i_glare + 1;
1301     sum_glare +=
1302     pow(pict_get_av_lum(p, i) /
1303     get_posindex(p, pict_get_av_posx(p, i),
1304     pict_get_av_posy(p, i), posindex_2),
1305     2) * pict_get_av_omega(p, i);
1306    
1307     }
1308     }
1309     ugp = 0.26 * log10(0.25 / lum_backg * sum_glare);
1310    
1311     return ugp;
1312    
1313     }
1314 greg 2.1
1315    
1316     /* subroutine for the calculation of the disability glare according to Poynter */
1317     float get_disability(pict * p, double lum_backg, int igs)
1318     {
1319     float disab;
1320     double sum_glare, sigma, deg;
1321     int i, i_glare;
1322    
1323    
1324     sum_glare = 0;
1325     i_glare = 0;
1326     deg = 180 / 3.1415927;
1327     for (i = 0; i <= igs; i++) {
1328    
1329     if (pict_get_npix(p, i) > 0) {
1330     i_glare = i_glare + 1;
1331     pict_get_sigma(p, pict_get_av_posx(p, i),
1332     pict_get_av_posy(p, i), p->view.vdir,
1333     p->view.vup, &sigma);
1334    
1335     sum_glare +=
1336     pict_get_av_lum(p,
1337     i) * cos(sigma +
1338     0.00000000001) *
1339     pict_get_av_omega(p, i)
1340     / (deg * sigma + 0.00000000001);
1341     if (isnan(sum_glare)) {
1342     printf("sigma for %f %f\n", pict_get_av_posx(p, i), pict_get_av_posy(p, i));
1343     printf("omega for %f %f\n", pict_get_av_posx(p, i), pict_get_av_posy(p, i));
1344     printf("avlum for %f %f\n", pict_get_av_posx(p, i), pict_get_av_posy(p, i));
1345     printf("avlum for %f %f %f\n", pict_get_av_posx(p, i), pict_get_av_posy(p, i), sigma);
1346     }
1347    
1348     }
1349     }
1350     disab = 5 * sum_glare;
1351    
1352     return disab;
1353    
1354     }
1355    
1356    
1357    
1358    
1359    
1360    
1361     /* subroutine for the calculation of the cie glare index */
1362    
1363 greg 2.3 float get_cgi(pict * p, double E_v, double E_v_dir, int igs, int posindex_2)
1364 greg 2.1 {
1365     float cgi;
1366     double sum_glare;
1367     int i, i_glare;
1368    
1369    
1370     sum_glare = 0;
1371     i_glare = 0;
1372     for (i = 0; i <= igs; i++) {
1373    
1374     if (pict_get_npix(p, i) > 0) {
1375     i_glare = i_glare + 1;
1376     sum_glare +=
1377     pow(pict_get_av_lum(p, i) /
1378     get_posindex(p, pict_get_av_posx(p, i),
1379     pict_get_av_posy(p, i), posindex_2),
1380     2) * pict_get_av_omega(p, i);
1381    
1382     }
1383     }
1384     cgi = 8 * log10((2 * (1 + E_v_dir / 500) / E_v) * sum_glare);
1385    
1386     return cgi;
1387 greg 2.3 }
1388    
1389 greg 2.9
1390    
1391     /* subroutine for the calculation of the PGSV_con; is only applied, when masking is done, since it refers only to the window. Important: masking area must be the window! */
1392     float get_pgsv_con(double E_v, double E_mask,double omega_mask,double lum_mask_av, double Lavg)
1393 greg 2.3 {
1394 greg 2.9 float pgsv_con;
1395 greg 2.3 double Lb;
1396    
1397 greg 2.9 /* Lb = (E_v-E_mask)/3.14159265359; */
1398     /* Lb = (2*E_v-lum_mask_av*omega_mask)/(2*3.14159265359-omega_mask); */
1399     Lb = (2*3.14159265359*Lavg-lum_mask_av*omega_mask)/(2*3.14159265359-omega_mask);
1400    
1401 greg 2.3
1402 greg 2.9 pgsv_con =3.2*log10(lum_mask_av)-0.64*log10(omega_mask)+(0.79*log10(omega_mask)-0.61)*log10(Lb)-8.2 ;
1403 greg 2.3
1404    
1405 greg 2.9 return pgsv_con;
1406 greg 2.3 }
1407    
1408     /* subroutine for the calculation of the PGSV_saturation; is only applied, when masking is done, since it refers only to the window. Important: masking area must be the window! */
1409     float get_pgsv_sat(double E_v)
1410     {
1411     float pgsv_sat;
1412    
1413 greg 2.9 pgsv_sat =3.3-(0.57+3.3)/(1+pow(E_v/3.14159265359/1250,1.7));
1414 greg 2.3
1415 greg 2.1
1416 greg 2.3 return pgsv_sat;
1417 greg 2.1 }
1418    
1419 greg 2.9 /* subroutine for the calculation of the PGSV; is only applied, when masking is done, since it refers only to the window. Important: masking area must be the window! */
1420    
1421     float get_pgsv(double E_v, double E_mask,double omega_mask,double lum_mask_av,double Ltask, double Lavg)
1422     {
1423     float pgsv;
1424     double Lb;
1425    
1426     /* Lb = (E_v-E_mask)/3.14159265359; */
1427     /* Lb = (2*E_v-lum_mask_av*omega_mask)/(2*3.14159265359-omega_mask); */
1428     Lb = (2*3.14159265359*Lavg-lum_mask_av*omega_mask)/(2*3.14159265359-omega_mask);
1429    
1430     if (Lb==0.0 ) {
1431     fprintf(stderr, " warning: Background luminance is 0 or masking area = full image! pgsv cannot be calculated (set to -99)!!\n");
1432     pgsv=-99;
1433     }else{
1434     if ( (lum_mask_av/Lb) > (E_v/(3.14159265359*Ltask))) {
1435     pgsv=get_pgsv_con(E_v,E_mask,omega_mask,lum_mask_av, Lavg);
1436     }else{
1437     pgsv=get_pgsv_sat(E_v) ;
1438     }}
1439     return pgsv;
1440    
1441     }
1442 greg 2.1
1443 greg 2.3
1444    
1445 greg 2.1 #ifdef EVALGLARE
1446    
1447    
1448     /* main program
1449     ------------------------------------------------------------------------------------------------------------------*/
1450    
1451    
1452     int main(int argc, char **argv)
1453     {
1454 greg 2.11 #define CLINEMAX 999999999 /* memory allocated for command line string */
1455 greg 2.1 pict *p = pict_create();
1456 greg 2.3 pict *pm = pict_create();
1457 greg 2.11 pict *pcoeff = pict_create();
1458     int lowlight,skip_second_scan,calcfast,age_corr,cut_view,cut_view_type,calc_vill, output, detail_out2, x1,y1, fill, yfillmax, yfillmin,
1459     ext_vill, set_lum_max, set_lum_max2, img_corr,x_disk,y_disk,task_color, i_splitstart,zones,act_gsn,splitgs,j,multi_image_mode,
1460     i_split, posindex_2, task_lum, checkfile, rval, i, i_max, x, y,x2,y2,x_zone,y_zone, i_z1, i_z2, thres_activate,num_images,xmap,ymap,
1461 greg 2.3 igs, actual_igs, lastpixelwas_gs, icol, xt, yt, change,checkpixels, before_igs, sgs, splithigh,uniform_gs,x_max, y_max,y_mid,
1462 greg 2.11 detail_out, posindex_picture, non_cos_lb, rx, ry,lastpixelwas_peak, rmx,rmy,apply_disability,band_calc,band_color,masking,i_mask,no_glaresources,force;
1463 greg 2.7 double LUM_replace,lum_total_max,age_corr_factor,age,dgp_ext,dgp,low_light_corr,omega_cos_contr, setvalue, lum_ideal, E_v_contr, sigma,om,delta_E,
1464 greg 2.9 E_vl_ext, lum_max, new_lum_max, r_center, ugp, ugr_exp, dgi_mod,lum_a, E_v_mask,angle_disk,dist,n_corner_px,zero_corner_px,
1465 greg 2.6 search_pix, a1, a2, a3, a4, a5, c3, c1, c2, r_split, max_angle,r_actual,lum_actual,dir_ill,
1466 greg 2.11 omegat, sang,Ez1,Ez2, E_v, E_v2, E_v_dir, avlum, act_lum, ang, angle_z1, angle_z2,per_95_band,per_75_band,pos,
1467 greg 2.3 l_max, lum_backg, lum_backg_cos, omega_sources, lum_sources,per_75_mask,per_95_mask,per_75_z1,per_95_z1,per_75_z2,per_95_z2,
1468     lum, lum_source,teta,Lveil_cie,Lveil_cie_sum,disability_thresh,u_r,u_g,u_b,band_angle,band_avlum,
1469     lum_mask[1],lum_mask_av,lum_mask_std[1],lum_mask_median[1],omega_mask,bbox[2],
1470     lum_band[1],lum_band_av,lum_band_std[1],lum_band_median[1],omega_band,bbox_band[2],
1471     lum_z1[1],lum_z1_av,lum_z1_std[1],lum_z1_median[1],omega_z1,bbox_z1[2],
1472     lum_z2[1],lum_z2_av,lum_z2_std[1],lum_z2_median[1],omega_z2,bbox_z2[2],
1473     lum_pos[1],lum_nopos_median[1],lum_pos_median[1],lum_pos2_median[1],lum_pos_mean,lum_pos2_mean;
1474 greg 2.9 float lum_task, lum_thres, dgi, vcp, cgi, ugr, limit, dgr,pgsv ,pgsv_sat,pgsv_con,
1475 greg 2.1 abs_max, Lveil;
1476 greg 2.11 char maskfile[500],file_out[500], file_out2[500], version[500],correction_type[500];
1477 greg 2.8 char *cline;
1478 greg 2.11 char** temp_image_name;
1479     int *x_temp_img, *y_temp_img;
1480 greg 2.1 VIEW userview = STDVIEW;
1481     int gotuserview = 0;
1482 greg 2.11
1483 greg 2.8 struct muc_rvar* s_mask;
1484 greg 2.3 s_mask = muc_rvar_create();
1485 greg 2.8 muc_rvar_set_dim(s_mask, 1);
1486 greg 2.3 muc_rvar_clear(s_mask);
1487 greg 2.8 struct muc_rvar* s_band;
1488 greg 2.3 s_band = muc_rvar_create();
1489 greg 2.8 muc_rvar_set_dim(s_band, 1);
1490 greg 2.3 muc_rvar_clear(s_band);
1491 greg 2.8 struct muc_rvar* s_z1;
1492 greg 2.3 s_z1 = muc_rvar_create();
1493 greg 2.8 muc_rvar_set_dim(s_z1, 1);
1494 greg 2.3 muc_rvar_clear(s_z1);
1495    
1496 greg 2.8 struct muc_rvar* s_z2;
1497 greg 2.3 s_z2 = muc_rvar_create();
1498 greg 2.8 muc_rvar_set_dim(s_z2, 1);
1499 greg 2.3 muc_rvar_clear(s_z2);
1500    
1501 greg 2.8 struct muc_rvar* s_noposweight;
1502 greg 2.3 s_noposweight = muc_rvar_create();
1503 greg 2.8 muc_rvar_set_dim(s_noposweight, 1);
1504 greg 2.3 muc_rvar_clear(s_noposweight);
1505    
1506 greg 2.8 struct muc_rvar* s_posweight;
1507 greg 2.3 s_posweight = muc_rvar_create();
1508 greg 2.8 muc_rvar_set_dim(s_posweight, 1);
1509 greg 2.3 muc_rvar_clear(s_posweight);
1510    
1511 greg 2.8 struct muc_rvar* s_posweight2;
1512 greg 2.3 s_posweight2 = muc_rvar_create();
1513 greg 2.8 muc_rvar_set_dim(s_posweight2, 1);
1514 greg 2.3 muc_rvar_clear(s_posweight2);
1515 greg 2.1
1516     /*set required user view parameters to invalid values*/
1517 greg 2.11 lowlight=1;
1518     multi_image_mode=0;
1519     lastpixelwas_peak=0;
1520     num_images=0;
1521     dir_ill=0.0;
1522 greg 2.3 delta_E=0.0;
1523     no_glaresources=0;
1524     n_corner_px=0;
1525     zero_corner_px=0;
1526     force=0;
1527     dist=0.0;
1528     u_r=0.33333;
1529     u_g=0.33333;
1530     u_b=0.33333;
1531     band_angle=0;
1532     angle_z1=0;
1533     angle_z2=0;
1534     x_zone=0;
1535     y_zone=0;
1536     per_75_z2=0;
1537     per_95_z2=0;
1538     lum_pos_mean=0;
1539     lum_pos2_mean=0;
1540     lum_band_av = 0.0;
1541     omega_band = 0.0;
1542     pgsv = 0.0 ;
1543 greg 2.9 pgsv_con = 0.0 ;
1544 greg 2.3 pgsv_sat = 0.0 ;
1545     E_v_mask = 0.0;
1546 greg 2.11 Ez1 = 0.0;
1547     Ez2 = 0.0;
1548 greg 2.3 lum_z1_av = 0.0;
1549     omega_z1 = 0.0;
1550     lum_z2_av = 0.0;
1551     omega_z2 = 0.0 ;
1552     i_z1 = 0;
1553     i_z2 = 0;
1554     zones = 0;
1555     lum_z2_av = 0.0;
1556     uniform_gs = 0;
1557 greg 2.1 apply_disability = 0;
1558     disability_thresh = 0;
1559     Lveil_cie_sum=0.0;
1560     skip_second_scan=0;
1561     lum_total_max=0.0;
1562     calcfast=0;
1563     age_corr_factor = 1.0;
1564     age_corr = 0;
1565     age = 20.0;
1566     userview.horiz = 0;
1567     userview.vert = 0;
1568     userview.type = 0;
1569     dgp_ext = 0;
1570     E_vl_ext = 0.0;
1571     new_lum_max = 0.0;
1572     lum_max = 0.0;
1573     omegat = 0.0;
1574     yt = 0;
1575     xt = 0;
1576 greg 2.3 x_disk=0;
1577     y_disk=0;
1578     angle_disk=0;
1579 greg 2.1 yfillmin = 0;
1580     yfillmax = 0;
1581     cut_view = 0;
1582     cut_view_type = 0;
1583     setvalue = 2e09;
1584     omega_cos_contr = 0.0;
1585     lum_ideal = 0.0;
1586     max_angle = 0.2;
1587 greg 2.8 lum_thres = 2000.0;
1588 greg 2.9 lum_task = 0.0;
1589 greg 2.1 task_lum = 0;
1590     sgs = 0;
1591     splithigh = 1;
1592     detail_out = 0;
1593     detail_out2 = 0;
1594     posindex_picture = 0;
1595     checkfile = 0;
1596     ext_vill = 0;
1597     fill = 0;
1598     a1 = 2.0;
1599     a2 = 1.0;
1600     a3 = 1.87;
1601     a4 = 2.0;
1602     a5 = 1.0;
1603     c1 = 5.87e-05;
1604     c2 = 0.092;
1605     c3 = 0.159;
1606 greg 2.8 non_cos_lb = 0;
1607 greg 2.1 posindex_2 = 0;
1608     task_color = 0;
1609     limit = 50000.0;
1610     set_lum_max = 0;
1611     set_lum_max2 = 0;
1612 greg 2.3 img_corr=0;
1613 greg 2.1 abs_max = 0;
1614 greg 2.12 fixargv0(argv[0]);
1615 greg 2.1 E_v_contr = 0.0;
1616 greg 2.3 strcpy(version, "1.19 release 09.12.2015 by J.Wienold");
1617 greg 2.1 low_light_corr=1.0;
1618     output = 0;
1619     calc_vill = 0;
1620     band_avlum = -99;
1621     band_calc = 0;
1622 greg 2.3 masking = 0;
1623     lum_mask[0]=0.0;
1624     lum_mask_av=0.0;
1625     omega_mask=0.0;
1626     i_mask=0;
1627     actual_igs=0;
1628 greg 2.7 LUM_replace=0;
1629 greg 2.8 thres_activate=0;
1630 greg 2.1 /* command line for output picture*/
1631    
1632 greg 2.11 cline = (char *) malloc(CLINEMAX+100);
1633 greg 2.1 cline[0] = '\0';
1634     for (i = 0; i < argc; i++) {
1635     /* fprintf(stderr, "%d %d \n",i,strlen(argv[i]));*/
1636     if (strlen(cline)+strlen(argv[i])+strlen(RELEASENAME)+2 >=CLINEMAX) {
1637     exit (-1);
1638     }
1639     else {
1640     strcat(cline, argv[i]);
1641     strcat(cline, " ");
1642     }
1643     }
1644     strcat(cline, "\n");
1645     strcat(cline, RELEASENAME);
1646     strcat(cline, "\n");
1647    
1648    
1649     /* program options */
1650    
1651     for (i = 1; i < argc && argv[i][0] == '-'; i++) {
1652     /* expand arguments */
1653     while ((rval = expandarg(&argc, &argv, i)) > 0);
1654     if (rval < 0) {
1655     fprintf(stderr, "%s: cannot expand '%s'", argv[0], argv[i]);
1656     exit(1);
1657     }
1658     rval = getviewopt(&userview, argc - i, argv + i);
1659     if (rval >= 0) {
1660     i += rval;
1661     gotuserview++;
1662     continue;
1663     }
1664     switch (argv[i][1]) {
1665     case 'a':
1666     age = atof(argv[++i]);
1667     age_corr = 1;
1668     printf("age factor not supported any more \n");
1669     exit(1);
1670     break;
1671 greg 2.3 case 'A':
1672     masking = 1;
1673     detail_out = 1;
1674     strcpy(maskfile, argv[++i]);
1675     pict_read(pm,maskfile );
1676    
1677     break;
1678 greg 2.1 case 'b':
1679     lum_thres = atof(argv[++i]);
1680 greg 2.11 lum_source =lum_thres;
1681 greg 2.8 thres_activate = 1;
1682 greg 2.1 break;
1683     case 'c':
1684     checkfile = 1;
1685     strcpy(file_out, argv[++i]);
1686     break;
1687     case 'u':
1688     uniform_gs = 1;
1689     u_r = atof(argv[++i]);
1690     u_g = atof(argv[++i]);
1691     u_b = atof(argv[++i]);
1692     break;
1693     case 'r':
1694     max_angle = atof(argv[++i]);
1695     break;
1696     case 's':
1697     sgs = 1;
1698     break;
1699 greg 2.3 case 'f':
1700     force = 1;
1701     break;
1702 greg 2.1 case 'k':
1703     apply_disability = 1;
1704     disability_thresh = atof(argv[++i]);
1705     break;
1706    
1707     case 'p':
1708     posindex_picture = 1;
1709     break;
1710 greg 2.3 case 'P':
1711     posindex_2 = atoi(argv[++i]);
1712     break;
1713    
1714 greg 2.1
1715     case 'y':
1716     splithigh = 1;
1717     break;
1718     case 'x':
1719     splithigh = 0;
1720     break;
1721     case 'Y':
1722     splithigh = 1;
1723     limit = atof(argv[++i]);
1724     break;
1725    
1726     case 'i':
1727     ext_vill = 1;
1728     E_vl_ext = atof(argv[++i]);
1729     break;
1730     case 'I':
1731     ext_vill = 1;
1732     fill = 1;
1733     E_vl_ext = atof(argv[++i]);
1734     yfillmax = atoi(argv[++i]);
1735     yfillmin = atoi(argv[++i]);
1736     break;
1737     case 'd':
1738     detail_out = 1;
1739     break;
1740     case 'D':
1741     detail_out2 = 1;
1742     break;
1743     case 'm':
1744 greg 2.3 img_corr = 1;
1745 greg 2.1 set_lum_max = 1;
1746     lum_max = atof(argv[++i]);
1747     new_lum_max = atof(argv[++i]);
1748     strcpy(file_out2, argv[++i]);
1749     /* printf("max lum set to %f\n",new_lum_max);*/
1750     break;
1751    
1752     case 'M':
1753 greg 2.3 img_corr = 1;
1754 greg 2.1 set_lum_max2 = 1;
1755     lum_max = atof(argv[++i]);
1756     E_vl_ext = atof(argv[++i]);
1757     strcpy(file_out2, argv[++i]);
1758     /* printf("max lum set to %f\n",new_lum_max);*/
1759     break;
1760 greg 2.3 case 'N':
1761     img_corr = 1;
1762     set_lum_max2 = 2;
1763     x_disk = atoi(argv[++i]);
1764     y_disk = atoi(argv[++i]);
1765     angle_disk = atof(argv[++i]);
1766     E_vl_ext = atof(argv[++i]);
1767     strcpy(file_out2, argv[++i]);
1768     /* printf("max lum set to %f\n",new_lum_max);*/
1769     break;
1770 greg 2.7 case 'O':
1771     img_corr = 1;
1772     set_lum_max2 = 3;
1773     x_disk = atoi(argv[++i]);
1774     y_disk = atoi(argv[++i]);
1775     angle_disk = atof(argv[++i]);
1776     LUM_replace = atof(argv[++i]);
1777     strcpy(file_out2, argv[++i]);
1778     /* printf("max lum set to %f\n",new_lum_max);*/
1779     break;
1780    
1781 greg 2.3
1782 greg 2.8 /* deactivated case 'n':
1783 greg 2.1 non_cos_lb = 0;
1784     break;
1785 greg 2.8 */
1786     case 'q':
1787     non_cos_lb = atoi(argv[++i]);
1788     break;
1789 greg 2.1
1790     case 't':
1791     task_lum = 1;
1792     xt = atoi(argv[++i]);
1793     yt = atoi(argv[++i]);
1794     omegat = atof(argv[++i]);
1795     task_color = 0;
1796     break;
1797     case 'T':
1798     task_lum = 1;
1799     xt = atoi(argv[++i]);
1800     yt = atoi(argv[++i]);
1801     /* omegat= DEG2RAD(atof(argv[++i]));*/
1802     omegat = atof(argv[++i]);
1803     task_color = 1;
1804     break;
1805 greg 2.3 case 'l':
1806     zones = 1;
1807     x_zone = atoi(argv[++i]);
1808     y_zone = atoi(argv[++i]);
1809     angle_z1 = atof(argv[++i]);
1810     angle_z2 = -1;
1811     break;
1812     case 'L':
1813     zones = 2;
1814     x_zone = atoi(argv[++i]);
1815     y_zone = atoi(argv[++i]);
1816     angle_z1 = atof(argv[++i]);
1817     angle_z2 = atof(argv[++i]);
1818     break;
1819    
1820    
1821 greg 2.1 case 'B':
1822     band_calc = 1;
1823     band_angle = atof(argv[++i]);
1824     band_color = 1;
1825     break;
1826    
1827    
1828     case 'w':
1829     a1 = atof(argv[++i]);
1830     a2 = atof(argv[++i]);
1831     a3 = atof(argv[++i]);
1832     a4 = atof(argv[++i]);
1833     a5 = atof(argv[++i]);
1834     c1 = atof(argv[++i]);
1835     c2 = atof(argv[++i]);
1836     c3 = atof(argv[++i]);
1837     break;
1838     case 'V':
1839     calc_vill = 1;
1840     break;
1841     case 'G':
1842     cut_view = 1;
1843     cut_view_type= atof(argv[++i]);
1844     break;
1845     case 'g':
1846     cut_view = 2;
1847     cut_view_type= atof(argv[++i]);
1848     break;
1849    
1850     /*case 'v':
1851     printf("evalglare %s \n",version);
1852     exit(1); */
1853 greg 2.11 case 'C':
1854     strcpy(correction_type,argv[++i]);
1855    
1856     if (!strcmp(correction_type,"l-") ){
1857     /* printf("low light off!\n"); */
1858     lowlight = 0; }
1859     if (!strcmp(correction_type,"l+") ){
1860     /* printf("low light on!\n"); */
1861     lowlight = 1; }
1862     if (!strcmp(correction_type,"0") ){
1863     /* printf("all corrections off!\n"); */
1864     lowlight = 0; }
1865    
1866     break;
1867    
1868     /*case 'v':
1869     printf("evalglare %s \n",version);
1870     exit(1); */
1871 greg 2.1
1872     case '1':
1873     output = 1;
1874     break;
1875 greg 2.6 case '2':
1876     output = 2;
1877     dir_ill = atof(argv[++i]);
1878     break;
1879 greg 2.11 case '3':
1880     output = 3;
1881     break;
1882     case '4':
1883     lowlight = 0;
1884     break;
1885     case 'Q':
1886     multi_image_mode=1;
1887     output= 3;
1888     calcfast=1;
1889     num_images =atoi(argv[++i]);
1890     temp_image_name = malloc(sizeof(char*)*num_images);
1891    
1892     x_temp_img=(int *) malloc(sizeof(int) * num_images);
1893     y_temp_img=(int *) malloc(sizeof(int) * num_images);
1894    
1895    
1896     /* iterate through all images and allocate 256 characters to each: */
1897     for (j = 0; j < num_images; j++) {
1898     temp_image_name[j] = malloc(256*sizeof(char));
1899     strcpy(temp_image_name[j], argv[++i]);
1900     x_temp_img[j] = atoi(argv[++i]);
1901     y_temp_img[j] = atoi(argv[++i]);
1902     }
1903    
1904    
1905     break;
1906 greg 2.1 case 'v':
1907     if (argv[i][2] == '\0') {
1908     printf("%s \n",RELEASENAME);
1909     exit(1);
1910     }
1911     if (argv[i][2] != 'f')
1912     goto userr;
1913     rval = viewfile(argv[++i], &userview, NULL);
1914     if (rval < 0) {
1915     fprintf(stderr,
1916     "%s: cannot open view file \"%s\"\n",
1917     progname, argv[i]);
1918     exit(1);
1919     } else if (rval == 0) {
1920     fprintf(stderr,
1921     "%s: bad view file \"%s\"\n", progname, argv[i]);
1922     exit(1);
1923     } else {
1924     gotuserview++;
1925     }
1926     break;
1927    
1928    
1929     default:
1930     goto userr;
1931     }
1932     }
1933    
1934 greg 2.8 /* set multiplier for task method to 5, if not specified */
1935    
1936     if ( task_lum == 1 && thres_activate == 0){
1937     lum_thres = 5.0;
1938     }
1939 greg 2.1 /*fast calculation, if gendgp_profile is used: No Vertical illuminance calculation, only dgp is calculated*/
1940    
1941 greg 2.6 if (output == 1 && ext_vill == 1 ) {
1942 greg 2.1 calcfast=1;
1943     }
1944 greg 2.6
1945     if (output == 2 && ext_vill == 1 ) {
1946     calcfast=2;
1947     }
1948    
1949 greg 2.3 /*masking and zoning cannot be applied at the same time*/
1950    
1951     if (masking ==1 && zones >0) {
1952     fprintf(stderr, " masking and zoning cannot be activated at the same time!\n");
1953     exit(1);
1954     }
1955 greg 2.1
1956     /* read picture file */
1957     if (i == argc) {
1958     SET_FILE_BINARY(stdin);
1959     FILE *fp = fdopen(fileno(stdin), "rb");
1960     if (!(fp)) {
1961     fprintf(stderr, "fdopen on stdin failed\n");
1962     return EXIT_FAILURE;
1963     }
1964     if (!(pict_read_fp(p, fp)))
1965     return EXIT_FAILURE;;
1966     } else {
1967     if (!pict_read(p, argv[i]))
1968     return EXIT_FAILURE;
1969     }
1970     if (gotuserview) {
1971     if (p->valid_view)
1972     fprintf(stderr,
1973     "warning: overriding image view by commandline argument\n");
1974     if ((userview.horiz == 0) || (userview.vert == 0) || (userview.type == 0)) {
1975     fprintf(stderr, "error: if specified, a view must at least contain -vt -vv and -vh\n");
1976     return EXIT_FAILURE;
1977     }
1978     p->view = userview;
1979     if (!(pict_update_view(p))) {
1980     fprintf(stderr, "error: invalid view specified");
1981     return EXIT_FAILURE;
1982     }
1983     pict_update_evalglare_caches(p);
1984     } else if (!(p->valid_view)) {
1985     fprintf(stderr, "error: no valid view specified\n");
1986     return EXIT_FAILURE;
1987     }
1988    
1989 greg 2.3
1990    
1991 greg 2.1 /* fprintf(stderr,"Picture read!");*/
1992    
1993     /* command line for output picture*/
1994    
1995     pict_set_comment(p, cline);
1996    
1997 greg 2.3 /* several checks */
1998 greg 2.1 if (p->view.type == VT_PAR) {
1999 greg 2.3 fprintf(stderr, "error: wrong view type! must not be parallel ! \n");
2000 greg 2.1 exit(1);
2001     }
2002    
2003 greg 2.3 if (p->view.type == VT_PER) {
2004     fprintf(stderr, "warning: image has perspective view type specified in header ! \n");
2005     }
2006    
2007     if (masking == 1) {
2008    
2009 greg 2.10 if (pict_get_xsize(p)!=pict_get_xsize(pm) || pict_get_ysize(p)!=pict_get_ysize(pm)) {
2010 greg 2.3 fprintf(stderr, "error: masking image has other resolution than main image ! \n");
2011     fprintf(stderr, "size must be identical \n");
2012     printf("resolution main image : %dx%d\n",pict_get_xsize(p),pict_get_ysize(p));
2013     printf("resolution masking image : %dx%d\n",pict_get_xsize(pm),pict_get_ysize(pm));
2014     exit(1);
2015    
2016     }
2017    
2018     }
2019     /* printf("resolution: %dx%d\n",pict_get_xsize(p),pict_get_ysize(p)); */
2020 greg 2.1
2021     /* Check size of search radius */
2022     rmx = (pict_get_xsize(p) / 2);
2023     rmy = (pict_get_ysize(p) / 2);
2024     rx = (pict_get_xsize(p) / 2 + 10);
2025     ry = (pict_get_ysize(p) / 2 + 10);
2026     r_center =
2027     acos(DOT(pict_get_cached_dir(p, rmx, rmy),
2028     pict_get_cached_dir(p, rx, ry))) * 2 / 10;
2029     search_pix = max_angle / r_center;
2030     if (search_pix < 1.0) {
2031     fprintf(stderr,
2032     "warning: search radius less than 1 pixel! deactivating smoothing and peak extraction...\n");
2033     splithigh = 0;
2034     sgs = 0;
2035    
2036     } else {
2037     if (search_pix < 3.0) {
2038     fprintf(stderr,
2039     "warning: search radius less than 3 pixels! -> %f \n",
2040     search_pix);
2041    
2042     }
2043     }
2044 greg 2.11
2045    
2046 greg 2.1 /* Check task position */
2047    
2048     if (task_lum == 1) {
2049     if (xt >= pict_get_xsize(p) || yt >= pict_get_ysize(p) || xt < 0
2050     || yt < 0) {
2051     fprintf(stderr,
2052     "error: task position outside picture!! exit...");
2053     exit(1);
2054     }
2055     }
2056    
2057    
2058     /* printf("resolution: %dx%d\n",pict_get_xsize(p),pict_get_ysize(p)); */
2059    
2060     sang = 0.0;
2061     E_v = 0.0;
2062     E_v_dir = 0.0;
2063     avlum = 0.0;
2064     pict_new_gli(p);
2065     igs = 0;
2066 greg 2.3 pict_get_z1_gsn(p,igs) = 0;
2067     pict_get_z2_gsn(p,igs) = 0;
2068    
2069 greg 2.11 if (multi_image_mode<1) {
2070    
2071 greg 2.1
2072     /* cut out GUTH field of view and exit without glare evaluation */
2073     if (cut_view==2) {
2074     if (cut_view_type==1) {
2075     cut_view_1(p);
2076     }else{
2077    
2078     if (cut_view_type==2) {
2079     cut_view_2(p);
2080     }else{
2081     if (cut_view_type==3) {
2082     fprintf(stderr,"warning: pixel luminance is weighted by position index - do not use image for glare evaluations!!");
2083     cut_view_3(p);
2084     }else{
2085     fprintf(stderr,"error: no valid option for view cutting!!");
2086     exit(1);
2087     }
2088     }}
2089     pict_write(p, file_out);
2090     exit(1); }
2091    
2092    
2093    
2094    
2095    
2096    
2097     /* write positionindex into checkfile and exit, activated by option -p */
2098     if (posindex_picture == 1) {
2099     for (x = 0; x < pict_get_xsize(p); x++)
2100     for (y = 0; y < pict_get_ysize(p); y++) {
2101     if (pict_get_hangle
2102     (p, x, y, p->view.vdir, p->view.vup, &ang)) {
2103     if (pict_is_validpixel(p, x, y)) {
2104     lum =
2105     get_posindex(p, x, y,
2106     posindex_2) / WHTEFFICACY;
2107    
2108     pict_get_color(p, x, y)[RED] = lum;
2109     pict_get_color(p, x, y)[GRN] = lum;
2110     pict_get_color(p, x, y)[BLU] = lum;
2111     lum_task = luminance(pict_get_color(p, x, y));
2112     /*printf("x,y,posindex=%i %i %f %f\n",x,y,lum*WHTEFFICACY,lum_task);*/
2113     }
2114     }
2115     }
2116     pict_write(p, file_out);
2117     exit(1);
2118     }
2119    
2120    
2121     /* calculation of vertical illuminance, average luminance, in case of filling activated-> fill picture */
2122     /* fill, if necessary from 0 to yfillmin */
2123    
2124     if (fill == 1) {
2125     for (x = 0; x < pict_get_xsize(p); x++)
2126     for (y = yfillmin; y > 0; y = y - 1) {
2127     y1 = y + 1;
2128     lum = luminance(pict_get_color(p, x, y1));
2129     pict_get_color(p, x, y)[RED] = lum / 179.0;
2130     pict_get_color(p, x, y)[GRN] = lum / 179.0;
2131     pict_get_color(p, x, y)[BLU] = lum / 179.0;
2132     }
2133     }
2134    
2135     if (calcfast == 0) {
2136     for (x = 0; x < pict_get_xsize(p); x++)
2137     for (y = 0; y < pict_get_ysize(p); y++) {
2138 greg 2.3 lum = luminance(pict_get_color(p, x, y));
2139     dist=sqrt((x-rmx)*(x-rmx)+(y-rmy)*(y-rmy));
2140     if (dist>((rmx+rmy)/2)) {
2141     n_corner_px=n_corner_px+1;
2142     if (lum<7.0) {
2143     zero_corner_px=zero_corner_px+1;
2144     }
2145     }
2146    
2147    
2148 greg 2.1 if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2149     if (pict_is_validpixel(p, x, y)) {
2150     if (fill == 1 && y >= yfillmax) {
2151     y1 = y - 1;
2152     lum = luminance(pict_get_color(p, x, y1));
2153     pict_get_color(p, x, y)[RED] = lum / 179.0;
2154     pict_get_color(p, x, y)[GRN] = lum / 179.0;
2155     pict_get_color(p, x, y)[BLU] = lum / 179.0;
2156     }
2157    
2158     if (lum > abs_max) {
2159     abs_max = lum;
2160     }
2161     /* set luminance restriction, if -m is set */
2162 greg 2.3 if (img_corr == 1 ) {
2163     if (set_lum_max == 1 && lum >= lum_max) {
2164     pict_get_color(p, x, y)[RED] = new_lum_max / 179.0;
2165     pict_get_color(p, x, y)[GRN] = new_lum_max / 179.0;
2166     pict_get_color(p, x, y)[BLU] = new_lum_max / 179.0;
2167     /* printf("old lum, new lum %f %f \n",lum,luminance(pict_get_color(p,x,y))); */
2168     lum = luminance(pict_get_color(p, x, y));
2169     }
2170     if (set_lum_max2 == 1 && lum >= lum_max) {
2171    
2172     E_v_contr +=DOT(p->view.vdir,pict_get_cached_dir(p, x,y)) * pict_get_omega(p,x,y)* lum;
2173     omega_cos_contr +=DOT(p->view.vdir,pict_get_cached_dir(p, x,y)) * pict_get_omega(p,x,y)* 1;
2174     }
2175     if (set_lum_max2 == 2 ) {
2176     r_actual =acos(DOT(pict_get_cached_dir(p, x_disk, y_disk), pict_get_cached_dir(p, x, y))) * 2;
2177     if (x_disk == x && y_disk==y ) r_actual=0.0;
2178    
2179     act_lum = luminance(pict_get_color(p, x, y));
2180    
2181     if (r_actual <= angle_disk) {
2182     E_v_contr +=DOT(p->view.vdir,pict_get_cached_dir(p, x,y)) * pict_get_omega(p,x,y)* lum;
2183     omega_cos_contr += DOT(p->view.vdir,pict_get_cached_dir(p, x,y)) * pict_get_omega(p,x,y)* 1;
2184     }
2185 greg 2.1
2186 greg 2.3
2187    
2188     }
2189 greg 2.1 }
2190 greg 2.3 om = pict_get_omega(p, x, y);
2191     sang += om;
2192     E_v += DOT(p->view.vdir, pict_get_cached_dir(p, x,y)) * om *lum;
2193     avlum += om * lum;
2194     pos=get_posindex(p, x, y,posindex_2);
2195    
2196     lum_pos[0]=lum;
2197     muc_rvar_add_sample(s_noposweight,lum_pos);
2198     lum_pos[0]=lum/pos;
2199     lum_pos_mean+=lum_pos[0]*om;
2200     muc_rvar_add_sample(s_posweight, lum_pos);
2201     lum_pos[0]=lum_pos[0]/pos;
2202     lum_pos2_mean+=lum_pos[0]*om;
2203     muc_rvar_add_sample(s_posweight2,lum_pos);
2204 greg 2.1
2205    
2206    
2207     } else {
2208     pict_get_color(p, x, y)[RED] = 0.0;
2209     pict_get_color(p, x, y)[GRN] = 0.0;
2210     pict_get_color(p, x, y)[BLU] = 0.0;
2211    
2212     }
2213 greg 2.3 }else {
2214     pict_get_color(p, x, y)[RED] = 0.0;
2215     pict_get_color(p, x, y)[GRN] = 0.0;
2216     pict_get_color(p, x, y)[BLU] = 0.0;
2217    
2218     }
2219 greg 2.1 }
2220    
2221 greg 2.3 /* check if image has black corners AND a perspective view */
2222    
2223     if (zero_corner_px/n_corner_px > 0.70 && (p->view.type == VT_PER) ) {
2224     printf (" corner pixels are to %f %% black! \n",zero_corner_px/n_corner_px*100);
2225     printf("error! The image has black corners AND header contains a perspective view type definition !!!\n") ;
2226    
2227     if (force==0) {
2228     printf("stopping...!!!!\n") ;
2229    
2230     exit(1);
2231     }
2232     }
2233    
2234    
2235    
2236    
2237     lum_pos_mean= lum_pos_mean/sang;
2238     lum_pos2_mean= lum_pos2_mean/sang;
2239    
2240 greg 2.8 if ((set_lum_max2 >= 1 && E_v_contr > 0 && (E_vl_ext - E_v) > 0 ) || set_lum_max2==3) {
2241 greg 2.1
2242 greg 2.7 if (set_lum_max2<3){
2243 greg 2.1 lum_ideal = (E_vl_ext - E_v + E_v_contr) / omega_cos_contr;
2244 greg 2.3 if (set_lum_max2 == 2 && lum_ideal >= 2e9) {
2245     printf("warning! luminance of replacement pixels would be larger than 2e9 cd/m2. Value set to 2e9cd/m2!\n") ;
2246     }
2247    
2248 greg 2.1 if (lum_ideal > 0 && lum_ideal < setvalue) {
2249     setvalue = lum_ideal;
2250     }
2251 greg 2.3 printf("change luminance values!! lum_ideal,setvalue,E_vl_ext,E_v,E_v_contr %f %f %f %f %f\n",
2252 greg 2.1 lum_ideal, setvalue, E_vl_ext, E_v, E_v_contr);
2253 greg 2.7 }else{setvalue=LUM_replace;
2254     }
2255 greg 2.1
2256 greg 2.3
2257 greg 2.1 for (x = 0; x < pict_get_xsize(p); x++)
2258     for (y = 0; y < pict_get_ysize(p); y++) {
2259     if (pict_get_hangle
2260     (p, x, y, p->view.vdir, p->view.vup, &ang)) {
2261     if (pict_is_validpixel(p, x, y)) {
2262     lum = luminance(pict_get_color(p, x, y));
2263 greg 2.3
2264    
2265 greg 2.1 if (set_lum_max2 == 1 && lum >= lum_max) {
2266    
2267     pict_get_color(p, x, y)[RED] =
2268     setvalue / 179.0;
2269     pict_get_color(p, x, y)[GRN] =
2270     setvalue / 179.0;
2271     pict_get_color(p, x, y)[BLU] =
2272     setvalue / 179.0;
2273    
2274 greg 2.7 }else{ if(set_lum_max2 >1 ) {
2275 greg 2.3 r_actual =acos(DOT(pict_get_cached_dir(p, x_disk, y_disk), pict_get_cached_dir(p, x, y))) * 2;
2276     if (x_disk == x && y_disk==y ) r_actual=0.0;
2277    
2278     if (r_actual <= angle_disk) {
2279    
2280     pict_get_color(p, x, y)[RED] =
2281     setvalue / 179.0;
2282     pict_get_color(p, x, y)[GRN] =
2283     setvalue / 179.0;
2284     pict_get_color(p, x, y)[BLU] =
2285     setvalue / 179.0;
2286    
2287 greg 2.7 }
2288 greg 2.3 }
2289 greg 2.1 }
2290     }
2291     }
2292     }
2293 greg 2.3
2294 greg 2.1
2295     pict_write(p, file_out2);
2296 greg 2.3 exit(1);
2297 greg 2.1 }
2298     if (set_lum_max == 1) {
2299     pict_write(p, file_out2);
2300    
2301     }
2302    
2303     if (calc_vill == 1) {
2304     printf("%f\n", E_v);
2305     exit(1);
2306     }
2307     }else{
2308     /* in fast calculation mode: ev=ev_ext and sang=2*pi */
2309     sang=2*3.14159265359;
2310     lum_task =E_vl_ext/sang;
2311     E_v=E_vl_ext;
2312     /* printf("calc fast!! %f %f\n", sang,lum_task);*/
2313    
2314    
2315     }
2316    
2317     /* cut out GUTH field of view for glare evaluation */
2318     if (cut_view==1) {
2319     if (cut_view_type==1) {
2320     cut_view_1(p);
2321     }else{
2322    
2323     if (cut_view_type==2) {
2324     cut_view_2(p);
2325     }else{
2326     if (cut_view_type==3) {
2327     fprintf(stderr,"warning: pixel luminance is weighted by position index - do not use image for glare evaluations!!");
2328     cut_view_3(p);
2329     }else{
2330     fprintf(stderr,"error: no valid option for view cutting!!");
2331     exit(1);
2332     }
2333     }}
2334     }
2335    
2336     if (calcfast == 0) {
2337     avlum = avlum / sang;
2338     lum_task = avlum;
2339     }
2340     /* if (ext_vill==1) {
2341     E_v=E_vl_ext;
2342     avlum=E_v/3.1415927;
2343     } */
2344    
2345     if (task_lum == 1) {
2346     lum_task = get_task_lum(p, xt, yt, omegat, task_color);
2347     }
2348     lum_source = lum_thres * lum_task;
2349     /* printf("Task Luminance=%f\n",lum_task);
2350     pict_write(p,"task.pic");*/
2351    
2352     if (lum_thres > 100) {
2353     lum_source = lum_thres;
2354     }
2355    
2356 greg 2.3 /* printf("Ev, avlum, Omega_tot%f %f %f \n",E_v, avlum, sang); */
2357 greg 2.1
2358     /* first glare source scan: find primary glare sources */
2359 greg 2.3 for (x = 0; x < pict_get_xsize(p); x++) {
2360 greg 2.11 lastpixelwas_gs=0;
2361     /* lastpixelwas_peak=0; */
2362 greg 2.1 for (y = 0; y < pict_get_ysize(p); y++) {
2363     if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2364     if (pict_is_validpixel(p, x, y)) {
2365     act_lum = luminance(pict_get_color(p, x, y));
2366     if (act_lum > lum_source) {
2367     if (act_lum >lum_total_max) {
2368     lum_total_max=act_lum;
2369     }
2370 greg 2.3 /* speed improvement first scan: when last pixel was glare source, then use this glare source number instead of searching.
2371 greg 2.11 has been deactivated with v1.25, reactivated with v2.10 */
2372 greg 2.3
2373 greg 2.11 if (lastpixelwas_gs==0 || search_pix <= 1.0 ) {
2374 greg 2.3 actual_igs = find_near_pgs(p, x, y, max_angle, 0, igs, 1);
2375 greg 2.11 }
2376 greg 2.1 if (actual_igs == 0) {
2377     igs = igs + 1;
2378     pict_new_gli(p);
2379     pict_get_lum_min(p, igs) = HUGE_VAL;
2380     pict_get_Eglare(p,igs) = 0.0;
2381     pict_get_Dglare(p,igs) = 0.0;
2382 greg 2.3 pict_get_z1_gsn(p,igs) = 0;
2383     pict_get_z2_gsn(p,igs) = 0;
2384 greg 2.1 actual_igs = igs;
2385 greg 2.3
2386 greg 2.1 }
2387 greg 2.3 /* no coloring any more here icol = setglcolor(p, x, y, actual_igs, uniform_gs, u_r, u_g , u_b); */
2388 greg 2.1 pict_get_gsn(p, x, y) = actual_igs;
2389     pict_get_pgs(p, x, y) = 1;
2390     add_pixel_to_gs(p, x, y, actual_igs);
2391 greg 2.11 lastpixelwas_gs=actual_igs;
2392 greg 2.1
2393     } else {
2394     pict_get_pgs(p, x, y) = 0;
2395 greg 2.11 lastpixelwas_gs=0;
2396 greg 2.1 }
2397     }
2398     }
2399 greg 2.3 }
2400     }
2401 greg 2.1 /* pict_write(p,"firstscan.pic"); */
2402    
2403 greg 2.3
2404 greg 2.6
2405    
2406     if (calcfast ==1 || search_pix <= 1.0 || calcfast == 2 ) {
2407 greg 2.1 skip_second_scan=1;
2408     }
2409 greg 2.6
2410 greg 2.1
2411     /* second glare source scan: combine glare sources facing each other */
2412     change = 1;
2413 greg 2.3 i = 0;
2414 greg 2.1 while (change == 1 && skip_second_scan==0) {
2415     change = 0;
2416 greg 2.3 i = i+1;
2417     for (x = 0; x < pict_get_xsize(p); x++) {
2418 greg 2.1 for (y = 0; y < pict_get_ysize(p); y++) {
2419     if (pict_get_hangle
2420     (p, x, y, p->view.vdir, p->view.vup, &ang)) {
2421 greg 2.3 checkpixels=1;
2422     before_igs = pict_get_gsn(p, x, y);
2423    
2424     /* speed improvement: search for other nearby glare sources only, when at least one adjacend pixel has another glare source number */
2425     if (x >1 && x<pict_get_xsize(p)-2 && y >1 && y<pict_get_ysize(p)-2 ) {
2426     x1=x-1;
2427     x2=x+1;
2428     y1=y-1;
2429     y2=y+1;
2430     if (before_igs == pict_get_gsn(p, x1, y) && before_igs == pict_get_gsn(p, x2, y) && before_igs == pict_get_gsn(p, x, y1) && before_igs == pict_get_gsn(p, x, y2) && before_igs == pict_get_gsn(p, x1, y1) && before_igs == pict_get_gsn(p, x2, y1) && before_igs == pict_get_gsn(p, x1, y2) && before_igs == pict_get_gsn(p, x2, y2) ) {
2431     checkpixels = 0;
2432     actual_igs = before_igs;
2433     } }
2434    
2435    
2436     if (pict_is_validpixel(p, x, y) && before_igs > 0 && checkpixels==1) {
2437 greg 2.1 actual_igs =
2438     find_near_pgs(p, x, y, max_angle, before_igs,
2439     igs, 1);
2440     if (!(actual_igs == before_igs)) {
2441     change = 1;
2442     }
2443     if (before_igs > 0) {
2444     actual_igs = pict_get_gsn(p, x, y);
2445 greg 2.3 /* icol = setglcolor(p, x, y, actual_igs, uniform_gs, u_r, u_g , u_b); */
2446 greg 2.1 }
2447    
2448     }
2449     }
2450     }
2451     /* pict_write(p,"secondscan.pic");*/
2452 greg 2.3 }}
2453 greg 2.1
2454     /*smoothing: add secondary glare sources */
2455     i_max = igs;
2456     if (sgs == 1) {
2457    
2458     /* simplified search radius: constant for entire picture, alway circle not an angle due to performance */
2459     x = (pict_get_xsize(p) / 2);
2460     y = (pict_get_ysize(p) / 2);
2461     rx = (pict_get_xsize(p) / 2 + 10);
2462     ry = (pict_get_ysize(p) / 2 + 10);
2463     r_center =
2464     acos(DOT(pict_get_cached_dir(p, x, y),
2465     pict_get_cached_dir(p, rx, ry))) * 2 / 10;
2466     search_pix = max_angle / r_center / 1.75;
2467    
2468     for (x = 0; x < pict_get_xsize(p); x++) {
2469     for (y = 0; y < pict_get_ysize(p); y++) {
2470     if (pict_get_hangle
2471     (p, x, y, p->view.vdir, p->view.vup, &ang)) {
2472     if (pict_is_validpixel(p, x, y)
2473     && pict_get_gsn(p, x, y) == 0) {
2474     for (i = 1; i <= i_max; i++) {
2475    
2476     if (pict_get_npix(p, i) > 0) {
2477     add_secondary_gs(p, x, y, search_pix, i, uniform_gs, u_r, u_g , u_b);
2478     }
2479     }
2480    
2481     }
2482     }
2483     }
2484     }
2485    
2486     }
2487    
2488     /* extract extremes from glare sources to extra glare source */
2489     if (splithigh == 1 && lum_total_max>limit) {
2490 greg 2.11 /* fprintf(stderr, " split of glare source!\n"); */
2491 greg 2.1
2492     r_split = max_angle / 2.0;
2493     for (i = 0; i <= i_max; i++) {
2494    
2495     if (pict_get_npix(p, i) > 0) {
2496     l_max = pict_get_lum_max(p, i);
2497     i_splitstart = igs + 1;
2498     if (l_max >= limit) {
2499     for (x = 0; x < pict_get_xsize(p); x++)
2500     for (y = 0; y < pict_get_ysize(p); y++) {
2501     if (pict_get_hangle
2502     (p, x, y, p->view.vdir, p->view.vup, &ang))
2503     {
2504     if (pict_is_validpixel(p, x, y)
2505     && luminance(pict_get_color(p, x, y))
2506     >= limit
2507     && pict_get_gsn(p, x, y) == i) {
2508     if (i_splitstart == (igs + 1)) {
2509     igs = igs + 1;
2510     pict_new_gli(p);
2511 greg 2.3 pict_get_z1_gsn(p,igs) = 0;
2512     pict_get_z2_gsn(p,igs) = 0;
2513    
2514 greg 2.1 pict_get_Eglare(p,igs) = 0.0;
2515     pict_get_Dglare(p,igs) = 0.0;
2516     pict_get_lum_min(p, igs) =
2517     99999999999999.999;
2518     i_split = igs;
2519     } else {
2520     i_split =
2521     find_split(p, x, y, r_split,
2522     i_splitstart, igs);
2523     }
2524     if (i_split == 0) {
2525     igs = igs + 1;
2526     pict_new_gli(p);
2527 greg 2.3 pict_get_z1_gsn(p,igs) = 0;
2528     pict_get_z2_gsn(p,igs) = 0;
2529    
2530 greg 2.1 pict_get_Eglare(p,igs) = 0.0;
2531     pict_get_Dglare(p,igs) = 0.0;
2532     pict_get_lum_min(p, igs) =
2533     99999999999999.999;
2534     i_split = igs;
2535     }
2536     split_pixel_from_gs(p, x, y, i_split, uniform_gs, u_r, u_g , u_b);
2537    
2538     }
2539     }
2540     }
2541    
2542     }
2543     change = 1;
2544     while (change == 1) {
2545     change = 0;
2546     for (x = 0; x < pict_get_xsize(p); x++)
2547     for (y = 0; y < pict_get_ysize(p); y++) {
2548     before_igs = pict_get_gsn(p, x, y);
2549     if (before_igs >= i_splitstart) {
2550     if (pict_get_hangle
2551     (p, x, y, p->view.vdir, p->view.vup,
2552     &ang)) {
2553     if (pict_is_validpixel(p, x, y)
2554     && before_igs > 0) {
2555     actual_igs =
2556     find_near_pgs(p, x, y,
2557     max_angle,
2558     before_igs, igs,
2559     i_splitstart);
2560     if (!(actual_igs == before_igs)) {
2561     change = 1;
2562     }
2563     if (before_igs > 0) {
2564     actual_igs =
2565     pict_get_gsn(p, x, y);
2566 greg 2.3 /* icol =
2567 greg 2.1 setglcolor(p, x, y,
2568 greg 2.3 actual_igs, uniform_gs, u_r, u_g , u_b);*/
2569 greg 2.1 }
2570    
2571     }
2572     }
2573     }
2574    
2575     }
2576     }
2577    
2578    
2579     }
2580     }
2581     }
2582    
2583 greg 2.3 /* calculation of direct vertical illuminance for CGI and for disability glare, coloring glare sources*/
2584 greg 2.1
2585 greg 2.6 if (calcfast == 0 || calcfast == 2) {
2586 greg 2.1 for (x = 0; x < pict_get_xsize(p); x++)
2587     for (y = 0; y < pict_get_ysize(p); y++) {
2588     if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2589     if (pict_is_validpixel(p, x, y)) {
2590     if (pict_get_gsn(p, x, y) > 0) {
2591 greg 2.3 actual_igs = pict_get_gsn(p, x, y);
2592     delta_E=DOT(p->view.vdir, pict_get_cached_dir(p, x, y))* pict_get_omega(p, x, y)* luminance(pict_get_color(p, x, y));
2593     pict_get_Eglare(p,actual_igs ) = pict_get_Eglare(p,actual_igs ) + delta_E;
2594     E_v_dir = E_v_dir + delta_E;
2595     setglcolor(p, x, y, actual_igs, uniform_gs, u_r, u_g , u_b);
2596 greg 2.1 }
2597     }
2598     }
2599     }
2600     lum_backg_cos = (E_v - E_v_dir) / 3.1415927;
2601 greg 2.3
2602 greg 2.1 }
2603 greg 2.3 /* calc of band luminance distribution if applied */
2604 greg 2.1 if (band_calc == 1) {
2605 greg 2.3 x_max = pict_get_xsize(p) - 1;
2606     y_max = pict_get_ysize(p) - 1;
2607     y_mid = (int)(y_max/2);
2608     for (x = 0; x <= x_max; x++)
2609     for (y = 0; y <= y_max; y++) {
2610     if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2611     if (pict_is_validpixel(p, x, y)) {
2612    
2613     r_actual = acos(DOT(pict_get_cached_dir(p, x, y_mid), pict_get_cached_dir(p, x, y))) ;
2614     act_lum = luminance(pict_get_color(p, x, y));
2615    
2616     if ((r_actual <= band_angle) || (y == y_mid) ) {
2617     lum_band[0]=luminance(pict_get_color(p, x, y));
2618     muc_rvar_add_sample(s_band, lum_band);
2619     act_lum = luminance(pict_get_color(p, x, y));
2620     lum_band_av += pict_get_omega(p, x, y) * act_lum;
2621     omega_band += pict_get_omega(p, x, y);
2622     if (band_color == 1) {
2623     pict_get_color(p, x, y)[RED] = 0.0;
2624     pict_get_color(p, x, y)[GRN] = act_lum / WHTEFFICACY / CIE_gf;
2625     pict_get_color(p, x, y)[BLU] = 0.0;
2626     }
2627     }
2628     }}}
2629     lum_band_av=lum_band_av/omega_band;
2630     muc_rvar_get_vx(s_band,lum_band_std);
2631     muc_rvar_get_percentile(s_band,lum_band_median,0.75);
2632     per_75_band=lum_band_median[0];
2633     muc_rvar_get_percentile(s_band,lum_band_median,0.95);
2634     per_95_band=lum_band_median[0];
2635     muc_rvar_get_median(s_band,lum_band_median);
2636     muc_rvar_get_bounding_box(s_band,bbox_band);
2637    
2638     printf ("band:band_omega,band_av_lum,band_median_lum,band_std_lum,band_perc_75,band_perc_95,band_lum_min,band_lum_max: %f %f %f %f %f %f %f %f\n",omega_band,lum_band_av,lum_band_median[0],sqrt(lum_band_std[0]),per_75_band,per_95_band,bbox_band[0],bbox_band[1] );
2639     /* av_lum = av_lum / omega_sum; */
2640     /* printf("average luminance of band %f \n",av_lum);*/
2641     /* printf("solid angle of band %f \n",omega_sum);*/
2642     }
2643 greg 2.1
2644     /*printf("total number of glare sources: %i\n",igs); */
2645     lum_sources = 0;
2646     omega_sources = 0;
2647 greg 2.3 i=0;
2648 greg 2.1 for (x = 0; x <= igs; x++) {
2649 greg 2.3 if (pict_get_npix(p, x) > 0) {
2650 greg 2.1 lum_sources += pict_get_av_lum(p, x) * pict_get_av_omega(p, x);
2651     omega_sources += pict_get_av_omega(p, x);
2652 greg 2.3 i=i+1;
2653     }}
2654    
2655     if (sang == omega_sources) {
2656     lum_backg =avlum;
2657     } else {
2658     lum_backg =(sang * avlum - lum_sources) / (sang - omega_sources);
2659 greg 2.1 }
2660 greg 2.3
2661    
2662     if (i == 0) {
2663     lum_sources =0.0;
2664     } else { lum_sources=lum_sources/omega_sources;
2665     }
2666    
2667    
2668    
2669     if (non_cos_lb == 0) {
2670     lum_backg = lum_backg_cos;
2671 greg 2.1 }
2672 greg 2.3
2673 greg 2.8 if (non_cos_lb == 2) {
2674     lum_backg = E_v / 3.1415927;
2675     }
2676    
2677    
2678 greg 2.3 /* file writing NOT here
2679     if (checkfile == 1) {
2680     pict_write(p, file_out);
2681     }
2682     */
2683    
2684 greg 2.1 /* print detailed output */
2685 greg 2.3
2686    
2687    
2688     /* masking */
2689    
2690     if ( masking == 1 ) {
2691    
2692    
2693     for (x = 0; x < pict_get_xsize(p); x++)
2694     for (y = 0; y < pict_get_ysize(p); y++) {
2695     if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2696     if (pict_is_validpixel(p, x, y)) {
2697     if (luminance(pict_get_color(pm, x, y))>0.1) {
2698     /* printf ("hallo %i %i %f \n",x,y,luminance(pict_get_color(pm, x, y)));*/
2699     i_mask=i_mask+1;
2700     lum_mask[0]=luminance(pict_get_color(p, x, y));
2701     /* printf ("%f \n",lum_mask[0]);*/
2702     muc_rvar_add_sample(s_mask, lum_mask);
2703     omega_mask += pict_get_omega(p, x, y);
2704     lum_mask_av += pict_get_omega(p, x, y)* luminance(pict_get_color(p, x, y));
2705     E_v_mask +=DOT(p->view.vdir, pict_get_cached_dir(p, x, y))*pict_get_omega(p, x, y)* luminance(pict_get_color(p, x, y));
2706    
2707     pict_get_color(pm, x, y)[RED] = luminance(pict_get_color(p, x, y))/179.0;
2708     pict_get_color(pm, x, y)[GRN] = luminance(pict_get_color(p, x, y))/179.0;
2709     pict_get_color(pm, x, y)[BLU] = luminance(pict_get_color(p, x, y))/179.0;
2710    
2711     } else {
2712     pict_get_color(p, x, y)[RED] = 0.0 ;
2713     pict_get_color(p, x, y)[GRN] = 0.0 ;
2714     pict_get_color(p, x, y)[BLU] = 0.0 ;
2715     }
2716     }
2717     }
2718     }
2719     /* Average luminance in masking area (weighted by solid angle) */
2720     lum_mask_av=lum_mask_av/omega_mask;
2721     muc_rvar_get_vx(s_mask,lum_mask_std);
2722     muc_rvar_get_percentile(s_mask,lum_mask_median,0.75);
2723     per_75_mask=lum_mask_median[0];
2724     muc_rvar_get_percentile(s_mask,lum_mask_median,0.95);
2725     per_95_mask=lum_mask_median[0];
2726     muc_rvar_get_median(s_mask,lum_mask_median);
2727     muc_rvar_get_bounding_box(s_mask,bbox);
2728     /* PSGV only why masking of window is applied! */
2729 greg 2.9
2730    
2731     if (task_lum == 0 || lum_task == 0.0 ) {
2732     fprintf(stderr, " warning: Task area not set or task luminance=0 ! pgsv cannot be calculated (set to -99)!!\n");
2733     pgsv = -99;
2734     } else {
2735     pgsv = get_pgsv(E_v, E_v_mask, omega_mask, lum_mask_av,lum_task,avlum);
2736     }
2737    
2738     pgsv_con = get_pgsv_con(E_v, E_v_mask, omega_mask, lum_mask_av,avlum);
2739 greg 2.3 pgsv_sat =get_pgsv_sat(E_v);
2740 greg 2.5
2741     if (detail_out == 1) {
2742    
2743 greg 2.9 printf ("masking:no_pixels,omega,av_lum,median_lum,std_lum,perc_75,perc_95,lum_min,lum_max,pgsv_con,pgsv_sat,pgsv,Ev_mask: %i %f %f %f %f %f %f %f %f %f %f %f %f\n",i_mask,omega_mask,lum_mask_av,lum_mask_median[0],sqrt(lum_mask_std[0]),per_75_mask,per_95_mask,bbox[0],bbox[1],pgsv_con,pgsv_sat,pgsv,E_v_mask );
2744 greg 2.3
2745 greg 2.5 }
2746 greg 2.3
2747     }
2748    
2749     /* zones */
2750    
2751     if ( zones > 0 ) {
2752    
2753     for (x = 0; x < pict_get_xsize(p); x++)
2754     for (y = 0; y < pict_get_ysize(p); y++) {
2755     if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2756     if (pict_is_validpixel(p, x, y)) {
2757    
2758    
2759     r_actual =acos(DOT(pict_get_cached_dir(p, x, y), pict_get_cached_dir(p, x_zone, y_zone))) * 2;
2760     lum_actual = luminance(pict_get_color(p, x, y));
2761     act_gsn=pict_get_gsn(p, x, y);
2762     /* printf("1act_gsn,pict_get_z1_gsn,pict_get_z2_gsn %i %f %f \n",act_gsn,pict_get_z1_gsn(p,act_gsn),pict_get_z2_gsn(p,act_gsn));*/
2763    
2764     /*zone1 */
2765     if (r_actual <= angle_z1) {
2766     i_z1=i_z1+1;
2767     lum_z1[0]=lum_actual;
2768     muc_rvar_add_sample(s_z1, lum_z1);
2769     omega_z1 += pict_get_omega(p, x, y);
2770     lum_z1_av += pict_get_omega(p, x, y)* lum_actual;
2771 greg 2.11 Ez1 += DOT(p->view.vdir, pict_get_cached_dir(p, x, y))* pict_get_omega(p, x, y)* lum_actual;
2772    
2773 greg 2.3 setglcolor(p,x,y,1,1 , 0.66, 0.01 ,0.33);
2774     /*check if separation gsn already exist */
2775    
2776     if (act_gsn > 0){
2777     if (pict_get_z1_gsn(p,act_gsn) == 0) {
2778     pict_new_gli(p);
2779     igs = igs + 1;
2780     pict_get_z1_gsn(p,act_gsn) = igs*1.000;
2781     pict_get_z1_gsn(p,igs) = -1.0;
2782     pict_get_z2_gsn(p,igs) = -1.0;
2783     splitgs=(int)(pict_get_z1_gsn(p,act_gsn));
2784     /* printf ("Glare source %i gets glare source %i in zone 1 : %i %f %f \n",act_gsn,igs,splitgs,pict_get_z1_gsn(p,act_gsn),pict_get_z1_gsn(p,igs)); */
2785     }
2786     splitgs=(int)(pict_get_z1_gsn(p,act_gsn));
2787     /* printf("splitgs%i \n",splitgs); */
2788     split_pixel_from_gs(p, x, y, splitgs, uniform_gs, u_r, u_g , u_b);
2789 greg 2.11 /* move direct illuminance contribution into zone -value */
2790     delta_E=DOT(p->view.vdir, pict_get_cached_dir(p, x, y))* pict_get_omega(p, x, y)* luminance(pict_get_color(p, x, y));
2791     pict_get_Eglare(p,act_gsn ) = pict_get_Eglare(p,act_gsn ) - delta_E;
2792     pict_get_Eglare(p,igs ) = pict_get_Eglare(p,igs ) + delta_E;
2793    
2794    
2795 greg 2.3 }
2796     }
2797     /*zone2 */
2798    
2799     if (r_actual > angle_z1 && r_actual<= angle_z2 ) {
2800    
2801     i_z2=i_z2+1;
2802     lum_z2[0]=lum_actual;
2803     muc_rvar_add_sample(s_z2, lum_z2);
2804     omega_z2 += pict_get_omega(p, x, y);
2805     lum_z2_av += pict_get_omega(p, x, y)* lum_actual;
2806 greg 2.11 Ez2 += DOT(p->view.vdir, pict_get_cached_dir(p, x, y))* pict_get_omega(p, x, y)* lum_actual;
2807 greg 2.3 setglcolor(p,x,y,1,1 , 0.65, 0.33 ,0.02);
2808     /* printf("zone 2 x y act_gsn pict_get_z1_gsn(p,act_gsn) pict_get_z2_gsn(p,act_gsn): %i %i %f 1:%f 2:%f \n",x,y,act_gsn,pict_get_z1_gsn(p,act_gsn),pict_get_z2_gsn(p,act_gsn));
2809     */ if (act_gsn > 0){
2810     if (pict_get_z2_gsn(p,act_gsn) == 0) {
2811     pict_new_gli(p);
2812     igs = igs + 1;
2813     pict_get_z2_gsn(p,act_gsn) = igs*1.000;
2814     pict_get_z1_gsn(p,igs) = -2.0;
2815     pict_get_z2_gsn(p,igs) = -2.0;
2816     /* printf ("Glare source %i gets glare source %i in zone 2 \n",act_gsn,igs ); */
2817     }
2818     splitgs=(int)(pict_get_z2_gsn(p,act_gsn));
2819     /* printf("splitgs %i \n",splitgs);*/
2820     split_pixel_from_gs(p, x, y, splitgs, uniform_gs, u_r, u_g , u_b);
2821 greg 2.11 /* move direct illuminance contribution into zone -value */
2822     delta_E=DOT(p->view.vdir, pict_get_cached_dir(p, x, y))* pict_get_omega(p, x, y)* luminance(pict_get_color(p, x, y));
2823     pict_get_Eglare(p,act_gsn ) = pict_get_Eglare(p,act_gsn ) - delta_E;
2824     pict_get_Eglare(p,igs ) = pict_get_Eglare(p,igs ) + delta_E;
2825    
2826 greg 2.3 }
2827     }
2828    
2829     }
2830     } }
2831     /* Average luminance in zones (weighted by solid angle), calculate percentiles, median min and max in zones */
2832     if (zones == 2 ) {
2833     lum_z2_av=lum_z2_av/omega_z2;
2834     muc_rvar_get_vx(s_z2,lum_z2_std);
2835     muc_rvar_get_percentile(s_z2,lum_z2_median,0.75);
2836     per_75_z2=lum_z2_median[0];
2837     muc_rvar_get_percentile(s_z2,lum_z2_median,0.95);
2838     per_95_z2=lum_z2_median[0];
2839     muc_rvar_get_median(s_z2,lum_z2_median);
2840     muc_rvar_get_bounding_box(s_z2,bbox_z2);
2841     }
2842     lum_z1_av=lum_z1_av/omega_z1;
2843     muc_rvar_get_vx(s_z1,lum_z1_std);
2844     muc_rvar_get_percentile(s_z1,lum_z1_median,0.75);
2845     per_75_z1=lum_z1_median[0];
2846     muc_rvar_get_percentile(s_z1,lum_z1_median,0.95);
2847     per_95_z1=lum_z1_median[0];
2848     muc_rvar_get_median(s_z1,lum_z1_median);
2849     muc_rvar_get_bounding_box(s_z1,bbox_z1);
2850 greg 2.5 if (detail_out == 1) {
2851    
2852 greg 2.11 printf ("zoning:z1_omega,z1_av_lum,z1_median_lum,z1_std_lum,z1_perc_75,z1_perc_95,z1_lum_min,z1_lum_max,Ez1: %f %f %f %f %f %f %f %f %f\n",omega_z1,lum_z1_av,lum_z1_median[0],sqrt(lum_z1_std[0]),per_75_z1,per_95_z1,bbox_z1[0],bbox_z1[1],Ez1 );
2853 greg 2.3
2854 greg 2.4 if (zones == 2 ) {
2855 greg 2.3
2856 greg 2.11 printf ("zoning:z2_omega,z2_av_lum,z2_median_lum,z2_std_lum,z2_perc_75,z2_perc_95,z2_lum_min,z2_lum_max,Ez1: %f %f %f %f %f %f %f %f %f\n",omega_z2,lum_z2_av,lum_z2_median[0],sqrt(lum_z2_std[0]),per_75_z2,per_95_z2,bbox_z2[0],bbox_z2[1],Ez2 );
2857 greg 2.5 } }
2858 greg 2.3
2859     }
2860    
2861 greg 2.1 i = 0;
2862     for (x = 0; x <= igs; x++) {
2863     /* resorting glare source numbers */
2864     if (pict_get_npix(p, x) > 0) {
2865     i = i + 1;
2866     }
2867     }
2868 greg 2.3 no_glaresources=i;
2869 greg 2.11 /*printf("%i",no_glaresources );*/
2870 greg 2.3 /* glare sources */
2871 greg 2.11 if (detail_out == 1 && output != 3) {
2872 greg 2.5
2873 greg 2.1 printf
2874 greg 2.3 ("%i No pixels x-pos y-pos L_s Omega_s Posindx L_b L_t E_vert Edir Max_Lum Sigma xdir ydir zdir Eglare_cie Lveil_cie teta glare_zone\n",
2875 greg 2.1 i);
2876     if (i == 0) {
2877 greg 2.3 printf("%i %f %f %f %f %.10f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n", i, 0.0, 0.0,
2878     0.0, 0.0, 0.0, 0.0, lum_backg, lum_task, E_v, E_v_dir,abs_max,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
2879 greg 2.1
2880     } else {
2881     i = 0;
2882     for (x = 0; x <= igs; x++) {
2883     if (pict_get_npix(p, x) > 0) {
2884     i = i + 1;
2885     pict_get_sigma(p, pict_get_av_posx(p, x),
2886     pict_get_av_posy(p, x), p->view.vdir,
2887     p->view.vup, &sigma);
2888    
2889     x2=pict_get_av_posx(p, x);
2890     y2=pict_get_av_posy(p, x);
2891     teta = 180.0 / 3.1415927 * acos(DOT(p->view.vdir, pict_get_cached_dir(p, x2, y2)));
2892     Lveil_cie = 10*pict_get_Eglare(p,x)/(teta*teta+0.0000000000000001);
2893    
2894     if (apply_disability == 1 && Lveil_cie <=disability_thresh) {
2895     Lveil_cie =0 ;
2896     }
2897     Lveil_cie_sum = Lveil_cie_sum + Lveil_cie;
2898 greg 2.3 if (pict_get_z1_gsn(p,x)<0) {
2899     act_gsn=(int)(-pict_get_z1_gsn(p,x));
2900     }else{
2901     act_gsn=0;
2902     }
2903     printf("%i %f %f %f %f %.10f %f %f %f %f %f %f %f %f %f %f %f %f %f %i \n",
2904 greg 2.1 i, pict_get_npix(p, x), pict_get_av_posx(p, x),
2905     pict_get_ysize(p) - pict_get_av_posy(p, x),
2906     pict_get_av_lum(p, x), pict_get_av_omega(p, x),
2907     get_posindex(p, pict_get_av_posx(p, x),
2908     pict_get_av_posy(p, x),
2909     posindex_2), lum_backg, lum_task,
2910     E_v, E_v_dir, abs_max, sigma * 180 / 3.1415927
2911 greg 2.3 ,pict_get_cached_dir(p, x2,y2)[0],pict_get_cached_dir(p, x2,y2)[1],pict_get_cached_dir(p, x2,y2)[2],pict_get_Eglare(p,x),Lveil_cie,teta,act_gsn );
2912 greg 2.1 }
2913     }
2914     }
2915     }
2916    
2917 greg 2.11 if ( output != 3) {
2918 greg 2.1
2919     /* calculation of indicees */
2920    
2921     /* check vertical illuminance range */
2922     E_v2 = E_v;
2923    
2924     if (E_v2 < 100) {
2925     fprintf(stderr,
2926     "Notice: Vertical illuminance is below 100 lux !!\n");
2927     }
2928     dgp =
2929     get_dgp(p, E_v2, igs, a1, a2, a3, a4, a5, c1, c2, c3, posindex_2);
2930     /* low light correction */
2931 greg 2.11 if (lowlight ==1) {
2932 greg 2.1 if (E_v < 1000) {
2933     low_light_corr=1.0*exp(0.024*E_v-4)/(1+exp(0.024*E_v-4));} else {low_light_corr=1.0 ;}
2934     dgp =low_light_corr*dgp;
2935 greg 2.11 }
2936 greg 2.1 /* age correction */
2937    
2938     if (age_corr == 1) {
2939     age_corr_factor=1.0/(1.1-0.5*age/100.0);
2940     }
2941     dgp =age_corr_factor*dgp;
2942    
2943    
2944     if (ext_vill == 1) {
2945     if (E_vl_ext < 100) {
2946     fprintf(stderr,
2947     "Notice: Vertical illuminance is below 100 lux !!\n");
2948     }
2949     }
2950    
2951     if (calcfast == 0) {
2952 greg 2.3 lum_a= E_v2/3.1415927;
2953 greg 2.1 dgi = get_dgi(p, lum_backg, igs, posindex_2);
2954     ugr = get_ugr(p, lum_backg, igs, posindex_2);
2955 greg 2.3 ugp = get_ugp (p,lum_backg, igs, posindex_2);
2956     ugr_exp = get_ugr_exp (p,lum_backg_cos,lum_a, igs, posindex_2);
2957     dgi_mod = get_dgi_mod(p, lum_a, igs, posindex_2);
2958 greg 2.1 cgi = get_cgi(p, E_v, E_v_dir, igs, posindex_2);
2959 greg 2.3 dgr = get_dgr(p, avlum, igs, posindex_2);
2960     vcp = get_vcp(dgr);
2961 greg 2.1 Lveil = get_disability(p, avlum, igs);
2962 greg 2.3 if (no_glaresources == 0) {
2963     dgi = 0.0;
2964     ugr = 0.0;
2965     ugp = 0.0;
2966     ugr_exp = 0.0;
2967     dgi_mod = 0.0;
2968     cgi = 0.0;
2969     dgr = 0.0;
2970     vcp = 100.0;
2971     }
2972 greg 2.1 }
2973     /* check dgp range */
2974     if (dgp <= 0.2) {
2975     fprintf(stderr,
2976     "Notice: Low brightness scene. dgp below 0.2! dgp might underestimate glare sources\n");
2977     }
2978     if (E_v < 380) {
2979     fprintf(stderr,
2980     "Notice: Low brightness scene. Vertical illuminance less than 380 lux! dgp might underestimate glare sources\n");
2981     }
2982    
2983    
2984    
2985     if (output == 0) {
2986     if (detail_out == 1) {
2987     if (ext_vill == 1) {
2988     dgp_ext =
2989     get_dgp(p, E_vl_ext, igs, a1, a2, a3, a4, a5, c1, c2, c3,
2990     posindex_2);
2991     dgp = dgp_ext;
2992     if (E_vl_ext < 1000) {
2993     low_light_corr=1.0*exp(0.024*E_vl_ext-4)/(1+exp(0.024*E_vl_ext-4));} else {low_light_corr=1.0 ;}
2994     dgp =low_light_corr*dgp;
2995     dgp =age_corr_factor*dgp;
2996     }
2997 greg 2.3 muc_rvar_get_median(s_noposweight,lum_nopos_median);
2998     muc_rvar_get_median(s_posweight,lum_pos_median);
2999     muc_rvar_get_median(s_posweight2,lum_pos2_median);
3000    
3001    
3002 greg 2.1
3003 greg 2.3
3004 greg 2.1 printf
3005 greg 2.3 ("dgp,av_lum,E_v,lum_backg,E_v_dir,dgi,ugr,vcp,cgi,lum_sources,omega_sources,Lveil,Lveil_cie,dgr,ugp,ugr_exp,dgi_mod,av_lum_pos,av_lum_pos2,med_lum,med_lum_pos,med_lum_pos2: %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n",
3006 greg 2.1 dgp, avlum, E_v, lum_backg, E_v_dir, dgi, ugr, vcp, cgi,
3007 greg 2.3 lum_sources, omega_sources, Lveil,Lveil_cie_sum,dgr,ugp,ugr_exp,dgi_mod,lum_pos_mean,lum_pos2_mean/sang,lum_nopos_median[0],lum_pos_median[0],lum_pos2_median[0]);
3008 greg 2.1 } else {
3009     if (detail_out2 == 1) {
3010    
3011     printf
3012     ("dgp,dgi,ugr,vcp,cgi,dgp_ext,Ev_calc,abs_max,Lveil: %f %f %f %f %f %f %f %f %f \n",
3013     dgp, dgi, ugr, vcp, cgi, dgp_ext, E_v, abs_max,
3014     Lveil);
3015    
3016     } else {
3017     if (ext_vill == 1) {
3018     dgp_ext = get_dgp(p, E_vl_ext, igs, a1, a2, a3, a4, a5, c1, c2, c3,posindex_2);
3019    
3020     if (E_vl_ext < 1000) {
3021     low_light_corr=1.0*exp(0.024*E_vl_ext-4)/(1+exp(0.024*E_vl_ext-4));} else {low_light_corr=1.0 ;}
3022     dgp =low_light_corr*dgp_ext;
3023     dgp =age_corr_factor*dgp;
3024     }
3025     printf("dgp,dgi,ugr,vcp,cgi,Lveil: %f %f %f %f %f %f \n",
3026     dgp, dgi, ugr, vcp, cgi, Lveil);
3027    
3028     }
3029     }
3030     } else {
3031     dgp_ext =
3032     get_dgp(p, E_vl_ext, igs, a1, a2, a3, a4, a5, c1, c2, c3,
3033     posindex_2);
3034     dgp = dgp_ext;
3035     if (E_vl_ext < 1000) {
3036     low_light_corr=1.0*exp(0.024*E_vl_ext-4)/(1+exp(0.024*E_vl_ext-4)); } else {low_light_corr=1.0 ;}
3037     dgp =low_light_corr*dgp;
3038 greg 2.6
3039     if (calcfast == 2) {
3040    
3041     lum_backg_cos=(E_vl_ext-dir_ill)/3.1415927;
3042     ugr = get_ugr(p, lum_backg_cos, igs, posindex_2);
3043     printf("%f %f \n", dgp,ugr);
3044     }else{
3045     printf("%f\n", dgp);
3046     }
3047 greg 2.1 }
3048 greg 2.11 }
3049    
3050     }else{
3051     /* only multiimagemode */
3052    
3053    
3054     for (j = 0; j < num_images; j++) {
3055    
3056    
3057     /* loop over temporal images */
3058    
3059     pict_read(pcoeff,temp_image_name[j] );
3060    
3061     /*printf ("num_img:%i x-size:%i xpos:%i y-size: %i ypos %i bigimg-xsize %i %i ",num_images,pict_get_xsize(pcoeff),x_temp_img[j],pict_get_ysize(pcoeff),y_temp_img[j],pict_get_xsize(p),pict_get_ysize(p));
3062     */
3063    
3064     /* copy luminance value into big image and remove glare sources*/
3065     for (x = 0; x < pict_get_xsize(pcoeff); x++) {
3066     for (y = 0; y < pict_get_ysize(pcoeff); y++) {
3067     xmap=x_temp_img[j]+x-1;
3068     ymap=y_temp_img[j]+y-1;
3069     if (xmap <0) { xmap=0;}
3070     if (ymap <0) { ymap=0;}
3071    
3072     pict_get_color(p, xmap, ymap)[RED] = pict_get_color(pcoeff, x, y)[RED];
3073     pict_get_color(p, xmap, ymap)[GRN] = pict_get_color(pcoeff, x, y)[GRN];
3074     pict_get_color(p, xmap, ymap)[BLU] = pict_get_color(pcoeff, x, y)[BLU];
3075     pict_get_gsn(p, xmap, ymap) = 0;
3076     pict_get_pgs(p, xmap, ymap) = 0;
3077     }}
3078    
3079     actual_igs =0;
3080    
3081     /* first glare source scan: find primary glare sources */
3082     for (x = 0; x < pict_get_xsize(pcoeff); x++) {
3083     lastpixelwas_gs=0;
3084     /* lastpixelwas_peak=0; */
3085     for (y = 0; y < pict_get_ysize(pcoeff); y++) {
3086     xmap=x_temp_img[j]+x;
3087     ymap=y_temp_img[j]+y;
3088     if (pict_get_hangle(p, xmap, ymap, p->view.vdir, p->view.vup, &ang)) {
3089     if (pict_is_validpixel(p, xmap, ymap)) {
3090     act_lum = luminance(pict_get_color(p, xmap, ymap));
3091     if (act_lum > lum_source) {
3092     if (act_lum >lum_total_max) {
3093     lum_total_max=act_lum;
3094     }
3095    
3096     if (lastpixelwas_gs==0 || search_pix <= 1.0 ) {
3097     actual_igs = find_near_pgs(p, xmap, ymap, max_angle, 0, igs, 1);
3098     }
3099     if (actual_igs == 0) {
3100     igs = igs + 1;
3101     pict_new_gli(p);
3102     pict_get_Eglare(p,igs) = 0.0;
3103     /* not necessary here pict_get_lum_min(p, igs) = HUGE_VAL;
3104     pict_get_Eglare(p,igs) = 0.0;
3105     pict_get_Dglare(p,igs) = 0.0;
3106     pict_get_z1_gsn(p,igs) = 0;
3107     pict_get_z2_gsn(p,igs) = 0; */
3108     actual_igs = igs;
3109    
3110     }
3111     pict_get_gsn(p, xmap, ymap) = actual_igs;
3112     pict_get_pgs(p, xmap, ymap) = 1;
3113     add_pixel_to_gs(p, xmap, ymap, actual_igs);
3114     lastpixelwas_gs=actual_igs;
3115    
3116    
3117    
3118     delta_E=DOT(p->view.vdir, pict_get_cached_dir(p, xmap, ymap))* pict_get_omega(p, xmap, ymap)* luminance(pict_get_color(p, xmap, ymap));
3119     pict_get_Eglare(p,actual_igs ) = pict_get_Eglare(p,actual_igs ) + delta_E;
3120    
3121    
3122    
3123    
3124     } else {
3125     pict_get_pgs(p, xmap, ymap) = 0;
3126     lastpixelwas_gs=0;
3127     }
3128     }
3129     }
3130     }
3131     }
3132    
3133    
3134     /* here should be peak extraction */
3135     i_max=igs;
3136     r_split = max_angle / 2.0;
3137     for (i = 0; i <= i_max; i++) {
3138    
3139     if (pict_get_npix(p, i) > 0) {
3140     l_max = pict_get_lum_max(p, i);
3141     i_splitstart = igs + 1;
3142     if (l_max >= limit) {
3143     for (x = 0; x < pict_get_xsize(pcoeff); x++)
3144     for (y = 0; y < pict_get_ysize(pcoeff); y++) {
3145     xmap=x_temp_img[j]+x;
3146     ymap=y_temp_img[j]+y;
3147    
3148    
3149     if (pict_get_hangle
3150     (p, xmap, ymap, p->view.vdir, p->view.vup, &ang))
3151     {
3152     if (pict_is_validpixel(p, xmap, ymap)
3153     && luminance(pict_get_color(p, xmap, ymap))
3154     >= limit
3155     && pict_get_gsn(p, xmap, ymap) == i) {
3156     if (i_splitstart == (igs + 1)) {
3157     igs = igs + 1;
3158     pict_new_gli(p);
3159     pict_get_z1_gsn(p,igs) = 0;
3160     pict_get_z2_gsn(p,igs) = 0;
3161    
3162     pict_get_Eglare(p,igs) = 0.0;
3163     pict_get_Dglare(p,igs) = 0.0;
3164     pict_get_lum_min(p, igs) =
3165     99999999999999.999;
3166     i_split = igs;
3167     } else {
3168     i_split =
3169     find_split(p, xmap, ymap, r_split,
3170     i_splitstart, igs);
3171     }
3172     if (i_split == 0) {
3173     igs = igs + 1;
3174     pict_new_gli(p);
3175     pict_get_z1_gsn(p,igs) = 0;
3176     pict_get_z2_gsn(p,igs) = 0;
3177    
3178     pict_get_Eglare(p,igs) = 0.0;
3179     pict_get_Dglare(p,igs) = 0.0;
3180     pict_get_lum_min(p, igs) =
3181     99999999999999.999;
3182     i_split = igs;
3183     }
3184     split_pixel_from_gs(p, xmap, ymap, i_split, uniform_gs, u_r, u_g , u_b);
3185    
3186     }
3187     }
3188     }
3189    
3190     }
3191     change = 1;
3192     while (change == 1) {
3193     change = 0;
3194     for (x = 0; x < pict_get_xsize(pcoeff); x++)
3195     for (y = 0; y < pict_get_ysize(pcoeff); y++) {
3196     xmap=x_temp_img[j]+x;
3197     ymap=y_temp_img[j]+y;
3198     before_igs = pict_get_gsn(p, xmap, ymap);
3199     if (before_igs >= i_splitstart) {
3200     if (pict_get_hangle
3201     (p, xmap, ymap, p->view.vdir, p->view.vup,
3202     &ang)) {
3203     if (pict_is_validpixel(p, xmap, ymap)
3204     && before_igs > 0) {
3205     actual_igs =
3206     find_near_pgs(p, xmap, ymap,
3207     max_angle,
3208     before_igs, igs,
3209     i_splitstart);
3210     if (!(actual_igs == before_igs)) {
3211     change = 1;
3212     }
3213     if (before_igs > 0) {
3214     actual_igs =
3215     pict_get_gsn(p, xmap, ymap);
3216     /* icol =
3217     setglcolor(p, x, y,
3218     actual_igs, uniform_gs, u_r, u_g , u_b);*/
3219     }
3220    
3221     }
3222     }
3223     }
3224    
3225     }
3226     }
3227    
3228    
3229     }
3230     }
3231    
3232     /* end peak extraction */
3233    
3234    
3235     /* calculation of direct vertical illuminance for th multi-image-mode */
3236    
3237    
3238     for (x = 0; x < pict_get_xsize(pcoeff); x++)
3239     for (y = 0; y < pict_get_ysize(pcoeff); y++) {
3240     xmap=x_temp_img[j]+x;
3241     ymap=y_temp_img[j]+y;
3242     if (pict_get_hangle(p, xmap, ymap, p->view.vdir, p->view.vup, &ang)) {
3243     if (pict_is_validpixel(p, xmap, ymap)) {
3244     if (pict_get_gsn(p, xmap, ymap) > 0) {
3245     actual_igs = pict_get_gsn(p, xmap, ymap);
3246     delta_E=DOT(p->view.vdir, pict_get_cached_dir(p, xmap, ymap))* pict_get_omega(p, xmap, ymap)* luminance(pict_get_color(p, xmap, ymap));
3247     pict_get_Eglare(p,actual_igs ) = pict_get_Eglare(p,actual_igs ) + delta_E;
3248     }
3249     }
3250     }
3251     }
3252    
3253    
3254    
3255    
3256    
3257    
3258    
3259    
3260     i = 0;
3261     for (x = 0; x <= igs; x++) {
3262     if (pict_get_npix(p, x) > 0) {
3263     i = i + 1;
3264     }}
3265     no_glaresources=i;
3266    
3267     /*
3268    
3269     sprintf(file_out, "%s%i%s","ray2/img_",j,".hdr");
3270     pict_write(p, file_out);
3271     */
3272     printf("%i ",no_glaresources);
3273     i = 0;
3274     for (x = 0; x <= igs; x++) {
3275     if (pict_get_npix(p, x) > 0) {
3276     i = i + 1;
3277     pict_get_sigma(p, pict_get_av_posx(p, x), pict_get_av_posy(p, x), p->view.vdir, p->view.vup, &sigma);
3278    
3279     x2=pict_get_av_posx(p, x);
3280     y2=pict_get_av_posy(p, x);
3281     printf("%f %.10f %f %f %f %f %f ", pict_get_av_lum(p, x), pict_get_av_omega(p, x), get_posindex(p, pict_get_av_posx(p, x), pict_get_av_posy(p, x),
3282     posindex_2),pict_get_cached_dir(p, x2,y2)[0],pict_get_cached_dir(p, x2,y2)[1],pict_get_cached_dir(p, x2,y2)[2],pict_get_Eglare(p,x) );
3283     }
3284     pict_get_npix(p, x)=0;
3285     pict_get_av_lum(p, x)=0;
3286     pict_get_av_posy(p, x)=0;
3287     pict_get_av_posx(p, x)=0;
3288     pict_get_av_omega(p, x)=0;
3289     }
3290     printf("\n");
3291    
3292    
3293     /* empty big image and remove glare sources*/
3294     for (x = 0; x < pict_get_xsize(pcoeff); x++) {
3295     for (y = 0; y < pict_get_ysize(pcoeff); y++) {
3296     xmap=x_temp_img[j]+x;
3297     ymap=y_temp_img[j]+y;
3298     pict_get_color(p, xmap, ymap)[RED] = 0;
3299     pict_get_color(p, xmap, ymap)[GRN] = 0;
3300     pict_get_color(p, xmap, ymap)[BLU] = 0;
3301     pict_get_gsn(p, xmap, ymap) = 0;
3302     pict_get_pgs(p, xmap, ymap) = 0;
3303     }}
3304     igs=0;
3305    
3306    
3307    
3308    
3309    
3310     }
3311    
3312     }
3313 greg 2.1
3314 greg 2.11 /* end multi-image-mode */
3315 greg 2.1
3316     /*printf("lowlight=%f\n", low_light_corr); */
3317    
3318    
3319     /* printf("hallo \n");
3320    
3321    
3322     apply_disability = 1;
3323     disability_thresh = atof(argv[++i]);
3324     coloring of disability glare sources red, remove all other colors
3325    
3326    
3327    
3328     this function was removed because of bugs....
3329     has to be re-written from scratch....
3330    
3331    
3332     */
3333    
3334    
3335    
3336    
3337    
3338    
3339    
3340    
3341     /*output */
3342     if (checkfile == 1) {
3343 greg 2.3
3344    
3345 greg 2.1 pict_write(p, file_out);
3346     }
3347    
3348    
3349 greg 2.8
3350 greg 2.1 return EXIT_SUCCESS;
3351 greg 2.8 exit(0);
3352 greg 2.1
3353     userr:
3354     fprintf(stderr,
3355     "Usage: %s [-s][-d][-c picture][-t xpos ypos angle] [-T xpos ypos angle] [-b fact] [-r angle] [-y] [-Y lum] [-i Ev] [-I Ev ymax ymin] [-v] picfile\n",
3356     progname);
3357 greg 2.8 exit(1);
3358 greg 2.1 }
3359    
3360    
3361    
3362     #endif