bump.c 3.83 KB
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include <PRimage.h>
#ifndef __sgi__
#define fexp(x)		expf(x)
#define fsqrt(x)	sqrtf(x)
#endif

#define Sqrt2PiInv .398942280402

int ImageWidth  = 32;
int ImageHeight = 32;

int PhongFactor   = 1;
int UseGaussian   = 0;
float Deviation   = 1.0;
float ScaleFactor = 1.0;

unsigned short **OutputRed, **OutputGreen, **OutputBlue;

char *OutputFileName;

void usage(void)
{
    fprintf(stderr, "Usage: bump [[-h <height>] [-w <width>] [-o <filename>]] [-s scale] [-p phong] [-g [-d dist]]\n");
    fprintf(stderr, " height is output image height \n");
    fprintf(stderr, " width is output image width \n");
    fprintf(stderr, " filename is output file name \n");    
    fprintf(stderr, " -s specifies an overall scale factor to be applied to image \n");
    fprintf(stderr, " -p specifies exponent to be applied to phong result \n");
    fprintf(stderr, " -g specifies that a Gaussian instead of Phong distribution is desired \n");
    fprintf(stderr, " -d specifies Gaussian standard deviation \n");
    exit(1);
}

void MallocOutputArrays(void)
{
    int i;

    OutputRed   = (unsigned short **) malloc(ImageHeight * sizeof(unsigned short *));
    OutputGreen = (unsigned short **) malloc(ImageHeight * sizeof(unsigned short *));
    OutputBlue  = (unsigned short **) malloc(ImageHeight * sizeof(unsigned short *));

    for (i=0; i < ImageHeight; i++)
	{
	    OutputRed[i]   = (unsigned short *) malloc(ImageWidth * sizeof(unsigned short));
	    OutputGreen[i] = (unsigned short *) malloc(ImageWidth * sizeof(unsigned short));
	    OutputBlue[i]  = (unsigned short *) malloc(ImageWidth * sizeof(unsigned short));
	}
}

void WriteRGBFile(void)
{
    IMAGE *image;
    int i;

    if ((image = iopen(OutputFileName, "w", RLE(1), 3, ImageWidth, ImageHeight, 3)) == NULL)
	{
	    fprintf(stderr, "Error, could not open output file colorbar.rgb \n");
	    exit(1);
	}

    for (i = 0; i < ImageHeight ; i++)
	{
	    putrow(image, OutputRed[i],   ImageHeight - 1 - i, 0);
	    putrow(image, OutputGreen[i], ImageHeight - 1 - i, 1);
	    putrow(image, OutputBlue[i],  ImageHeight - 1 - i, 2);
	}

    iclose(image);
}

int Phong(float xf, float yf)
{
    int Nz;
    float zf;
		
    zf = 1.0 - xf*xf - yf*yf;
    if (zf < 0.0)
	Nz = 0;
    else
	Nz = (int) (255.0 * ScaleFactor * powf(fsqrt(zf), (float) PhongFactor) + 0.5);

    return(Nz > 255 ? 255 : Nz);    
}

int Gaussian(float xf, float yf)
{
    int Nz;
		
    Nz = (int) (0.5  + 255.0 * ScaleFactor * Sqrt2PiInv / Deviation * 
		fexp(- (xf*xf + yf*yf) / (2.0 * Deviation * Deviation)));
   
    return(Nz > 255 ? 255 : Nz);    
}

void FillOutputArrays(void)
{
    int x, y, Nz;
    float xf, yf;    

    for (y=0; y < ImageHeight; y++)
	{
	    for (x=0; x < ImageWidth; x++)
		{
		    xf = 2.0/((float) ImageWidth  - 1.0) * (float) x - 1.0;
		    yf = 2.0/((float) ImageHeight - 1.0) * (float) y - 1.0;
    
		    if (UseGaussian)
			Nz = Gaussian(xf, yf);
		    else
			Nz = Phong(xf, yf);

		    OutputRed[y][x]   = Nz;
		    OutputGreen[y][x] = Nz;
		    OutputBlue[y][x]  = Nz;
		}
	}
}

ParseOptions(int argc, char **argv)
{
    int c;
    extern char *optarg;

    while ((c = getopt(argc, argv, "gd:s:h:w:o:p:")) != EOF)
	switch (c)
	    {
	    case 'o':
		OutputFileName = strdup(optarg);
		break;
	    case 'h':
		ImageHeight = atoi(optarg);
		break;
	    case 'w':
		ImageWidth  = atoi(optarg);
		break;
	    case 'p':
		PhongFactor = atoi(optarg);
		break;
	    case 'g':
		UseGaussian = 1;
		break;
	    case 'd':
		Deviation = atof(optarg);
		break;
	    case 's':
		ScaleFactor = atof(optarg);
		break;

	    case '?':
		usage();
		break;		
	    }       

    if (OutputFileName == NULL)
	OutputFileName = strdup("bump.rgb");
}

main(int argc, char **argv)
{
    ParseOptions(argc, argv);
    MallocOutputArrays();
    FillOutputArrays();
    WriteRGBFile();
}