home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises. All rights reserved.
-
- This file is part of Aladdin Ghostscript.
-
- Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
- or distributor accepts any responsibility for the consequences of using it,
- or for whether it serves any particular purpose or works at all, unless he
- or she says so in writing. Refer to the Aladdin Ghostscript Free Public
- License (the "License") for full details.
-
- Every copy of Aladdin Ghostscript must include a copy of the License,
- normally in a plain ASCII text file named PUBLIC. The License grants you
- the right to copy, modify and redistribute Aladdin Ghostscript, but only
- under certain conditions described in the License. Among other things, the
- License requires that the copyright notice and this notice be preserved on
- all copies.
- */
-
- /* gsmisc.c */
- /* Miscellaneous utilities for Ghostscript library */
- #include "gx.h"
- #include "memory_.h"
- #include "gxfixed.h"
-
- /* Define private replacements for stdin, stdout, and stderr. */
- FILE *gs_stdin, *gs_stdout, *gs_stderr;
- /* Ghostscript writes debugging output to gs_debug_out. */
- /* We define gs_debug and gs_debug_out even if DEBUG isn't defined, */
- /* so that we can compile individual modules with DEBUG set. */
- char gs_debug[128];
- FILE *gs_debug_out;
-
- /* ------ Substitutes for missing C library functions ------ */
-
- #ifdef memory__need_memmove /* see memory_.h */
- /* Copy bytes like memcpy, guaranteed to handle overlap correctly. */
- /* ANSI C defines the returned value as being the src argument, */
- /* but with the const restriction removed! */
- void *
- memmove(void *dest, const void *src, uint len)
- { if ( !len )
- return (void *)src;
- #define bdest ((byte *)dest)
- #define bsrc ((const byte *)src)
- /* We use len-1 for comparisons because adding len */
- /* might produce an offset overflow on segmented systems. */
- if ( ptr_le(bdest, bsrc) )
- { register byte *end = bdest + (len - 1);
- if ( ptr_le(bsrc, end) )
- { /* Source overlaps destination from above. */
- register const byte *from = bsrc;
- register byte *to = bdest;
- for ( ; ; )
- { *to = *from;
- if ( to >= end ) /* faster than = */
- return (void *)src;
- to++; from++;
- }
- }
- }
- else
- { register const byte *from = bsrc + (len - 1);
- if ( ptr_le(bdest, from) )
- { /* Source overlaps destination from below. */
- register const byte *end = bsrc;
- register byte *to = bdest + (len - 1);
- for ( ; ; )
- { *to = *from;
- if ( from <= end ) /* faster than = */
- return (void *)src;
- to--; from--;
- }
- }
- }
- #undef bdest
- #undef bsrc
- /* No overlap, it's safe to use memcpy. */
- memcpy(dest, src, len);
- return (void *)src;
- }
- #endif
-
- #ifdef memory__need_memchr /* see memory_.h */
- /* ch should obviously be char rather than int, */
- /* but the ANSI standard declaration uses int. */
- const char *
- memchr(const char *ptr, int ch, size_t len)
- { if ( len > 0 )
- { register const char *p = ptr;
- register uint count = len;
- do { if ( *p == (char)ch ) return p; p++; } while ( --count );
- }
- return 0;
- }
- #endif
-
- #ifdef memory__need_memset /* see memory_.h */
- /* ch should obviously be char rather than int, */
- /* but the ANSI standard declaration uses int. */
- void *
- memset(void *dest, register int ch, size_t len)
- { if ( ch == 0 )
- bzero(dest, len);
- else if ( len > 0 )
- { register char *p = dest;
- register uint count = len;
- do { *p++ = (char)ch; } while ( --count );
- }
- return dest;
- }
- #endif
-
- /* ------ Debugging support ------ */
-
- /* Dump a region of memory. */
- void
- debug_dump_bytes(const byte *from, const byte *to, const char *msg)
- { const byte *p = from;
- if ( from < to && msg )
- dprintf1("%s:\n", msg);
- while ( p != to )
- { const byte *q = min(p + 16, to);
- dprintf1("0x%lx:", (ulong)p);
- while ( p != q ) dprintf1(" %02x", *p++);
- dputc('\n');
- }
- }
-
- /* ------ Arithmetic ------ */
-
- #if defined(fmul2fixed_vars) && !USE_ASM
-
- /*
- * Floating multiply with fixed result, for avoiding floating point in
- * common coordinate transformations. Assumes IEEE representation,
- * 16-bit short, 32-bit long. Optimized for the case where the first
- * operand has no more than 16 mantissa bits, e.g., where it is a user space
- * coordinate (which are often integers).
- *
- * The assembly language version of this code is actually faster than
- * the FPU, if the code is compiled with FPU_TYPE=0 (which requires taking
- * a trap on every FPU operation). If there is no FPU, the assembly
- * language version of this code is over 10 times as fast as the emulated FPU.
- */
- /* Some of the following code has been tweaked for the Borland 16-bit */
- /* compiler. The tweaks do not change the algorithms. */
- #if arch_ints_are_short && !defined(FOR80386)
- # define SHORT_ARITH
- #endif
- fixed
- fmul2fixed_(long /*float*/ a, long /*float*/ b)
- {
- #ifdef SHORT_ARITH
- # define long_rsh8_ushort(x)\
- (((ushort)(x) >> 8) | ((ushort)((ulong)(x) >> 16) << 8))
- # define utemp ushort
- #else
- # define long_rsh8_ushort(x) ((ushort)((x) >> 8))
- # define utemp ulong
- #endif
- /* utemp may be either ushort or ulong. This is OK because */
- /* we only use ma and mb in multiplications involving */
- /* a long or ulong operand. */
- utemp ma = long_rsh8_ushort(a) | 0x8000;
- utemp mb = long_rsh8_ushort(b) | 0x8000;
- int e = 260 + _fixed_shift - ((
- (((uint)((ulong)a >> 16)) & 0x7f80) +
- (((uint)((ulong)b >> 16)) & 0x7f80)
- ) >> 7);
- ulong p1 = ma * (b & 0xff);
- ulong p = (ulong)ma * mb;
-
- if ( (byte)a ) /* >16 mantissa bits */
- { ulong p2 = (a & 0xff) * mb;
- p += ((((uint)(byte)a * (uint)(byte)b) >> 8) + p1 + p2) >> 8;
- }
- else
- p += p1 >> 8;
- if ( (uint)e < 32 ) /* e = -1 is possible */
- p >>= e;
- else if ( e >= 32 ) /* also detects a=0 or b=0 */
- return fixed_0;
- else
- p <<= -e;
- return ((a ^ b) < 0 ? -p : p);
- }
- fixed
- dfmul2fixed_(ulong /*double lo*/ xalo, long /*float*/ b, long /*double hi*/ xahi)
- {
- #ifdef SHORT_ARITH
- # define long_lsh3(x) ((((x) << 1) << 1) << 1)
- # define long_rsh(x,ng16) ((uint)((x) >> 16) >> (ng16 - 16))
- #else
- # define long_lsh3(x) ((x) << 3)
- # define long_rsh(x,ng16) ((x) >> ng16)
- #endif
- return fmul2fixed_(
- (xahi & 0xc0000000) +
- (long_lsh3(xahi) & 0x3ffffff8) +
- long_rsh(xalo, 29),
- b);
- }
-
- #endif
-