mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
342 lines
14 KiB
342 lines
14 KiB
/*
|
|
|
|
$Log: S:\gfs32\libgfs\wfgtinfo.c_v $
|
|
*
|
|
* Rev 1.1 19 Apr 1995 16:35:22 RWR
|
|
* Make sure WIN32_LEAN_AND_MEAN is defined (explicitly or via GFSINTRN.H)
|
|
* Also surround local include files with quotes instead of angle brackets
|
|
*
|
|
* Rev 1.0 06 Apr 1995 14:02:42 HEIDI
|
|
* Initial entry
|
|
*
|
|
* Rev 1.0 28 Mar 1995 15:53:16 JAR
|
|
* Initial entry
|
|
|
|
*/
|
|
/*
|
|
Copyright 1989, 1990, 1991 by Wang Laboratories Inc.
|
|
Permission to use, copy, modify, and distribute this
|
|
software and its documentation for any purpose 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, and that the name of WANG not be used in
|
|
advertising or publicity pertaining to distribution of the
|
|
software without specific, written prior permission.
|
|
WANG makes no representations about the suitability of
|
|
this software for any purpose. It is provided "as is"
|
|
without express or implied warranty.
|
|
*
|
|
*/
|
|
/*
|
|
* SccsId: @(#)Source wfgtinfo.c 1.29@(#)
|
|
*
|
|
* GFS: WIFF _INFO Structure Handling
|
|
*
|
|
* Routines:
|
|
* wfgtinfo(), gthdbknum()
|
|
*/
|
|
/*LINTLIBRARY*/
|
|
#define GFS_CORE
|
|
|
|
#include "gfsintrn.h"
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include "gfs.h"
|
|
#include "gfct.h"
|
|
#include "rtbk.h"
|
|
#include "hdbk.h"
|
|
|
|
extern long FAR PASCAL ulseek();
|
|
#if (SYSBYTEORDER == II)
|
|
extern void FAR PASCAL swaphdbk();
|
|
extern void FAR PASCAL swapdbt();
|
|
extern void FAR PASCAL swapdbcb();
|
|
#endif
|
|
|
|
/* Given fct and page #, return completed _INFO structure. */
|
|
int FAR PASCAL wfgtinfo(fct, pgnum, bufsz) /*errno_KEY*/
|
|
struct _gfct FAR *fct;
|
|
u_short pgnum;
|
|
u_long FAR *bufsz;
|
|
{
|
|
int i = 0;
|
|
int dbcb_cnt = (int) HDR_CNT;
|
|
int num_read = 0;
|
|
int first_one;
|
|
long fp = 0;
|
|
long block_num = 0;
|
|
long gthdbknum();
|
|
struct gfsinfo FAR *uinfo;
|
|
struct _pmt FAR *p_pmt;
|
|
struct _hdbk FAR *p_hdbk;
|
|
struct _dbt FAR *prv_dbt, FAR *sav_dbt;
|
|
struct _dbcb FAR *prv_dbcb, FAR *sav_dbcb;
|
|
u_long nxt_dbt = 0;
|
|
|
|
uinfo = &fct->uinfo;
|
|
|
|
p_pmt = (struct _pmt FAR *) fct->u.wif.pmt_in_mem;
|
|
p_hdbk = (struct _hdbk FAR *) fct->u.wif.hdbk_in_mem;
|
|
/* See if the hdbk contains
|
|
stuff that need freein' */
|
|
prv_dbt = (struct _dbt FAR *) &p_hdbk->first_dbt;
|
|
first_one = (int) TRUE;
|
|
if (prv_dbt != (struct _dbt FAR *) NULL) {
|
|
do {
|
|
sav_dbt = prv_dbt->nu.next_dbt;
|
|
if (first_one)
|
|
first_one = (int) FALSE;
|
|
else
|
|
free((char FAR *) prv_dbt);
|
|
prv_dbt = sav_dbt;
|
|
} while (sav_dbt != (struct _dbt FAR *) NULL);
|
|
}
|
|
/* Find the block # in PMT */
|
|
block_num = gthdbknum(p_pmt, pgnum);
|
|
if (block_num <= (long) 0) {
|
|
errno = (int) EPAGENOTINFILE;
|
|
return ( (int) -1);
|
|
}
|
|
/* Seek to header block */
|
|
fp = ulseek(fct->fildes, (u_long) block_num * 4 * K);
|
|
if (fp < (long) 0)
|
|
return ( (int) -1);
|
|
/* Read in the header block */
|
|
num_read = read(fct->fildes, (char FAR *) p_hdbk, (unsigned) 4 * K);
|
|
if (num_read <= 0)
|
|
return ( (int) -1);
|
|
#if (SYSBYTEORDER == II)
|
|
(void) swaphdbk((struct _hdbk FAR *) p_hdbk);
|
|
#endif
|
|
/* Get gen'l info from header */
|
|
uinfo->type = (u_long) GFS_MAIN;
|
|
uinfo->_file.fmt.wiff.oldstylecompression = (u_long)
|
|
p_hdbk->compression;
|
|
switch ((int) p_hdbk->compression) {
|
|
case 2:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP4_FACS;
|
|
uinfo->fill_order = (u_long) HIGHTOLOW;
|
|
uinfo->img_cmpr.opts.grp4 = (u_long) 0;
|
|
break;
|
|
case 3: /* data is packed */
|
|
uinfo->img_cmpr.type = (u_long) UNCOMPRESSED;
|
|
uinfo->fill_order = (u_long) LOWTOHIGH;
|
|
break;
|
|
case 4:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_FACS;
|
|
uinfo->fill_order = (u_long) LOWTOHIGH;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long) 0;
|
|
break;
|
|
case 5:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP4_FACS;
|
|
uinfo->fill_order = (u_long) LOWTOHIGH;
|
|
uinfo->img_cmpr.opts.grp4 = (u_long) 0;
|
|
break;
|
|
case 6: /* data is packed */
|
|
uinfo->img_cmpr.type = (u_long) UNCOMPRESSED;
|
|
uinfo->fill_order = (u_long) HIGHTOLOW;
|
|
break;
|
|
case 7:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_FACS;
|
|
uinfo->fill_order = (u_long) LOWTOHIGH;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long) LEAD_EOL;
|
|
break;
|
|
case 8:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_FACS;
|
|
uinfo->fill_order = (u_long) LOWTOHIGH;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long) GRP3_EOLS_BYTEBOUNDED;
|
|
break;
|
|
case 9:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_FACS;
|
|
uinfo->fill_order = (u_long) LOWTOHIGH;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long)
|
|
(GRP3_EOLS_BYTEBOUNDED | LEAD_EOL);
|
|
break;
|
|
case 10:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_NO_EOLS;
|
|
uinfo->fill_order = (u_long) LOWTOHIGH;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long) 0;
|
|
break;
|
|
case 11:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_NO_EOLS;
|
|
uinfo->fill_order = (u_long) LOWTOHIGH;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long) DATA_ALIGNED;
|
|
break;
|
|
case 12:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_FACS;
|
|
uinfo->fill_order = (u_long) HIGHTOLOW;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long) 0;
|
|
break;
|
|
case 13:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_FACS;
|
|
uinfo->fill_order = (u_long) HIGHTOLOW;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long) LEAD_EOL;
|
|
break;
|
|
case 14:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_FACS;
|
|
uinfo->fill_order = (u_long) HIGHTOLOW;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long) GRP3_EOLS_BYTEBOUNDED;
|
|
break;
|
|
case 15:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_NO_EOLS;
|
|
uinfo->fill_order = (u_long) HIGHTOLOW;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long) DATA_ALIGNED;
|
|
break;
|
|
case 19:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_FACS;
|
|
uinfo->fill_order = (u_long) HIGHTOLOW;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long)
|
|
( GRP3_EOLS_BYTEBOUNDED | LEAD_EOL) ;
|
|
break;
|
|
case 20:
|
|
uinfo->img_cmpr.type = (u_long) CCITT_GRP3_NO_EOLS;
|
|
uinfo->fill_order = (u_long) HIGHTOLOW;
|
|
uinfo->img_cmpr.opts.grp3 = (u_long) 0;
|
|
break;
|
|
case 64:
|
|
uinfo->img_cmpr.type = (u_long) PACKBITS;
|
|
uinfo->fill_order = (u_long) HIGHTOLOW;
|
|
break;
|
|
case 65:
|
|
uinfo->img_cmpr.type = (u_long) PACKBITS;
|
|
uinfo->fill_order = (u_long) LOWTOHIGH;
|
|
break;
|
|
default:
|
|
errno = (int) EINVALID_COMPRESSION;
|
|
prv_dbt = (struct _dbt FAR *) &p_hdbk->first_dbt;
|
|
prv_dbt->nu.next_dbt = (struct _dbt FAR *) NULL;
|
|
return ( (int) -1);
|
|
}
|
|
uinfo->horiz_res[0] = (u_long) p_hdbk->horiz_res;
|
|
uinfo->horiz_res[1] = (u_long) 1;
|
|
uinfo->vert_res[0] = (u_long) p_hdbk->vert_res;
|
|
uinfo->vert_res[1] = (u_long) 1;
|
|
uinfo->res_unit = (u_long) 2; /* WIFF Default */
|
|
uinfo->horiz_size = (u_long) p_hdbk->horiz_size;
|
|
uinfo->vert_size = (u_long) p_hdbk->vert_size;
|
|
uinfo->bits_per_sample[0]
|
|
= (u_long) p_hdbk->bits_pixel;
|
|
uinfo->samples_per_pix = (u_long) 1;
|
|
|
|
/* this should not be used for bilevel images and needs more work to
|
|
be used with the color anyway. Just comment out for now.- lcm */
|
|
/*if (uinfo->PSEUDO_PTR != (struct pseudo_color FAR *) NULL)
|
|
uinfo->PSEUDO_PTR->plane_config = (u_long) SINGLE_IMAGE_PLANE;*/
|
|
|
|
uinfo->byte_order = (u_long) MM;
|
|
uinfo->origin = (u_long) p_hdbk->scan_dir;
|
|
switch ( (int) p_hdbk->rotation ) {
|
|
|
|
case 0: /* 0 degrees */
|
|
uinfo->rotation = (u_long) DEGREES_0;
|
|
break;
|
|
|
|
case 1: /* 90 degrees */
|
|
uinfo->rotation = (u_long) DEGREES_90;
|
|
break;
|
|
|
|
case 2: /* 180 degrees */
|
|
uinfo->rotation = (u_long) DEGREES_180;
|
|
break;
|
|
|
|
case 3: /* 270 degrees */
|
|
uinfo->rotation = (u_long) DEGREES_270;
|
|
break;
|
|
|
|
default:
|
|
uinfo->rotation = (u_long) DEGREES_0;
|
|
return ( (int) -1 );
|
|
|
|
}
|
|
|
|
uinfo->reflection = (u_long) p_hdbk->reflection;
|
|
uinfo->img_clr.img_interp = (u_long) p_hdbk->type;
|
|
/* Get WIFF specific stuff */
|
|
uinfo->_file.fmt.wiff.db_size
|
|
= p_hdbk->db_size;
|
|
/* Count valid data for first
|
|
DBT */
|
|
prv_dbt = (struct _dbt FAR *) &p_hdbk->first_dbt;
|
|
prv_dbcb = (struct _dbcb FAR *) &prv_dbt->first_dbcb;
|
|
#if (SYSBYTEORDER == II)
|
|
(void) swapdbt((struct _dbt FAR *) prv_dbt);
|
|
(void) swapdbcb((struct _dbcb FAR *) prv_dbcb,
|
|
(long) prv_dbt->entries);
|
|
#endif
|
|
*bufsz = (u_long) 0;
|
|
for (i = 1; i <= dbcb_cnt; i++) {
|
|
sav_dbcb = prv_dbcb;
|
|
*bufsz += prv_dbcb->data_cnt;
|
|
if ( (++sav_dbcb)->data_cnt <= 0)
|
|
break;
|
|
prv_dbcb->nu.next_dbcb = sav_dbcb;
|
|
prv_dbcb = prv_dbcb->nu.next_dbcb;
|
|
}
|
|
dbcb_cnt = (int) DBT_CNT;
|
|
/* Read in all the DBT's for
|
|
the page and continue to
|
|
count valid data */
|
|
nxt_dbt = (u_long) prv_dbt->nu.nxt_blk;
|
|
while (nxt_dbt != 0) {
|
|
prv_dbt->nu.next_dbt = /* This is freed above ^ */
|
|
(struct _dbt FAR *) calloc( (unsigned) 1, (unsigned) 4 * K);
|
|
if (prv_dbt->nu.next_dbt == (struct _dbt FAR *) NULL) {
|
|
errno = (int) ENOMEM;
|
|
return ( (int) -1);
|
|
}
|
|
fp = ulseek(fct->fildes, (u_long) nxt_dbt * 4 * K);
|
|
if (fp < (long) 0)
|
|
return ( (int) -1);
|
|
num_read = read(fct->fildes, (char FAR *) prv_dbt->nu.next_dbt,
|
|
(unsigned) 4 * K);
|
|
if (num_read <= 0) /* 0 is eof */
|
|
return ( (int) -1);
|
|
prv_dbt = prv_dbt->nu.next_dbt;
|
|
prv_dbcb = (struct _dbcb FAR *) &prv_dbt->first_dbcb;
|
|
#if (SYSBYTEORDER == II)
|
|
(void) swapdbt((struct _dbt FAR *) prv_dbt);
|
|
(void) swapdbcb((struct _dbcb FAR *) prv_dbcb,
|
|
(long) prv_dbt->entries);
|
|
#endif
|
|
nxt_dbt = (u_long) prv_dbt->nu.nxt_blk;
|
|
for (i = 1; i <= dbcb_cnt; i++) {
|
|
sav_dbcb = prv_dbcb;
|
|
*bufsz += prv_dbcb->data_cnt;
|
|
if ( (++sav_dbcb)->data_cnt <= 0)
|
|
break;
|
|
prv_dbcb->nu.next_dbcb = sav_dbcb;
|
|
prv_dbcb = prv_dbcb->nu.next_dbcb;
|
|
}
|
|
}
|
|
/** BUG lynn says (--prv_dbcb)->nu.next_dbcb = (struct _dbcb FAR *) NULL; **/
|
|
return( (int) 0);
|
|
}
|
|
|
|
/* Given pmt table pointer and page #, return block # of page header. */
|
|
long gthdbknum(pmt, pgnum) /*errno_KEY*/
|
|
struct _pmt FAR *pmt;
|
|
u_short pgnum;
|
|
{
|
|
struct _pmt FAR *next_pmt;
|
|
struct _pmte FAR *p_pmte;
|
|
/* Page in 1st PMT ?? */
|
|
if (pgnum < (u_short) ROOT_PMTS) {
|
|
p_pmte = (struct _pmte FAR *) &pmt->first_pmte;
|
|
return( (long) p_pmte[pgnum].first_full);
|
|
}
|
|
/* Nope, keep lookin' */
|
|
pgnum -= (u_short) ROOT_PMTS;
|
|
next_pmt = pmt->nu.next_pmt;
|
|
|
|
while (next_pmt != 0) {
|
|
if (pgnum < (u_short) OTHER_PMTS) {
|
|
p_pmte = (struct _pmte FAR *) &next_pmt->first_pmte;
|
|
return( (long) p_pmte[pgnum].first_full);
|
|
}
|
|
pgnum -= (u_short) OTHER_PMTS;
|
|
next_pmt = next_pmt->nu.next_pmt;
|
|
}
|
|
/* Oops, page not found !! */
|
|
return ( (long) -1);
|
|
}
|