home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)pf2.c 2.3 10/2/92 LBL";
- #endif
-
- /*
- * pf2.c - routines used by pfilt.
- *
- * 10/3/85
- */
-
- #include <stdio.h>
-
- #include <math.h>
-
- #include "random.h"
-
- #include "color.h"
-
- #define PI 3.14159265359
-
- #define FTINY (1e-6)
-
- extern int nrows, ncols; /* number of rows and columns for output */
-
- extern int xres, yres; /* x and y resolution */
-
- extern int avghot; /* true means average in avgbrt spots */
-
- extern double hotlvl; /* brightness considered "hot" */
-
- extern int npts; /* # of points for stars */
-
- extern double spread; /* spread for star points */
-
- extern char *progname;
-
- extern COLOR exposure; /* exposure for frame */
-
- #define AVGLVL 0.5 /* target mean brightness */
-
- double avgbrt; /* average picture brightness */
-
- typedef struct hotpix { /* structure for avgbrt pixels */
- struct hotpix *next; /* next in list */
- COLOR val; /* pixel color */
- short x, y; /* pixel position */
- float slope; /* random slope for diffraction */
- } HOTPIX;
-
- HOTPIX *head; /* head of avgbrt pixel list */
-
- double sprdfact; /* computed spread factor */
-
-
- pass1init() /* prepare for first pass */
- {
- avgbrt = 0.0;
- head = NULL;
- }
-
-
- pass1default() /* for single pass */
- {
- avgbrt = AVGLVL * xres * yres;
- head = NULL;
- }
-
-
- pass1scan(scan, y) /* process first pass scanline */
- register COLOR *scan;
- int y;
- {
- extern char *malloc();
- double cbrt;
- register int x;
- register HOTPIX *hp;
-
- for (x = 0; x < xres; x++) {
-
- cbrt = bright(scan[x]);
-
- if (avghot || cbrt < hotlvl)
- avgbrt += cbrt;
-
- if (npts && cbrt >= hotlvl) {
- hp = (HOTPIX *)malloc(sizeof(HOTPIX));
- if (hp == NULL) {
- fprintf(stderr, "%s: out of memory\n",
- progname);
- quit(1);
- }
- copycolor(hp->val, scan[x]);
- hp->x = x;
- hp->y = y;
- hp->slope = tan(PI*(0.5-(random()%npts+0.5)/npts));
- hp->next = head;
- head = hp;
- }
- }
- }
-
-
- pass2init() /* prepare for final pass */
- {
- avgbrt /= (double)xres * yres;
-
- if (avgbrt <= FTINY) {
- fprintf(stderr, "%s: picture too dark\n", progname);
- quit(1);
- }
-
- scalecolor(exposure, AVGLVL/avgbrt);
-
- sprdfact = spread / (hotlvl * bright(exposure))
- * ((double)xres*xres + (double)yres*yres) / 4.0;
- }
-
-
- pass2scan(scan, y) /* process final pass scanline */
- register COLOR *scan;
- int y;
- {
- int xmin, xmax;
- register int x;
- register HOTPIX *hp;
-
- for (hp = head; hp != NULL; hp = hp->next) {
- if (hp->slope > FTINY) {
- xmin = (y - hp->y - 0.5)/hp->slope + hp->x;
- xmax = (y - hp->y + 0.5)/hp->slope + hp->x;
- } else if (hp->slope < -FTINY) {
- xmin = (y - hp->y + 0.5)/hp->slope + hp->x;
- xmax = (y - hp->y - 0.5)/hp->slope + hp->x;
- } else if (y == hp->y) {
- xmin = 0;
- xmax = xres-1;
- } else {
- xmin = 1;
- xmax = 0;
- }
- if (xmin < 0)
- xmin = 0;
- if (xmax >= xres)
- xmax = xres-1;
- for (x = xmin; x <= xmax; x++)
- starpoint(scan[x], x, y, hp);
- }
- for (x = 0; x < xres; x++)
- multcolor(scan[x], exposure);
- }
-
-
- starpoint(fcol, x, y, hp) /* pixel is on the star's point */
- COLOR fcol;
- int x, y;
- register HOTPIX *hp;
- {
- COLOR ctmp;
- double d2;
-
- d2 = (double)(x - hp->x)*(x - hp->x) + (double)(y - hp->y)*(y - hp->y);
- if (d2 > sprdfact) {
- d2 = sprdfact / d2;
- if (d2 < FTINY)
- return;
- copycolor(ctmp, hp->val);
- scalecolor(ctmp, d2);
- addcolor(fcol, ctmp);
- } else if (d2 > FTINY) {
- addcolor(fcol, hp->val);
- }
- }
-