/*****************************************************************
*
* Program to generate and write namy images of many different sizes
* as RISs, then read them back and verify their correctness.
*
* User supplies number of images and file name.
*
* NOTE: Currently does not test imcomp compression.
*
******************************************************************/

#include "df.h"
#include <stdio.h>

#ifdef UNICOS
#define RAND_MAX 32767.0
#else
#define RAND_MAX 2147483648.0
#endif

#define RND(max) ((int) (( rand() / RAND_MAX) * max))
#define NUM_PAL  2
#define PAL_SIZE 768
#define DIM_MAX  100.0
#define TRUE	 1
#define FALSE	 0

typedef struct {
  int xdim, ydim;
  char *img;
  char *pal;
  int comp;
} record;

record *rec;

char *palette[NUM_PAL];

void putImages();
void checkImages();
char *randArray();
char *calloc();
char *malloc();

main(argc, argv)
     int argc;
     char *argv[];
{
  int i, numImages;
  char *fname;

  if (argc < 3) {
    puts("Usage :");
    printf("\t%s <# image> <file name>\n", argv[0]);
    exit(1);
  }

  numImages = atoi(argv[1]);
  fname = argv[2];
  printf("Test invoked with %d images and file %s.\n", numImages, fname);

  srand(getpid());
  rec = (record *) calloc(numImages, sizeof(record));
  if (rec == NULL) {
    puts("--Calloc error");
    exit(1);
  }

  for (i=0;i<NUM_PAL;i++)
    palette[i] = randArray(PAL_SIZE);

  printf("\n===== Now putting images ==============\n\n");
  putImages(fname, numImages);
  printf("\n\n===== Now checking images ==============\n\n");
  checkImages(fname, numImages);
}

void
putImages(fname, numImages)
     char *fname;
     int numImages;
{
  int i, ret;
  int firstImage = TRUE;

  for (i=0;i<numImages;i++) {
    printf("Putting image %d.\n", i);

    rec[i].xdim = RND(DIM_MAX) + 1; /* add 1 so range from 1 to 100 */
    rec[i].ydim = RND(DIM_MAX) + 1;
    rec[i].img = randArray(rec[i].xdim * rec[i].ydim);
    rec[i].comp = rndCompress();

    if (rec[i].comp == DFTAG_IMC)  /* REMOVE THIS WHEN IMCOMP IS FIXED */
      rec[i].comp = DFTAG_RLE;

    if (RND(2) || (rec[i].comp == DFTAG_IMC))
      rec[i].pal = palette[RND(NUM_PAL)];
    else
      rec[i].pal = NULL;



    printf("Image %d stats : %d * %d, %d compress scheme.\n",
	   i, rec[i].xdim, rec[i].ydim, rec[i].comp);

    ret = DFR8setpalette(rec[i].pal);
    printf("DFR8setpalette return %d.\n", ret);

    if (firstImage) {
      ret = DFR8putimage(fname, rec[i].img, rec[i].xdim,
			 rec[i].ydim, rec[i].comp);
      printf("DFR8putimage return %d.\n", ret);
      firstImage = FALSE;
    }
    else {
      ret = DFR8addimage(fname, rec[i].img, rec[i].xdim,
			 rec[i].ydim, rec[i].comp);
      printf("DFR8addimage return %d.\n", ret);
    }
    if (ret)
      printf("DFerror %d.\n", DFerror);
  }
}

void
checkImages(fname, numImages)
     char *fname;
     int numImages;
{
  int i, xdim, ydim, ispal, ret;
  char space[10000], pal[768];

  for (i=0;i<numImages;i++) {
    printf("checkImages image %d.\n", i);

    ret = DFR8getdims(fname, &xdim, &ydim, &ispal);
    printf("DFR8getdims return %d.\n", ret);
    if (ret) {
      printf("DFerror %d.\n", DFerror);
      exit(1);
    }
    printf("DFR8getdims %s, %d * %d, %d palette.\n", fname, xdim, ydim, ispal);

    if (rec[i].xdim != xdim)
      puts("xdim is wrong!!");
    if (rec[i].ydim != ydim)
      puts("ydim is wrong!!");
    if ((ispal && (rec[i].pal == NULL)) ||
	(!ispal && (rec[i].pal != NULL)))
      puts("ispal is wrong!!");

    ret = DFR8getimage(fname, space, xdim, ydim, pal);
    printf("DFR8getimage return %d.\n", ret);
    if (ret) {
      printf("DFerror %d.\n", DFerror);
      exit(1);
    }

    if (strncmp(space, rec[i].img, xdim * ydim))
      puts("Image is wrong!!");
    if (ispal && strncmp(pal, rec[i].pal, PAL_SIZE))
      puts("Palette is wrong!!");

    printf("\n");
  }
}

char *
randArray(size)
     int size;
{
  char *space;
  int i;

  space = malloc(size);
  if (space == NULL) {
    puts("--malloc error");
    exit(1);
  }

  for (i=0;i<size;i++)
    space[i] = RND(256);

  return space;
}

int
rndCompress()
{
  switch(RND(3)) {
  case 0:
    return 0;
    break;			/* for uniformity */
  case 1:
    return DFTAG_RLE;
    break;
  case 2:
    return DFTAG_IMC;
    break;
  }
}
