
/* Generated by Interface Builder */

#import "ToTIFF.h"
#import <appkit/Form.h>
#import <streams/streams.h>
#import <appkit/Application.h>
#import <appkit/OpenPanel.h>
#import <appkit/NXImage.h>
#import <appkit/NXBitmapImageRep.h>
#import <appkit/Button.h>
#import <appkit/Control.h>
#import <appkit/SavePanel.h>
#import <appkit/tiff.h>
#import <dpsclient/psops.h>
#import <dpsclient/wraps.h>
#import <sys/param.h>
#import <stdio.h>
#import <stdlib.h>
#import <strings.h>


@implementation ToTIFF

#define WIDTH		256
#define HEIGHT		256
#define	BITMAPDIRECTORY	"Library/Images/bitmaps"
#define	REDFILE		"b7"
#define	GREENFILE	"b4"
#define BLUEFILE	"b2"
#define STARTFRAME	1
#define ENDFRAME	40
#define LZW		0
#define PACKBITS	1
#define	JPEG		2
#define	NONE		3
#define FALSE		0
#define TRUE		!FALSE

void prefixdirectory(char *dirname, char *filename)
{
	char *tmp;
	tmp = (char *)malloc(200);
	strcpy(tmp, dirname);
	if(strcmp(&tmp[strlen(tmp)-1],"/"))  strcat(tmp,"/");
	strcat(tmp, filename);
	strcpy(filename, tmp);
	free(tmp);
}

void postfixframe(char *filename, int frameInt)
{
	char *frameString;
	frameString = (char *)malloc(6);
	if(strcmp(&filename[strlen(filename)-1],"."))  strcat(filename,".");
	sprintf(frameString, "%d", frameInt);
	strcat(filename, frameString);
	free(frameString);
}

unsigned char *loadbyteimage(char *imagename, int *bytecount)
{
	NXStream *stream;
	char *streambuffer=NULL;
	int length, maxlength;
	if ((stream = NXMapFile(imagename, NX_READONLY)) != NULL) {
    		NXGetMemoryBuffer(stream, &streambuffer, &length, &maxlength);
		*bytecount = length;
		NXClose(stream);
		return((unsigned char *)streambuffer);
	} else {
    		NXRunAlertPanel("Error Opening File",
				"Filename: %s","OK",NULL,NULL,imagename);
		return(NULL);
	}
}


unsigned char *equalizebyteimage(unsigned char *buffer, int bytecount)
{
	long int histogram[256], fill;
	int i=0;
	unsigned char *cursor;
/* point to the start of the image data  */
	cursor=buffer;
/* zero the histogram array  */
	for(i=0;i<256;i++)   histogram[i]=0L;
/* count up each byte value and store it in the histogram array  */
	i=0;
	while(i++<bytecount) histogram[(unsigned int)*(cursor++)]++;
/* compute the cumulative histogram  */
	for(i=1;i<256;i++)   histogram[i]=histogram[i]+histogram[i-1];
/* Check that the total counts are correct!!!          */
/* If so, then normalize the cumulative histogram and  */
/*      compute and return the equalized buffer;       */
/*  if not, then alert the user.                       */
	if(histogram[255]==bytecount) {
		fill=histogram[0];
		for(i=0;i<256;i++)histogram[i]=
			255*(histogram[i]-fill)
			/(histogram[255]-fill);
		cursor=buffer; 
		i=0;
		while(i++<bytecount){
		   *cursor=(unsigned char)histogram[(unsigned int)*cursor]; 
		    cursor++;
		}
		return(buffer);
	}  else {
		NXRunAlertPanel("Error in Cumulative Histogram count",
				"bytecount=%d != histogram[255]= %d",
				"OK",NULL,NULL,bytecount, histogram[255]);
		return(NULL);
	}
}

- setDefaults:sender
{

	char *home, *bitmapdirectory;
	home = (char *)malloc(100);
	bitmapdirectory = (char *)malloc(200);
	strcpy(home,getenv("HOME"));
	strcpy(bitmapdirectory, BITMAPDIRECTORY);
	prefixdirectory(home, bitmapdirectory);
/* initialize bitmapinfo table with default values  */
	[bitmapinfo setIntValue:WIDTH at:0];
	[bitmapinfo setIntValue:HEIGHT at:1];
	[bitmapinfo setStringValue:bitmapdirectory at:2];
	[bitmapinfo setStringValue:REDFILE at:3];
	[bitmapinfo setStringValue:GREENFILE at:4];
	[bitmapinfo setStringValue:BLUEFILE at:5];
	[bitmapinfo setIntValue:STARTFRAME at:6];
	[bitmapinfo setIntValue:ENDFRAME at:7];
/* initialize compression type with default value   */
	compression = NX_TIFF_COMPRESSION_JPEG;
	[compressiontype selectCellAt:JPEG:0];
/* initialize equalize switch with default value   */
	equalize = FALSE;
	[equalizeswitch setState:equalize];
	return self;
}

- doLZW:sender
{
	compression = NX_TIFF_COMPRESSION_LZW;
	[compressiontype selectCellAt:LZW:0];
	return self;
}
	
- doPACKBITS:sender
{
	compression = NX_TIFF_COMPRESSION_PACKBITS;
	[compressiontype selectCellAt:PACKBITS:0];
	return self;
}

- doJPEG:sender
{
	compression = NX_TIFF_COMPRESSION_JPEG;
	[compressiontype selectCellAt:JPEG:0];
	return self;
}

- doNONE:sender
{
	compression = NX_TIFF_COMPRESSION_NONE;
	[compressiontype selectCellAt:NONE:0];
	return self;
}


- doEQUALIZE:sender
{
	equalize = ![equalizeswitch state];
	[equalizeswitch setState:equalize];
	return self;
}

- toTIFFMethod:sender
{
    	char filename[MAXPATHLEN+1], tempfilename[MAXPATHLEN+1];
	id myImage;
	unsigned char *myImagePlanes[3];
	int width, height, startframe, endframe, currentframe;
	int bytecount, redbytes=0, greenbytes=0, bluebytes=0;
	char *bitmapsdirectory, *redfile, *greenfile, *bluefile;
	char *tempredfile, *tempgreenfile, *tempbluefile;
	unsigned char *redbuffer=NULL, *greenbuffer=NULL, *bluebuffer=NULL;
	
/* allocate space for strings  */
	bitmapsdirectory = (char *)malloc(100);
	redfile = (char *)malloc(200);
	greenfile = (char *)malloc(200);
	bluefile = (char *)malloc(200);
	tempredfile = (char *)malloc(200);
	tempgreenfile = (char *)malloc(200);
	tempbluefile = (char *)malloc(200);


/* store user's table entries into variables	 */
	width = [bitmapinfo intValueAt:0];
	height = [bitmapinfo intValueAt:1];
	strcpy(bitmapsdirectory, [bitmapinfo stringValueAt:2]);
	strcpy(redfile, [bitmapinfo stringValueAt:3]);
	strcpy(greenfile,[bitmapinfo stringValueAt:4]);
	strcpy(bluefile, [bitmapinfo stringValueAt:5]);
	startframe = [bitmapinfo intValueAt:6];
	endframe = [bitmapinfo intValueAt:7];

/* prefix redfile, greenfile and bluefile with bitmapsdirectory  */
 	prefixdirectory(bitmapsdirectory, redfile);
	prefixdirectory(bitmapsdirectory,  greenfile);
	prefixdirectory(bitmapsdirectory, bluefile);
    
   	bytecount = width*height;
	
/*  read in the frames, beginning with startframe, ending with endframe    */
	currentframe = startframe;
	while(currentframe <= endframe) {
	
/*  tack the current frame number onto the end of each filename   */
		strcpy(tempredfile, redfile);
		strcpy(tempgreenfile, greenfile);
		strcpy(tempbluefile, bluefile);
		postfixframe(tempredfile, currentframe);
		postfixframe(tempgreenfile, currentframe);
		postfixframe(tempbluefile, currentframe);
	
/* read in the bitmap files for this particular frame  */	
/*         and put bytes into 3 buffers                */
		if((redbuffer = loadbyteimage(tempredfile, &redbytes))==NULL)
			return self;
		if((greenbuffer = loadbyteimage(tempgreenfile, &greenbytes))==NULL)
			return self;
		if((bluebuffer = loadbyteimage(tempbluefile, &bluebytes))==NULL)
			return self;
	
	
		if ((redbytes==bytecount)&&(greenbytes==bytecount)&&(bluebytes==bytecount))
		{
	
	/* apply appropriate stretch, if requested  */
		if(equalize) {
		if(equalizebyteimage(redbuffer, redbytes)==NULL) return self;
		if(equalizebyteimage(greenbuffer,greenbytes)==NULL)return self;
		if(equalizebyteimage(bluebuffer, bluebytes)==NULL)return self;
		}

	
	/* assign them to myImagePlanes     */
			myImagePlanes[0] = (unsigned char *)redbuffer;
			myImagePlanes[1] = (unsigned char *)greenbuffer;
			myImagePlanes[2] = (unsigned char *)bluebuffer;
	
			myImage = [[NXBitmapImageRep alloc]
			initDataPlanes:myImagePlanes
				pixelsWide:width
				pixelsHigh:height
				bitsPerSample:8
				samplesPerPixel:3
				hasAlpha:NO
				isPlanar:YES
				colorSpace:NX_RGBColorSpace
				bytesPerRow:width
				bitsPerPixel:8];
	
 			if (myImage)  {
				NXStream *s = NXOpenMemory (NULL, 0, NX_READWRITE);
				if(currentframe == startframe) {
					id mySavePanel = [SavePanel new];
    					[mySavePanel runModal];
    					if([mySavePanel filename]) strcpy(filename,[mySavePanel filename]);
				}
				strcpy(tempfilename, filename);
				postfixframe(tempfilename, currentframe);
      				strcat(tempfilename,".tiff");
      				if (s) {
        				[myImage writeTIFF:s usingCompression:compression];
        				NXFlush (s);
        				if (NXSaveToFile (s, tempfilename))
          					NXRunAlertPanel("Error Saving File",
				      	 "Filename: %s","OK",NULL,NULL,filename);
        				NXCloseMemory (s, NX_FREEBUFFER);
      				}
    			}
    			[myImage free];
		}  else {
			NXRunAlertPanel("Incorrect byte count !",
			"%d in red, %d in blue, %d in green.\nAll should = width*height = %d",
			"OK",NULL,NULL,redbytes, greenbytes, bluebytes, bytecount);
		}
		currentframe++;
	}
  	return self;
}


@end
