home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / tiff / tif_vms.c < prev    next >
C/C++ Source or Header  |  1999-11-30  |  14KB  |  589 lines

  1. /* $Header: /home/wxcvs/wxWindows/src/tiff/tif_vms.c,v 1.1 1999/11/30 18:42:34 RR Exp $ */
  2.  
  3. /*
  4.  * Copyright (c) 1988-1997 Sam Leffler
  5.  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  6.  *
  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.
  14.  * 
  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.  
  18.  * 
  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 
  24.  * OF THIS SOFTWARE.
  25.  */
  26.  
  27. /*
  28.  * TIFF Library VMS-specific Routines.
  29.  */
  30.  
  31. #include <stdlib.h>
  32. #include <unixio.h>
  33. #include "tiffiop.h"
  34. #if !HAVE_IEEEFP
  35. #include <math.h>
  36. #endif
  37.  
  38. #ifdef VAXC
  39. #define    NOSHARE    noshare
  40. #else
  41. #define    NOSHARE
  42. #endif
  43.  
  44. #ifdef __alpha
  45. /* Dummy entry point for backwards compatibility */
  46. void TIFFModeCCITTFax3(void){}
  47. #endif
  48.  
  49. static tsize_t
  50. _tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
  51. {
  52.     return (read((int) fd, buf, size));
  53. }
  54.  
  55. static tsize_t
  56. _tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
  57. {
  58.     return (write((int) fd, buf, size));
  59. }
  60.  
  61. static toff_t
  62. _tiffSeekProc(thandle_t fd, toff_t off, int whence)
  63. {
  64.     return ((toff_t) lseek((int) fd, (off_t) off, whence));
  65. }
  66.  
  67. static int
  68. _tiffCloseProc(thandle_t fd)
  69. {
  70.     return (close((int) fd));
  71. }
  72.  
  73. #include <sys/stat.h>
  74.  
  75. static toff_t
  76. _tiffSizeProc(thandle_t fd)
  77. {
  78.     struct stat sb;
  79.     return (toff_t) (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size);
  80. }
  81.  
  82. #ifdef HAVE_MMAP
  83. #include <starlet.h>
  84. #include <fab.h>
  85. #include <secdef.h>
  86.  
  87. /*
  88.  * Table for storing information on current open sections. 
  89.  * (Should really be a linked list)
  90.  */
  91. #define MAX_MAPPED 100
  92. static int no_mapped = 0;
  93. static struct {
  94.     char *base;
  95.     char *top;
  96.     unsigned short channel;
  97. } map_table[MAX_MAPPED];
  98.  
  99. /* 
  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
  103.  * example:
  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
  108.  *   or another process
  109.  * - There is no free "hole" in virtual memory that fits the
  110.  *   size of the file
  111.  */
  112. static int
  113. _tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
  114. {
  115.     char name[256];
  116.     struct FAB fab;
  117.     unsigned short channel;
  118.     char *inadr[2], *retadr[2];
  119.     unsigned long status;
  120.     long size;
  121.     
  122.     if (no_mapped >= MAX_MAPPED)
  123.         return(0);
  124.     /*
  125.      * We cannot use a file descriptor, we
  126.      * must open the file once more.
  127.      */
  128.     if (getname((int)fd, name, 1) == NULL)
  129.         return(0);
  130.     /* prepare the FAB for a user file open */
  131.     fab = cc$rms_fab;
  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 */
  138.     if ((status&1) == 0)
  139.         return(0);
  140.     channel = (unsigned short)fab.fab$l_stv;
  141.     inadr[0] = inadr[1] = (char *)0; /* just an address in P0 space */
  142.     /*
  143.      * Map the blocks of the file up to
  144.      * the EOF block into virtual memory.
  145.      */
  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){
  150.         sys$dassgn(channel);
  151.         return(0);
  152.     }
  153.     *pbase = (tdata_t) retadr[0];    /* starting virtual address */
  154.     /*
  155.      * Use the size of the file up to the
  156.      * EOF mark for UNIX compatibility.
  157.      */
  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;
  163.     no_mapped++;
  164.  
  165.         return(1);
  166. }
  167.  
  168. /*
  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.
  172.  */
  173. static void
  174. _tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
  175. {
  176.     char *inadr[2];
  177.     int i, j;
  178.     
  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];
  190.             no_mapped--;
  191.             return;
  192.         }
  193.     }
  194. }
  195. #else /* !HAVE_MMAP */
  196. static int
  197. _tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
  198. {
  199.     return (0);
  200. }
  201.  
  202. static void
  203. _tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
  204. {
  205. }
  206. #endif /* !HAVE_MMAP */
  207.  
  208. /*
  209.  * Open a TIFF file descriptor for read/writing.
  210.  */
  211. TIFF*
  212. TIFFFdOpen(int fd, const char* name, const char* mode)
  213. {
  214.     TIFF* tif;
  215.  
  216.     tif = TIFFClientOpen(name, mode,
  217.         (thandle_t) fd,
  218.         _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc,
  219.         _tiffSizeProc, _tiffMapProc, _tiffUnmapProc);
  220.     if (tif)
  221.         tif->tif_fd = fd;
  222.     return (tif);
  223. }
  224.  
  225. /*
  226.  * Open a TIFF file for read/writing.
  227.  */
  228. TIFF*
  229. TIFFOpen(const char* name, const char* mode)
  230. {
  231.     static const char module[] = "TIFFOpen";
  232.     int m, fd;
  233.  
  234.     m = _TIFFgetMode(mode, module);
  235.     if (m == -1)
  236.         return ((TIFF*)0);
  237.         if (m&O_TRUNC){
  238.                 /*
  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.
  243.                  */
  244.                 fd = creat((char *) /* bug in stdio.h */ name, 0666,
  245.             "alq = 128", "deq = 64", "mbc = 32",
  246.             "fop = tef");
  247.     } else if (m&O_RDWR) {
  248.         fd = open(name, m, 0666,
  249.             "deq = 64", "mbc = 32", "fop = tef", "ctx = stm");
  250.     } else
  251.         fd = open(name, m, 0666, "mbc = 32", "ctx = stm");
  252.     if (fd < 0) {
  253.         TIFFError(module, "%s: Cannot open", name);
  254.         return ((TIFF*)0);
  255.     }
  256.     return (TIFFFdOpen(fd, name, mode));
  257. }
  258.  
  259. tdata_t
  260. _TIFFmalloc(tsize_t s)
  261. {
  262.     return (malloc((size_t) s));
  263. }
  264.  
  265. void
  266. _TIFFfree(tdata_t p)
  267. {
  268.     free(p);
  269. }
  270.  
  271. tdata_t
  272. _TIFFrealloc(tdata_t p, tsize_t s)
  273. {
  274.     return (realloc(p, (size_t) s));
  275. }
  276.  
  277. void
  278. _TIFFmemset(tdata_t p, int v, tsize_t c)
  279. {
  280.     memset(p, v, (size_t) c);
  281. }
  282.  
  283. void
  284. _TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
  285. {
  286.     memcpy(d, s, (size_t) c);
  287. }
  288.  
  289. int
  290. _TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
  291. {
  292.     return (memcmp(p1, p2, (size_t) c));
  293. }
  294.  
  295. /*
  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. 
  299.  * 
  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.
  304.  */
  305.  
  306. static void
  307. vmsWarningHandler(const char* module, const char* fmt, va_list ap)
  308. {
  309.     if (module != NULL)
  310.         fprintf(stderr, "%s: ", module);
  311.     fprintf(stderr, "Warning, ");
  312.     vfprintf(stderr, fmt, ap);
  313.     fprintf(stderr, ".\n");
  314. }
  315.  
  316. NOSHARE TIFFErrorHandler _TIFFwarningHandler = vmsWarningHandler
  317. #if defined(VAX) && defined(__GNUC__)
  318. asm("_$$PsectAttributes_NOSHR$$_TIFFwarningHandler")
  319. #endif
  320. ;
  321.  
  322. static void
  323. vmsErrorHandler(const char* module, const char* fmt, va_list ap)
  324. {
  325.     if (module != NULL)
  326.         fprintf(stderr, "%s: ", module);
  327.     vfprintf(stderr, fmt, ap);
  328.     fprintf(stderr, ".\n");
  329. }
  330.  
  331. NOSHARE TIFFErrorHandler _TIFFerrorHandler = vmsErrorHandler
  332. #if defined(VAX) && defined(__GNUC__)
  333. asm("_$$PsectAttributes_NOSHR$$_TIFFerrorHandler")
  334. #endif
  335. ;
  336.  
  337.  
  338. #if !HAVE_IEEEFP
  339. /* IEEE floting point handling */
  340.  
  341. typedef    struct ieeedouble {
  342.     u_long    mant2;            /* fix NDR: full 8-byte swap */
  343.     u_long    mant    : 20,
  344.         exp    : 11,
  345.         sign    : 1;
  346. } ieeedouble;
  347. typedef    struct ieeefloat {
  348.     u_long    mant    : 23,
  349.         exp    : 8,
  350.         sign    : 1;
  351. } ieeefloat;
  352.  
  353. /* 
  354.  * NB: These are D_FLOAT's, not G_FLOAT's. A G_FLOAT is
  355.  *  simply a reverse-IEEE float/double.
  356.  */
  357.  
  358. typedef    struct {
  359.     u_long    mant1    : 7,
  360.         exp    : 8,
  361.         sign    : 1,
  362.         mant2    : 16,
  363.         mant3   : 16,
  364.         mant4   : 16;
  365. } nativedouble;
  366. typedef    struct {
  367.     u_long    mant1    : 7,
  368.         exp    : 8,
  369.         sign    : 1,
  370.         mant2    : 16;
  371. } nativefloat;
  372.  
  373. typedef    union {
  374.     ieeedouble    ieee;
  375.     nativedouble    native;
  376.     char        b[8];
  377.     uint32        l[2];
  378.     double        d;
  379. } double_t;
  380.  
  381. typedef    union {
  382.     ieeefloat    ieee;
  383.     nativefloat    native;
  384.     char        b[4];
  385.     uint32        l;
  386.     float        f;
  387. } float_t;
  388.  
  389. #if defined(VAXC) || defined(DECC)
  390. #pragma inline(ieeetod,dtoieee)
  391. #endif
  392.  
  393. /*
  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
  399.  * LSB first.)
  400.  * 
  401.  * First longword:
  402.  *    32 least significant bits of mantissa
  403.  * Second longword:
  404.  *    0-19:    20 most significant bits of mantissa
  405.  *    20-30:    exponent
  406.  *    31:    sign
  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.
  415.  * 
  416.  * If the number is too large for the machine or was specified as overflow, 
  417.  * +/-HUGE_VAL is returned.
  418.  */
  419. INLINE static void
  420. ieeetod(double *dp)
  421. {
  422.     double_t source;
  423.     long sign,exp,mant;
  424.     double dmant;
  425.  
  426.     source.ieee = ((double_t*)dp)->ieee;
  427.     sign = source.ieee.sign;
  428.     exp = source.ieee.exp;
  429.     mant = source.ieee.mant;
  430.  
  431.     if (exp == 2047) {
  432.         if (mant)            /* Not a Number (NAN) */
  433.             *dp = HUGE_VAL;
  434.         else                /* +/- infinity */
  435.             *dp = (sign ? -HUGE_VAL : HUGE_VAL);
  436.         return;
  437.     }
  438.     if (!exp) {
  439.         if (!(mant || source.ieee.mant2)) {    /* zero */
  440.             *dp=0;
  441.             return;
  442.         } else {            /* Unnormalized number */
  443.             /* NB: not -1023, the 1 bit is not implied */
  444.             exp= -1022;
  445.         }
  446.     } else {
  447.         mant |= 1<<20;
  448.         exp -= 1023;
  449.     }
  450.     dmant = (((double) mant) +
  451.         ((double) source.ieee.mant2) / (((double) (1<<16)) *
  452.         ((double) (1<<16)))) / (double) (1<<20);
  453.     dmant = ldexp(dmant, exp);
  454.     if (sign)
  455.         dmant= -dmant;
  456.     *dp = dmant;
  457. }
  458.  
  459. INLINE static void
  460. dtoieee(double *dp)
  461. {
  462.     double_t num;
  463.     double x;
  464.     int exp;
  465.  
  466.     num.d = *dp;
  467.     if (!num.d) {            /* Zero is just binary all zeros */
  468.         num.l[0] = num.l[1] = 0;
  469.         return;
  470.     }
  471.  
  472.     if (num.d < 0) {        /* Sign is encoded separately */
  473.         num.d = -num.d;
  474.         num.ieee.sign = 1;
  475.     } else {
  476.         num.ieee.sign = 0;
  477.     }
  478.  
  479.     /* Now separate the absolute value into mantissa and exponent */
  480.     x = frexp(num.d, &exp);
  481.  
  482.     /*
  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.)
  487.      */
  488.     if (exp < -1022) {        /* Unnormalized number */
  489.         x = ldexp(x, -1023-exp);
  490.         exp = 0;
  491.     } else if (exp > 1023) {    /* +/- infinity */
  492.         x = 0;
  493.         exp = 2047;
  494.     } else {            /* Get rid of most significant bit */
  495.         x *= 2;
  496.         x -= 1;
  497.         exp += 1022; /* fix NDR: 1.0 -> x=0.5, exp=1 -> ieee.exp = 1023 */
  498.     }
  499.     num.ieee.exp = exp;
  500.  
  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)));
  505.  
  506.     if (!(num.ieee.mant || num.ieee.exp || num.ieee.mant2)) {
  507.         /* Avoid negative zero */
  508.         num.ieee.sign = 0;
  509.     }
  510.     ((double_t*)dp)->ieee = num.ieee;
  511. }
  512.  
  513. /*
  514.  * Beware, these do not handle over/under-flow
  515.  * during conversion from ieee to native format.
  516.  */
  517. #define    NATIVE2IEEEFLOAT(fp) { \
  518.     float_t t; \
  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; \
  523.     *(fp) = t; \
  524. }
  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; \
  532.     t.native.mant2 = v;\
  533.     *(fp) = t; \
  534. }
  535.  
  536. #define IEEEDOUBLE2NATIVE(dp) ieeetod(dp)
  537.  
  538. #define NATIVE2IEEEDOUBLE(dp) dtoieee(dp)
  539.  
  540.  
  541. /*
  542.  * These unions are used during floating point
  543.  * conversions.  The above macros define the
  544.  * conversion operations.
  545.  */
  546. void
  547. TIFFCvtIEEEFloatToNative(TIFF* tif, u_int n, float* f)
  548. {
  549.     float_t* fp = (float_t*) f;
  550.  
  551.     while (n-- > 0) {
  552.         IEEEFLOAT2NATIVE(fp);
  553.         fp++;
  554.     }
  555. }
  556.  
  557. void
  558. TIFFCvtNativeToIEEEFloat(TIFF* tif, u_int n, float* f)
  559. {
  560.     float_t* fp = (float_t*) f;
  561.  
  562.     while (n-- > 0) {
  563.         NATIVE2IEEEFLOAT(fp);
  564.         fp++;
  565.     }
  566. }
  567. void
  568. TIFFCvtIEEEDoubleToNative(TIFF* tif, u_int n, double* f)
  569. {
  570.     double_t* fp = (double_t*) f;
  571.  
  572.     while (n-- > 0) {
  573.         IEEEDOUBLE2NATIVE(fp);
  574.         fp++;
  575.     }
  576. }
  577.  
  578. void
  579. TIFFCvtNativeToIEEEDouble(TIFF* tif, u_int n, double* f)
  580. {
  581.     double_t* fp = (double_t*) f;
  582.  
  583.     while (n-- > 0) {
  584.         NATIVE2IEEEDOUBLE(fp);
  585.         fp++;
  586.     }
  587. }
  588. #endif
  589.