Back to index

radiance  4R0+20100331
pf2.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: pf2.c,v 2.7 2004/03/28 20:33:14 schorsch Exp $";
00003 #endif
00004 /*
00005  *  pf2.c - routines used by pfilt.
00006  */
00007 
00008 #include  <stdio.h>
00009 #include  <stdlib.h>
00010 #include  <math.h>
00011 
00012 #include  "rterror.h"
00013 #include  "random.h"
00014 #include  "color.h"
00015 #include  "pfilt.h"
00016 
00017 #define        PI           3.14159265359
00018 #define        FTINY        (1e-6)
00019 
00020 #define        AVGLVL              0.5    /* target mean brightness */
00021 
00022 double avgbrt;                     /* average picture brightness */
00023 long   npix;                /* # pixels in average */
00024 
00025 typedef struct       hotpix {      /* structure for avgbrt pixels */
00026        struct hotpix  *next;       /* next in list */
00027        COLOR  val;          /* pixel color */
00028        short  x, y;         /* pixel position */
00029        float  slope;        /* random slope for diffraction */
00030 }  HOTPIX;
00031 
00032 HOTPIX *head;               /* head of avgbrt pixel list */
00033 
00034 double sprdfact;            /* computed spread factor */
00035 
00036 static void starpoint(COLOR  fcol, int  x, int  y, HOTPIX       *hp);
00037 
00038 
00039 extern void
00040 pass1init(void)                    /* prepare for first pass */
00041 {
00042        avgbrt = 0.0;
00043        npix = 0;
00044        head = NULL;
00045 }
00046 
00047 
00048 extern void
00049 pass1default(void)                 /* for single pass */
00050 {
00051        avgbrt = AVGLVL;
00052        npix = 1;
00053        head = NULL;
00054 }
00055 
00056 
00057 extern void
00058 pass1scan(           /* process first pass scanline */
00059        register COLOR       *scan,
00060        int  y
00061 )
00062 {
00063        double cbrt;
00064        register int  x;
00065        register HOTPIX       *hp;
00066 
00067        for (x = 0; x < xres; x++) {
00068        
00069               cbrt = (*ourbright)(scan[x]);
00070 
00071               if (cbrt <= 0)
00072                      continue;
00073 
00074               if (avghot || cbrt < hotlvl) {
00075                      avgbrt += cbrt;
00076                      npix++;
00077               }
00078               if (npts && cbrt >= hotlvl) {
00079                      hp = (HOTPIX *)malloc(sizeof(HOTPIX));
00080                      if (hp == NULL) {
00081                             fprintf(stderr, "%s: out of memory\n",
00082                                           progname);
00083                             quit(1);
00084                      }
00085                      copycolor(hp->val, scan[x]);
00086                      hp->x = x;
00087                      hp->y = y;
00088                      hp->slope = tan(PI*(0.5-(random()%npts+0.5)/npts));
00089                      hp->next = head;
00090                      head = hp;
00091               }
00092        }
00093 }
00094 
00095 
00096 extern void
00097 pass2init(void)                    /* prepare for final pass */
00098 {
00099        if (!npix) {
00100               fprintf(stderr, "%s: picture too dark or too bright\n",
00101                             progname);
00102               quit(1);
00103        }
00104        avgbrt /= (double)npix;
00105 
00106        scalecolor(exposure,  AVGLVL/avgbrt);
00107        
00108        sprdfact = spread / (hotlvl * (*ourbright)(exposure))
00109                      * ((double)xres*xres + (double)yres*yres) / 4.0;
00110 }
00111 
00112 
00113 extern void
00114 pass2scan(           /* process final pass scanline */
00115        register COLOR       *scan,
00116        int  y
00117 )
00118 {
00119        int  xmin, xmax;
00120        register int  x;
00121        register HOTPIX       *hp;
00122        
00123        for (hp = head; hp != NULL; hp = hp->next) {
00124               if (hp->slope > FTINY) {
00125                      xmin = (y - hp->y - 0.5)/hp->slope + hp->x;
00126                      xmax = (y - hp->y + 0.5)/hp->slope + hp->x;
00127               } else if (hp->slope < -FTINY) {
00128                      xmin = (y - hp->y + 0.5)/hp->slope + hp->x;
00129                      xmax = (y - hp->y - 0.5)/hp->slope + hp->x;
00130               } else if (y == hp->y) {
00131                      xmin = 0;
00132                      xmax = xres-1;
00133               } else {
00134                      xmin = 1;
00135                      xmax = 0;
00136               }
00137               if (xmin < 0)
00138                      xmin = 0;
00139               if (xmax >= xres)
00140                      xmax = xres-1;
00141               for (x = xmin; x <= xmax; x++)
00142                      starpoint(scan[x], x, y, hp);
00143        }
00144        for (x = 0; x < xres; x++)
00145               multcolor(scan[x], exposure);
00146 }
00147 
00148 
00149 static void
00150 starpoint(           /* pixel is on the star's point */
00151        COLOR  fcol,
00152        int  x,
00153        int  y,
00154        register HOTPIX       *hp
00155 )
00156 {
00157        COLOR  ctmp;
00158        double d2;
00159        
00160        d2 = (double)(x - hp->x)*(x - hp->x) + (double)(y - hp->y)*(y - hp->y);
00161        if (d2 > sprdfact) {
00162               d2 = sprdfact / d2;
00163               if (d2 < FTINY)
00164                      return;
00165               copycolor(ctmp, hp->val);
00166               scalecolor(ctmp, d2);
00167               addcolor(fcol, ctmp);
00168        } else if (d2 > FTINY) {
00169               addcolor(fcol, hp->val);
00170        }
00171 }