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

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

/*
* C utilities for the Tag Image File Format routines
*/

#include
#define NODEBUG 1 /* VJ 11/10 */
#define NOWINDOWS
#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 * pascal GlobalLock();
extern BOOL pascal GlobalUnlock();
extern SHORT pascal GlobalAlloc();
extern void pascal GlobalFree();
extern void pascal TextOut();
extern unsigned short pascal GetDC();
extern void pascal ReleaseDC();
extern unsigned short MainWindow;

#define GHND 0x0040 /* fixed + zeroinit */

#endif /* NOWINDOWS */

extern LONG bigRead();

extern BOOL _TIFF_reorder_bytes;
extern BOOL _TIFF_debug_flag;

/* allocate up to one megabyte of data */
LONGPTR
bigalloc(size)
LONG size;
{
return((LONGPTR) malloc ((int) size));
}

/* free data allocated by bigalloc() */
void
bigfree(memptr)
LONGPTR memptr;
{
free (memptr);
}

/* 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 *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 *dirent;
{
LONG littleRead();

if(littleRead(fhandle, dirent, (LONG)TIFF_DIR_ENTRY_SIZE) <
TIFF_DIR_ENTRY_SIZE)
{
return(TRUE);
}

/* reorder bytes if necessary */
reorder((SHORT *)&(dirent->tag), SHORT_SIZE);
reorder((SHORT *)&(dirent->type), SHORT_SIZE);
reorder((LONG *)&(dirent->length), LONG_SIZE);
if(dirent->type == SHORT_TYPE && dirent->length == 1) {
reorder((SHORT *)&(dirent->value_offset), SHORT_SIZE);
} else {
reorder((LONG *)&(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 *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 *)entry_count, (LONG)SHORT_SIZE) <
SHORT_SIZE)
{
return(TRUE);
}
offset += SHORT_SIZE;

/* reorder bytes if necessary */
reorder((SHORT *)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 *)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;
{
return(read ((int) fhandle, buffer, (int) size));
}

LONG littleRead(fhandle,buffer,size)
SHORT fhandle;
LONGPTR buffer;
LONG size;
{
long bytes;

bytes = read (fhandle,buffer,(int) 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 */
}