/* hpcdtoppm (Hadmut's pcdtoppm) v0.6
*  Copyright (c) 1992, 1993, 1994 by Hadmut Danisch (danisch@ira.uka.de).
*  Permission to use and distribute this software and its
*  documentation for noncommercial use and without fee is hereby granted,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation. It is not allowed to sell this software in 
*  any way. This software is not public domain.
*/


/* NOTE: Don't use this file for compiling hpcdtoppm, it is heavily */
/* modified.  (By me, Günther Röhrich)                              */
/* EMAIL: Guenther@studbox.uni-stuttgart.de  */


#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "config.h"





/* Format definitions */

#define BaseW ((dim)768)
#define BaseH ((dim)512)

#define SECSIZE 0x800

#define SeHead   2
#define L_Head   (1+SeHead)

#define SeBase16 18
#define L_Base16 (1+SeBase16)

#define SeBase4  72
#define L_Base4  (1+SeBase4)

#define SeBase   288
#define L_Base   (1+SeBase)


#define neutrLum 128
#define neutrCh1 156
#define neutrCh2 137







/* Structures and definitions */
struct _implane
 {dim  mwidth,mheight,
       iwidth,iheight;
  uBYTE *im,*mp;
 };
typedef struct _implane implane;

#define nullplane ((implane *) 0)





struct _sizeinfo
 {dim w,h;  /* Image Resolution */
  dim rdhoff,rdhlen, rdvoff, rdvlen; /* Size of Image in Memory */
  dim imhoff,imhlen, imvoff, imvlen; /* Real Size of Image */
 };
typedef struct _sizeinfo sizeinfo;




/* Definitions for 64Base */

struct file32 { uBYTE x1,x2,x3,x4;};
struct file16 { uBYTE x1,x2;};
#define FILE32(x) ( (((uINT)x.x1)<<24) | (((uINT)x.x2)<<16) | (((uINT)x.x3)<<8) | (uINT)x.x4 )
#define FILE16(x) ( (((uINT)x.x1)<<8) | (uINT)x.x2 )

struct ic_header {char ic_name[0x28];
                  struct file16 val1;
                  struct file16 val2;
                  struct file32 off_descr;
                  struct file32 off_fnames;
                  struct file32 off_pointers;
                  struct file32 off_huffman;
                 };

struct ic_descr {struct file16 len;
                 uBYTE  color;
                 uBYTE  fill;  /* Don't know */
                 struct file16 width;
                 struct file16 height;
                 struct file16 offset;
                 struct file32 length;
                 struct file32 off_pointers;
                 struct file32 off_huffman;
                };


struct ic_fname  {char fname[12];
                  struct file32 size;
                 };

struct ic_entry {struct file16 fno;
                 struct file32 offset;
                };



enum   TURNS  { T_UNSPEC,T_NONE,T_RIGHT,T_LEFT,T_HEAD,T_AUTO };
enum   SIZES  { S_UNSPEC,S_Base16,S_Base4,S_Base,S_4Base,S_16Base,S_64Base,S_Over,S_Contact };
enum   OUTFOR { O_UNSPEC,O_PPM,O_PGM,O_DCOLOR,O_DGRAY, O_YCC};
enum   CORR   { C_UNSPEC,C_LINEAR,C_DARK,C_BRIGHT };

enum   ERRORS { E_NONE,E_READ,E_WRITE,E_INTERN,E_ARG,E_OPT,E_MEM,E_HUFF, E_MAPFILE,
                E_SEQ,E_SEQ1,E_SEQ2,E_SEQ3,E_SEQ4,E_SEQ5,E_SEQ6,E_SEQ7,E_POS,E_IMP,E_OVSKIP,
                E_TAUTO,E_TCANT,E_SUBR,E_PRPAR,E_CONFIG,E_FOPEN, E_DISPLAY, E_ABORT };





/**** Macros ****/



#ifdef DEBUG
#define RPRINT  {fprintf(stderr,"R-Position %x\n",bufpos);}
#else
#define RPRINT
#endif

#define melde(x) {if (do_melde) fprintf(stderr,x);}


#define READBUF   READ(sbuffer,sizeof(sbuffer))
#define EREADBUF {if(READBUF < 1) error(E_READ);}

#define SKIP(p)  { if (SKIPn(p)) error(E_READ);}
#define SKIPr(p) { if (SKIPn(p)) return(E_READ);}


#define TRIF(x,u,o,a,b,c) ((x)<(u)? (a) : ( (x)>(o)?(c):(b)  ))
#define xNORM(x) x=TRIF(x,0,255,0,x,255)
#define NORM(x) { if(x<0) x=0; else if (x>255) x=255;}

#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif








/* main.c */
extern void         close_all(void);

extern char         *ppmname,*pcdname;
extern sINT         do_overskip,monochrome,do_melde,do_crop,do_sharp,do_rep;


extern void         SEEK(int);
extern int          SKIPn(int);
extern int          READ(uBYTE *,int);
extern sINT         bufpos;
extern enum OUTFOR  outfor;
extern sINT         flvert,flhori;
extern enum CORR    corrmode;
extern uBYTE        sbuffer[SECSIZE];


/* error.c */
extern void         eerror(enum ERRORS,char *, int);



/* tools.c */
extern void         interpolate(implane *);
extern void         planealloc(implane *,dim,dim);
extern enum ERRORS  readplain(sizeinfo *,int,implane *,implane *,implane *);
extern void         druckeid(void);

/* Type definitions for output format drives, used in output.c and the drivers */

typedef void (OUT1PL)(FILE *,dim,dim, uBYTE *,sdim,sdim);
typedef void (OUT3PL)(FILE *,dim,dim, uBYTE *,sdim,sdim, uBYTE *,sdim,sdim, uBYTE *,sdim,sdim); 

/* color.c */
extern void         colconvert(sizeinfo *,implane *,implane *,implane *);


/* ppm.c */
extern OUT3PL       write_ppm;
extern OUT1PL       write_pgm;

/* wrdisplay.c */
extern OUT3PL write_dcolor;
extern OUT1PL write_dgray;
