#include <stdio.h>
#include "config.h"
#include "unixlib.h"

#if defined(ATARI_ST)
#include <string.h>
#include <ext.h>

#elif defined(MSDOS) || defined(SUN) || defined(SEQUENT386) || defined(AVIION)
#include <sys/types.h>
#include <sys/stat.h>

#else
#error Wrong machine type. Edit config.h and follow the instructions.

#endif

#include "portab.h"
#include "picstat.h"


typedef struct
{
  UBYTE x_manu;
  UBYTE x_version;
  UBYTE x_encode;
  UBYTE x_pres;
  UWORD x_xmin;
  UWORD x_ymin;
  UWORD x_xmax;
  UWORD x_ymax;
  UWORD x_dwidth;
  UWORD x_dheight;
  UBYTE x_cmap[48];
  UBYTE x_unused;
  UBYTE x_nplanes;
  UWORD x_bscan;
  UWORD x_pinfo;
} PCXBUF;


/*
 *  return PCX stats of a file
 */

int pcxstat (name, buf, mode)
 char *name;
 struct picstat *buf;
 int mode;

{
  int ret;
  struct stat sbuf;
  FILE *fp;
  PCXBUF pcxbuf;
  UBYTE *col;
  int i, j;
  int ncols;
  int magic;

  if (mode)
    {
      ret = lstat (name, &sbuf);
    }
  else
    {
      ret = stat (name, &sbuf);
    }
  if (ret)
    {
      return (-1);
    }
  if ((fp = fopen (name, "rb")) == NULL)
    {
      return (-1);
    }
  if (sizeof(PCXBUF) != fread (&pcxbuf, 1L, sizeof(PCXBUF), fp))
    {
      fclose (fp);
      return (-1);
    }
  switch (pcxbuf.x_version)
    {
      case 0:
      case 2:
      case 3:
        {
          ncols = 16;
          col = pcxbuf.x_cmap;
          break;
        }
      case 5:
        {
          if (fseek(fp, -769L, SEEK_END) != 0)
            {
              fclose (fp);
              return (-1);
            }
          magic = fgetc(fp);
          if (magic == EOF)
            {
              fclose (fp);
              return (-1);
            }
          if (magic != 12)
            {
              fclose (fp);
              return (-1);
            }
          ncols = 256;
          col = (UBYTE *) malloc (768L);
          if (col == NULL)
            {
              fclose (fp);
              return (-1);
            }
          if (768L != fread (col, 1L, 768L, fp))
            {
              free (col);
              fclose (fp);
              return (-1);
            }
          break;
        }
      default:
        {
          fclose (fp);
          return (-1);
        }
    }
  if (fclose (fp))
    {
      free (col);
      return (-1);
    }
  if (pcxbuf.x_manu != 10)
    {
      return (-1);
    }
  buf->p_fsize = sbuf.st_size;
  buf->p_sizex = SWAP2(pcxbuf.x_xmax) - SWAP2(pcxbuf.x_xmin) + 1;
  buf->p_sizey = SWAP2(pcxbuf.x_ymax) - SWAP2(pcxbuf.x_ymin) + 1;
  buf->p_colrez = pcxbuf.x_pres * pcxbuf.x_nplanes;
  if (buf->p_colrez == 1)
    {
      buf->p_coltype = CT_BW;
      buf->p_ncol = 2;
    }
  else
    {
      for (buf->p_coltype=CT_BW, i=0; i < ncols; i++)
        {
            if ((col[3*i] != col[3*i+1]) || (col[3*i+1] != col[3*i+2]))
              {
                buf->p_coltype = CT_COLOR;
                break;
              }
          }
      buf->p_ncol = ncols;
      for (i=0; i<ncols; i++)
        {
          for (j=0; j<i; j++)
            {
              if ((col[3*i] == col[3*j]) &&
                  (col[3*i+1] == col[3*j+1]) &&
                  (col[3*i+2] == col[3*j+2]))
                {
                  col[3*j] = col[0];
                  col[3*j+1] = col[1];
                  col[3*j+2] = col[2];
                  buf->p_ncol--;
                  break;
                }
            }
        }
      if (buf->p_ncol >= 1<<buf->p_colrez)
        {
          buf->p_ncol = 1<<buf->p_colrez;
        }
    }
  buf->p_nframes = 1;
  buf->p_speed = 0;
  strcpy (buf->p_type, "PCX");
  buf->p_cols = NULL;
  free (col);
  return (0);
}
