/* $Id: tif_vms.c,v 1.12 2009/07/14 21:10:27 drolon 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){}
#endif

static 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 100
static 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) {
		TIFFErrorExt(0, 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 void
vmsWarningHandler(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 void
vmsErrorHandler(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 {
	unsigned long	mant2;          /* fix NDR: full 8-byte swap */
	unsigned long	mant	: 20,
		        exp	: 11,
		        sign	: 1;
} ieeedouble;
typedef	struct ieeefloat {
	unsigned 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 {
	unsigned long	mant1	: 7,
		        exp	: 8,
		        sign	: 1,
		        mant2	: 16,
		        mant3   : 16,
		        mant4   : 16;
} nativedouble;
typedef	struct {
	unsigned 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 void
ieeetod(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 void
dtoieee(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.
 */
void
TIFFCvtIEEEFloatToNative(TIFF* tif, u_int n, float* f)
{
	float_t* fp = (float_t*) f;

	while (n-- > 0) {
		IEEEFLOAT2NATIVE(fp);
		fp++;
	}
}

void
TIFFCvtNativeToIEEEFloat(TIFF* tif, u_int n, float* f)
{
	float_t* fp = (float_t*) f;

	while (n-- > 0) {
		NATIVE2IEEEFLOAT(fp);
		fp++;
	}
}
void
TIFFCvtIEEEDoubleToNative(TIFF* tif, u_int n, double* f)
{
	double_t* fp = (double_t*) f;

	while (n-- > 0) {
		IEEEDOUBLE2NATIVE(fp);
		fp++;
	}
}

void
TIFFCvtNativeToIEEEDouble(TIFF* tif, u_int n, double* f)
{
	double_t* fp = (double_t*) f;

	while (n-- > 0) {
		NATIVE2IEEEDOUBLE(fp);
		fp++;
	}
}
#endif
