⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tif_vms.c

📁 tiff文件开发库
💻 C
字号:
/* $Header: /cvsroot/osrs/libtiff/libtiff/tif_vms.c,v 1.1.1.1 1999/07/27 21:50:27 mike Exp $ *//* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and  * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. *  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   *  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  * OF THIS SOFTWARE. *//* * TIFF Library VMS-specific Routines. */#include <stdlib.h>#include <unixio.h>#include "tiffiop.h"#if !HAVE_IEEEFP#include <math.h>#endif#ifdef VAXC#define	NOSHARE	noshare#else#define	NOSHARE#endif#ifdef __alpha/* Dummy entry point for backwards compatibility */void TIFFModeCCITTFax3(void){}#endifstatic tsize_t_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size){	return (read((int) fd, buf, size));}static tsize_t_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size){	return (write((int) fd, buf, size));}static toff_t_tiffSeekProc(thandle_t fd, toff_t off, int whence){	return ((toff_t) lseek((int) fd, (off_t) off, whence));}static int_tiffCloseProc(thandle_t fd){	return (close((int) fd));}#include <sys/stat.h>static toff_t_tiffSizeProc(thandle_t fd){	struct stat sb;	return (toff_t) (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size);}#ifdef HAVE_MMAP#include <starlet.h>#include <fab.h>#include <secdef.h>/* * Table for storing information on current open sections.  * (Should really be a linked list) */#define MAX_MAPPED 100static int no_mapped = 0;static struct {	char *base;	char *top;	unsigned short channel;} map_table[MAX_MAPPED];/*  * This routine maps a file into a private section. Note that this  * method of accessing a file is by far the fastest under VMS. * The routine may fail (i.e. return 0) for several reasons, for * example: * - There is no more room for storing the info on sections. * - The process is out of open file quota, channels, ... * - fd does not describe an opened file. * - The file is already opened for write access by this process *   or another process * - There is no free "hole" in virtual memory that fits the *   size of the file */static int_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize){	char name[256];	struct FAB fab;	unsigned short channel;	char *inadr[2], *retadr[2];	unsigned long status;	long size;		if (no_mapped >= MAX_MAPPED)		return(0);	/*	 * We cannot use a file descriptor, we	 * must open the file once more.	 */	if (getname((int)fd, name, 1) == NULL)		return(0);	/* prepare the FAB for a user file open */	fab = cc$rms_fab;	fab.fab$l_fop |= FAB$V_UFO;	fab.fab$b_fac = FAB$M_GET;	fab.fab$b_shr = FAB$M_SHRGET;	fab.fab$l_fna = name;	fab.fab$b_fns = strlen(name);	status = sys$open(&fab);	/* open file & get channel number */	if ((status&1) == 0)		return(0);	channel = (unsigned short)fab.fab$l_stv;	inadr[0] = inadr[1] = (char *)0; /* just an address in P0 space */	/*	 * Map the blocks of the file up to	 * the EOF block into virtual memory.	 */	size = _tiffSizeProc(fd);	status = sys$crmpsc(inadr, retadr, 0, SEC$M_EXPREG, 0,0,0, channel,		TIFFhowmany(size,512), 0,0,0);	if ((status&1) == 0){		sys$dassgn(channel);		return(0);	}	*pbase = (tdata_t) retadr[0];	/* starting virtual address */	/*	 * Use the size of the file up to the	 * EOF mark for UNIX compatibility.	 */	*psize = (toff_t) size;	/* Record the section in the table */	map_table[no_mapped].base = retadr[0];	map_table[no_mapped].top = retadr[1];	map_table[no_mapped].channel = channel;	no_mapped++;        return(1);}/* * This routine unmaps a section from the virtual address space of  * the process, but only if the base was the one returned from a * call to TIFFMapFileContents. */static void_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size){	char *inadr[2];	int i, j;		/* Find the section in the table */	for (i = 0;i < no_mapped; i++) {		if (map_table[i].base == (char *) base) {			/* Unmap the section */			inadr[0] = (char *) base;			inadr[1] = map_table[i].top;			sys$deltva(inadr, 0, 0);			sys$dassgn(map_table[i].channel);			/* Remove this section from the list */			for (j = i+1; j < no_mapped; j++)				map_table[j-1] = map_table[j];			no_mapped--;			return;		}	}}#else /* !HAVE_MMAP */static int_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize){	return (0);}static void_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size){}#endif /* !HAVE_MMAP *//* * Open a TIFF file descriptor for read/writing. */TIFF*TIFFFdOpen(int fd, const char* name, const char* mode){	TIFF* tif;	tif = TIFFClientOpen(name, mode,	    (thandle_t) fd,	    _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,	    _tiffSizeProc, _tiffMapProc, _tiffUnmapProc);	if (tif)		tif->tif_fd = fd;	return (tif);}/* * Open a TIFF file for read/writing. */TIFF*TIFFOpen(const char* name, const char* mode){	static const char module[] = "TIFFOpen";	int m, fd;	m = _TIFFgetMode(mode, module);	if (m == -1)		return ((TIFF*)0);        if (m&O_TRUNC){                /*		 * There is a bug in open in VAXC. If you use		 * open w/ m=O_RDWR|O_CREAT|O_TRUNC the		 * wrong thing happens.  On the other hand		 * creat does the right thing.                 */                fd = creat((char *) /* bug in stdio.h */ name, 0666,		    "alq = 128", "deq = 64", "mbc = 32",		    "fop = tef");	} else if (m&O_RDWR) {		fd = open(name, m, 0666,		    "deq = 64", "mbc = 32", "fop = tef", "ctx = stm");	} else		fd = open(name, m, 0666, "mbc = 32", "ctx = stm");	if (fd < 0) {		TIFFError(module, "%s: Cannot open", name);		return ((TIFF*)0);	}	return (TIFFFdOpen(fd, name, mode));}tdata_t_TIFFmalloc(tsize_t s){	return (malloc((size_t) s));}void_TIFFfree(tdata_t p){	free(p);}tdata_t_TIFFrealloc(tdata_t p, tsize_t s){	return (realloc(p, (size_t) s));}void_TIFFmemset(tdata_t p, int v, tsize_t c){	memset(p, v, (size_t) c);}void_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c){	memcpy(d, s, (size_t) c);}int_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c){	return (memcmp(p1, p2, (size_t) c));}/* * On the VAX, we need to make those global, writable pointers * non-shareable, otherwise they would be made shareable by default. * On the AXP, this brain damage has been corrected.  *  * I (Karsten Spang, krs@kampsax.dk) have dug around in the GCC * manual and the GAS code and have come up with the following * construct, but I don't have GCC on my VAX, so it is untested. * Please tell me if it does not work. */static voidvmsWarningHandler(const char* module, const char* fmt, va_list ap){	if (module != NULL)		fprintf(stderr, "%s: ", module);	fprintf(stderr, "Warning, ");	vfprintf(stderr, fmt, ap);	fprintf(stderr, ".\n");}NOSHARE TIFFErrorHandler _TIFFwarningHandler = vmsWarningHandler#if defined(VAX) && defined(__GNUC__)asm("_$$PsectAttributes_NOSHR$$_TIFFwarningHandler")#endif;static voidvmsErrorHandler(const char* module, const char* fmt, va_list ap){	if (module != NULL)		fprintf(stderr, "%s: ", module);	vfprintf(stderr, fmt, ap);	fprintf(stderr, ".\n");}NOSHARE TIFFErrorHandler _TIFFerrorHandler = vmsErrorHandler#if defined(VAX) && defined(__GNUC__)asm("_$$PsectAttributes_NOSHR$$_TIFFerrorHandler")#endif;#if !HAVE_IEEEFP/* IEEE floting point handling */typedef	struct ieeedouble {	u_long	mant2;			/* fix NDR: full 8-byte swap */	u_long	mant	: 20,		exp	: 11,		sign	: 1;} ieeedouble;typedef	struct ieeefloat {	u_long	mant	: 23,		exp	: 8,		sign	: 1;} ieeefloat;/*  * NB: These are D_FLOAT's, not G_FLOAT's. A G_FLOAT is *  simply a reverse-IEEE float/double. */typedef	struct {	u_long	mant1	: 7,		exp	: 8,		sign	: 1,		mant2	: 16,		mant3   : 16,		mant4   : 16;} nativedouble;typedef	struct {	u_long	mant1	: 7,		exp	: 8,		sign	: 1,		mant2	: 16;} nativefloat;typedef	union {	ieeedouble	ieee;	nativedouble	native;	char		b[8];	uint32		l[2];	double		d;} double_t;typedef	union {	ieeefloat	ieee;	nativefloat	native;	char		b[4];	uint32		l;	float		f;} float_t;#if defined(VAXC) || defined(DECC)#pragma inline(ieeetod,dtoieee)#endif/* * Convert an IEEE double precision number to native double precision. * The source is contained in two longwords, the second holding the sign, * exponent and the higher order bits of the mantissa, and the first * holding the rest of the mantissa as follows: * (Note: It is assumed that the number has been eight-byte swapped to * LSB first.) *  * First longword: *	32 least significant bits of mantissa * Second longword: *	0-19:	20 most significant bits of mantissa *	20-30:	exponent *	31:	sign * The exponent is stored as excess 1023. * The most significant bit of the mantissa is implied 1, and not stored. * If the exponent and mantissa are zero, the number is zero. * If the exponent is 0 (i.e. -1023) and the mantissa is non-zero, it is an * unnormalized number with the most significant bit NOT implied. * If the exponent is 2047, the number is invalid, in case the mantissa is zero, * this means overflow (+/- depending of the sign bit), otherwise * it simply means invalid number. *  * If the number is too large for the machine or was specified as overflow,  * +/-HUGE_VAL is returned. */INLINE static voidieeetod(double *dp){	double_t source;	long sign,exp,mant;	double dmant;	source.ieee = ((double_t*)dp)->ieee;	sign = source.ieee.sign;	exp = source.ieee.exp;	mant = source.ieee.mant;	if (exp == 2047) {		if (mant)			/* Not a Number (NAN) */			*dp = HUGE_VAL;		else				/* +/- infinity */			*dp = (sign ? -HUGE_VAL : HUGE_VAL);		return;	}	if (!exp) {		if (!(mant || source.ieee.mant2)) {	/* zero */			*dp=0;			return;		} else {			/* Unnormalized number */			/* NB: not -1023, the 1 bit is not implied */			exp= -1022;		}	} else {		mant |= 1<<20;		exp -= 1023;	}	dmant = (((double) mant) +		((double) source.ieee.mant2) / (((double) (1<<16)) *		((double) (1<<16)))) / (double) (1<<20);	dmant = ldexp(dmant, exp);	if (sign)		dmant= -dmant;	*dp = dmant;}INLINE static voiddtoieee(double *dp){	double_t num;	double x;	int exp;	num.d = *dp;	if (!num.d) {			/* Zero is just binary all zeros */		num.l[0] = num.l[1] = 0;		return;	}	if (num.d < 0) {		/* Sign is encoded separately */		num.d = -num.d;		num.ieee.sign = 1;	} else {		num.ieee.sign = 0;	}	/* Now separate the absolute value into mantissa and exponent */	x = frexp(num.d, &exp);	/*	 * Handle cases where the value is outside the	 * range for IEEE floating point numbers. 	 * (Overflow cannot happen on a VAX, but underflow	 * can happen for G float.)	 */	if (exp < -1022) {		/* Unnormalized number */		x = ldexp(x, -1023-exp);		exp = 0;	} else if (exp > 1023) {	/* +/- infinity */		x = 0;		exp = 2047;	} else {			/* Get rid of most significant bit */		x *= 2;		x -= 1;		exp += 1022; /* fix NDR: 1.0 -> x=0.5, exp=1 -> ieee.exp = 1023 */	}	num.ieee.exp = exp;	x *= (double) (1<<20);	num.ieee.mant = (long) x;	x -= (double) num.ieee.mant;	num.ieee.mant2 = (long) (x*((double) (1<<16)*(double) (1<<16)));	if (!(num.ieee.mant || num.ieee.exp || num.ieee.mant2)) {		/* Avoid negative zero */		num.ieee.sign = 0;	}	((double_t*)dp)->ieee = num.ieee;}/* * Beware, these do not handle over/under-flow * during conversion from ieee to native format. */#define	NATIVE2IEEEFLOAT(fp) { \    float_t t; \    if (t.ieee.exp = (fp)->native.exp) \	t.ieee.exp += -129 + 127; \    t.ieee.sign = (fp)->native.sign; \    t.ieee.mant = ((fp)->native.mant1<<16)|(fp)->native.mant2; \    *(fp) = t; \}#define	IEEEFLOAT2NATIVE(fp) { \    float_t t; int v = (fp)->ieee.exp; \    if (v) v += -127 + 129;		/* alter bias of exponent */\    t.native.exp = v;			/* implicit truncation of exponent */\    t.native.sign = (fp)->ieee.sign; \    v = (fp)->ieee.mant; \    t.native.mant1 = v >> 16; \    t.native.mant2 = v;\    *(fp) = t; \}#define IEEEDOUBLE2NATIVE(dp) ieeetod(dp)#define NATIVE2IEEEDOUBLE(dp) dtoieee(dp)/* * These unions are used during floating point * conversions.  The above macros define the * conversion operations. */voidTIFFCvtIEEEFloatToNative(TIFF* tif, u_int n, float* f){	float_t* fp = (float_t*) f;	while (n-- > 0) {		IEEEFLOAT2NATIVE(fp);		fp++;	}}voidTIFFCvtNativeToIEEEFloat(TIFF* tif, u_int n, float* f){	float_t* fp = (float_t*) f;	while (n-- > 0) {		NATIVE2IEEEFLOAT(fp);		fp++;	}}voidTIFFCvtIEEEDoubleToNative(TIFF* tif, u_int n, double* f){	double_t* fp = (double_t*) f;	while (n-- > 0) {		IEEEDOUBLE2NATIVE(fp);		fp++;	}}voidTIFFCvtNativeToIEEEDouble(TIFF* tif, u_int n, double* f){	double_t* fp = (double_t*) f;	while (n-- > 0) {		NATIVE2IEEEDOUBLE(fp);		fp++;	}}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -