ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/evalglare.c
Revision: 2.5
Committed: Tue Aug 2 16:35:01 2016 UTC (7 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +13 -6 lines
Log Message:
Bug fix from Jan for output error spotted by David G-M

File Contents

# User Rev Content
1 greg 2.2 #ifndef lint
2     static const char RCSid[] = "$Id$";
3     #endif
4 greg 2.5 /* EVALGLARE V1.31
5 greg 2.3 * Evalglare Software License, Version 2.0
6 greg 2.1 *
7 greg 2.3 * Copyright (c) 1995 - 2016 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.1 #define EVALGLARE
316     #define PROGNAME "evalglare"
317 greg 2.5 #define VERSION "1.31 release 02.08.2016 by EPFL, J.Wienold"
318 greg 2.1 #define RELEASENAME PROGNAME " " VERSION
319    
320 greg 2.3
321     #include "pictool.h"
322 greg 2.1 #include "rtio.h"
323     #include <math.h>
324     #include <string.h>
325 greg 2.3 #include "platform.h"
326     #include "muc_randvar.h"
327    
328 greg 2.1 char *progname;
329    
330     /* subroutine to add a pixel to a glare source */
331     void add_pixel_to_gs(pict * p, int x, int y, int gsn)
332     {
333     double old_av_posx, old_av_posy, old_av_lum, old_omega, act_omega,
334     new_omega, act_lum;
335    
336    
337     pict_get_npix(p, gsn) = pict_get_npix(p, gsn) + 1;
338     old_av_posx = pict_get_av_posx(p, gsn);
339     old_av_posy = pict_get_av_posy(p, gsn);
340     old_av_lum = pict_get_av_lum(p, gsn);
341     old_omega = pict_get_av_omega(p, gsn);
342    
343     act_omega = pict_get_omega(p, x, y);
344     act_lum = luminance(pict_get_color(p, x, y));
345     new_omega = old_omega + act_omega;
346     pict_get_av_posx(p, gsn) =
347     (old_av_posx * old_omega + x * act_omega) / new_omega;
348     pict_get_av_posy(p, gsn) =
349     (old_av_posy * old_omega + y * act_omega) / new_omega;
350     if (isnan((pict_get_av_posx(p, gsn))))
351     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);
352    
353     pict_get_av_lum(p, gsn) =
354     (old_av_lum * old_omega + act_lum * act_omega) / new_omega;
355     pict_get_av_omega(p, gsn) = new_omega;
356     pict_get_gsn(p, x, y) = gsn;
357     if (act_lum < pict_get_lum_min(p, gsn)) {
358     pict_get_lum_min(p, gsn) = act_lum;
359     }
360     if (act_lum > pict_get_lum_max(p, gsn)) {
361     pict_get_lum_max(p, gsn) = act_lum;
362     }
363    
364     /* 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)); */
365    
366     }
367    
368     /* subroutine for peak extraction */
369     int
370     find_split(pict * p, int x, int y, double r, int i_split_start,
371     int i_split_end)
372     {
373     int i_find_split, x_min, x_max, y_min, y_max, ix, iy, iix, iiy, dx, dy,
374     out_r;
375     double r_actual;
376    
377     i_find_split = 0;
378    
379     x_min = 0;
380     y_min = 0;
381     x_max = pict_get_ysize(p) - 1;
382    
383     y_max = pict_get_ysize(p) - 1;
384    
385     for (iiy = 1; iiy <= 2; iiy++) {
386     dy = iiy * 2 - 3;
387     if (dy == -1) {
388     iy = y;
389     } else {
390     iy = y + 1;
391     }
392     while (iy <= y_max && iy >= y_min) {
393     out_r = 0;
394     for (iix = 1; iix <= 2; iix++) {
395     dx = iix * 2 - 3;
396     if (dx == -1) {
397     ix = x;
398     } else {
399     ix = x + 1;
400     }
401     while (ix <= x_max && ix >= x_min && iy >= y_min) {
402    
403     r_actual =
404     acos(DOT(pict_get_cached_dir(p, x, y),
405     pict_get_cached_dir(p, ix, iy))) * 2;
406     if (r_actual <= r) {
407     out_r = 1;
408     if (pict_get_gsn(p, ix, iy) >= i_split_start
409     && pict_get_gsn(p, ix, iy) <= i_split_end) {
410     i_find_split = pict_get_gsn(p, ix, iy);
411     }
412     } else {
413     ix = -99;
414     }
415     ix = ix + dx;
416     }
417     }
418     if (out_r == 0) {
419     iy = -99;
420     }
421     iy = iy + dy;
422    
423     }
424     }
425    
426    
427    
428     return i_find_split;
429     }
430    
431     /*
432     static int icomp(int* a,int* b)
433     {
434     if (*a < *b)
435     return -1;
436     if (*a > *b)
437     return 1;
438     return 0;
439     }
440    
441     */
442    
443     /* subroutine to find nearby glare source pixels */
444    
445     int
446     find_near_pgs(pict * p, int x, int y, float r, int act_gsn, int max_gsn,
447     int min_gsn)
448     {
449     int dx, dy, i_near_gs, xx, yy, x_min, x_max, y_min, y_max, ix, iy, iix,
450     iiy, old_gsn, new_gsn, find_gsn, change, stop_y_search,
451     stop_x_search;
452     double r_actual;
453     int ixm[3];
454    
455     i_near_gs = 0;
456     stop_y_search = 0;
457     stop_x_search = 0;
458     x_min = 0;
459     y_min = 0;
460     if (act_gsn == 0) {
461     x_max = x;
462     } else {
463     x_max = pict_get_xsize(p) - 1;
464     }
465    
466     y_max = pict_get_ysize(p) - 1;
467    
468     old_gsn = pict_get_gsn(p, x, y);
469     new_gsn = old_gsn;
470     change = 0;
471     if (act_gsn > 0) {
472     i_near_gs = pict_get_gsn(p, x, y);
473     }
474     for (iiy = 1; iiy <= 2; iiy++) {
475     dy = iiy * 2 - 3;
476     if (dy == -1) {
477     iy = y;
478     } else {
479     iy = y + 1;
480     }
481     ixm[1] = x;
482     ixm[2] = x;
483     stop_y_search = 0;
484    
485    
486     while (iy <= y_max && iy >= y_min) {
487     for (iix = 1; iix <= 2; iix++) {
488     dx = iix * 2 - 3;
489     ix = (ixm[1] + ixm[2]) / 2;
490     stop_x_search = 0;
491     while (ix <= x_max && ix >= x_min && stop_x_search == 0
492     && stop_y_search == 0) {
493     /* 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);*/
494     r_actual =
495     acos(DOT(pict_get_cached_dir(p, x, y),
496     pict_get_cached_dir(p, ix, iy))) * 2;
497     if (r_actual <= r) {
498     if (pict_get_gsn(p, ix, iy) > 0) {
499     if (act_gsn == 0) {
500     i_near_gs = pict_get_gsn(p, ix, iy);
501     stop_x_search = 1;
502     stop_y_search = 1;
503     } else {
504     find_gsn = pict_get_gsn(p, ix, iy);
505     if (pict_get_av_omega(p, old_gsn) <
506     pict_get_av_omega(p, find_gsn)
507     && pict_get_av_omega(p,
508     find_gsn) >
509     pict_get_av_omega(p, new_gsn)
510     && find_gsn >= min_gsn
511     && find_gsn <= max_gsn) {
512     /* other primary glare source found with larger solid angle -> add together all */
513     new_gsn = find_gsn;
514     change = 1;
515     stop_x_search = 1;
516     stop_y_search = 1;
517     }
518     }
519     }
520     } else {
521     ixm[iix] = ix - dx;
522     stop_x_search = 1;
523     }
524     ix = ix + dx;
525     }
526     }
527     iy = iy + dy;
528     }
529     }
530     if (change > 0) {
531     pict_get_av_lum(p, old_gsn) = 0.;
532     pict_get_av_omega(p, old_gsn) = 0.;
533     pict_get_npix(p, old_gsn) = 0.;
534     pict_get_lum_max(p, old_gsn) = 0.;
535    
536    
537     i_near_gs = new_gsn;
538     /* printf(" changing gs no %i",old_gsn);
539     printf(" to %i\n",new_gsn);
540     */
541     for (xx = 0; xx < pict_get_xsize(p); xx++)
542     for (yy = 0; yy < pict_get_ysize(p); yy++) {
543     if (pict_is_validpixel(p, x, y)) {
544     if (pict_get_gsn(p, xx, yy) == old_gsn) {
545     add_pixel_to_gs(p, xx, yy, new_gsn);
546     }
547     }
548     }
549     }
550    
551     return i_near_gs;
552    
553    
554     }
555    
556     /* subroutine for calculation of task luminance */
557     double get_task_lum(pict * p, int x, int y, float r, int task_color)
558     {
559     int x_min, x_max, y_min, y_max, ix, iy;
560     double r_actual, av_lum, omega_sum, act_lum;
561    
562    
563     x_max = pict_get_xsize(p) - 1;
564     y_max = pict_get_ysize(p) - 1;
565     x_min = 0;
566     y_min = 0;
567    
568    
569    
570     av_lum = 0.0;
571     omega_sum = 0.0;
572    
573     for (iy = y_min; iy <= y_max; iy++) {
574     for (ix = x_min; ix <= x_max; ix++) {
575    
576     /* if (DOT(pict_get_cached_dir(p,ix,iy),p->view.vdir) < 0.0)
577     continue;*/
578     r_actual =
579     acos(DOT(pict_get_cached_dir(p, x, y),
580     pict_get_cached_dir(p, ix, iy))) * 2;
581     act_lum = luminance(pict_get_color(p, ix, iy));
582    
583     if (r_actual <= r) {
584     act_lum = luminance(pict_get_color(p, ix, iy));
585     av_lum += pict_get_omega(p, ix, iy) * act_lum;
586     omega_sum += pict_get_omega(p, ix, iy);
587     if (task_color == 1) {
588     pict_get_color(p, ix, iy)[RED] = 0.0;
589     pict_get_color(p, ix, iy)[GRN] = 0.0;
590     pict_get_color(p, ix, iy)[BLU] =
591     act_lum / WHTEFFICACY / CIE_bf;
592     }
593     }
594     }
595     }
596    
597     av_lum = av_lum / omega_sum;
598     /* printf("average luminance of task %f \n",av_lum);
599     printf("solid angle of task %f \n",omega_sum);*/
600     return av_lum;
601     }
602    
603    
604    
605    
606    
607     /* subroutine for coloring the glare sources
608     red is used only for explicit call of the subroutine with acol=0 , e.g. for disability glare
609     -1: set to grey*/
610     int setglcolor(pict * p, int x, int y, int acol, int uniform_gs, double u_r, double u_g ,double u_b)
611     {
612     int icol;
613     double pcol[3][1000], act_lum, l;
614    
615     l=u_r+u_g+u_b ;
616    
617     pcol[RED][0] = 1.0 / CIE_rf;
618 greg 2.3 pcol[GRN][0] = 0.0 / CIE_gf;
619     pcol[BLU][0] = 0.0 / CIE_bf;
620 greg 2.1
621 greg 2.3 pcol[RED][1] = 0.0 / CIE_rf;
622 greg 2.1 pcol[GRN][1] = 1.0 / CIE_gf;
623 greg 2.3 pcol[BLU][1] = 0.0 / CIE_bf;
624 greg 2.1
625 greg 2.3 pcol[RED][2] = 0.15 / CIE_rf;
626     pcol[GRN][2] = 0.15 / CIE_gf;
627     pcol[BLU][2] = 0.7 / CIE_bf;
628    
629     pcol[RED][3] = .5 / CIE_rf;
630     pcol[GRN][3] = .5 / CIE_gf;
631     pcol[BLU][3] = 0.0 / CIE_bf;
632    
633     pcol[RED][4] = .5 / CIE_rf;
634     pcol[GRN][4] = .0 / CIE_gf;
635     pcol[BLU][4] = .5 / CIE_bf ;
636    
637     pcol[RED][5] = .0 / CIE_rf;
638     pcol[GRN][5] = .5 / CIE_gf;
639     pcol[BLU][5] = .5 / CIE_bf;
640    
641     pcol[RED][6] = 0.333 / CIE_rf;
642     pcol[GRN][6] = 0.333 / CIE_gf;
643     pcol[BLU][6] = 0.333 / CIE_bf;
644 greg 2.1
645    
646     pcol[RED][999] = 1.0 / WHTEFFICACY;
647     pcol[GRN][999] = 1.0 / WHTEFFICACY;
648     pcol[BLU][999] = 1.0 / WHTEFFICACY;
649    
650    
651     pcol[RED][998] = u_r /(l* CIE_rf) ;
652     pcol[GRN][998] = u_g /(l* CIE_gf);
653     pcol[BLU][998] = u_b /(l* CIE_bf);
654 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); */
655 greg 2.1 icol = acol ;
656     if ( acol == -1) {icol=999;
657     }else{if (acol>0){icol = acol % 5 +1;
658     }};
659     if ( uniform_gs == 1) {icol=998;
660     } ;
661    
662     act_lum = luminance(pict_get_color(p, x, y));
663    
664     pict_get_color(p, x, y)[RED] = pcol[RED][icol] * act_lum / WHTEFFICACY;
665     pict_get_color(p, x, y)[GRN] = pcol[GRN][icol] * act_lum / WHTEFFICACY;
666     pict_get_color(p, x, y)[BLU] = pcol[BLU][icol] * act_lum / WHTEFFICACY;
667 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))); */
668 greg 2.1 return icol;
669     }
670    
671     /* this is the smooting subroutine */
672     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)
673     {
674     int x_min, x_max, y_min, y_max, ix, iy, icol;
675     double r_actual, omega_gs, omega_total, om;
676    
677    
678    
679     omega_gs = 0.0;
680     omega_total = 0.0;
681     x_min = x - r;
682     if (x_min < 0) {
683     x_min = 0;
684     }
685     x_max = x + r;
686     if (x_max > pict_get_xsize(p) - 1) {
687     x_max = pict_get_xsize(p) - 2;
688     }
689     y_min = y - r;
690     if (y_min < 0) {
691     y_min = 0;
692     }
693     y_max = y + r;
694     if (y_max > pict_get_ysize(p) - 1) {
695     y_max = pict_get_ysize(p) - 2;
696     }
697    
698     for (ix = x_min; ix <= x_max; ix++)
699     for (iy = y_min; iy <= y_max; iy++) {
700     r_actual = sqrt((x - ix) * (x - ix) + (y - iy) * (y - iy));
701     if (r_actual <= r) {
702     om = pict_get_omega(p, ix, iy);
703     omega_total += om;
704     if (pict_get_gsn(p, ix, iy) == act_gs
705     && pict_get_pgs(p, ix, iy) == 1) {
706     omega_gs = omega_gs + 1 * om;
707     }
708     }
709     }
710    
711    
712     if (omega_gs / omega_total > 0.2) {
713     /* add pixel to gs */
714    
715     add_pixel_to_gs(p, x, y, act_gs);
716    
717     /* color pixel of gs */
718    
719 greg 2.3 /* icol = setglcolor(p, x, y, act_gs, uniform_gs, u_r, u_g , u_b); */
720 greg 2.1
721     }
722     }
723    
724     /* subroutine for removing a pixel from a glare source */
725     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)
726     {
727     int old_gsn, icol;
728     double old_av_posx, old_av_posy, old_av_lum, old_omega, act_omega,
729     new_omega, act_lum;
730    
731    
732     /* change existing gs */
733     old_gsn = pict_get_gsn(p, x, y);
734     pict_get_npix(p, old_gsn) = pict_get_npix(p, old_gsn) - 1;
735    
736     act_omega = pict_get_omega(p, x, y);
737     old_av_posx = pict_get_av_posx(p, old_gsn);
738     old_av_posy = pict_get_av_posy(p, old_gsn);
739     old_omega = pict_get_av_omega(p, old_gsn);
740    
741     new_omega = old_omega - act_omega;
742     pict_get_av_omega(p, old_gsn) = new_omega;
743     pict_get_av_posx(p, old_gsn) =
744     (old_av_posx * old_omega - x * act_omega) / new_omega;
745     pict_get_av_posy(p, old_gsn) =
746     (old_av_posy * old_omega - y * act_omega) / new_omega;
747    
748    
749     act_lum = luminance(pict_get_color(p, x, y));
750     old_av_lum = pict_get_av_lum(p, old_gsn);
751     pict_get_av_lum(p, old_gsn) =
752     (old_av_lum * old_omega - act_lum * act_omega) / new_omega;
753     /* add pixel to new gs */
754    
755     add_pixel_to_gs(p, x, y, new_gsn);
756    
757     /* color pixel of new gs */
758    
759 greg 2.3 /* icol = setglcolor(p, x, y, new_gsn, uniform_gs, u_r, u_g , u_b); */
760    
761 greg 2.1
762     }
763    
764     /* subroutine for the calculation of the position index */
765     float get_posindex(pict * p, float x, float y, int postype)
766     {
767     float posindex;
768     double teta, phi, sigma, tau, deg, d, s, r, fact;
769    
770    
771     pict_get_vangle(p, x, y, p->view.vdir, p->view.vup, &phi);
772     pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &teta);
773     pict_get_sigma(p, x, y, p->view.vdir, p->view.vup, &sigma);
774     pict_get_tau(p, x, y, p->view.vdir, p->view.vup, &tau);
775    
776     /* return (phi+teta+2*3.1415927); */
777    
778     deg = 180 / 3.1415927;
779     fact = 0.8;
780     if (phi == 0) {
781     phi = 0.00001;
782     }
783     if (sigma <= 0) {
784     sigma = -sigma;
785     }
786     if (teta == 0) {
787     teta = 0.0001;
788     }
789     tau = tau * deg;
790     sigma = sigma * deg;
791    
792 greg 2.3 if (postype == 1) {
793     /* KIM model */
794     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));
795     }else{
796     /* Guth model, equation from IES lighting handbook */
797 greg 2.1 posindex =
798     exp((35.2 - 0.31889 * tau -
799     1.22 * exp(-2 * tau / 9)) / 1000 * sigma + (21 +
800     0.26667 * tau -
801     0.002963 * tau *
802     tau) / 100000 *
803     sigma * sigma);
804     /* below line of sight, using Iwata model */
805     if (phi < 0) {
806     d = 1 / tan(phi);
807     s = tan(teta) / tan(phi);
808     r = sqrt(1 / d * 1 / d + s * s / d / d);
809     if (r > 0.6)
810     fact = 1.2;
811     if (r > 3) {
812     fact = 1.2;
813     r = 3;
814     }
815    
816     posindex = 1 + fact * r;
817     }
818 greg 2.3 if (posindex > 16)
819 greg 2.1 posindex = 16;
820 greg 2.3 }
821 greg 2.1
822     return posindex;
823    
824     }
825    
826    
827    
828     double get_upper_cut_2eyes(float teta)
829     {
830     double phi;
831    
832     phi=pow(7.7458218+0.00057407915*teta-0.00021746318*teta*teta+8.5572726e-6*teta*teta*teta,2);
833    
834     return phi;
835     }
836     double get_lower_cut_2eyes(float teta)
837     {
838     double phi;
839    
840     phi=1/(-0.014699242-1.5541106e-5*teta+4.6898068e-6*teta*teta-5.1539687e-8*teta*teta*teta);
841    
842     return phi;
843     }
844    
845     double get_lower_cut_central(float teta)
846     {
847     double phi;
848    
849     phi=(68.227109-2.9524084*teta+0.046674262*teta*teta)/(1-0.042317294*teta+0.00075698419*teta*teta-6.5364285e-7*teta*teta*teta);
850    
851     if (teta>73) {
852     phi=60;
853     }
854    
855     return phi;
856     }
857    
858     /* subroutine for the cutting the total field of view */
859     void cut_view_1(pict*p)
860     {
861     int x,y;
862     double border,ang,teta,phi,phi2;
863     for(x=0;x<pict_get_xsize(p)-1;x++)
864     for(y=0;y<pict_get_ysize(p)-1;y++) {
865     if (pict_get_hangle(p,x,y,p->view.vdir,p->view.vup,&ang)) {
866     if (pict_is_validpixel(p, x, y)) {
867     pict_get_vangle(p,x,y,p->view.vdir,p->view.vup,&phi2);
868     pict_get_sigma(p,x,y,p->view.vdir,p->view.vup,&phi);
869     pict_get_tau(p,x,y,p->view.vdir,p->view.vup,&teta);
870     phi=phi*180/3.1415927;
871     phi2=phi2*180/3.1415927;
872     teta=teta*180/3.1415927;
873     if (teta<0) {
874     teta=-teta;
875     }
876     if(phi2>0){
877     border=get_upper_cut_2eyes(teta);
878    
879     if (phi>border) {
880     pict_get_color(p,x,y)[RED]=0;
881     pict_get_color(p,x,y)[GRN]=0;
882     pict_get_color(p,x,y)[BLU]=0;
883     }
884     }else{
885     border=get_lower_cut_2eyes(180-teta);
886     if (-phi<border && teta>135) {
887     pict_get_color(p,x,y)[RED]=0;
888     pict_get_color(p,x,y)[GRN]=0;
889     pict_get_color(p,x,y)[BLU]=0;
890     }
891     }
892    
893    
894    
895     }else{
896     pict_get_color(p,x,y)[RED]=0;
897     pict_get_color(p,x,y)[GRN]=0;
898     pict_get_color(p,x,y)[BLU]=0;
899    
900    
901     }
902    
903     /* printf("teta,phi,border=%f %f %f\n",teta,phi,border);*/
904     }
905     }
906    
907    
908     return;
909    
910     }
911     /* subroutine for the cutting the field of view seen by both eyes*/
912     void cut_view_2(pict*p)
913     {
914    
915     int x,y;
916     double border,ang,teta,phi,phi2;
917     for(x=0;x<pict_get_xsize(p)-1;x++)
918     for(y=0;y<pict_get_ysize(p)-1;y++) {
919     if (pict_get_hangle(p,x,y,p->view.vdir,p->view.vup,&ang)) {
920     if (pict_is_validpixel(p, x, y)) {
921     pict_get_vangle(p,x,y,p->view.vdir,p->view.vup,&phi2);
922     pict_get_hangle(p,x,y,p->view.vdir,p->view.vup,&teta);
923     pict_get_sigma(p,x,y,p->view.vdir,p->view.vup,&phi);
924     pict_get_tau(p,x,y,p->view.vdir,p->view.vup,&teta);
925     phi=phi*180/3.1415927;
926     phi2=phi2*180/3.1415927;
927     teta=teta*180/3.1415927;
928     /* printf("x,y,teta,phi,border=%i %i %f %f %f\n",x,y,teta,phi,border);*/
929     if (teta<0) {
930     teta=-teta;
931     }
932     if(phi2>0){
933     border=60;
934    
935     if (phi>border) {
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     }else{
941     border=get_lower_cut_central(180-teta);
942     if (phi>border) {
943     pict_get_color(p,x,y)[RED]=0;
944     pict_get_color(p,x,y)[GRN]=0;
945     pict_get_color(p,x,y)[BLU]=0;
946     }
947     }
948    
949    
950    
951     }else{
952     pict_get_color(p,x,y)[RED]=0;
953     pict_get_color(p,x,y)[GRN]=0;
954     pict_get_color(p,x,y)[BLU]=0;
955    
956    
957     }
958     }
959     }
960    
961    
962     return;
963    
964     }
965    
966     /* subroutine for the cutting the field of view seen by both eyes
967     luminance is modified by position index - just for experiments - undocumented */
968     void cut_view_3(pict*p)
969     {
970    
971     int x,y;
972     double border,ang,teta,phi,phi2,lum,newlum;
973     for(x=0;x<pict_get_xsize(p)-1;x++)
974     for(y=0;y<pict_get_ysize(p)-1;y++) {
975     if (pict_get_hangle(p,x,y,p->view.vdir,p->view.vup,&ang)) {
976     if (DOT(pict_get_cached_dir(p,x,y),p->view.vdir) >= 0.0) {
977     pict_get_vangle(p,x,y,p->view.vdir,p->view.vup,&phi2);
978     pict_get_hangle(p,x,y,p->view.vdir,p->view.vup,&teta);
979     pict_get_sigma(p,x,y,p->view.vdir,p->view.vup,&phi);
980     pict_get_tau(p,x,y,p->view.vdir,p->view.vup,&teta);
981     phi=phi*180/3.1415927;
982     phi2=phi2*180/3.1415927;
983     teta=teta*180/3.1415927;
984     lum=luminance(pict_get_color(p,x,y));
985    
986     newlum=lum/get_posindex(p,x,y,0);
987    
988     pict_get_color(p,x,y)[RED]=newlum/WHTEFFICACY;
989     pict_get_color(p,x,y)[GRN]=newlum/WHTEFFICACY;
990     pict_get_color(p,x,y)[BLU]=newlum/WHTEFFICACY;
991    
992    
993    
994    
995     /* printf("x,y,teta,phi,border=%i %i %f %f %f\n",x,y,teta,phi,border);*/
996     if (teta<0) {
997     teta=-teta;
998     }
999     if(phi2>0){
1000     border=60;
1001    
1002     if (phi>border) {
1003     pict_get_color(p,x,y)[RED]=0;
1004     pict_get_color(p,x,y)[GRN]=0;
1005     pict_get_color(p,x,y)[BLU]=0;
1006     }
1007     }else{
1008     border=get_lower_cut_central(180-teta);
1009     if (phi>border) {
1010     pict_get_color(p,x,y)[RED]=0;
1011     pict_get_color(p,x,y)[GRN]=0;
1012     pict_get_color(p,x,y)[BLU]=0;
1013     }
1014     }
1015    
1016    
1017    
1018     }else{
1019     pict_get_color(p,x,y)[RED]=0;
1020     pict_get_color(p,x,y)[GRN]=0;
1021     pict_get_color(p,x,y)[BLU]=0;
1022    
1023    
1024     }
1025     }
1026     }
1027    
1028    
1029     return;
1030    
1031     }
1032    
1033 greg 2.3 /* subroutine for the calculation of the daylight glare index DGI*/
1034 greg 2.1
1035    
1036     float get_dgi(pict * p, float lum_backg, int igs, int posindex_2)
1037     {
1038     float dgi, sum_glare, omega_s;
1039     int i;
1040    
1041    
1042     sum_glare = 0;
1043     omega_s = 0;
1044    
1045     for (i = 0; i <= igs; i++) {
1046    
1047     if (pict_get_npix(p, i) > 0) {
1048     omega_s =
1049     pict_get_av_omega(p, i) / get_posindex(p,pict_get_av_posx(p,i), pict_get_av_posy(p,i),posindex_2) /
1050     get_posindex(p, pict_get_av_posx(p, i), pict_get_av_posy(p, i), posindex_2);
1051     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));
1052     /* printf("i,sum_glare %i %f\n",i,sum_glare); */
1053     }
1054     }
1055     dgi = 10 * log10(sum_glare);
1056    
1057     return dgi;
1058    
1059     }
1060 greg 2.3 /* subroutine for the calculation of the modified daylight glare index DGI_mod (Fisekis2003)
1061     several glare sources are taken into account and summed up, original equation has no summary
1062     */
1063    
1064    
1065     float get_dgi_mod(pict * p, float lum_a, int igs, int posindex_2)
1066     {
1067     float dgi_mod, sum_glare, omega_s;
1068     int i;
1069    
1070    
1071     sum_glare = 0;
1072     omega_s = 0;
1073    
1074     for (i = 0; i <= igs; i++) {
1075    
1076     if (pict_get_npix(p, i) > 0) {
1077     omega_s =
1078     pict_get_av_omega(p, i) / get_posindex(p,pict_get_av_posx(p,i), pict_get_av_posy(p,i),posindex_2) /
1079     get_posindex(p, pict_get_av_posx(p, i), pict_get_av_posy(p, i), posindex_2);
1080     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));
1081     /* printf("i,sum_glare %i %f\n",i,sum_glare); */
1082     }
1083     }
1084     dgi_mod = 10 * log10(sum_glare);
1085    
1086     return dgi_mod;
1087    
1088     }
1089 greg 2.1
1090     /* subroutine for the calculation of the daylight glare probability */
1091     double
1092     get_dgp(pict * p, double E_v, int igs, double a1, double a2, double a3,
1093     double a4, double a5, double c1, double c2, double c3,
1094     int posindex_2)
1095     {
1096     double dgp;
1097     double sum_glare;
1098     int i;
1099    
1100     sum_glare = 0;
1101     if (igs > 0) {
1102     for (i = 0; i <= igs; i++) {
1103    
1104     if (pict_get_npix(p, i) > 0) {
1105     sum_glare +=
1106     pow(pict_get_av_lum(p, i),
1107     a1) / pow(get_posindex(p, pict_get_av_posx(p, i),
1108     pict_get_av_posy(p, i),
1109     posindex_2),
1110     a4) * pow(pict_get_av_omega(p, i), a2);
1111     /* printf("i,sum_glare %i %f\n",i,sum_glare);*/
1112     }
1113     }
1114     dgp =
1115     c1 * pow(E_v,
1116     a5) + c3 + c2 * log10(1 + sum_glare / pow(E_v, a3));
1117     } else {
1118     dgp = c3 + c1 * pow(E_v, a5);
1119     }
1120    
1121     if (dgp > 1) {
1122     dgp = 1;
1123     }
1124     /* printf("dgp %f\n",dgp);*/
1125     return dgp;
1126    
1127     }
1128    
1129     /* subroutine for the calculation of the visual comfort probability */
1130 greg 2.3 float get_dgr(pict * p, double lum_a, int igs, int posindex_2)
1131 greg 2.1 {
1132 greg 2.3 float dgr;
1133     double sum_glare;
1134 greg 2.1 int i, i_glare;
1135    
1136    
1137     sum_glare = 0;
1138     i_glare = 0;
1139     for (i = 0; i <= igs; i++) {
1140    
1141     if (pict_get_npix(p, i) > 0) {
1142     i_glare = i_glare + 1;
1143     sum_glare +=
1144     (0.5 * pict_get_av_lum(p, i) *
1145     (20.4 * pict_get_av_omega(p, i) +
1146     1.52 * pow(pict_get_av_omega(p, i),
1147     0.2) - 0.075)) / (get_posindex(p,
1148     pict_get_av_posx
1149     (p, i),
1150     pict_get_av_posy
1151     (p, i),
1152     posindex_2) *
1153     pow(lum_a, 0.44));
1154    
1155     }
1156     }
1157     dgr = pow(sum_glare, pow(i_glare, -0.0914));
1158    
1159 greg 2.3
1160    
1161     return dgr;
1162    
1163     }
1164    
1165     float get_vcp(float dgr )
1166     {
1167     float vcp;
1168    
1169 greg 2.1 vcp = 50 * erf((6.347 - 1.3227 * log(dgr)) / 1.414213562373) + 50;
1170     if (dgr > 750) {
1171     vcp = 0;
1172     }
1173     if (dgr < 20) {
1174     vcp = 100;
1175     }
1176     return vcp;
1177    
1178     }
1179    
1180 greg 2.3
1181 greg 2.1 /* subroutine for the calculation of the unified glare rating */
1182     float get_ugr(pict * p, double lum_backg, int igs, int posindex_2)
1183     {
1184     float ugr;
1185     double sum_glare;
1186     int i, i_glare;
1187    
1188    
1189     sum_glare = 0;
1190     i_glare = 0;
1191     for (i = 0; i <= igs; i++) {
1192    
1193     if (pict_get_npix(p, i) > 0) {
1194     i_glare = i_glare + 1;
1195     sum_glare +=
1196     pow(pict_get_av_lum(p, i) /
1197     get_posindex(p, pict_get_av_posx(p, i),
1198     pict_get_av_posy(p, i), posindex_2),
1199     2) * pict_get_av_omega(p, i);
1200    
1201     }
1202     }
1203     ugr = 8 * log10(0.25 / lum_backg * sum_glare);
1204    
1205     return ugr;
1206    
1207     }
1208 greg 2.3 /* subroutine for the calculation of the experimental unified glare rating (Fisekis 2003)*/
1209     float get_ugr_exp(pict * p, double lum_backg, double lum_a, int igs, int posindex_2)
1210     {
1211     float ugr_exp;
1212     double sum_glare;
1213     int i, i_glare;
1214    
1215    
1216     sum_glare = 0;
1217     i_glare = 0;
1218     for (i = 0; i <= igs; i++) {
1219    
1220     if (pict_get_npix(p, i) > 0) {
1221     i_glare = i_glare + 1;
1222     sum_glare +=
1223     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);
1224    
1225     }
1226     }
1227     ugr_exp =8 * log10(lum_a) + 8 * log10(sum_glare/lum_backg);
1228    
1229     return ugr_exp;
1230    
1231     }
1232     /* subroutine for the calculation of the unified glare probability (Hirning 2014)*/
1233     float get_ugp(pict * p, double lum_backg, int igs, int posindex_2)
1234     {
1235     float ugp;
1236     double sum_glare;
1237     int i, i_glare;
1238    
1239    
1240     sum_glare = 0;
1241     i_glare = 0;
1242     for (i = 0; i <= igs; i++) {
1243    
1244     if (pict_get_npix(p, i) > 0) {
1245     i_glare = i_glare + 1;
1246     sum_glare +=
1247     pow(pict_get_av_lum(p, i) /
1248     get_posindex(p, pict_get_av_posx(p, i),
1249     pict_get_av_posy(p, i), posindex_2),
1250     2) * pict_get_av_omega(p, i);
1251    
1252     }
1253     }
1254     ugp = 0.26 * log10(0.25 / lum_backg * sum_glare);
1255    
1256     return ugp;
1257    
1258     }
1259 greg 2.1
1260    
1261     /* subroutine for the calculation of the disability glare according to Poynter */
1262     float get_disability(pict * p, double lum_backg, int igs)
1263     {
1264     float disab;
1265     double sum_glare, sigma, deg;
1266     int i, i_glare;
1267    
1268    
1269     sum_glare = 0;
1270     i_glare = 0;
1271     deg = 180 / 3.1415927;
1272     for (i = 0; i <= igs; i++) {
1273    
1274     if (pict_get_npix(p, i) > 0) {
1275     i_glare = i_glare + 1;
1276     pict_get_sigma(p, pict_get_av_posx(p, i),
1277     pict_get_av_posy(p, i), p->view.vdir,
1278     p->view.vup, &sigma);
1279    
1280     sum_glare +=
1281     pict_get_av_lum(p,
1282     i) * cos(sigma +
1283     0.00000000001) *
1284     pict_get_av_omega(p, i)
1285     / (deg * sigma + 0.00000000001);
1286     if (isnan(sum_glare)) {
1287     printf("sigma for %f %f\n", pict_get_av_posx(p, i), pict_get_av_posy(p, i));
1288     printf("omega for %f %f\n", pict_get_av_posx(p, i), pict_get_av_posy(p, i));
1289     printf("avlum for %f %f\n", pict_get_av_posx(p, i), pict_get_av_posy(p, i));
1290     printf("avlum for %f %f %f\n", pict_get_av_posx(p, i), pict_get_av_posy(p, i), sigma);
1291     }
1292    
1293     }
1294     }
1295     disab = 5 * sum_glare;
1296    
1297     return disab;
1298    
1299     }
1300    
1301    
1302    
1303    
1304    
1305    
1306     /* subroutine for the calculation of the cie glare index */
1307    
1308 greg 2.3 float get_cgi(pict * p, double E_v, double E_v_dir, int igs, int posindex_2)
1309 greg 2.1 {
1310     float cgi;
1311     double sum_glare;
1312     int i, i_glare;
1313    
1314    
1315     sum_glare = 0;
1316     i_glare = 0;
1317     for (i = 0; i <= igs; i++) {
1318    
1319     if (pict_get_npix(p, i) > 0) {
1320     i_glare = i_glare + 1;
1321     sum_glare +=
1322     pow(pict_get_av_lum(p, i) /
1323     get_posindex(p, pict_get_av_posx(p, i),
1324     pict_get_av_posy(p, i), posindex_2),
1325     2) * pict_get_av_omega(p, i);
1326    
1327     }
1328     }
1329     cgi = 8 * log10((2 * (1 + E_v_dir / 500) / E_v) * sum_glare);
1330    
1331     return cgi;
1332 greg 2.3 }
1333    
1334     /* 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! */
1335     float get_pgsv(double E_v, double E_mask,double omega_mask,double lum_mask_av)
1336     {
1337     float pgsv;
1338     double Lb;
1339    
1340     Lb = (E_v-E_mask)/1.414213562373;
1341    
1342     pgsv =3.2*log10(lum_mask_av)-0.64*log10(omega_mask)+(0.79*log10(omega_mask)-0.61)*log10(Lb)-8.2 ;
1343    
1344    
1345     return pgsv;
1346     }
1347    
1348     /* 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! */
1349     float get_pgsv_sat(double E_v)
1350     {
1351     float pgsv_sat;
1352    
1353     pgsv_sat =3.3-(0.57+3.3)/pow((1+E_v/1.414213562373/1250),1.7);
1354    
1355 greg 2.1
1356 greg 2.3 return pgsv_sat;
1357 greg 2.1 }
1358    
1359    
1360 greg 2.3
1361    
1362 greg 2.1 #ifdef EVALGLARE
1363    
1364    
1365     /* main program
1366     ------------------------------------------------------------------------------------------------------------------*/
1367    
1368    
1369     int main(int argc, char **argv)
1370     {
1371     #define CLINEMAX 4095 /* memory allocated for command line string */
1372     pict *p = pict_create();
1373 greg 2.3 pict *pm = pict_create();
1374     int skip_second_scan,calcfast,age_corr,cut_view,cut_view_type,calc_vill, output, detail_out2, x1,y1, fill, yfillmax, yfillmin,
1375     ext_vill, set_lum_max, set_lum_max2, img_corr,x_disk,y_disk,task_color, i_splitstart,zones,act_gsn,splitgs,
1376     i_split, posindex_2, task_lum, checkfile, rval, i, i_max, x, y,x2,y2,x_zone,y_zone, i_z1, i_z2,
1377     igs, actual_igs, lastpixelwas_gs, icol, xt, yt, change,checkpixels, before_igs, sgs, splithigh,uniform_gs,x_max, y_max,y_mid,
1378     detail_out, posindex_picture, non_cos_lb, rx, ry, rmx,rmy,apply_disability,band_calc,band_color,masking,i_mask,no_glaresources,force;
1379     double 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,
1380     E_vl_ext, lum_max, new_lum_max, r_center, ugp, ugr_exp, dgi_mod,lum_a, pgsv,E_v_mask,pgsv_sat,angle_disk,dist,n_corner_px,zero_corner_px,
1381     search_pix, a1, a2, a3, a4, a5, c3, c1, c2, r_split, max_angle,r_actual,lum_actual,
1382     omegat, sang, E_v, E_v2, E_v_dir, avlum, act_lum, ang, angle_z1, angle_z2,per_95_band,per_75_band,pos,
1383     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,
1384     lum, lum_source,teta,Lveil_cie,Lveil_cie_sum,disability_thresh,u_r,u_g,u_b,band_angle,band_avlum,
1385     lum_mask[1],lum_mask_av,lum_mask_std[1],lum_mask_median[1],omega_mask,bbox[2],
1386     lum_band[1],lum_band_av,lum_band_std[1],lum_band_median[1],omega_band,bbox_band[2],
1387     lum_z1[1],lum_z1_av,lum_z1_std[1],lum_z1_median[1],omega_z1,bbox_z1[2],
1388     lum_z2[1],lum_z2_av,lum_z2_std[1],lum_z2_median[1],omega_z2,bbox_z2[2],
1389     lum_pos[1],lum_nopos_median[1],lum_pos_median[1],lum_pos2_median[1],lum_pos_mean,lum_pos2_mean;
1390     float lum_task, lum_thres, dgi, vcp, cgi, ugr, limit, dgr,
1391 greg 2.1 abs_max, Lveil;
1392 greg 2.3 char maskfile[500],file_out[500], file_out2[500], version[500];
1393 greg 2.1 char *cline;
1394     VIEW userview = STDVIEW;
1395     int gotuserview = 0;
1396 greg 2.3 struct muc_rvar* s_mask;
1397     s_mask = muc_rvar_create();
1398     muc_rvar_set_dim(s_mask, 1);
1399     muc_rvar_clear(s_mask);
1400     struct muc_rvar* s_band;
1401     s_band = muc_rvar_create();
1402     muc_rvar_set_dim(s_band, 1);
1403     muc_rvar_clear(s_band);
1404     struct muc_rvar* s_z1;
1405     s_z1 = muc_rvar_create();
1406     muc_rvar_set_dim(s_z1, 1);
1407     muc_rvar_clear(s_z1);
1408    
1409     struct muc_rvar* s_z2;
1410     s_z2 = muc_rvar_create();
1411     muc_rvar_set_dim(s_z2, 1);
1412     muc_rvar_clear(s_z2);
1413    
1414     struct muc_rvar* s_noposweight;
1415     s_noposweight = muc_rvar_create();
1416     muc_rvar_set_dim(s_noposweight, 1);
1417     muc_rvar_clear(s_noposweight);
1418    
1419     struct muc_rvar* s_posweight;
1420     s_posweight = muc_rvar_create();
1421     muc_rvar_set_dim(s_posweight, 1);
1422     muc_rvar_clear(s_posweight);
1423    
1424     struct muc_rvar* s_posweight2;
1425     s_posweight2 = muc_rvar_create();
1426     muc_rvar_set_dim(s_posweight2, 1);
1427     muc_rvar_clear(s_posweight2);
1428 greg 2.1
1429     /*set required user view parameters to invalid values*/
1430 greg 2.3 delta_E=0.0;
1431     no_glaresources=0;
1432     n_corner_px=0;
1433     zero_corner_px=0;
1434     force=0;
1435     dist=0.0;
1436     u_r=0.33333;
1437     u_g=0.33333;
1438     u_b=0.33333;
1439     band_angle=0;
1440     angle_z1=0;
1441     angle_z2=0;
1442     x_zone=0;
1443     y_zone=0;
1444     per_75_z2=0;
1445     per_95_z2=0;
1446     lum_pos_mean=0;
1447     lum_pos2_mean=0;
1448     lum_band_av = 0.0;
1449     omega_band = 0.0;
1450     pgsv = 0.0 ;
1451     pgsv_sat = 0.0 ;
1452     E_v_mask = 0.0;
1453     lum_z1_av = 0.0;
1454     omega_z1 = 0.0;
1455     lum_z2_av = 0.0;
1456     omega_z2 = 0.0 ;
1457     i_z1 = 0;
1458     i_z2 = 0;
1459     zones = 0;
1460     lum_z2_av = 0.0;
1461     uniform_gs = 0;
1462 greg 2.1 apply_disability = 0;
1463     disability_thresh = 0;
1464     Lveil_cie_sum=0.0;
1465     skip_second_scan=0;
1466     lum_total_max=0.0;
1467     calcfast=0;
1468     age_corr_factor = 1.0;
1469     age_corr = 0;
1470     age = 20.0;
1471     userview.horiz = 0;
1472     userview.vert = 0;
1473     userview.type = 0;
1474     dgp_ext = 0;
1475     E_vl_ext = 0.0;
1476     new_lum_max = 0.0;
1477     lum_max = 0.0;
1478     omegat = 0.0;
1479     yt = 0;
1480     xt = 0;
1481 greg 2.3 x_disk=0;
1482     y_disk=0;
1483     angle_disk=0;
1484 greg 2.1 yfillmin = 0;
1485     yfillmax = 0;
1486     cut_view = 0;
1487     cut_view_type = 0;
1488     setvalue = 2e09;
1489     omega_cos_contr = 0.0;
1490     lum_ideal = 0.0;
1491     max_angle = 0.2;
1492     lum_thres = 5.0;
1493     task_lum = 0;
1494     sgs = 0;
1495     splithigh = 1;
1496     detail_out = 0;
1497     detail_out2 = 0;
1498     posindex_picture = 0;
1499     checkfile = 0;
1500     ext_vill = 0;
1501     fill = 0;
1502     a1 = 2.0;
1503     a2 = 1.0;
1504     a3 = 1.87;
1505     a4 = 2.0;
1506     a5 = 1.0;
1507     c1 = 5.87e-05;
1508     c2 = 0.092;
1509     c3 = 0.159;
1510     non_cos_lb = 1;
1511     posindex_2 = 0;
1512     task_color = 0;
1513     limit = 50000.0;
1514     set_lum_max = 0;
1515     set_lum_max2 = 0;
1516 greg 2.3 img_corr=0;
1517 greg 2.1 abs_max = 0;
1518     progname = argv[0];
1519     E_v_contr = 0.0;
1520 greg 2.3 strcpy(version, "1.19 release 09.12.2015 by J.Wienold");
1521 greg 2.1 low_light_corr=1.0;
1522     output = 0;
1523     calc_vill = 0;
1524     band_avlum = -99;
1525     band_calc = 0;
1526 greg 2.3 masking = 0;
1527     lum_mask[0]=0.0;
1528     lum_mask_av=0.0;
1529     omega_mask=0.0;
1530     i_mask=0;
1531     actual_igs=0;
1532 greg 2.1 /* command line for output picture*/
1533    
1534     cline = (char *) malloc(CLINEMAX+1);
1535     cline[0] = '\0';
1536     for (i = 0; i < argc; i++) {
1537     /* fprintf(stderr, "%d %d \n",i,strlen(argv[i]));*/
1538     if (strlen(cline)+strlen(argv[i])+strlen(RELEASENAME)+2 >=CLINEMAX) {
1539     exit (-1);
1540     }
1541     else {
1542     strcat(cline, argv[i]);
1543     strcat(cline, " ");
1544     }
1545     }
1546     strcat(cline, "\n");
1547     strcat(cline, RELEASENAME);
1548     strcat(cline, "\n");
1549    
1550    
1551     /* program options */
1552    
1553     for (i = 1; i < argc && argv[i][0] == '-'; i++) {
1554     /* expand arguments */
1555     while ((rval = expandarg(&argc, &argv, i)) > 0);
1556     if (rval < 0) {
1557     fprintf(stderr, "%s: cannot expand '%s'", argv[0], argv[i]);
1558     exit(1);
1559     }
1560     rval = getviewopt(&userview, argc - i, argv + i);
1561     if (rval >= 0) {
1562     i += rval;
1563     gotuserview++;
1564     continue;
1565     }
1566     switch (argv[i][1]) {
1567     case 'a':
1568     age = atof(argv[++i]);
1569     age_corr = 1;
1570     printf("age factor not supported any more \n");
1571     exit(1);
1572     break;
1573 greg 2.3 case 'A':
1574     masking = 1;
1575     detail_out = 1;
1576     strcpy(maskfile, argv[++i]);
1577     pict_read(pm,maskfile );
1578    
1579     break;
1580 greg 2.1 case 'b':
1581     lum_thres = atof(argv[++i]);
1582     break;
1583     case 'c':
1584     checkfile = 1;
1585     strcpy(file_out, argv[++i]);
1586     break;
1587     case 'u':
1588     uniform_gs = 1;
1589     u_r = atof(argv[++i]);
1590     u_g = atof(argv[++i]);
1591     u_b = atof(argv[++i]);
1592     break;
1593     case 'r':
1594     max_angle = atof(argv[++i]);
1595     break;
1596     case 's':
1597     sgs = 1;
1598     break;
1599 greg 2.3 case 'f':
1600     force = 1;
1601     break;
1602 greg 2.1 case 'k':
1603     apply_disability = 1;
1604     disability_thresh = atof(argv[++i]);
1605     break;
1606    
1607     case 'p':
1608     posindex_picture = 1;
1609     break;
1610 greg 2.3 case 'P':
1611     posindex_2 = atoi(argv[++i]);
1612     break;
1613    
1614 greg 2.1
1615     case 'y':
1616     splithigh = 1;
1617     break;
1618     case 'x':
1619     splithigh = 0;
1620     break;
1621     case 'Y':
1622     splithigh = 1;
1623     limit = atof(argv[++i]);
1624     break;
1625    
1626     case 'i':
1627     ext_vill = 1;
1628     E_vl_ext = atof(argv[++i]);
1629     break;
1630     case 'I':
1631     ext_vill = 1;
1632     fill = 1;
1633     E_vl_ext = atof(argv[++i]);
1634     yfillmax = atoi(argv[++i]);
1635     yfillmin = atoi(argv[++i]);
1636     break;
1637     case 'd':
1638     detail_out = 1;
1639     break;
1640     case 'D':
1641     detail_out2 = 1;
1642     break;
1643     case 'm':
1644 greg 2.3 img_corr = 1;
1645 greg 2.1 set_lum_max = 1;
1646     lum_max = atof(argv[++i]);
1647     new_lum_max = atof(argv[++i]);
1648     strcpy(file_out2, argv[++i]);
1649     /* printf("max lum set to %f\n",new_lum_max);*/
1650     break;
1651    
1652     case 'M':
1653 greg 2.3 img_corr = 1;
1654 greg 2.1 set_lum_max2 = 1;
1655     lum_max = atof(argv[++i]);
1656     E_vl_ext = atof(argv[++i]);
1657     strcpy(file_out2, argv[++i]);
1658     /* printf("max lum set to %f\n",new_lum_max);*/
1659     break;
1660 greg 2.3 case 'N':
1661     img_corr = 1;
1662     set_lum_max2 = 2;
1663     x_disk = atoi(argv[++i]);
1664     y_disk = atoi(argv[++i]);
1665     angle_disk = atof(argv[++i]);
1666     E_vl_ext = atof(argv[++i]);
1667     strcpy(file_out2, argv[++i]);
1668     /* printf("max lum set to %f\n",new_lum_max);*/
1669     break;
1670    
1671 greg 2.1 case 'n':
1672     non_cos_lb = 0;
1673     break;
1674    
1675     case 't':
1676     task_lum = 1;
1677     xt = atoi(argv[++i]);
1678     yt = atoi(argv[++i]);
1679     omegat = atof(argv[++i]);
1680     task_color = 0;
1681     break;
1682     case 'T':
1683     task_lum = 1;
1684     xt = atoi(argv[++i]);
1685     yt = atoi(argv[++i]);
1686     /* omegat= DEG2RAD(atof(argv[++i]));*/
1687     omegat = atof(argv[++i]);
1688     task_color = 1;
1689     break;
1690 greg 2.3 case 'l':
1691     zones = 1;
1692     x_zone = atoi(argv[++i]);
1693     y_zone = atoi(argv[++i]);
1694     angle_z1 = atof(argv[++i]);
1695     angle_z2 = -1;
1696     break;
1697     case 'L':
1698     zones = 2;
1699     x_zone = atoi(argv[++i]);
1700     y_zone = atoi(argv[++i]);
1701     angle_z1 = atof(argv[++i]);
1702     angle_z2 = atof(argv[++i]);
1703     break;
1704    
1705    
1706 greg 2.1 case 'B':
1707     band_calc = 1;
1708     band_angle = atof(argv[++i]);
1709     band_color = 1;
1710     break;
1711    
1712    
1713     case 'w':
1714     a1 = atof(argv[++i]);
1715     a2 = atof(argv[++i]);
1716     a3 = atof(argv[++i]);
1717     a4 = atof(argv[++i]);
1718     a5 = atof(argv[++i]);
1719     c1 = atof(argv[++i]);
1720     c2 = atof(argv[++i]);
1721     c3 = atof(argv[++i]);
1722     break;
1723     case 'V':
1724     calc_vill = 1;
1725     break;
1726     case 'G':
1727     cut_view = 1;
1728     cut_view_type= atof(argv[++i]);
1729     break;
1730     case 'g':
1731     cut_view = 2;
1732     cut_view_type= atof(argv[++i]);
1733     break;
1734    
1735     /*case 'v':
1736     printf("evalglare %s \n",version);
1737     exit(1); */
1738    
1739     case '1':
1740     output = 1;
1741     break;
1742    
1743     case 'v':
1744     if (argv[i][2] == '\0') {
1745     printf("%s \n",RELEASENAME);
1746     exit(1);
1747     }
1748     if (argv[i][2] != 'f')
1749     goto userr;
1750     rval = viewfile(argv[++i], &userview, NULL);
1751     if (rval < 0) {
1752     fprintf(stderr,
1753     "%s: cannot open view file \"%s\"\n",
1754     progname, argv[i]);
1755     exit(1);
1756     } else if (rval == 0) {
1757     fprintf(stderr,
1758     "%s: bad view file \"%s\"\n", progname, argv[i]);
1759     exit(1);
1760     } else {
1761     gotuserview++;
1762     }
1763     break;
1764    
1765    
1766     default:
1767     goto userr;
1768     }
1769     }
1770    
1771     /*fast calculation, if gendgp_profile is used: No Vertical illuminance calculation, only dgp is calculated*/
1772    
1773     if (output == 1 && ext_vill == 1) {
1774     calcfast=1;
1775     }
1776 greg 2.3 /*masking and zoning cannot be applied at the same time*/
1777    
1778     if (masking ==1 && zones >0) {
1779     fprintf(stderr, " masking and zoning cannot be activated at the same time!\n");
1780     exit(1);
1781     }
1782 greg 2.1
1783     /* read picture file */
1784     if (i == argc) {
1785     SET_FILE_BINARY(stdin);
1786     FILE *fp = fdopen(fileno(stdin), "rb");
1787     if (!(fp)) {
1788     fprintf(stderr, "fdopen on stdin failed\n");
1789     return EXIT_FAILURE;
1790     }
1791     if (!(pict_read_fp(p, fp)))
1792     return EXIT_FAILURE;;
1793     } else {
1794     if (!pict_read(p, argv[i]))
1795     return EXIT_FAILURE;
1796     }
1797     if (gotuserview) {
1798     if (p->valid_view)
1799     fprintf(stderr,
1800     "warning: overriding image view by commandline argument\n");
1801     if ((userview.horiz == 0) || (userview.vert == 0) || (userview.type == 0)) {
1802     fprintf(stderr, "error: if specified, a view must at least contain -vt -vv and -vh\n");
1803     return EXIT_FAILURE;
1804     }
1805     p->view = userview;
1806     if (!(pict_update_view(p))) {
1807     fprintf(stderr, "error: invalid view specified");
1808     return EXIT_FAILURE;
1809     }
1810     pict_update_evalglare_caches(p);
1811     } else if (!(p->valid_view)) {
1812     fprintf(stderr, "error: no valid view specified\n");
1813     return EXIT_FAILURE;
1814     }
1815    
1816 greg 2.3
1817    
1818 greg 2.1 /* fprintf(stderr,"Picture read!");*/
1819    
1820     /* command line for output picture*/
1821    
1822     pict_set_comment(p, cline);
1823    
1824 greg 2.3 /* several checks */
1825 greg 2.1 if (p->view.type == VT_PAR) {
1826 greg 2.3 fprintf(stderr, "error: wrong view type! must not be parallel ! \n");
1827 greg 2.1 exit(1);
1828     }
1829    
1830 greg 2.3 if (p->view.type == VT_PER) {
1831     fprintf(stderr, "warning: image has perspective view type specified in header ! \n");
1832     }
1833    
1834     if (masking == 1) {
1835    
1836     if (!pict_get_xsize(p)==pict_get_xsize(pm) || !pict_get_ysize(p)==pict_get_ysize(pm)) {
1837     fprintf(stderr, "error: masking image has other resolution than main image ! \n");
1838     fprintf(stderr, "size must be identical \n");
1839     printf("resolution main image : %dx%d\n",pict_get_xsize(p),pict_get_ysize(p));
1840     printf("resolution masking image : %dx%d\n",pict_get_xsize(pm),pict_get_ysize(pm));
1841     exit(1);
1842    
1843     }
1844    
1845     }
1846     /* printf("resolution: %dx%d\n",pict_get_xsize(p),pict_get_ysize(p)); */
1847 greg 2.1
1848     /* Check size of search radius */
1849     rmx = (pict_get_xsize(p) / 2);
1850     rmy = (pict_get_ysize(p) / 2);
1851     rx = (pict_get_xsize(p) / 2 + 10);
1852     ry = (pict_get_ysize(p) / 2 + 10);
1853     r_center =
1854     acos(DOT(pict_get_cached_dir(p, rmx, rmy),
1855     pict_get_cached_dir(p, rx, ry))) * 2 / 10;
1856     search_pix = max_angle / r_center;
1857     if (search_pix < 1.0) {
1858     fprintf(stderr,
1859     "warning: search radius less than 1 pixel! deactivating smoothing and peak extraction...\n");
1860     splithigh = 0;
1861     sgs = 0;
1862    
1863     } else {
1864     if (search_pix < 3.0) {
1865     fprintf(stderr,
1866     "warning: search radius less than 3 pixels! -> %f \n",
1867     search_pix);
1868    
1869     }
1870     }
1871    
1872     /* Check task position */
1873    
1874     if (task_lum == 1) {
1875     if (xt >= pict_get_xsize(p) || yt >= pict_get_ysize(p) || xt < 0
1876     || yt < 0) {
1877     fprintf(stderr,
1878     "error: task position outside picture!! exit...");
1879     exit(1);
1880     }
1881     }
1882    
1883    
1884     /* printf("resolution: %dx%d\n",pict_get_xsize(p),pict_get_ysize(p)); */
1885    
1886     sang = 0.0;
1887     E_v = 0.0;
1888     E_v_dir = 0.0;
1889     avlum = 0.0;
1890     pict_new_gli(p);
1891     igs = 0;
1892 greg 2.3 pict_get_z1_gsn(p,igs) = 0;
1893     pict_get_z2_gsn(p,igs) = 0;
1894    
1895 greg 2.1
1896     /* cut out GUTH field of view and exit without glare evaluation */
1897     if (cut_view==2) {
1898     if (cut_view_type==1) {
1899     cut_view_1(p);
1900     }else{
1901    
1902     if (cut_view_type==2) {
1903     cut_view_2(p);
1904     }else{
1905     if (cut_view_type==3) {
1906     fprintf(stderr,"warning: pixel luminance is weighted by position index - do not use image for glare evaluations!!");
1907     cut_view_3(p);
1908     }else{
1909     fprintf(stderr,"error: no valid option for view cutting!!");
1910     exit(1);
1911     }
1912     }}
1913     pict_write(p, file_out);
1914     exit(1); }
1915    
1916    
1917    
1918    
1919    
1920    
1921     /* write positionindex into checkfile and exit, activated by option -p */
1922     if (posindex_picture == 1) {
1923     for (x = 0; x < pict_get_xsize(p); x++)
1924     for (y = 0; y < pict_get_ysize(p); y++) {
1925     if (pict_get_hangle
1926     (p, x, y, p->view.vdir, p->view.vup, &ang)) {
1927     if (pict_is_validpixel(p, x, y)) {
1928     lum =
1929     get_posindex(p, x, y,
1930     posindex_2) / WHTEFFICACY;
1931    
1932     pict_get_color(p, x, y)[RED] = lum;
1933     pict_get_color(p, x, y)[GRN] = lum;
1934     pict_get_color(p, x, y)[BLU] = lum;
1935     lum_task = luminance(pict_get_color(p, x, y));
1936     /*printf("x,y,posindex=%i %i %f %f\n",x,y,lum*WHTEFFICACY,lum_task);*/
1937     }
1938     }
1939     }
1940     pict_write(p, file_out);
1941     exit(1);
1942     }
1943    
1944    
1945     /* calculation of vertical illuminance, average luminance, in case of filling activated-> fill picture */
1946     /* fill, if necessary from 0 to yfillmin */
1947    
1948     if (fill == 1) {
1949     for (x = 0; x < pict_get_xsize(p); x++)
1950     for (y = yfillmin; y > 0; y = y - 1) {
1951     y1 = y + 1;
1952     lum = luminance(pict_get_color(p, x, y1));
1953     pict_get_color(p, x, y)[RED] = lum / 179.0;
1954     pict_get_color(p, x, y)[GRN] = lum / 179.0;
1955     pict_get_color(p, x, y)[BLU] = lum / 179.0;
1956     }
1957     }
1958    
1959     if (calcfast == 0) {
1960     for (x = 0; x < pict_get_xsize(p); x++)
1961     for (y = 0; y < pict_get_ysize(p); y++) {
1962 greg 2.3 lum = luminance(pict_get_color(p, x, y));
1963     dist=sqrt((x-rmx)*(x-rmx)+(y-rmy)*(y-rmy));
1964     if (dist>((rmx+rmy)/2)) {
1965     n_corner_px=n_corner_px+1;
1966     if (lum<7.0) {
1967     zero_corner_px=zero_corner_px+1;
1968     }
1969     }
1970    
1971    
1972 greg 2.1 if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
1973     if (pict_is_validpixel(p, x, y)) {
1974     if (fill == 1 && y >= yfillmax) {
1975     y1 = y - 1;
1976     lum = luminance(pict_get_color(p, x, y1));
1977     pict_get_color(p, x, y)[RED] = lum / 179.0;
1978     pict_get_color(p, x, y)[GRN] = lum / 179.0;
1979     pict_get_color(p, x, y)[BLU] = lum / 179.0;
1980     }
1981    
1982     if (lum > abs_max) {
1983     abs_max = lum;
1984     }
1985     /* set luminance restriction, if -m is set */
1986 greg 2.3 if (img_corr == 1 ) {
1987     if (set_lum_max == 1 && lum >= lum_max) {
1988     pict_get_color(p, x, y)[RED] = new_lum_max / 179.0;
1989     pict_get_color(p, x, y)[GRN] = new_lum_max / 179.0;
1990     pict_get_color(p, x, y)[BLU] = new_lum_max / 179.0;
1991     /* printf("old lum, new lum %f %f \n",lum,luminance(pict_get_color(p,x,y))); */
1992     lum = luminance(pict_get_color(p, x, y));
1993     }
1994     if (set_lum_max2 == 1 && lum >= lum_max) {
1995    
1996     E_v_contr +=DOT(p->view.vdir,pict_get_cached_dir(p, x,y)) * pict_get_omega(p,x,y)* lum;
1997     omega_cos_contr +=DOT(p->view.vdir,pict_get_cached_dir(p, x,y)) * pict_get_omega(p,x,y)* 1;
1998     }
1999     if (set_lum_max2 == 2 ) {
2000     r_actual =acos(DOT(pict_get_cached_dir(p, x_disk, y_disk), pict_get_cached_dir(p, x, y))) * 2;
2001     if (x_disk == x && y_disk==y ) r_actual=0.0;
2002    
2003     act_lum = luminance(pict_get_color(p, x, y));
2004    
2005     if (r_actual <= angle_disk) {
2006     E_v_contr +=DOT(p->view.vdir,pict_get_cached_dir(p, x,y)) * pict_get_omega(p,x,y)* lum;
2007     omega_cos_contr += DOT(p->view.vdir,pict_get_cached_dir(p, x,y)) * pict_get_omega(p,x,y)* 1;
2008     }
2009 greg 2.1
2010 greg 2.3
2011    
2012     }
2013 greg 2.1 }
2014 greg 2.3 om = pict_get_omega(p, x, y);
2015     sang += om;
2016     E_v += DOT(p->view.vdir, pict_get_cached_dir(p, x,y)) * om *lum;
2017     avlum += om * lum;
2018     pos=get_posindex(p, x, y,posindex_2);
2019    
2020     lum_pos[0]=lum;
2021     muc_rvar_add_sample(s_noposweight,lum_pos);
2022     lum_pos[0]=lum/pos;
2023     lum_pos_mean+=lum_pos[0]*om;
2024     muc_rvar_add_sample(s_posweight, lum_pos);
2025     lum_pos[0]=lum_pos[0]/pos;
2026     lum_pos2_mean+=lum_pos[0]*om;
2027     muc_rvar_add_sample(s_posweight2,lum_pos);
2028 greg 2.1
2029    
2030    
2031     } else {
2032     pict_get_color(p, x, y)[RED] = 0.0;
2033     pict_get_color(p, x, y)[GRN] = 0.0;
2034     pict_get_color(p, x, y)[BLU] = 0.0;
2035    
2036     }
2037 greg 2.3 }else {
2038     pict_get_color(p, x, y)[RED] = 0.0;
2039     pict_get_color(p, x, y)[GRN] = 0.0;
2040     pict_get_color(p, x, y)[BLU] = 0.0;
2041    
2042     }
2043 greg 2.1 }
2044    
2045 greg 2.3 /* check if image has black corners AND a perspective view */
2046    
2047     if (zero_corner_px/n_corner_px > 0.70 && (p->view.type == VT_PER) ) {
2048     printf (" corner pixels are to %f %% black! \n",zero_corner_px/n_corner_px*100);
2049     printf("error! The image has black corners AND header contains a perspective view type definition !!!\n") ;
2050    
2051     if (force==0) {
2052     printf("stopping...!!!!\n") ;
2053    
2054     exit(1);
2055     }
2056     }
2057    
2058    
2059    
2060    
2061     lum_pos_mean= lum_pos_mean/sang;
2062     lum_pos2_mean= lum_pos2_mean/sang;
2063    
2064     if (set_lum_max2 >= 1 && E_v_contr > 0 && (E_vl_ext - E_v) > 0) {
2065 greg 2.1
2066     lum_ideal = (E_vl_ext - E_v + E_v_contr) / omega_cos_contr;
2067 greg 2.3 if (set_lum_max2 == 2 && lum_ideal >= 2e9) {
2068     printf("warning! luminance of replacement pixels would be larger than 2e9 cd/m2. Value set to 2e9cd/m2!\n") ;
2069     }
2070    
2071 greg 2.1 if (lum_ideal > 0 && lum_ideal < setvalue) {
2072     setvalue = lum_ideal;
2073     }
2074 greg 2.3 printf("change luminance values!! lum_ideal,setvalue,E_vl_ext,E_v,E_v_contr %f %f %f %f %f\n",
2075 greg 2.1 lum_ideal, setvalue, E_vl_ext, E_v, E_v_contr);
2076    
2077 greg 2.3
2078 greg 2.1 for (x = 0; x < pict_get_xsize(p); x++)
2079     for (y = 0; y < pict_get_ysize(p); y++) {
2080     if (pict_get_hangle
2081     (p, x, y, p->view.vdir, p->view.vup, &ang)) {
2082     if (pict_is_validpixel(p, x, y)) {
2083     lum = luminance(pict_get_color(p, x, y));
2084 greg 2.3
2085    
2086 greg 2.1 if (set_lum_max2 == 1 && lum >= lum_max) {
2087    
2088     pict_get_color(p, x, y)[RED] =
2089     setvalue / 179.0;
2090     pict_get_color(p, x, y)[GRN] =
2091     setvalue / 179.0;
2092     pict_get_color(p, x, y)[BLU] =
2093     setvalue / 179.0;
2094    
2095 greg 2.3 }else{ if(set_lum_max2 ==2 ) {
2096     r_actual =acos(DOT(pict_get_cached_dir(p, x_disk, y_disk), pict_get_cached_dir(p, x, y))) * 2;
2097     if (x_disk == x && y_disk==y ) r_actual=0.0;
2098    
2099     if (r_actual <= angle_disk) {
2100    
2101     pict_get_color(p, x, y)[RED] =
2102     setvalue / 179.0;
2103     pict_get_color(p, x, y)[GRN] =
2104     setvalue / 179.0;
2105     pict_get_color(p, x, y)[BLU] =
2106     setvalue / 179.0;
2107    
2108     }
2109    
2110    
2111     }
2112 greg 2.1 }
2113     }
2114     }
2115     }
2116 greg 2.3
2117 greg 2.1
2118     pict_write(p, file_out2);
2119 greg 2.3 exit(1);
2120 greg 2.1 }
2121     if (set_lum_max == 1) {
2122     pict_write(p, file_out2);
2123    
2124     }
2125    
2126     if (calc_vill == 1) {
2127     printf("%f\n", E_v);
2128     exit(1);
2129     }
2130     }else{
2131     /* in fast calculation mode: ev=ev_ext and sang=2*pi */
2132     sang=2*3.14159265359;
2133     lum_task =E_vl_ext/sang;
2134     E_v=E_vl_ext;
2135     /* printf("calc fast!! %f %f\n", sang,lum_task);*/
2136    
2137    
2138     }
2139    
2140     /* cut out GUTH field of view for glare evaluation */
2141     if (cut_view==1) {
2142     if (cut_view_type==1) {
2143     cut_view_1(p);
2144     }else{
2145    
2146     if (cut_view_type==2) {
2147     cut_view_2(p);
2148     }else{
2149     if (cut_view_type==3) {
2150     fprintf(stderr,"warning: pixel luminance is weighted by position index - do not use image for glare evaluations!!");
2151     cut_view_3(p);
2152     }else{
2153     fprintf(stderr,"error: no valid option for view cutting!!");
2154     exit(1);
2155     }
2156     }}
2157     }
2158    
2159     if (calcfast == 0) {
2160     avlum = avlum / sang;
2161     lum_task = avlum;
2162     }
2163     /* if (ext_vill==1) {
2164     E_v=E_vl_ext;
2165     avlum=E_v/3.1415927;
2166     } */
2167    
2168     if (task_lum == 1) {
2169     lum_task = get_task_lum(p, xt, yt, omegat, task_color);
2170     }
2171     lum_source = lum_thres * lum_task;
2172     /* printf("Task Luminance=%f\n",lum_task);
2173     pict_write(p,"task.pic");*/
2174    
2175     if (lum_thres > 100) {
2176     lum_source = lum_thres;
2177     }
2178    
2179 greg 2.3 /* printf("Ev, avlum, Omega_tot%f %f %f \n",E_v, avlum, sang); */
2180 greg 2.1
2181     /* first glare source scan: find primary glare sources */
2182 greg 2.3 for (x = 0; x < pict_get_xsize(p); x++) {
2183     /* lastpixelwas_gs=0; */
2184 greg 2.1 for (y = 0; y < pict_get_ysize(p); y++) {
2185     if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2186     if (pict_is_validpixel(p, x, y)) {
2187     act_lum = luminance(pict_get_color(p, x, y));
2188     if (act_lum > lum_source) {
2189     if (act_lum >lum_total_max) {
2190     lum_total_max=act_lum;
2191     }
2192 greg 2.3 /* speed improvement first scan: when last pixel was glare source, then use this glare source number instead of searching.
2193     has been deactivated with v1.25
2194    
2195     if (lastpixelwas_gs==0 || search_pix <= 1.0 ) { */
2196     actual_igs = find_near_pgs(p, x, y, max_angle, 0, igs, 1);
2197     /* }*/
2198 greg 2.1 if (actual_igs == 0) {
2199     igs = igs + 1;
2200     pict_new_gli(p);
2201     pict_get_lum_min(p, igs) = HUGE_VAL;
2202     pict_get_Eglare(p,igs) = 0.0;
2203     pict_get_Dglare(p,igs) = 0.0;
2204 greg 2.3 pict_get_z1_gsn(p,igs) = 0;
2205     pict_get_z2_gsn(p,igs) = 0;
2206 greg 2.1 actual_igs = igs;
2207 greg 2.3
2208 greg 2.1 }
2209 greg 2.3 /* no coloring any more here icol = setglcolor(p, x, y, actual_igs, uniform_gs, u_r, u_g , u_b); */
2210 greg 2.1 pict_get_gsn(p, x, y) = actual_igs;
2211     pict_get_pgs(p, x, y) = 1;
2212     add_pixel_to_gs(p, x, y, actual_igs);
2213 greg 2.3 /* lastpixelwas_gs=actual_igs; */
2214 greg 2.1
2215     } else {
2216     pict_get_pgs(p, x, y) = 0;
2217 greg 2.3 /* lastpixelwas_gs=0;*/
2218 greg 2.1 }
2219     }
2220     }
2221 greg 2.3 }
2222     }
2223 greg 2.1 /* pict_write(p,"firstscan.pic"); */
2224    
2225 greg 2.3
2226     if (calcfast == 1 || search_pix <= 1.0) {
2227 greg 2.1 skip_second_scan=1;
2228     }
2229    
2230     /* second glare source scan: combine glare sources facing each other */
2231     change = 1;
2232 greg 2.3 i = 0;
2233 greg 2.1 while (change == 1 && skip_second_scan==0) {
2234     change = 0;
2235 greg 2.3 i = i+1;
2236     for (x = 0; x < pict_get_xsize(p); x++) {
2237 greg 2.1 for (y = 0; y < pict_get_ysize(p); y++) {
2238     if (pict_get_hangle
2239     (p, x, y, p->view.vdir, p->view.vup, &ang)) {
2240 greg 2.3 checkpixels=1;
2241     before_igs = pict_get_gsn(p, x, y);
2242    
2243     /* speed improvement: search for other nearby glare sources only, when at least one adjacend pixel has another glare source number */
2244     if (x >1 && x<pict_get_xsize(p)-2 && y >1 && y<pict_get_ysize(p)-2 ) {
2245     x1=x-1;
2246     x2=x+1;
2247     y1=y-1;
2248     y2=y+1;
2249     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) ) {
2250     checkpixels = 0;
2251     actual_igs = before_igs;
2252     } }
2253    
2254    
2255     if (pict_is_validpixel(p, x, y) && before_igs > 0 && checkpixels==1) {
2256 greg 2.1 actual_igs =
2257     find_near_pgs(p, x, y, max_angle, before_igs,
2258     igs, 1);
2259     if (!(actual_igs == before_igs)) {
2260     change = 1;
2261     }
2262     if (before_igs > 0) {
2263     actual_igs = pict_get_gsn(p, x, y);
2264 greg 2.3 /* icol = setglcolor(p, x, y, actual_igs, uniform_gs, u_r, u_g , u_b); */
2265 greg 2.1 }
2266    
2267     }
2268     }
2269     }
2270     /* pict_write(p,"secondscan.pic");*/
2271 greg 2.3 }}
2272 greg 2.1
2273     /*smoothing: add secondary glare sources */
2274     i_max = igs;
2275     if (sgs == 1) {
2276    
2277     /* simplified search radius: constant for entire picture, alway circle not an angle due to performance */
2278     x = (pict_get_xsize(p) / 2);
2279     y = (pict_get_ysize(p) / 2);
2280     rx = (pict_get_xsize(p) / 2 + 10);
2281     ry = (pict_get_ysize(p) / 2 + 10);
2282     r_center =
2283     acos(DOT(pict_get_cached_dir(p, x, y),
2284     pict_get_cached_dir(p, rx, ry))) * 2 / 10;
2285     search_pix = max_angle / r_center / 1.75;
2286    
2287     for (x = 0; x < pict_get_xsize(p); x++) {
2288     for (y = 0; y < pict_get_ysize(p); y++) {
2289     if (pict_get_hangle
2290     (p, x, y, p->view.vdir, p->view.vup, &ang)) {
2291     if (pict_is_validpixel(p, x, y)
2292     && pict_get_gsn(p, x, y) == 0) {
2293     for (i = 1; i <= i_max; i++) {
2294    
2295     if (pict_get_npix(p, i) > 0) {
2296     add_secondary_gs(p, x, y, search_pix, i, uniform_gs, u_r, u_g , u_b);
2297     }
2298     }
2299    
2300     }
2301     }
2302     }
2303     }
2304    
2305     }
2306    
2307     /* extract extremes from glare sources to extra glare source */
2308     if (splithigh == 1 && lum_total_max>limit) {
2309    
2310     r_split = max_angle / 2.0;
2311     for (i = 0; i <= i_max; i++) {
2312    
2313     if (pict_get_npix(p, i) > 0) {
2314     l_max = pict_get_lum_max(p, i);
2315     i_splitstart = igs + 1;
2316     if (l_max >= limit) {
2317     for (x = 0; x < pict_get_xsize(p); x++)
2318     for (y = 0; y < pict_get_ysize(p); y++) {
2319     if (pict_get_hangle
2320     (p, x, y, p->view.vdir, p->view.vup, &ang))
2321     {
2322     if (pict_is_validpixel(p, x, y)
2323     && luminance(pict_get_color(p, x, y))
2324     >= limit
2325     && pict_get_gsn(p, x, y) == i) {
2326     if (i_splitstart == (igs + 1)) {
2327     igs = igs + 1;
2328     pict_new_gli(p);
2329 greg 2.3 pict_get_z1_gsn(p,igs) = 0;
2330     pict_get_z2_gsn(p,igs) = 0;
2331    
2332 greg 2.1 pict_get_Eglare(p,igs) = 0.0;
2333     pict_get_Dglare(p,igs) = 0.0;
2334     pict_get_lum_min(p, igs) =
2335     99999999999999.999;
2336     i_split = igs;
2337     } else {
2338     i_split =
2339     find_split(p, x, y, r_split,
2340     i_splitstart, igs);
2341     }
2342     if (i_split == 0) {
2343     igs = igs + 1;
2344     pict_new_gli(p);
2345 greg 2.3 pict_get_z1_gsn(p,igs) = 0;
2346     pict_get_z2_gsn(p,igs) = 0;
2347    
2348 greg 2.1 pict_get_Eglare(p,igs) = 0.0;
2349     pict_get_Dglare(p,igs) = 0.0;
2350     pict_get_lum_min(p, igs) =
2351     99999999999999.999;
2352     i_split = igs;
2353     }
2354     split_pixel_from_gs(p, x, y, i_split, uniform_gs, u_r, u_g , u_b);
2355    
2356     }
2357     }
2358     }
2359    
2360     }
2361     change = 1;
2362     while (change == 1) {
2363     change = 0;
2364     for (x = 0; x < pict_get_xsize(p); x++)
2365     for (y = 0; y < pict_get_ysize(p); y++) {
2366     before_igs = pict_get_gsn(p, x, y);
2367     if (before_igs >= i_splitstart) {
2368     if (pict_get_hangle
2369     (p, x, y, p->view.vdir, p->view.vup,
2370     &ang)) {
2371     if (pict_is_validpixel(p, x, y)
2372     && before_igs > 0) {
2373     actual_igs =
2374     find_near_pgs(p, x, y,
2375     max_angle,
2376     before_igs, igs,
2377     i_splitstart);
2378     if (!(actual_igs == before_igs)) {
2379     change = 1;
2380     }
2381     if (before_igs > 0) {
2382     actual_igs =
2383     pict_get_gsn(p, x, y);
2384 greg 2.3 /* icol =
2385 greg 2.1 setglcolor(p, x, y,
2386 greg 2.3 actual_igs, uniform_gs, u_r, u_g , u_b);*/
2387 greg 2.1 }
2388    
2389     }
2390     }
2391     }
2392    
2393     }
2394     }
2395    
2396    
2397     }
2398     }
2399     }
2400    
2401 greg 2.3 /* calculation of direct vertical illuminance for CGI and for disability glare, coloring glare sources*/
2402 greg 2.1
2403     if (calcfast == 0) {
2404     for (x = 0; x < pict_get_xsize(p); x++)
2405     for (y = 0; y < pict_get_ysize(p); y++) {
2406     if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2407     if (pict_is_validpixel(p, x, y)) {
2408     if (pict_get_gsn(p, x, y) > 0) {
2409 greg 2.3 actual_igs = pict_get_gsn(p, x, y);
2410     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));
2411     pict_get_Eglare(p,actual_igs ) = pict_get_Eglare(p,actual_igs ) + delta_E;
2412     E_v_dir = E_v_dir + delta_E;
2413     setglcolor(p, x, y, actual_igs, uniform_gs, u_r, u_g , u_b);
2414 greg 2.1 }
2415     }
2416     }
2417     }
2418     lum_backg_cos = (E_v - E_v_dir) / 3.1415927;
2419 greg 2.3
2420 greg 2.1 }
2421 greg 2.3 /* calc of band luminance distribution if applied */
2422 greg 2.1 if (band_calc == 1) {
2423 greg 2.3 x_max = pict_get_xsize(p) - 1;
2424     y_max = pict_get_ysize(p) - 1;
2425     y_mid = (int)(y_max/2);
2426     for (x = 0; x <= x_max; x++)
2427     for (y = 0; y <= y_max; y++) {
2428     if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2429     if (pict_is_validpixel(p, x, y)) {
2430    
2431     r_actual = acos(DOT(pict_get_cached_dir(p, x, y_mid), pict_get_cached_dir(p, x, y))) ;
2432     act_lum = luminance(pict_get_color(p, x, y));
2433    
2434     if ((r_actual <= band_angle) || (y == y_mid) ) {
2435     lum_band[0]=luminance(pict_get_color(p, x, y));
2436     muc_rvar_add_sample(s_band, lum_band);
2437     act_lum = luminance(pict_get_color(p, x, y));
2438     lum_band_av += pict_get_omega(p, x, y) * act_lum;
2439     omega_band += pict_get_omega(p, x, y);
2440     if (band_color == 1) {
2441     pict_get_color(p, x, y)[RED] = 0.0;
2442     pict_get_color(p, x, y)[GRN] = act_lum / WHTEFFICACY / CIE_gf;
2443     pict_get_color(p, x, y)[BLU] = 0.0;
2444     }
2445     }
2446     }}}
2447     lum_band_av=lum_band_av/omega_band;
2448     muc_rvar_get_vx(s_band,lum_band_std);
2449     muc_rvar_get_percentile(s_band,lum_band_median,0.75);
2450     per_75_band=lum_band_median[0];
2451     muc_rvar_get_percentile(s_band,lum_band_median,0.95);
2452     per_95_band=lum_band_median[0];
2453     muc_rvar_get_median(s_band,lum_band_median);
2454     muc_rvar_get_bounding_box(s_band,bbox_band);
2455    
2456     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] );
2457     /* av_lum = av_lum / omega_sum; */
2458     /* printf("average luminance of band %f \n",av_lum);*/
2459     /* printf("solid angle of band %f \n",omega_sum);*/
2460     }
2461 greg 2.1
2462     /*printf("total number of glare sources: %i\n",igs); */
2463     lum_sources = 0;
2464     omega_sources = 0;
2465 greg 2.3 i=0;
2466 greg 2.1 for (x = 0; x <= igs; x++) {
2467 greg 2.3 if (pict_get_npix(p, x) > 0) {
2468 greg 2.1 lum_sources += pict_get_av_lum(p, x) * pict_get_av_omega(p, x);
2469     omega_sources += pict_get_av_omega(p, x);
2470 greg 2.3 i=i+1;
2471     }}
2472    
2473     if (sang == omega_sources) {
2474     lum_backg =avlum;
2475     } else {
2476     lum_backg =(sang * avlum - lum_sources) / (sang - omega_sources);
2477 greg 2.1 }
2478 greg 2.3
2479    
2480     if (i == 0) {
2481     lum_sources =0.0;
2482     } else { lum_sources=lum_sources/omega_sources;
2483     }
2484    
2485    
2486    
2487     if (non_cos_lb == 0) {
2488     lum_backg = lum_backg_cos;
2489 greg 2.1 }
2490 greg 2.3
2491     /* file writing NOT here
2492     if (checkfile == 1) {
2493     pict_write(p, file_out);
2494     }
2495     */
2496    
2497 greg 2.1 /* print detailed output */
2498 greg 2.3
2499    
2500    
2501     /* masking */
2502    
2503     if ( masking == 1 ) {
2504    
2505    
2506     for (x = 0; x < pict_get_xsize(p); x++)
2507     for (y = 0; y < pict_get_ysize(p); y++) {
2508     if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2509     if (pict_is_validpixel(p, x, y)) {
2510     if (luminance(pict_get_color(pm, x, y))>0.1) {
2511     /* printf ("hallo %i %i %f \n",x,y,luminance(pict_get_color(pm, x, y)));*/
2512     i_mask=i_mask+1;
2513     lum_mask[0]=luminance(pict_get_color(p, x, y));
2514     /* printf ("%f \n",lum_mask[0]);*/
2515     muc_rvar_add_sample(s_mask, lum_mask);
2516     omega_mask += pict_get_omega(p, x, y);
2517     lum_mask_av += pict_get_omega(p, x, y)* luminance(pict_get_color(p, x, y));
2518     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));
2519    
2520     pict_get_color(pm, x, y)[RED] = luminance(pict_get_color(p, x, y))/179.0;
2521     pict_get_color(pm, x, y)[GRN] = luminance(pict_get_color(p, x, y))/179.0;
2522     pict_get_color(pm, x, y)[BLU] = luminance(pict_get_color(p, x, y))/179.0;
2523    
2524     } else {
2525     pict_get_color(p, x, y)[RED] = 0.0 ;
2526     pict_get_color(p, x, y)[GRN] = 0.0 ;
2527     pict_get_color(p, x, y)[BLU] = 0.0 ;
2528     }
2529     }
2530     }
2531     }
2532     /* Average luminance in masking area (weighted by solid angle) */
2533     lum_mask_av=lum_mask_av/omega_mask;
2534     muc_rvar_get_vx(s_mask,lum_mask_std);
2535     muc_rvar_get_percentile(s_mask,lum_mask_median,0.75);
2536     per_75_mask=lum_mask_median[0];
2537     muc_rvar_get_percentile(s_mask,lum_mask_median,0.95);
2538     per_95_mask=lum_mask_median[0];
2539     muc_rvar_get_median(s_mask,lum_mask_median);
2540     muc_rvar_get_bounding_box(s_mask,bbox);
2541     /* PSGV only why masking of window is applied! */
2542     pgsv = get_pgsv(E_v, E_v_mask, omega_mask, lum_mask_av);
2543     pgsv_sat =get_pgsv_sat(E_v);
2544 greg 2.5
2545     if (detail_out == 1) {
2546    
2547 greg 2.3 printf ("masking:no_pixels,omega,av_lum,median_lum,std_lum,perc_75,perc_95,lum_min,lum_max,pgsv,pgsv_sat: %i %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,pgsv_sat );
2548    
2549 greg 2.5 }
2550 greg 2.3
2551     }
2552    
2553     /* zones */
2554    
2555     if ( zones > 0 ) {
2556    
2557     for (x = 0; x < pict_get_xsize(p); x++)
2558     for (y = 0; y < pict_get_ysize(p); y++) {
2559     if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) {
2560     if (pict_is_validpixel(p, x, y)) {
2561    
2562    
2563     r_actual =acos(DOT(pict_get_cached_dir(p, x, y), pict_get_cached_dir(p, x_zone, y_zone))) * 2;
2564     lum_actual = luminance(pict_get_color(p, x, y));
2565     act_gsn=pict_get_gsn(p, x, y);
2566     /* 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));*/
2567    
2568     /*zone1 */
2569     if (r_actual <= angle_z1) {
2570     i_z1=i_z1+1;
2571     lum_z1[0]=lum_actual;
2572     muc_rvar_add_sample(s_z1, lum_z1);
2573     omega_z1 += pict_get_omega(p, x, y);
2574     lum_z1_av += pict_get_omega(p, x, y)* lum_actual;
2575     setglcolor(p,x,y,1,1 , 0.66, 0.01 ,0.33);
2576     /*check if separation gsn already exist */
2577    
2578     if (act_gsn > 0){
2579     if (pict_get_z1_gsn(p,act_gsn) == 0) {
2580     pict_new_gli(p);
2581     igs = igs + 1;
2582     pict_get_z1_gsn(p,act_gsn) = igs*1.000;
2583     pict_get_z1_gsn(p,igs) = -1.0;
2584     pict_get_z2_gsn(p,igs) = -1.0;
2585     splitgs=(int)(pict_get_z1_gsn(p,act_gsn));
2586     /* 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)); */
2587     }
2588     splitgs=(int)(pict_get_z1_gsn(p,act_gsn));
2589     /* printf("splitgs%i \n",splitgs); */
2590     split_pixel_from_gs(p, x, y, splitgs, uniform_gs, u_r, u_g , u_b);
2591     }
2592     }
2593     /*zone2 */
2594    
2595     if (r_actual > angle_z1 && r_actual<= angle_z2 ) {
2596    
2597     i_z2=i_z2+1;
2598     lum_z2[0]=lum_actual;
2599     muc_rvar_add_sample(s_z2, lum_z2);
2600     omega_z2 += pict_get_omega(p, x, y);
2601     lum_z2_av += pict_get_omega(p, x, y)* lum_actual;
2602     setglcolor(p,x,y,1,1 , 0.65, 0.33 ,0.02);
2603     /* 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));
2604     */ if (act_gsn > 0){
2605     if (pict_get_z2_gsn(p,act_gsn) == 0) {
2606     pict_new_gli(p);
2607     igs = igs + 1;
2608     pict_get_z2_gsn(p,act_gsn) = igs*1.000;
2609     pict_get_z1_gsn(p,igs) = -2.0;
2610     pict_get_z2_gsn(p,igs) = -2.0;
2611     /* printf ("Glare source %i gets glare source %i in zone 2 \n",act_gsn,igs ); */
2612     }
2613     splitgs=(int)(pict_get_z2_gsn(p,act_gsn));
2614     /* printf("splitgs %i \n",splitgs);*/
2615     split_pixel_from_gs(p, x, y, splitgs, uniform_gs, u_r, u_g , u_b);
2616     }
2617     }
2618    
2619     }
2620     } }
2621     /* Average luminance in zones (weighted by solid angle), calculate percentiles, median min and max in zones */
2622     if (zones == 2 ) {
2623     lum_z2_av=lum_z2_av/omega_z2;
2624     muc_rvar_get_vx(s_z2,lum_z2_std);
2625     muc_rvar_get_percentile(s_z2,lum_z2_median,0.75);
2626     per_75_z2=lum_z2_median[0];
2627     muc_rvar_get_percentile(s_z2,lum_z2_median,0.95);
2628     per_95_z2=lum_z2_median[0];
2629     muc_rvar_get_median(s_z2,lum_z2_median);
2630     muc_rvar_get_bounding_box(s_z2,bbox_z2);
2631     }
2632     lum_z1_av=lum_z1_av/omega_z1;
2633     muc_rvar_get_vx(s_z1,lum_z1_std);
2634     muc_rvar_get_percentile(s_z1,lum_z1_median,0.75);
2635     per_75_z1=lum_z1_median[0];
2636     muc_rvar_get_percentile(s_z1,lum_z1_median,0.95);
2637     per_95_z1=lum_z1_median[0];
2638     muc_rvar_get_median(s_z1,lum_z1_median);
2639     muc_rvar_get_bounding_box(s_z1,bbox_z1);
2640 greg 2.5 if (detail_out == 1) {
2641    
2642 greg 2.3 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: %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] );
2643    
2644 greg 2.4 if (zones == 2 ) {
2645 greg 2.3
2646     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: %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] );
2647 greg 2.5 } }
2648 greg 2.3
2649     }
2650    
2651 greg 2.1 i = 0;
2652     for (x = 0; x <= igs; x++) {
2653     /* resorting glare source numbers */
2654     if (pict_get_npix(p, x) > 0) {
2655     i = i + 1;
2656     }
2657     }
2658 greg 2.3 no_glaresources=i;
2659 greg 2.1
2660 greg 2.3 /* glare sources */
2661 greg 2.5 if (detail_out == 1) {
2662    
2663 greg 2.1 printf
2664 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",
2665 greg 2.1 i);
2666     if (i == 0) {
2667 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,
2668     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);
2669 greg 2.1
2670     } else {
2671     i = 0;
2672     for (x = 0; x <= igs; x++) {
2673     if (pict_get_npix(p, x) > 0) {
2674     i = i + 1;
2675     pict_get_sigma(p, pict_get_av_posx(p, x),
2676     pict_get_av_posy(p, x), p->view.vdir,
2677     p->view.vup, &sigma);
2678    
2679     x2=pict_get_av_posx(p, x);
2680     y2=pict_get_av_posy(p, x);
2681     teta = 180.0 / 3.1415927 * acos(DOT(p->view.vdir, pict_get_cached_dir(p, x2, y2)));
2682     Lveil_cie = 10*pict_get_Eglare(p,x)/(teta*teta+0.0000000000000001);
2683    
2684     if (apply_disability == 1 && Lveil_cie <=disability_thresh) {
2685     Lveil_cie =0 ;
2686     }
2687     Lveil_cie_sum = Lveil_cie_sum + Lveil_cie;
2688 greg 2.3 if (pict_get_z1_gsn(p,x)<0) {
2689     act_gsn=(int)(-pict_get_z1_gsn(p,x));
2690     }else{
2691     act_gsn=0;
2692     }
2693     printf("%i %f %f %f %f %.10f %f %f %f %f %f %f %f %f %f %f %f %f %f %i \n",
2694 greg 2.1 i, pict_get_npix(p, x), pict_get_av_posx(p, x),
2695     pict_get_ysize(p) - pict_get_av_posy(p, x),
2696     pict_get_av_lum(p, x), pict_get_av_omega(p, x),
2697     get_posindex(p, pict_get_av_posx(p, x),
2698     pict_get_av_posy(p, x),
2699     posindex_2), lum_backg, lum_task,
2700     E_v, E_v_dir, abs_max, sigma * 180 / 3.1415927
2701 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 );
2702 greg 2.1 }
2703     }
2704     }
2705     }
2706    
2707    
2708    
2709     /* calculation of indicees */
2710    
2711     /* check vertical illuminance range */
2712     E_v2 = E_v;
2713    
2714     if (E_v2 < 100) {
2715     fprintf(stderr,
2716     "Notice: Vertical illuminance is below 100 lux !!\n");
2717     }
2718     dgp =
2719     get_dgp(p, E_v2, igs, a1, a2, a3, a4, a5, c1, c2, c3, posindex_2);
2720     /* low light correction */
2721     if (E_v < 1000) {
2722     low_light_corr=1.0*exp(0.024*E_v-4)/(1+exp(0.024*E_v-4));} else {low_light_corr=1.0 ;}
2723     dgp =low_light_corr*dgp;
2724    
2725     /* age correction */
2726    
2727     if (age_corr == 1) {
2728     age_corr_factor=1.0/(1.1-0.5*age/100.0);
2729     }
2730     dgp =age_corr_factor*dgp;
2731    
2732    
2733     if (ext_vill == 1) {
2734     if (E_vl_ext < 100) {
2735     fprintf(stderr,
2736     "Notice: Vertical illuminance is below 100 lux !!\n");
2737     }
2738     }
2739    
2740     if (calcfast == 0) {
2741 greg 2.3 lum_a= E_v2/3.1415927;
2742 greg 2.1 dgi = get_dgi(p, lum_backg, igs, posindex_2);
2743     ugr = get_ugr(p, lum_backg, igs, posindex_2);
2744 greg 2.3 ugp = get_ugp (p,lum_backg, igs, posindex_2);
2745     ugr_exp = get_ugr_exp (p,lum_backg_cos,lum_a, igs, posindex_2);
2746     dgi_mod = get_dgi_mod(p, lum_a, igs, posindex_2);
2747 greg 2.1 cgi = get_cgi(p, E_v, E_v_dir, igs, posindex_2);
2748 greg 2.3 dgr = get_dgr(p, avlum, igs, posindex_2);
2749     vcp = get_vcp(dgr);
2750 greg 2.1 Lveil = get_disability(p, avlum, igs);
2751 greg 2.3 if (no_glaresources == 0) {
2752     dgi = 0.0;
2753     ugr = 0.0;
2754     ugp = 0.0;
2755     ugr_exp = 0.0;
2756     dgi_mod = 0.0;
2757     cgi = 0.0;
2758     dgr = 0.0;
2759     vcp = 100.0;
2760     }
2761 greg 2.1 }
2762     /* check dgp range */
2763     if (dgp <= 0.2) {
2764     fprintf(stderr,
2765     "Notice: Low brightness scene. dgp below 0.2! dgp might underestimate glare sources\n");
2766     }
2767     if (E_v < 380) {
2768     fprintf(stderr,
2769     "Notice: Low brightness scene. Vertical illuminance less than 380 lux! dgp might underestimate glare sources\n");
2770     }
2771    
2772    
2773    
2774     if (output == 0) {
2775     if (detail_out == 1) {
2776     if (ext_vill == 1) {
2777     dgp_ext =
2778     get_dgp(p, E_vl_ext, igs, a1, a2, a3, a4, a5, c1, c2, c3,
2779     posindex_2);
2780     dgp = dgp_ext;
2781     if (E_vl_ext < 1000) {
2782     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 ;}
2783     dgp =low_light_corr*dgp;
2784     dgp =age_corr_factor*dgp;
2785     }
2786 greg 2.3 muc_rvar_get_median(s_noposweight,lum_nopos_median);
2787     muc_rvar_get_median(s_posweight,lum_pos_median);
2788     muc_rvar_get_median(s_posweight2,lum_pos2_median);
2789    
2790    
2791 greg 2.1
2792 greg 2.3
2793 greg 2.1 printf
2794 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",
2795 greg 2.1 dgp, avlum, E_v, lum_backg, E_v_dir, dgi, ugr, vcp, cgi,
2796 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]);
2797 greg 2.1 } else {
2798     if (detail_out2 == 1) {
2799    
2800     printf
2801     ("dgp,dgi,ugr,vcp,cgi,dgp_ext,Ev_calc,abs_max,Lveil: %f %f %f %f %f %f %f %f %f \n",
2802     dgp, dgi, ugr, vcp, cgi, dgp_ext, E_v, abs_max,
2803     Lveil);
2804    
2805     } else {
2806     if (ext_vill == 1) {
2807     dgp_ext = get_dgp(p, E_vl_ext, igs, a1, a2, a3, a4, a5, c1, c2, c3,posindex_2);
2808    
2809     if (E_vl_ext < 1000) {
2810     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 ;}
2811     dgp =low_light_corr*dgp_ext;
2812     dgp =age_corr_factor*dgp;
2813     }
2814     printf("dgp,dgi,ugr,vcp,cgi,Lveil: %f %f %f %f %f %f \n",
2815     dgp, dgi, ugr, vcp, cgi, Lveil);
2816    
2817     }
2818     }
2819     } else {
2820     dgp_ext =
2821     get_dgp(p, E_vl_ext, igs, a1, a2, a3, a4, a5, c1, c2, c3,
2822     posindex_2);
2823     dgp = dgp_ext;
2824     if (E_vl_ext < 1000) {
2825     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 ;}
2826     dgp =low_light_corr*dgp;
2827     dgp =age_corr_factor*dgp;
2828     printf("%f\n", dgp);
2829     }
2830    
2831    
2832     /*printf("lowlight=%f\n", low_light_corr); */
2833    
2834    
2835     /* printf("hallo \n");
2836    
2837    
2838     apply_disability = 1;
2839     disability_thresh = atof(argv[++i]);
2840     coloring of disability glare sources red, remove all other colors
2841    
2842    
2843    
2844     this function was removed because of bugs....
2845     has to be re-written from scratch....
2846    
2847    
2848     */
2849    
2850    
2851    
2852    
2853    
2854    
2855    
2856    
2857     /*output */
2858     if (checkfile == 1) {
2859 greg 2.3
2860    
2861 greg 2.1 pict_write(p, file_out);
2862     }
2863    
2864    
2865    
2866     return EXIT_SUCCESS;
2867     exit(0);
2868    
2869     userr:
2870     fprintf(stderr,
2871     "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",
2872     progname);
2873     exit(1);
2874     }
2875    
2876    
2877    
2878     #endif