/*
 *   fixPEF.c		Modify PEF image files by adding "Corporation" after
 *			"Pentax" to allow files created under K20D firmware 1.01
 *			to be read by RAW workflow applications like Aperture,
 *			CaptureOne, etc.
 *			The program takes 2 arguments:
 *			1. input filename
 *			2. output filename
 *
 *   Author: Allan Packer
 *   Date: 23 June 2008
 *
 *   Copyright Notice: This software may be freely copied and used on condition
 *   that the user acknowledges they do so at their own risk.
 *   In providing this software, the author does not warrant or imply its
 *   fitness for any particular purpose.
 */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

void openData( char* inName, char* outName );
void convData( int fpin, int fpout, char* inName, char* outName );

int main(int argc, char **argv)
{
	int		i;
	char	inName[4097], outName[4097];
	
	if (argc <2 ) {
		fprintf(stderr, "usage: %s fnamein...\n",
				argv[0], argv[1]);
		exit(1);
	}
	
	for( i = 1; i < argc; i++ ) {
		// main loop
		strcpy( inName, argv[i] );
		strcpy( outName, inName + 1);
		openData( inName, outName );
	}

	return 0;
}

void openData( char* inName, char* outName ) {
	int fpin,fpout, inbytes, outbytes;
	char	inbuff[4097], *pinbuff = &inbuff[0];
	
	if ((fpin = open(inName, O_RDONLY)) == -1) {
		fprintf(stderr, "Unable to open %s for reading\n", inName);
		exit(1);
	}
	if ((fpout = open(outName, O_CREAT|O_TRUNC|O_RDWR|O_APPEND, (mode_t)0644)) == -1) {
		fprintf(stderr, "Unable to open %s for writing\n", outName);
		exit(1);
	}
	if ((inbytes = read(fpin, (void *)pinbuff, 249)) == -1) {
		fprintf(stderr, "Error reading from %s, errno=%d\n",
				inName, errno);
		exit(1);
	}
	if ((outbytes = write(fpout, (void *)pinbuff, 249)) == -1) {
		fprintf(stderr, "Error writing to %s, errno=%d\n",
				outName, errno);
		exit(1);
	}
	if (outbytes != inbytes) {
		fprintf(stderr, "Error: %d bytes written to %s instead of %d\n", outbytes, outName, inbytes);
		exit(1);
	}
	convData( fpin, fpout, inName, outName);
}

void convData( int fpin, int fpout, char* inName, char* outName ) {
	int inbytes, outbytes, count=0;
	char	inbuff[4097], *pinbuff = &inbuff[0];
	char	*pin, *pout;
	char	*pfixstr = "Corporation";
	
	while ((inbytes = read(fpin, (void *)pinbuff, 4096)) != -1) {
		if (!inbytes) {
			close(fpin);
			close(fpout);
			return;
		}
		if (!count++) {
			pin = pfixstr;
			pout = pinbuff;
			while (*pin != '\0')
				*pout++ = *pin++;
		}
		if ((outbytes = write(fpout, (void *)pinbuff, inbytes)) == -1) {
			fprintf(stderr, "Error writing to %s, errno=%d\n",
					outName, errno);
			exit(1);
		}
		else {
			if (outbytes != inbytes) {
				fprintf(stderr, "Error: %d bytes written to %s instead of %d\n", outbytes, outName, inbytes);
				exit(1);
			}
		}
	}
	fprintf(stderr, "Error reading from %s, errno=%d\n", inName, errno);
	exit(1);
	
}