/***********************************************
 *  PS Encryptor.c
 *	
 *	This is sample code for the Acumen Journal
 *	This demonstrates how to convert PostScript 
 *	code into encrypted PostScript suitable for
 *	executing with eexec.
 ***********************************************/

#include <stdio.h>
#include <stdlib.h>


// Procedure declarations
int main(void);
void EncryptBuffer(unsigned char *, size_t);


// Constants
#define kSrcFileName	"source.ps"	// This is our clear-text PostScript
#define kDestFileName	"dest.ps"	// This will receive our encrypted PS
#define kBufferLength	4096

enum errorCode	{
	errNone = 0,
	errSrcFileFailed,
	errDestFileFailed,
	errMemoryFailed
};


int main(void)
{
	FILE			*src, *dest;
	unsigned char	*buffer;
	size_t			count;
	char			phoneyBytes[] = "WXYZ";	// Our initial phoney bytes
	
	src = fopen(kSrcFileName, "rb");		// Open our files
	if (!src)
		return errSrcFileFailed;
		
	dest = fopen(kDestFileName, "wb");
	if (!dest)	{
		fclose(src);
		return errDestFileFailed;
	}
	
	buffer = (unsigned char *)malloc(kBufferLength);	// Allocate a read buffer
	if (!buffer)	{
		fclose(src);
		fclose(dest);
		return errMemoryFailed;
	}
	
	fputs("%!PS\rcurrentfile eexec\r", dest);	// Put the eexec call into "dest"

	EncryptBuffer((unsigned char *)phoneyBytes,4);	// Encrypt the four phoney bytes...
	fwrite(phoneyBytes, 1, 4, dest);				// ...and write them to dest.
	
	while (!feof(src))	{						// While there's source PostScript remaining...
		count = fread(buffer, 1, kBufferLength, src);	// ...read some PostScript code...
		EncryptBuffer(buffer, count);					// ...encrypt it...
		fwrite(buffer, 1, count, dest);					// ...and write it to dest.
	}
	
	fclose(src);				// Tidy up
	fclose(dest);
	free(buffer);
	
	return errNone;
}


// See the Acumen Journal article (May 2001) for a description of this algorithm.
void EncryptBuffer(unsigned char *buffer, size_t len)
{
	static unsigned short 	r = 55665;
	static unsigned short 	c1 = 52845;
	static unsigned short 	c2 = 22719;
	unsigned char 			*b, *b0;			// current byte
	
	b0 = buffer + len;
	for (b = buffer; b < b0; b++)	{
		*b = (*b ^ (r >> 8));
		r = (*b + r) * c1 + c2;
	}
}
