/*
 *      THIS ROUTINE IS PART OF THE CLEMENTINE PDS FILE READER PROGRAM.
 *      IT WAS WRITTEN BY ACT CORP. IN DIRECT SUPPORT TO THE
 *      CLEMENTINE (DSPSE) PROGRAM.
 *
 *      IF YOU FIND A PROBLEM OR MAKE ANY CHANGES TO THIS CODE PLEASE CONTACT
 *      Dr. Erick Malaret at ACT Corp.
 *                      tel: (703) 742-0294
 *                           (703) 683-7431
 *                       email: nrlvax.nrl.navy.mil
 *
 *
 */
#include 
#include 
/*#include */
#include 
/* #include  */
#include 
#include "jpeg_c.h"
#include "pds.h"

#define READ_PARAM "rb"
#define WRITE_PARAM "wb"

PDSINFO pds;
FILE    *qparm;
char    histfname[80];
int     USEHIST    = 0;
int     OPTIMIZE   = 1;
int     SLOWDECOMP = 0;
extern long     *DCTHist[64];
extern float    *Rn[64];
extern float    Q[64];
extern float    C[64], Ct[64];

void init_qt(FILE *fptr);
void readhufftbls(FILE *fptr);
void pds_decomp(FILE *fptr,CHARH *p,long sizej,long sizei);
#ifdef  sun
void PClong2SUNlongVector(unsigned long invec[],int npts) ;
void PCshort2SUNshortVector(unsigned short invec[],int npts) ;
#endif
extern void getDCTHist(BitStream *bs, long rows, long cols);
extern void getRn(void);
extern void initC(float *m, short N);
extern void transp(float *out, float *in, short N);


PDSINFO *PDSR(char *fname, long *rows, long *cols)
{
	FILE    *fptr;
	int     n;
	int     j,i;
	CHARH   *c;
	char    nstring[84],sdummy[80],buffer[10],low;
	long    sizej;                  /* number of rows in the image */
	long    sizei;                  /* number of columns in the image */
	int     bitpix;                 /* bits per pixel */
	int     record_bytes;
	int     hist_rec,brw_rec,image_rec,ns,brwsize;
	char    cval, *sptr, *ptr;
	char    record_type[20];
	int     COMPRESSED;
	long    k,hdr_size;

	if( (fptr = fopen(fname,READ_PARAM)) == NULL){  /* open disk file */
		printf("Can't open %s.\n",fname);
		return NULL;
	}

	/* initialize some basic variables */
	bitpix                  = 0;
	sizej=sizei             = 0;
	pds.browse_nrows        = 0;
	pds.browse_ncols        = 0;
	pds.image_nrows = 0;
	pds.image_ncols = 0;
	hist_rec = brw_rec = image_rec = -1;

	/* read header */
	do{
		/* read next line of text */
		for (n=0; (cval=fgetc(fptr)); n++) {
			nstring[n]=cval;
			if(cval=='\n') {
				if( (cval=fgetc(fptr)) != '\r') ungetc(cval,fptr);
				nstring[++n]='\0';
				break;
			}
		}

		/* find line's first non-space character */
		for (ns=0; nstring[ns]==' ';ns++);
		sptr = &nstring[ns];

		if (strncmp("^IMAGE_HISTOGRAM ",sptr,17)==0) {
			n=sscanf(nstring,"%s = %d", sdummy, &hist_rec);
		}

		if (strncmp("^BROWSE_IMAGE ",sptr,14)==0) {
			n=sscanf(nstring,"%s = %d", sdummy, &brw_rec);
		}

		if (strncmp("^IMAGE ",sptr,7)==0) {
			n=sscanf(nstring,"%s = %d", sdummy, &image_rec);
		}

		if (strncmp("RECORD_TYPE",sptr,9)==0) {
			n=sscanf(nstring,"%s = %s", sdummy, &record_type);
		}

		if (strncmp("RECORD_BYTES",sptr,12)==0) {
			n=sscanf(nstring,"%s = %d", sdummy, &record_bytes);
		}

		if (strncmp("ENCODING_TYPE",sptr,13)==0) {
			n=sscanf(nstring,"%s = %s", sdummy, buffer);
			if ( strstr(buffer,"JPEG") )
				COMPRESSED = 1;
			else
				COMPRESSED = 0;
		}

		if (strncmp("LINES ",sptr,6)==0) {
			n=sscanf(nstring,"%s = %d", sdummy, &sizej);
		}

		if (strncmp("LINE_SAMPLES",sptr,12)==0) {
			n=sscanf(nstring,"%s = %d", sdummy, &sizei);
		}

		if (strncmp("SAMPLE_BITS",sptr,11)==0) {
			n=sscanf(nstring,"%s = %d", sdummy, &bitpix);
		}

		if (strncmp("END",sptr,3)==0) {
			if ( *(sptr+3)=='\n' || *(sptr+3)==' ' || *(sptr+3)=='\r' ) {
				hdr_size = ftell(fptr);
				break;
			}
		}
	} while(1);

	/**************   read histogram  ***************/
	if ( hist_rec != -1 ) {
		fseek(fptr,hist_rec-1,0);
		pds.hist = (long *)malloc(256*sizeof(long));
		if(pds.hist == NULL) {
			printf(" histogram memory not allocated \n");
		}
		if ( pds.hist ) {
			fread(pds.hist,sizeof(long),256,fptr);
#ifdef sun
			PClong2SUNlongVector((unsigned long*)pds.hist,256);
#endif
		}
	}

	/**************   read browse image **********/
	if ( brw_rec != -1 ) {
		pds.browse_ncols        = sizei/8;
		pds.browse_nrows        = sizej/8;
		fseek(fptr,brw_rec-1,0);
		brwsize = (sizej/8) * (sizei/8);
		pds.brw_imag = (unsigned char *)malloc(brwsize);
		if ( pds.brw_imag )
			fread(pds.brw_imag,sizeof(char),brwsize,fptr);
	}

	/*************   read image data ***************/
	if (strncmp(record_type,"UNDEFINED",9)==0) {
		record_bytes=1;
		fseek(fptr,(image_rec-1),0);
	} else {
		fseek(fptr,(image_rec-1)*record_bytes,0);
	}

	switch (bitpix) {
	case 8:
		c = (CHARH *)MALLOC(sizej*sizei);
		if ( c == NULL ) {
			printf("Can't allocate memory for image array.\n");
			fclose(fptr);
			return NULL;
		}

		if ( COMPRESSED ) {
			qparm = fopen("paramtrs.dat","w");
			init_qt(fptr);
			readhufftbls(fptr);
			pds_decomp(fptr,c,sizej,sizei);
			fclose(qparm);
		} else {

			for (j=0, k=0; j 60000L ) {
			blocks = nbytes / 32768;
			rem = nbytes % 32768;
			nb = 32768;
		};
		ptr = ibs.outstring;
		for (i=0; i < blocks; i++,ptr+=nb) {
			if ( fread(ptr,sizeof(char),nb,fptr) != nb ) {
				printf("Error reading data string.\n");
				FLAG = 1;
				break;
			}
		}
		if ( rem ) {
			if ( fread(ptr,sizeof(char),rem,fptr) != rem ) {
				printf("Error reading data string.\n");
				FLAG = 1;
			}
		}
		ibs.mode = MEMORY;
	} else {
		ibs.bytestream.file = fptr;
		ibs.mode = DISK;
	}

	if ( !FLAG ) {
		npanels = sizej/32;
		bytesperpanel = 32*sizei;

		if ( OPTIMIZE ) {
			for (i=0; i<64; i++) {
				DCTHist[i] = (long FAR *)MALLOC(sizeof(long)*513);
				memset(DCTHist[i],0,sizeof(long)*513);
				DCTHist[i] += 256;
			}
			for (i=0; i<64; i++) {
				Rn[i] = (float FAR *)MALLOC(sizeof(float)*513);
				memset(Rn[i],0,sizeof(float)*513);
				Rn[i] += 256;
			}

			if ( USEHIST ) {
				FILE *  f1;
				long    sx, sy;
				char    cdummy;
				float   histval;
				f1 = fopen(histfname,"rb");
				fread(&sx,sizeof(long),1,f1);
				fread(&sy,sizeof(long),1,f1);
				fread(&cdummy,sizeof(char),1,f1);
				sy -= 256;
				for (i=0; i>8) +
			  ((ival&0xff000000)>>24);
		invec[i]= oval;
	}
}

void PCshort2SUNshortVector(unsigned short invec[],int npts){
	int     i;
	unsigned short  ival,oval;

	for(i=0;i>8)&0x00ff);
		invec[i]= oval;
	}
}
#endif