//
//	Take a JamCam raw file and rearrange it into a format which
//	will compress well as a PNG file.  Calls pnmtopng to do the
//	compression.
//

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define PROGRAM "jc_pack_raw"

void 
error(char *fmt, ...) {
   va_list ap;
   va_start(ap, fmt);
   fprintf(stderr, PROGRAM ": ");
   vfprintf(stderr, fmt, ap);
   fprintf(stderr, "\n");
   exit(1);
}

void *Alloc(int size) {
   void *vp= calloc(1, size);
   if (!vp) error("Out of memory");
   return vp;
}

#define NL "\n"

void 
usage() {
   error("Usage:" NL
	 NL PROGRAM " <raw-in-file> <png-out-file>"
	 );
}

char *
load_file(char *fnam, int *lenp) {
   int fd, len;
   char *rv;

   fd= open(fnam, O_RDONLY);
   if (fd < 0) error("Can't open file: %s", fnam);

   len= lseek(fd, 0, SEEK_END);
   if (len < 0) error("Can't find file length: %s", fnam);

   lseek(fd, 0, SEEK_SET);

   rv= Alloc(len);
   if (len != read(fd, rv, len) ||
       0 != close(fd))
      error("Read error on file: %s", fnam);

   *lenp= len;
   return rv;
}

//
//	Globals
//

typedef unsigned char uchar;

int sx, sy;	// Image size
uchar *idata;	// Input data
uchar *odata;	// Output data


//
//	Main routine
//

int 
main(int ac, char **av) {
   ac--; av++;

   if (ac != 2) usage();

   // Load up raw data file into idata
   {
      int len= 0;
      idata= load_file(av[0], &len);
      if (len == 261600) {
	 sx= 600; sy= 436;
      } else if (len == 76800) {
	 sx= 320; sy= 240;
      } else {
	 error("Unknown JamCam raw file length: %d", len);
      }
   }

   // Copy input array to output array
   odata= Alloc(sx*sy);
   {
      int xx, yy, ox, oy;
      for (xx= 0; xx<sx; xx++) {
	 for (yy= 0; yy<sy; yy++) {
	    ox= (xx >> 1) + ((xx&1) ? sx/2 : 0);
	    oy= (yy >> 1) + ((yy&1) ? sy/2 : 0);
	    odata[ox+oy*sx]= idata[xx+yy*sx];
	 }
      }
   }

   // Write output and pack into png
   {
      char buf[256];
      FILE *out;

      snprintf(buf, sizeof(buf), "pnmtopng -compression 9 >%s", av[1]);
      out= popen(buf, "w");
      if (!out) error("Can't start pnmtopng tool");
      
      fprintf(out, "P5\n%d %d\n255\n", sx, sy);
      if (1 != fwrite(odata, sx*sy, 1, out)) 
	 error("Write error to pnmtopng tool");

      if (pclose(out))
	 error("Write error to pnmtopng tool");
   }

   return 0;
}
      
// END //

