Category : C Source Code
Archive   : TIFSRC.ZIP
Filename : READUTIL.C

 
Output of file : READUTIL.C contained in archive : TIFSRC.ZIP

#include

#define LINE_SIZE 320
#define BUFFER_SIZE 512
#define NULL 0
#define BITS_PER_BYTE 8
#define ONE_D_MODIFIED_HUFFMAN 2

extern void bigfree();
extern void debug();
extern int sprintf();

extern SHORT read_header();
extern SHORT read_tag();
extern SHORT read_dirent();
extern SHORT decompress_block();
extern SHORT decompress_error;

extern BOOL access_ifd();

extern LONGPTR bigalloc();
extern LONGPTR decblk; /* decompression block */
extern LONGPTR decblk2;
extern SHORT l_compression;

extern LONG lseek();
extern LONG bigRead();

/*
* Declaring a global variable to be "static" causes it to be considered
* global only within this source file. Hence, these "statics" will be
* invisible to any other routines. This avoids unnecessary name clashes
* and keeps these routines and variables out of the load map.
*/

/* static routines */
static LONG get_buffer();

static BOOL readimg_init();
static BOOL read_strip_tables();
static BOOL read_dirct_valu();

/* static global variables */
static SHORT current_handle = (SHORT)(-1);
SHORT readimg_handle = (SHORT)(-1);
static SHORT image_width;
static SHORT compression_type = 0;
static SHORT residual = 0;

static BOOL decompress = FALSE;
static BOOL initialize_read = FALSE;
static BOOL one_at_a_time = FALSE;

static char *dc_ptr = NULL;
static char temp_line_buff[LINE_SIZE];
static char decomp_buffer[BUFFER_SIZE];

static LONG rows_per_strip;
static LONG bytes_per_line;
static LONG start_strip;
static LONG num_strips;
static LONG prev_start_strip = -1L;
static LONG prev_num_strips = -1L;
static LONG strip_index;
static LONG current_line;
static LONG current_byte;
static LONG decomp_bytes_left = 0L;
static LONG num_sb_count;
static LONG off_sb_count;
static LONG num_str_off;
static LONG off_str_off;
static LONG max_strip_size;
static LONG file_position = -1L;
static LONG next_line_to_read = -1L;
static LONG save_file_position = -1L;
static LONG number_of_bytes;
static SHORT samp_per_pix;
static SHORT bits_per_samp;

/*
* These globals are accessible by any routine.
*/

LONG far *sbc_table;
LONG far *so_table;

LONG _TIFF_image_bytes_read;
LONG _TIFF_image_lines_read;
#ifdef DEBUG
BOOL _TIFF_debug_flag = TRUE;
#else
BOOL _TIFF_debug_flag = FALSE;
#endif /* DEBUG */
LONG bytes_processed = 0;

/* return position of top of IFD list (or zero if error) */
LONG
far get_1st_ifd(fhandle)
SHORT fhandle;
{

static TIFF_HEADER curr_header;

if(fhandle != current_handle)
{
current_handle = fhandle;
if(read_header(fhandle, (TIFF_HEADER far *)&curr_header) !=
TIFF_HEADER_SIZE)
{
return(0L);
}
}
return(curr_header.dir_offset);
}

/* clean up image reading environment */
SHORT
close_read(fhandle)
SHORT fhandle;
{
/* reinitialize handles */
if(current_handle == fhandle)
{
current_handle = (SHORT)(-1);
}
if(readimg_handle == fhandle)
{
readimg_handle = (SHORT)(-1);
}

/* free buffers, reinitialize pointers and sizes */
bigfree(sbc_table);
bigfree(so_table);
sbc_table = 0L;
so_table = 0L;
file_position = -1L;
return(1);
}


/* read appropriate tags and such */
static BOOL
readimg_init(fhandle, fdtype)
SHORT fhandle;
SHORT fdtype;
{
TIFF_DIR_ENTRY dirent;

readimg_handle = fhandle;
bigfree(so_table);
bigfree(sbc_table);
start_strip = -1L;
prev_start_strip = -1L;
num_strips = 0L;
prev_num_strips = -1L;
so_table = 0L;
sbc_table = 0L;
decomp_bytes_left = 0L;
dc_ptr = NULL;
num_sb_count = 0L;
off_sb_count = 0L;
num_str_off = 0L;
off_str_off = 0L;
max_strip_size = 0L;
compression_type = 0;
decompress = FALSE;
next_line_to_read = -1L;
save_file_position = -1L;

if(!read_tag(fhandle, fdtype, IMAGE_WIDTH_TAG,
(LONGPTR)&image_width, (SHORT)SHORT_SIZE))
{
return(TRUE);
}

/* bits per sample */
if(!read_tag(fhandle, fdtype, BITS_PER_SAMPLE_TAG,
(LONGPTR)&bits_per_samp, (SHORT)SHORT_SIZE))

{
bits_per_samp = 1;
}

/* samples_per_pixel */
if(!read_tag(fhandle, fdtype, SAMPLES_PER_PIXEL_TAG,
(LONGPTR)&samp_per_pix, (SHORT)SHORT_SIZE))
{
samp_per_pix = 1;
}

/* rows per strip */
if(!read_tag(fhandle, fdtype, ROWS_PER_STRIP_TAG,
(LONGPTR)&rows_per_strip, (SHORT)LONG_SIZE))
{
rows_per_strip = 0L;
}

/* compression */
if(!read_tag(fhandle, fdtype, COMPRESSION_TAG,
(LONGPTR)&compression_type, (SHORT)SHORT_SIZE))
{
decompress = FALSE;
}
else
{
/*
* Currently (9/7/86), the only compression this
* routine can handle is the 1-Dimensional Modified
* Huffman run length encoding technique.
*/
switch(compression_type)
{
case ONE_D_MOD_HUFFMAN:
decompress = TRUE;
break;

default:
decompress = FALSE;
compression_type = 0;
}
}

/* strip offsets */
if(!read_dirent(fhandle, fdtype, STRIP_OFFSETS_TAG,
(TIFF_DIR_ENTRY far *)&dirent))
{
return(TRUE);
}
num_str_off = dirent.length;
off_str_off = dirent.value_offset;

/* strip byte counts */
if(!read_dirent(fhandle, fdtype, STRIP_BYTE_COUNTS_TAG,
(TIFF_DIR_ENTRY far *)&dirent))
{
return(TRUE);
}
num_sb_count = dirent.length;
off_sb_count = dirent.value_offset;

debug(" # of strip offsets = %lu, 1st strip offset at %lu\n",
num_str_off, off_str_off);
debug(" # of strip byte counts = %lu, 1st strip byte count at %lu\n",
num_sb_count, off_sb_count);
return(FALSE);
}

/* read the strip offsets and strip bytes counts tables */
static BOOL
read_strip_tables(fhandle)
SHORT fhandle;
{
LONG n;
LONG seek_pos;
LONG read_len;

prev_start_strip = start_strip;
prev_num_strips = num_strips;

bigfree(so_table);
bigfree(sbc_table);
so_table = 0L;
sbc_table = 0L;

/* allocate space for strip offsets table */
so_table = (LONG far *)bigalloc(num_strips * (LONG)LONG_SIZE);
if(!so_table)
{
readimg_handle = -1;
return(TRUE);
}

/* allocate space for strip byte counts table */
sbc_table = (LONG far *)bigalloc(num_strips *
(LONG)LONG_SIZE);
if(!sbc_table)
{
readimg_handle = -1;
bigfree(so_table);
so_table = 0L;
return(TRUE);
}

/* read appropriate portion of strip offsets table */
seek_pos = off_str_off + start_strip * (LONG)LONG_SIZE;
if(lseek(fhandle, seek_pos, 0) != seek_pos)
{
readimg_handle = -1;
file_position = -1L;
bigfree(sbc_table);
bigfree(so_table);
so_table = 0L;
sbc_table = 0L;
return(TRUE);
}
read_len = num_strips * (LONG)LONG_SIZE;
if(bigRead(fhandle, so_table, read_len) != read_len)
{
readimg_handle = -1;
file_position = -1L;
bigfree(sbc_table);
bigfree(so_table);
so_table = 0L;
sbc_table = 0L;
return(TRUE);
}

/* read appropriate portion of strip byte counts table */
seek_pos = off_sb_count + start_strip * (LONG)LONG_SIZE;
if(lseek(fhandle, seek_pos, 0) != seek_pos)
{
readimg_handle = -1;
file_position = -1L;
bigfree(sbc_table);
bigfree(so_table);
so_table = 0L;
sbc_table = 0L;
return(TRUE);
}
read_len = num_strips * (LONG)LONG_SIZE;
if(bigRead(fhandle, sbc_table, read_len) != read_len)
{
readimg_handle = -1;
file_position = -1L;
bigfree(sbc_table);
bigfree(so_table);
so_table = 0L;
sbc_table = 0L;
return(TRUE);
}

/* go through table of strip byte counts and get maximum */
max_strip_size = 0L;
for(n = 0; n < num_strips; ++n)
{
debug(" strip %4ld: offset %lu, byte count %lu\n", n, so_table[n],
sbc_table[n]);
if(max_strip_size < sbc_table[n])
{
max_strip_size = sbc_table[n];
}
}

return(FALSE);
}

/* get a buffer from the file */
static LONG
get_buffer(data_buffer, size)
LONGPTR data_buffer;
LONG size;
{
LONG table_offset = strip_index - start_strip;
LONG bytes_per_strip = sbc_table[table_offset];
LONG seek_pos;
LONG read_len;
LONG len;

/* see if we need to go to the next strip */
if(current_byte >= bytes_per_strip)
{
/* we're done if strip table is exhausted */
if(++table_offset >= num_strips)
{
return(-1L);
}
bytes_per_strip = sbc_table[table_offset];

/* we're done if it's an empty strip */
if(bytes_per_strip < 1)
{
return(-1L);
}
strip_index = start_strip + table_offset;
current_byte = 0L;
residual = 0;
}

/*
* Seek to the appropriate position. Do this each time in case
* the caller has seeked elsewhere in the interim.
*/
seek_pos = so_table[table_offset] + current_byte;
if((file_position = lseek(readimg_handle, seek_pos, 0)) != seek_pos)
{
file_position = -1L;
return(-1L);
}

/* figure out how much to read and then do it */
read_len = size;
if(read_len + current_byte > bytes_per_strip)
{
read_len = bytes_per_strip - current_byte;
}
if(read_len <= 0)
{
return(-1L);
}
len = bigRead(readimg_handle, data_buffer, read_len);
if(len >= 0)
{
current_byte += len;
}
return(len);
}

/*
* This module is to read the stripoffset and stripbytecount values
* when rows per strip is equal to the image length, 1/12/87
*/

static BOOL
read_dirct_valu(fhandle)
SHORT fhandle;
{

LONG n;
prev_start_strip = start_strip;
prev_num_strips = num_strips;

bigfree(so_table);
bigfree(sbc_table);
so_table = 0L;
sbc_table = 0L;

/* allocate space for strip offsets table */
so_table = (LONG far *)bigalloc(num_strips * (LONG)LONG_SIZE);
if(!so_table)
{
readimg_handle = -1;
return(TRUE);
}

/* allocate space for strip byte counts table */
sbc_table = (LONG far *)bigalloc(num_strips *
(LONG)LONG_SIZE);
if(!sbc_table)
{
readimg_handle = -1;
bigfree(so_table);
so_table = 0L;
return(TRUE);
}

*so_table = off_str_off;
*sbc_table = off_sb_count;

max_strip_size = 0L;
for(n = 0; n < num_strips; ++n)
{
debug(" strip %4ld: offset %lu, byte count %lu\n", n, so_table[n],
sbc_table[n]);
if(max_strip_size < sbc_table[n])
{
max_strip_size = sbc_table[n];
}
}

return(FALSE);

}

/*
* General get-byte routine. It's needed for decompression, so I
* might as well use it for uncompressed data as well.
*/
SHORT
GetDecompByte()
{
SHORT ch;
LONG table_offset = strip_index - start_strip;
LONG bytes_per_strip = sbc_table[table_offset];
LONG seek_pos;

/* read next buffer if necessary */
if(decomp_bytes_left <= 0 || !dc_ptr)
{
decomp_bytes_left =
get_buffer((LONGPTR)decomp_buffer,
(LONG)BUFFER_SIZE);

/* if error or eof, return 0xffff */
if(decomp_bytes_left <= 0)
{
return((SHORT)0xffff);
}
dc_ptr = decomp_buffer;
}

/* return next character */
--decomp_bytes_left;
++file_position;
++number_of_bytes;
ch = (SHORT)(*dc_ptr++);
return(ch & 0xff);
}