#include <stdio.h>
#include <string.h>
#include "giflib.h"
#include "util.h"

void myerror(char *buf, char *s1, char *s2) {
  strcpy(buf, s1);
  strcat(buf, s2);
  perror(buf);
}

/* Get n bits starting at position p of x */
int getbits (int n, int p, int x) {
  return((x >> (p+1-n)) & ~(~0 << n));
}

int ipow (int x, int y) {
  int answer = 1;

  for ( ; (y > 0) ; y--) {
    answer = answer * x;
  }
  return(answer);
}


/* unsigned char fread */
/* This function assumes that ptr is at least (num) long. */
void uc_fread (unsigned char * ptr, int num, FILE *fp) {
  int HaveRead;

  HaveRead = fread( (void *) ptr, 1, (size_t) num, fp);

  if (HaveRead != num) {
    if (feof(fp) != 0) {
      fprintf(stderr, "Unexpected EOF encountered in input file.\n");
      exit(1);
    } else if (ferror(fp) != 0) {
      perror("Error reading file: ");
      exit(1);
    }
  }
}

int  suckchunk (unsigned char *buf, int bufsiz, FILE *fp) {
  int HaveRead;

  /* This probably needs some work. I'm not going to worry about
   * it right now. XXX
   */

  HaveRead = fread( (void *) buf, 1, (size_t) bufsiz, fp);

  if (HaveRead != bufsiz) {
    if (feof(fp) != 0) {
      return(HaveRead); /* EOF */
    } else if (ferror(fp) != 0) {
      perror("Error reading file: ");
      exit(1);
    }
  }

  return(HaveRead);

}

/* unsigned char fwrite */
/* This function assumes that ptr is at least (num) long. */
void uc_fwrite (unsigned char * ptr, int num, FILE *fp) {
  int HaveWritten;

    HaveWritten = fwrite( (void *) ptr, 1, (size_t) num, fp);

    if ((HaveWritten != num) && (ferror(fp) != 0)) {
      perror("Error writing output stream: ");
      exit(1);
    }
}

/*
 * From cat(1):
 * 
 *         while ((nr = read(rfd, buf, bsize)) > 0)
 *                 for (off = 0; nr; nr -= nw, off += nw)
 *                         if ((nw = write(wfd, buf + off, nr)) < 0)
 *                                 err(1, "stdout");
 */

void spewrest (FILE *IStream, FILE *OStream) {
  unsigned char buf[BUFSIZ];
  int nr, nw, offset; /* nr/nw == NumberRead, NumberWritten */

  /* It might be worthwhile to put some error-handling code in here. */
  /* But I'm not going to bother with it for now. */

  while ((nr = fread( (void *) buf, 1, BUFSIZ, IStream)) > 0) {
    for (offset = 0; nr; nr -= nw, offset += nr)
      if ((nw = fwrite( (void *) buf + offset, 1, nr, OStream)) < 0) {
	perror("Error writing output stream: ");
      }
  }
}

#ifdef DEBUG
void debugimageinfo (imageinfo *iinfo) {
  if (iinfo->itis87a == 1) {
    fprintf(stderr, "Hey, it's 87a.\n");
  } else {
    fprintf(stderr, "Hey, it's 89a.\n");
  }
  fprintf(stderr, "Width:  %i\nHeight: %i\n", iinfo->width, iinfo->height);
  fprintf(stderr, "GCTF:   %u\n", iinfo->gct_p);
  fprintf(stderr, "CR:     %u\n", iinfo->color_res);
  fprintf(stderr, "SF:     %u\n", iinfo->sort_flag);
  fprintf(stderr, "SGCT:   %u\n", iinfo->size_gct);
  fprintf(stderr, "BCI:    %u\n", iinfo->bkg_color_index);
  fprintf(stderr, "PAR:    %u\n", iinfo->pixel_aratio);
}
#endif
