// Tabs:3 Indent:3

/*
 * JPEGFilter.m, Independent JPEG Group's (JFIF) image filter service.
 * Author: Michael McCulloch
 * From example code by: Ali T. Ozer, NeXT Computer, Inc.
 * Written for 3.2, January 15, 1994.
 *
 * You may freely copy, distribute and reuse the code in this example.
 * There is no warranty of any kind, expressed or implied, as to its
 * fitness for any particular use.
 */

#import	<appkit/appkit.h>

extern NXBitmapImageRep *convertJPEGToTIFF(const char *imageFile, float gammaFactor, BOOL showMessage);


@interface JPEGConverter : Object
{
	float gammaFactor;
	BOOL showMessage;
}

- init;
- convertToTIFF:pb userData:(const char *)userData error:(char **)errorMessage;
@end



@implementation JPEGConverter

- init
{
	static const NXDefaultsVector myDefaults = {
		{"JPEGgamma", "1.5"},{"showMessages", "1"},{NULL, NULL}
	};
 
	self = [super init];
	NXRegisterDefaults("McFilter", myDefaults);
	gammaFactor = atof(NXGetDefaultValue("McFilter", "JPEGgamma"));
	showMessage = (BOOL)atoi(NXGetDefaultValue("McFilter", "showMessages")); 
  
	return self;
}

- convertToTIFF:pasteboard userData:(const char *)userData 
          error:(char **)errorMessage
{
	static NXAtom typesThatCanBeConverted[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
	NXAtom typeToBeConverted;
	char fileToBeConverted[MAXPATHLEN+1];
	char *imageFile = NULL;
	const char *gammaDefault;
	const char *messageDefault;

	if(!typesThatCanBeConverted[0]){
		typesThatCanBeConverted[0] = NXCreateFilenamePboardType("jpg");
		typesThatCanBeConverted[1] = NXCreateFilenamePboardType("jpeg");
		typesThatCanBeConverted[2] = NXCreateFilenamePboardType("JPG");
		typesThatCanBeConverted[3] = NXCreateFilenamePboardType("JPEG");
		typesThatCanBeConverted[4] = NXCreateFilenamePboardType("jff");
		typesThatCanBeConverted[5] = NXCreateFilenamePboardType("jfif");
		typesThatCanBeConverted[6] = NULL;
	}

	if(typeToBeConverted = [pasteboard findAvailableTypeFrom:typesThatCanBeConverted num:4]){
		char *data, *separator, *extension;
		int dataLen;
		[pasteboard readType:typeToBeConverted data:&data length:&dataLen];
		if(data && dataLen){
			// Copy the name of the first file in the file list into "path"
			// (Usually there will only be one file, but don't take any chances!)
			int strLen = (separator = index(data, '\t')) ? (separator - data) : dataLen;
			strncpy(fileToBeConverted, data, strLen);
			fileToBeConverted[strLen] = 0;
			// Make sure the file extension is what we want. If not, we punt.
			extension = rindex(fileToBeConverted, '.');
			if(extension && ((strcmp(extension, ".jpg") == 0) 
					||  (strcmp(extension, ".jpeg") == 0)
					||  (strcmp(extension, ".JPG") == 0)
					||  (strcmp(extension, ".JPEG") == 0)
					||  (strcmp(extension, ".jff") == 0)
					||  (strcmp(extension, ".jfif") == 0))){
				imageFile = fileToBeConverted;
			}
		}
		// Deallocate the file name list
		[pasteboard deallocatePasteboardData:data length:dataLen];
	}

	/* go ahead and convert if stream was successfully opened */
	if(imageFile){
		NXBitmapImageRep *tiffImage = nil;
		NXStream *tiffStream = NULL;
		if((gammaDefault = NXUpdateDefault("McFilter","JPEGgamma")) != NULL)
			gammaFactor = atof(gammaDefault);
		if((messageDefault = NXUpdateDefault("McFilter", "showMessages")) != NULL)
			showMessage = (BOOL)atoi(messageDefault);

		NX_DURING
#ifdef DEBUG
			fprintf(stderr, "Called JPEGToTIFF for %s.\n", fileToBeConverted);
#endif
			if(tiffImage = convertJPEGToTIFF(imageFile,gammaFactor,showMessage)){
				tiffStream = NXOpenMemory (NULL, 0, NX_READWRITE);
				[tiffImage writeTIFF:tiffStream];
				[pasteboard declareTypes:&NXTIFFPboardType num:1 owner:self];
				[pasteboard writeType:NXTIFFPboardType fromStream:tiffStream];
			}
		NX_HANDLER
			NXLogError("Error occurred while converting file %s:",fileToBeConverted);
			NXReportError(&NXLocalHandler);
		NX_ENDHANDLER
  
		if(tiffImage){
			[tiffImage free];
		}

		if(tiffStream) NXCloseMemory (tiffStream, NX_FREEBUFFER);
		imageFile = NULL;
	}

	return self;
}

@end


int main(int argc, char **argv)
{
	id listener = [Listener new];
	[listener setServicesDelegate:[JPEGConverter new]];
	[listener checkInAs:"JPEG Converter"];
	[listener addPort];
	[Listener run];
}

