/***********************************************************************
$Id: writejbig2.h,v 1.30 2003/01/08 21:51:47 hahe Exp hahe $
***********************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include "ptexlib.h"
#include "ptexmac.h"
#include "image.h"

/* 7.3 Segment types */
#define M_SymbolDictionary 0
#define M_IntermediateTextRegion 4
#define M_ImmediateTextRegion 6
#define M_ImmediateLosslessTextRegion 7
#define M_PatternDictionary 16
#define M_IntermediateHalftoneRegion 20
#define M_ImmediateHalftoneRegion 22
#define M_ImmediateLosslessHalftoneRegion 23
#define M_IntermediateGenericRegion 36
#define M_ImmediateGenericRegion 38
#define M_ImmediateLosslessGenericRegion 39
#define M_IntermediateGenericRefinementRegion 40
#define M_ImmediateGenericRefinementRegion 42
#define M_ImmediateLosslessGenericRefinementRegion 43
#define M_PageInformation 48
#define M_EndOfPage 49
#define M_EndOfStripe 50
#define M_EndOfFile 51
#define M_Profiles 52
#define M_Tables 53
#define M_Extension 62

typedef struct _LITEM {
    struct _LITEM *prev;
    struct _LITEM *next;
    struct _LITEM *lchild;
    struct _LITEM *rchild;
    void *d;			/* data */
} LITEM;

typedef struct _LIST {
    LITEM *first;
    LITEM *last;
    LITEM *root;
} LIST;

typedef struct _SEGINFO {
    unsigned long segnum;
    unsigned int isrefered;
    unsigned int refers;
    unsigned int shdrflags;	/*  set by readseghdr() */
    unsigned int pageassocsize;	/*  set by readseghdr() */
    unsigned int reftosegcount;	/*  set by readseghdr() */
    unsigned int countofrefered;	/*  set by readseghdr() */
    unsigned int fieldlen;	/*  set by readseghdr() */
    unsigned int segnumwidth;	/*  set by readseghdr() */
    long segpage;		/*  set by readseghdr() */
    unsigned long segdatalen;	/*  set by readseghdr() */
    unsigned long hdrstart;	/*  set by readseghdr() */
    unsigned long hdrend;	/*  set by readseghdr() */
    unsigned long datastart;
    unsigned long dataend;
    unsigned int endofstripeflag;	/*  set by checkseghdrflags() */
    unsigned int endofpageflag;	/*  set by checkseghdrflags() */
    unsigned int pageinfoflag;	/*  set by checkseghdrflags() */
    unsigned int endoffileflag;	/*  set by checkseghdrflags() */
} SEGINFO;

typedef struct _PAGEINFO {
    LIST segments;		/* segments associated with page */
    unsigned long pagenum;
    unsigned int width;
    unsigned int height;
    unsigned int xres;
    unsigned int yres;
    unsigned int pagesegmentflags;
    unsigned int stripinginfo;
    unsigned int stripedheight;
} PAGEINFO;

typedef struct _FILEINFO {
    FILE *file;
    char *filename;
    LIST pages;			/* not including page0 */
    LIST page0;
    unsigned int fhdrflags;	/* set by readfilehdr() */
    unsigned int sequentialaccess;	/* set by readfilehdr() */
    unsigned long numofpages;	/* set by readfilehdr() */
    unsigned long streamstart;	/* set by get_jbig2_info() */
    unsigned long pdfpage0objnum;
    unsigned int phase;
} FILEINFO;

/**********************************************************************/

enum infotype { SEG, PAGE0, PAGES };
enum phase { INITIAL, HAVEINFO, WRITEPDF };

/**********************************************************************/

void initfileinfo(FILEINFO * fip);
void initpageinfo(PAGEINFO * pip);
void initseginfo(SEGINFO * sip);
void initlinkedlist(LIST * lp);
LIST *litem_append(LIST * lp);
LIST *litem_remove(LIST * lp);
LIST *list_remove(LIST * lp);
void file_append(LIST * lp);
void page_append(LIST * lp);
void segment_append(LIST * lp);
FILEINFO *fileinfo_create();
void pages_maketree(LIST * plp);
void segments_maketree(LIST * slp);
LITEM *list_mktree(LITEM * fromip, LITEM * toip);
PAGEINFO *find_pageinfo(LIST * lp, unsigned long pagenum);
SEGINFO *find_seginfo(LIST * lp, unsigned long segnum);
unsigned int read2bytes(FILE * f);
unsigned long read4bytes(FILE * f);
unsigned long getstreamlen(LITEM * slip, int refer);
void readfilehdr(FILEINFO * fip);
void readseghdr(FILEINFO * fip, SEGINFO * sip);
void writeseghdr(FILEINFO * fip, SEGINFO * sip);
void checkseghdr(FILEINFO * fip, SEGINFO * sip);
void checkseghdrflags(SEGINFO * sip);
void markpage0seg(FILEINFO * fip, unsigned long referedseg);
unsigned long findstreamstart(FILEINFO * fip);
FILEINFO *rd_jbig2_info(FILEINFO * fip);
void wr_jbig2(FILEINFO * fip, unsigned long page);
void read_jbig2_info(integer img);
void write_jbig2(integer img);
void flushjbig2page0objects();

/**********************************************************************/
