home *** CD-ROM | disk | FTP | other *** search
- #include "tiff.h"
-
- #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.
- */
- extern LONG far *so_table;
- extern LONG far *sbc_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;
-
- #ifdef NOWINDOWS
- /*
- * The flag for one-byte-at-a-time versus buffered mode is a static, so
- * that no routine that is linked in can access it. It is set or cleared
- * by means of this SetBufferedMode() routine. When debugging, compile
- * with the NOWINDOWS flag defined if you want to be able to use this
- * routine to alter this mode. Without NOWINDOWS, this routine never
- * gets compiled, and so there'd be no way to alter the buffering mode
- * from the default value (default == buffered) short of using a debugger
- * or patching the code.
- */
- void
- SetBufferedMode(buffered)
- BOOL buffered;
- {
- if(buffered)
- {
- one_at_a_time = FALSE;
- }
- else
- {
- one_at_a_time = TRUE;
- }
- }
- #endif /* NOWINDOWS */
-
- /* 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);
- if(l_compression == ONE_D_MODIFIED_HUFFMAN) {
- bigfree(decblk);
- bigfree(decblk2);
- }
- 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;
-
- #ifdef NOWINDOWS
- if(one_at_a_time)
- {
- if(initialize_read)
- {
- current_byte = bytes_per_strip;
- --table_offset;
- initialize_read = FALSE;
- }
- /* 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((SHORT)0xffff);
- }
- bytes_per_strip = sbc_table[table_offset];
-
- /* we're done if it's an empty strip */
- if(bytes_per_strip < 1L)
- {
- return((SHORT)0xffff);
- }
- strip_index = start_strip + table_offset;
- current_byte = 0L;
- residual = 0;
- seek_pos = so_table[table_offset];
- if((file_position = lseek(readimg_handle, seek_pos,
- 0)) != seek_pos)
- {
- file_position = -1L;
- return((SHORT)0xffff);
- }
- }
-
- if(bigRead(readimg_handle, (LONGPTR)&ch, 1L) < 1L)
- {
- return((SHORT)0xffff);
- }
- ++current_byte;
- ++number_of_bytes;
- file_position = lseek(readimg_handle, 0L, 1);
- return(ch & 0xff);
- }
- else
- {
- #endif /* NOWINDOWS */
- /* 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);
- #ifdef NOWINDOWS
- }
- #endif /* NOWINDOWS */
- }
-