home *** CD-ROM | disk | FTP | other *** search
- /*
- * C utilities for the Tag Image File Format routines
- */
-
- #include <tiff.h>
- #define NODEBUG 1 /* VJ 11/10 */
- #define SHORT_TYPE 3 /* BGM 11/12/87 */
-
- #ifndef NULL
- #define NULL 0L
- #endif /* NULL */
-
- typedef char *va_list;
-
- #define va_start(ap,v) ap = (va_list)&v + sizeof(v)
- #define va_arg(ap,t) ((t*)(ap += sizeof(t)))[-1]
- #define va_end(ap) ap = NULL
-
- static char temp[160];
- extern int vsprintf();
-
- #ifdef NOWINDOWS /* Windows-specific stuff */
-
- extern void write();
-
- #else
-
- #define GMEM_LOCKCOUNT 0x00ff
- extern SHORT pascal GlobalFlags();
- extern char far * far pascal GlobalLock();
- extern BOOL far pascal GlobalUnlock();
- extern SHORT far pascal GlobalAlloc();
- extern void far pascal GlobalFree();
- extern void far pascal TextOut();
- extern unsigned short far pascal GetDC();
- extern void far pascal ReleaseDC();
- extern unsigned short MainWindow;
-
- #define GHND 0x0040 /* fixed + zeroinit */
-
- #endif /* NOWINDOWS */
-
- extern unsigned short tlRead();
- extern LONG bigRead();
- extern SHORT tdosAlloc();
- extern void tdosFree();
-
- extern BOOL _TIFF_reorder_bytes;
- extern BOOL _TIFF_debug_flag;
-
- /* allocate up to one megabyte of data */
- LONGPTR
- bigalloc(size)
- LONG size;
- {
- #ifdef NOWINDOWS /* non-Windows allocator */
-
- /* convert to paragraphs */
- LONG temp = (size + 15) >> 4; /* convert to paragraphs */
- SHORT segment;
-
- /* must be < 1 megabyte */
- if(HIWORD(temp))
- {
- return((LONGPTR)0L);
- }
-
- if(!(segment = tdosAlloc(LOWORD(temp))))
- {
- return((LONGPTR)0L);
- }
- temp = (LONG)segment;
- temp <<= 16;
- return((LONGPTR)temp);
-
- #else /* Windows allocator */
-
- LONGPTR temp;
- SHORT handle;
-
- /* get the space and make room for the handle */
- handle = GlobalAlloc((SHORT)GHND, (LONG)(size + (LONG)SHORT_SIZE));
- if(!handle)
- {
- return((LONGPTR)0L);
- }
-
- /* lock the memory */
- temp = GlobalLock(handle);
- if(!temp)
- {
- GlobalFree(handle);
- return((LONGPTR)0L);
- }
-
- /* store the handle, adjust the pointer, and then return */
- *((SHORT far *)temp) = handle;
- return((LONGPTR)(temp + SHORT_SIZE));
-
- #endif /* NOWINDOWS */
- }
-
- /* free data allocated by bigalloc() */
- void
- bigfree(memptr)
- LONGPTR memptr;
- {
- #ifdef NOWINDOWS /* non-Windows */
-
- LONG temp = (LONG)memptr;
-
- if(!memptr)
- {
- return;
- }
-
- /* must be of form SEG:0 if it was returned from bigalloc() */
- if(LOWORD(temp))
- {
- return;
- }
- tdosFree(HIWORD(temp));
-
- #else /* Windows */
-
- SHORT handle;
-
- /* mustn't be a null pointer */
- if(!memptr)
- {
- return;
- }
-
- /* get the handle */
- memptr -= SHORT_SIZE;
- handle = *((SHORT far *)memptr);
-
- /* free the memory */
- /* this is kind of kludgie, but ... */
- while( GlobalFlags(handle) & GMEM_LOCKCOUNT > 0 ) {
- GlobalUnlock(handle);
- }
- GlobalFree(handle);
- return;
-
- #endif /* NOWINDOWS */
- }
-
- /* reorder bytes if necessary */
- void
- reorder(data, size)
- LONGPTR data;
- SHORT size;
- {
- if(_TIFF_reorder_bytes)
- {
- LONGPTR end = (data + size) - 1;
- char temp;
- while(data < end)
- {
- temp = *data;
- *data++ = *end;
- *end-- = temp;
- }
- }
- }
-
- /* check if supplied value is correct version number */
- BOOL
- correct_version(value)
- SHORT value;
- {
- /*
- * For now, just compare to legal version number. But this
- * might get more complex as time goes on.
- */
- if(value == LEGAL_VERSION)
- {
- return(TRUE);
- }
- else
- {
- return(FALSE);
- }
- }
-
- /* return the length of a given type */
- SHORT
- type_length(type)
- SHORT type;
- {
- static SHORT length_array[] =
- {
- BYTE_SIZE,
- ASCII_SIZE,
- SHORT_SIZE,
- LONG_SIZE,
- RATIONAL_SIZE,
- };
-
- if(type < 1 || type > ELEMENTS(length_array))
- {
- return(0);
- }
- else
- {
- return(length_array[--type]);
- }
- }
-
- /* get value of tag */
- SHORT
- value_of(dirent, value)
- TIFF_DIR_ENTRY far *dirent;
- LONGPTR value;
- {
- SHORT tlen = type_length(dirent->type);
- SHORT code = DIRECT_VALUE;
- LONG len;
- long x;
- LONGPTR cp;
-
- if(tlen < 1)
- {
- return(ERROR_VALUE);
- }
-
- /* calculate real length */
- len = (LONG)tlen;
- len *= dirent->length;
-
- /* if longer than a LONG, only return the pointer to the data */
- if(len >= LONG_SIZE)
- {
- len = LONG_SIZE;
- code = INDIRECT_VALUE;
- }
-
- /* move the value */
- cp = (LONGPTR)&(dirent->value_offset);
- x = (long)len;
- while(x-- > 0)
- {
- *value++ = *cp++;
- }
-
- return(code);
- }
-
- /* read pertinent data from currently-pointed-to directory entry */
- BOOL
- read_dir(fhandle, dirent)
- SHORT fhandle;
- TIFF_DIR_ENTRY far *dirent;
- {
- LONG littleRead();
-
- if(littleRead(fhandle, dirent, (LONG)TIFF_DIR_ENTRY_SIZE) <
- TIFF_DIR_ENTRY_SIZE)
- {
- return(TRUE);
- }
-
- /* reorder bytes if necessary */
- reorder((SHORT far *)&(dirent->tag), SHORT_SIZE);
- reorder((SHORT far *)&(dirent->type), SHORT_SIZE);
- reorder((LONG far *)&(dirent->length), LONG_SIZE);
- if(dirent->type == SHORT_TYPE && dirent->length == 1) {
- reorder((SHORT far *)&(dirent->value_offset), SHORT_SIZE);
- } else {
- reorder((LONG far *)&(dirent->value_offset), LONG_SIZE);
- }
-
- return(FALSE);
- }
-
- /* return entry count and subfile type of referenced IFD */
- BOOL
- access_ifd(fhandle, offset, dirent, entry_count, subfile_type,
- next_dir_offset)
- SHORT fhandle;
- LONG offset;
- TIFF_DIR_ENTRY far *dirent;
- SHORT *entry_count;
- SHORT *subfile_type;
- LONG *next_dir_offset;
- {
- BOOL retcode = FALSE;
- LONG next_offset;
- LONG lseek();
-
- /* seek to appropriate file position and exit if seek fails */
- if(lseek(fhandle, offset, 0) != offset)
- {
- return(TRUE);
- }
-
- /* attempt to read entry count */
- if(littleRead(fhandle, (SHORT far *)entry_count, (LONG)SHORT_SIZE) <
- SHORT_SIZE)
- {
- return(TRUE);
- }
- offset += SHORT_SIZE;
-
- /* reorder bytes if necessary */
- reorder((SHORT far *)entry_count, SHORT_SIZE);
-
- /* entry count must be >= 1 (for now and maybe forever) */
- if(*entry_count < 1)
- {
- return(TRUE);
- }
-
- /* read directory entry at current file offset and return info */
- if(read_dir(fhandle, dirent))
- {
- return(TRUE);
- }
- offset += TIFF_DIR_ENTRY_SIZE;
-
- /* first entry must be "SubfileType" or else it's an error */
- if(dirent->tag != SUBFILE_TYPE_TAG)
- {
- return(TRUE);
- }
-
- /* retrieve value (subfile type in this case) */
- if(value_of(dirent, (LONGPTR)subfile_type) != DIRECT_VALUE)
- {
- return(TRUE);
- }
-
- /* seek (relative) to end of IFD and read offset of next IFD */
- next_offset = (LONG)*entry_count - 1;
- next_offset *= TIFF_DIR_ENTRY_SIZE;
- if(lseek(fhandle, next_offset, 1) == (LONG)(-1))
- {
- retcode = TRUE;
- }
- else if(littleRead(fhandle, (LONG far *)next_dir_offset, (LONG)LONG_SIZE)
- != LONG_SIZE)
- {
- retcode = TRUE;
- }
-
- /* seek back to where we were before seek to end of IFD */
- if(lseek(fhandle, offset, 0) != offset)
- {
- retcode = TRUE;
- }
- return(retcode);
- }
-
- LONG
- bigRead(fhandle, buffer, size)
- SHORT fhandle;
- LONGPTR buffer;
- LONG size;
- {
- SHORT pages = HIWORD(size);
- unsigned short rest = (unsigned short)LOWORD(size);
- unsigned short bytes;
- unsigned long total = 0;
-
- while(pages-- > 0)
- {
- int repeat = 2;
- while(repeat-- > 0)
- {
- bytes = tlRead(fhandle, buffer, 0x8000);
- total += (unsigned long)bytes;
- if(bytes != 0x8000)
- {
- return((LONG)total);
- }
- buffer += bytes;
- }
- }
- bytes = tlRead(fhandle, buffer, rest);
- total += (unsigned long)bytes;
- return((LONG)total);
- }
-
- LONG littleRead(fhandle,buffer,size)
- SHORT fhandle;
- LONGPTR buffer;
- LONG size;
- {
- long bytes;
-
- bytes = tlRead(fhandle,buffer,size);
-
- return(bytes);
- }
-
- void
- copybytes(to, from, amount)
- LONGPTR to;
- LONGPTR from;
- LONG amount;
- {
- if(!to || !from)
- {
- return;
- }
- while(amount-- > 0)
- {
- *to++ = *from++;
- }
- }
-
- void
- debug(fmt)
- char *fmt;
-
- {
- #ifndef NODEBUG /* vj, 11/10 */
- va_list arg_ptr;
- if(_TIFF_debug_flag)
- {
- #ifndef NOWINDOWS
- unsigned short hdc;
- #endif /* not NOWINDOWS */
- int len;
- va_start(arg_ptr, fmt);
- len = vsprintf(temp, fmt, arg_ptr);
- #ifdef NOWINDOWS
- write(1, temp, len);
- #else
- if(temp[len - 1] == '\n')
- {
- temp[--len] = '\0';
- }
- hdc = GetDC(MainWindow);
- TextOut(hdc, 40, 40, (LONGPTR)temp, len);
- ReleaseDC(MainWindow, hdc);
- #endif /* NOWINDOWS */
- va_end(arg_ptr);
- }
- #endif /* no debug */
- }
-