4  * Copyright (c) 1988-1997 Sam Leffler 
   5  * Copyright (c) 1991-1997 Silicon Graphics, Inc. 
   7  * Permission to use, copy, modify, distribute, and sell this software and  
   8  * its documentation for any purpose is hereby granted without fee, provided 
   9  * that (i) the above copyright notices and this permission notice appear in 
  10  * all copies of the software and related documentation, and (ii) the names of 
  11  * Sam Leffler and Silicon Graphics may not be used in any advertising or 
  12  * publicity relating to the software without the specific, prior written 
  13  * permission of Sam Leffler and Silicon Graphics. 
  15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  
  16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  
  17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   
  19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 
  20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 
  21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  
  23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  
  28  * TIFF Library VMS-specific Routines. 
  39 #define NOSHARE noshare 
  45 /* Dummy entry point for backwards compatibility */ 
  46 void TIFFModeCCITTFax3(void){} 
  50 _tiffReadProc(thandle_t fd
, tdata_t buf
, tsize_t size
) 
  52         return (read((int) fd
, buf
, size
)); 
  56 _tiffWriteProc(thandle_t fd
, tdata_t buf
, tsize_t size
) 
  58         return (write((int) fd
, buf
, size
)); 
  62 _tiffSeekProc(thandle_t fd
, toff_t off
, int whence
) 
  64         return ((toff_t
) lseek((int) fd
, (off_t
) off
, whence
)); 
  68 _tiffCloseProc(thandle_t fd
) 
  70         return (close((int) fd
)); 
  76 _tiffSizeProc(thandle_t fd
) 
  79         return (toff_t
) (fstat((int) fd
, &sb
) < 0 ? 0 : sb
.st_size
); 
  88  * Table for storing information on current open sections.  
  89  * (Should really be a linked list) 
  91 #define MAX_MAPPED 100 
  92 static int no_mapped 
= 0; 
  96         unsigned short channel
; 
  97 } map_table
[MAX_MAPPED
]; 
 100  * This routine maps a file into a private section. Note that this  
 101  * method of accessing a file is by far the fastest under VMS. 
 102  * The routine may fail (i.e. return 0) for several reasons, for 
 104  * - There is no more room for storing the info on sections. 
 105  * - The process is out of open file quota, channels, ... 
 106  * - fd does not describe an opened file. 
 107  * - The file is already opened for write access by this process 
 109  * - There is no free "hole" in virtual memory that fits the 
 113 _tiffMapProc(thandle_t fd
, tdata_t
* pbase
, toff_t
* psize
) 
 117         unsigned short channel
; 
 118         char *inadr
[2], *retadr
[2]; 
 119         unsigned long status
; 
 122         if (no_mapped 
>= MAX_MAPPED
) 
 125          * We cannot use a file descriptor, we 
 126          * must open the file once more. 
 128         if (getname((int)fd
, name
, 1) == NULL
) 
 130         /* prepare the FAB for a user file open */ 
 132         fab
.fab$l_fop 
|= FAB$V_UFO
; 
 133         fab
.fab$b_fac 
= FAB$M_GET
; 
 134         fab
.fab$b_shr 
= FAB$M_SHRGET
; 
 135         fab
.fab$l_fna 
= name
; 
 136         fab
.fab$b_fns 
= strlen(name
); 
 137         status 
= sys$
open(&fab
);        /* open file & get channel number */ 
 140         channel 
= (unsigned short)fab
.fab$l_stv
; 
 141         inadr
[0] = inadr
[1] = (char *)0; /* just an address in P0 space */ 
 143          * Map the blocks of the file up to 
 144          * the EOF block into virtual memory. 
 146         size 
= _tiffSizeProc(fd
); 
 147         status 
= sys$
crmpsc(inadr
, retadr
, 0, SEC$M_EXPREG
, 0,0,0, channel
, 
 148                 TIFFhowmany(size
,512), 0,0,0); 
 149         if ((status
&1) == 0){ 
 153         *pbase 
= (tdata_t
) retadr
[0];   /* starting virtual address */ 
 155          * Use the size of the file up to the 
 156          * EOF mark for UNIX compatibility. 
 158         *psize 
= (toff_t
) size
; 
 159         /* Record the section in the table */ 
 160         map_table
[no_mapped
].base 
= retadr
[0]; 
 161         map_table
[no_mapped
].top 
= retadr
[1]; 
 162         map_table
[no_mapped
].channel 
= channel
; 
 169  * This routine unmaps a section from the virtual address space of  
 170  * the process, but only if the base was the one returned from a 
 171  * call to TIFFMapFileContents. 
 174 _tiffUnmapProc(thandle_t fd
, tdata_t base
, toff_t size
) 
 179         /* Find the section in the table */ 
 180         for (i 
= 0;i 
< no_mapped
; i
++) { 
 181                 if (map_table
[i
].base 
== (char *) base
) { 
 182                         /* Unmap the section */ 
 183                         inadr
[0] = (char *) base
; 
 184                         inadr
[1] = map_table
[i
].top
; 
 185                         sys$
deltva(inadr
, 0, 0); 
 186                         sys$
dassgn(map_table
[i
].channel
); 
 187                         /* Remove this section from the list */ 
 188                         for (j 
= i
+1; j 
< no_mapped
; j
++) 
 189                                 map_table
[j
-1] = map_table
[j
]; 
 195 #else /* !HAVE_MMAP */ 
 197 _tiffMapProc(thandle_t fd
, tdata_t
* pbase
, toff_t
* psize
) 
 203 _tiffUnmapProc(thandle_t fd
, tdata_t base
, toff_t size
) 
 206 #endif /* !HAVE_MMAP */ 
 209  * Open a TIFF file descriptor for read/writing. 
 212 TIFFFdOpen(int fd
, const char* name
, const char* mode
) 
 216         tif 
= TIFFClientOpen(name
, mode
, 
 218             _tiffReadProc
, _tiffWriteProc
, _tiffSeekProc
, _tiffCloseProc
, 
 219             _tiffSizeProc
, _tiffMapProc
, _tiffUnmapProc
); 
 226  * Open a TIFF file for read/writing. 
 229 TIFFOpen(const char* name
, const char* mode
) 
 231         static const char module[] = "TIFFOpen"; 
 234         m 
= _TIFFgetMode(mode
, module); 
 239                  * There is a bug in open in VAXC. If you use 
 240                  * open w/ m=O_RDWR|O_CREAT|O_TRUNC the 
 241                  * wrong thing happens.  On the other hand 
 242                  * creat does the right thing. 
 244                 fd 
= creat((char *) /* bug in stdio.h */ name
, 0666, 
 245                     "alq = 128", "deq = 64", "mbc = 32", 
 247         } else if (m
&O_RDWR
) { 
 248                 fd 
= open(name
, m
, 0666, 
 249                     "deq = 64", "mbc = 32", "fop = tef", "ctx = stm"); 
 251                 fd 
= open(name
, m
, 0666, "mbc = 32", "ctx = stm"); 
 253                 TIFFError(module, "%s: Cannot open", name
); 
 256         return (TIFFFdOpen(fd
, name
, mode
)); 
 260 _TIFFmalloc(tsize_t s
) 
 262         return (malloc((size_t) s
)); 
 272 _TIFFrealloc(tdata_t p
, tsize_t s
) 
 274         return (realloc(p
, (size_t) s
)); 
 278 _TIFFmemset(tdata_t p
, int v
, tsize_t c
) 
 280         memset(p
, v
, (size_t) c
); 
 284 _TIFFmemcpy(tdata_t d
, const tdata_t s
, tsize_t c
) 
 286         memcpy(d
, s
, (size_t) c
); 
 290 _TIFFmemcmp(const tdata_t p1
, const tdata_t p2
, tsize_t c
) 
 292         return (memcmp(p1
, p2
, (size_t) c
)); 
 296  * On the VAX, we need to make those global, writable pointers 
 297  * non-shareable, otherwise they would be made shareable by default. 
 298  * On the AXP, this brain damage has been corrected.  
 300  * I (Karsten Spang, krs@kampsax.dk) have dug around in the GCC 
 301  * manual and the GAS code and have come up with the following 
 302  * construct, but I don't have GCC on my VAX, so it is untested. 
 303  * Please tell me if it does not work. 
 307 vmsWarningHandler(const char* module, const char* fmt
, va_list ap
) 
 310                 fprintf(stderr
, "%s: ", module); 
 311         fprintf(stderr
, "Warning, "); 
 312         vfprintf(stderr
, fmt
, ap
); 
 313         fprintf(stderr
, ".\n"); 
 316 NOSHARE TIFFErrorHandler _TIFFwarningHandler 
= vmsWarningHandler
 
 317 #if defined(VAX) && defined(__GNUC__) 
 318 asm("_$$PsectAttributes_NOSHR$$_TIFFwarningHandler") 
 323 vmsErrorHandler(const char* module, const char* fmt
, va_list ap
) 
 326                 fprintf(stderr
, "%s: ", module); 
 327         vfprintf(stderr
, fmt
, ap
); 
 328         fprintf(stderr
, ".\n"); 
 331 NOSHARE TIFFErrorHandler _TIFFerrorHandler 
= vmsErrorHandler
 
 332 #if defined(VAX) && defined(__GNUC__) 
 333 asm("_$$PsectAttributes_NOSHR$$_TIFFerrorHandler") 
 339 /* IEEE floting point handling */ 
 341 typedef struct ieeedouble 
{ 
 342         u_long  mant2
;                  /* fix NDR: full 8-byte swap */ 
 347 typedef struct ieeefloat 
{ 
 354  * NB: These are D_FLOAT's, not G_FLOAT's. A G_FLOAT is 
 355  *  simply a reverse-IEEE float/double. 
 389 #if defined(VAXC) || defined(DECC) 
 390 #pragma inline(ieeetod,dtoieee) 
 394  * Convert an IEEE double precision number to native double precision. 
 395  * The source is contained in two longwords, the second holding the sign, 
 396  * exponent and the higher order bits of the mantissa, and the first 
 397  * holding the rest of the mantissa as follows: 
 398  * (Note: It is assumed that the number has been eight-byte swapped to 
 402  *      32 least significant bits of mantissa 
 404  *      0-19:   20 most significant bits of mantissa 
 407  * The exponent is stored as excess 1023. 
 408  * The most significant bit of the mantissa is implied 1, and not stored. 
 409  * If the exponent and mantissa are zero, the number is zero. 
 410  * If the exponent is 0 (i.e. -1023) and the mantissa is non-zero, it is an 
 411  * unnormalized number with the most significant bit NOT implied. 
 412  * If the exponent is 2047, the number is invalid, in case the mantissa is zero, 
 413  * this means overflow (+/- depending of the sign bit), otherwise 
 414  * it simply means invalid number. 
 416  * If the number is too large for the machine or was specified as overflow,  
 417  * +/-HUGE_VAL is returned. 
 426         source
.ieee 
= ((double_t
*)dp
)->ieee
; 
 427         sign 
= source
.ieee
.sign
; 
 428         exp 
= source
.ieee
.exp
; 
 429         mant 
= source
.ieee
.mant
; 
 432                 if (mant
)                       /* Not a Number (NAN) */ 
 434                 else                            /* +/- infinity */ 
 435                         *dp 
= (sign 
? -HUGE_VAL 
: HUGE_VAL
); 
 439                 if (!(mant 
|| source
.ieee
.mant2
)) {     /* zero */ 
 442                 } else {                        /* Unnormalized number */ 
 443                         /* NB: not -1023, the 1 bit is not implied */ 
 450         dmant 
= (((double) mant
) + 
 451                 ((double) source
.ieee
.mant2
) / (((double) (1<<16)) * 
 452                 ((double) (1<<16)))) / (double) (1<<20); 
 453         dmant 
= ldexp(dmant
, exp
); 
 467         if (!num
.d
) {                   /* Zero is just binary all zeros */ 
 468                 num
.l
[0] = num
.l
[1] = 0; 
 472         if (num
.d 
< 0) {                /* Sign is encoded separately */ 
 479         /* Now separate the absolute value into mantissa and exponent */ 
 480         x 
= frexp(num
.d
, &exp
); 
 483          * Handle cases where the value is outside the 
 484          * range for IEEE floating point numbers.  
 485          * (Overflow cannot happen on a VAX, but underflow 
 486          * can happen for G float.) 
 488         if (exp 
< -1022) {              /* Unnormalized number */ 
 489                 x 
= ldexp(x
, -1023-exp
); 
 491         } else if (exp 
> 1023) {        /* +/- infinity */ 
 494         } else {                        /* Get rid of most significant bit */ 
 497                 exp 
+= 1022; /* fix NDR: 1.0 -> x=0.5, exp=1 -> ieee.exp = 1023 */ 
 501         x 
*= (double) (1<<20); 
 502         num
.ieee
.mant 
= (long) x
; 
 503         x 
-= (double) num
.ieee
.mant
; 
 504         num
.ieee
.mant2 
= (long) (x
*((double) (1<<16)*(double) (1<<16))); 
 506         if (!(num
.ieee
.mant 
|| num
.ieee
.exp 
|| num
.ieee
.mant2
)) { 
 507                 /* Avoid negative zero */ 
 510         ((double_t
*)dp
)->ieee 
= num
.ieee
; 
 514  * Beware, these do not handle over/under-flow 
 515  * during conversion from ieee to native format. 
 517 #define NATIVE2IEEEFLOAT(fp) { \ 
 519     if (t.ieee.exp = (fp)->native.exp) \ 
 520         t.ieee.exp += -129 + 127; \ 
 521     t.ieee.sign = (fp)->native.sign; \ 
 522     t.ieee.mant = ((fp)->native.mant1<<16)|(fp)->native.mant2; \ 
 525 #define IEEEFLOAT2NATIVE(fp) { \ 
 526     float_t t; int v = (fp)->ieee.exp; \ 
 527     if (v) v += -127 + 129;             /* alter bias of exponent */\ 
 528     t.native.exp = v;                   /* implicit truncation of exponent */\ 
 529     t.native.sign = (fp)->ieee.sign; \ 
 530     v = (fp)->ieee.mant; \ 
 531     t.native.mant1 = v >> 16; \ 
 536 #define IEEEDOUBLE2NATIVE(dp) ieeetod(dp) 
 538 #define NATIVE2IEEEDOUBLE(dp) dtoieee(dp) 
 542  * These unions are used during floating point 
 543  * conversions.  The above macros define the 
 544  * conversion operations. 
 547 TIFFCvtIEEEFloatToNative(TIFF
* tif
, u_int n
, float* f
) 
 549         float_t
* fp 
= (float_t
*) f
; 
 552                 IEEEFLOAT2NATIVE(fp
); 
 558 TIFFCvtNativeToIEEEFloat(TIFF
* tif
, u_int n
, float* f
) 
 560         float_t
* fp 
= (float_t
*) f
; 
 563                 NATIVE2IEEEFLOAT(fp
); 
 568 TIFFCvtIEEEDoubleToNative(TIFF
* tif
, u_int n
, double* f
) 
 570         double_t
* fp 
= (double_t
*) f
; 
 573                 IEEEDOUBLE2NATIVE(fp
); 
 579 TIFFCvtNativeToIEEEDouble(TIFF
* tif
, u_int n
, double* f
) 
 581         double_t
* fp 
= (double_t
*) f
; 
 584                 NATIVE2IEEEDOUBLE(fp
);