Back to index

texmacs  1.0.7.15
numbers.c
Go to the documentation of this file.
00001 /*  $Header: /home/cvsroot/dvipdfmx/src/numbers.c,v 1.9 2008/11/30 21:12:27 matthias Exp $
00002 
00003     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
00004 
00005     Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
00006     the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
00007     
00008     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014     
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU General Public License for more details.
00019     
00020     You should have received a copy of the GNU General Public License
00021     along with this program; if not, write to the Free Software
00022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00023 */
00024 
00025 #include "system.h"  
00026 #include "error.h"
00027 #include "mfileio.h"
00028 #include "numbers.h"
00029 
00030 UNSIGNED_BYTE get_unsigned_byte (FILE *file)
00031 {
00032   int ch;
00033   if ((ch = fgetc (file)) < 0)
00034     ERROR ("File ended prematurely\n");
00035   return (UNSIGNED_BYTE) ch;
00036 }
00037 
00038 #if 0
00039 UNSIGNED_BYTE sget_unsigned_byte (char *s)
00040 {
00041   return *((unsigned char *) s);
00042 }
00043 #endif
00044 
00045 SIGNED_BYTE get_signed_byte (FILE *file)
00046 {
00047   int byte;
00048   byte = get_unsigned_byte(file);
00049   if (byte >= 0x80) 
00050     byte -= 0x100;
00051   return (SIGNED_BYTE) byte;
00052 }
00053 
00054 UNSIGNED_PAIR get_unsigned_pair (FILE *file)
00055 {
00056   int i;
00057   UNSIGNED_BYTE byte;
00058   UNSIGNED_PAIR pair = 0;
00059   for (i=0; i<2; i++) {
00060     byte = get_unsigned_byte(file);
00061     pair = pair*0x100u + byte;
00062   }
00063   return pair;
00064 }
00065 
00066 UNSIGNED_PAIR sget_unsigned_pair (unsigned char *s)
00067 {
00068   int i;
00069   UNSIGNED_BYTE byte;
00070   UNSIGNED_PAIR pair = 0;
00071   for (i=0; i<2; i++) {
00072     byte = *(s++);
00073     pair = pair*0x100u + byte;
00074   }
00075   return pair;
00076 }
00077 
00078 SIGNED_PAIR get_signed_pair (FILE *file)
00079 {
00080   int i;
00081   long pair = 0;
00082   for (i=0; i<2; i++) {
00083     pair = pair*0x100 + get_unsigned_byte(file);
00084   }
00085   if (pair >= 0x8000) {
00086     pair -= 0x10000l;
00087   }
00088   return (SIGNED_PAIR) pair;
00089 }
00090 
00091 
00092 UNSIGNED_TRIPLE get_unsigned_triple(FILE *file)
00093 {
00094   int i;
00095   long triple = 0;
00096   for (i=0; i<3; i++) {
00097     triple = triple*0x100u + get_unsigned_byte(file);
00098   }
00099   return (UNSIGNED_TRIPLE) triple;
00100 }
00101 
00102 SIGNED_TRIPLE get_signed_triple(FILE *file)
00103 {
00104   int i;
00105   long triple = 0;
00106   for (i=0; i<3; i++) {
00107     triple = triple*0x100 + get_unsigned_byte(file);
00108   }
00109   if (triple >= 0x800000l) 
00110     triple -= 0x1000000l;
00111   return (SIGNED_TRIPLE) triple;
00112 }
00113 
00114 SIGNED_QUAD get_signed_quad(FILE *file)
00115 {
00116   int byte, i;
00117   long quad = 0;
00118 
00119   /* Check sign on first byte before reading others */
00120   byte = get_unsigned_byte(file);
00121   quad = byte;
00122   if (quad >= 0x80) 
00123     quad = byte - 0x100;
00124   for (i=0; i<3; i++) {
00125     quad = quad*0x100 + get_unsigned_byte(file);
00126   }
00127   return (SIGNED_QUAD) quad;
00128 }
00129 
00130 UNSIGNED_QUAD get_unsigned_quad(FILE *file)
00131 {
00132   int i;
00133   unsigned long quad = 0;
00134   for (i=0; i<4; i++) {
00135     quad = quad*0x100u + get_unsigned_byte(file);
00136   }
00137   return (UNSIGNED_QUAD) quad;
00138 }
00139 
00140 SIGNED_QUAD sqxfw (SIGNED_QUAD sq, fixword fw)
00141 {
00142   int sign = 1;
00143   unsigned long a, b, c, d, ad, bd, bc, ac;
00144   unsigned long e, f, g, h, i, j, k;
00145   unsigned long result;
00146   /* Make positive. */
00147   if (sq < 0) {
00148     sign = -sign;
00149     sq = -sq;
00150   }
00151   if (fw < 0) {
00152     sign = -sign;
00153     fw = -fw;
00154   }
00155   a = ((unsigned long) sq) >> 16u;
00156   b = ((unsigned long) sq) & 0xffffu;
00157   c = ((unsigned long) fw) >> 16u;
00158   d = ((unsigned long) fw) & 0xffffu;
00159   ad = a*d; bd = b*d; bc = b*c; ac = a*c;
00160   e = bd >> 16u;
00161   f = ad >> 16u;
00162   g = ad & 0xffffu;
00163   h = bc >> 16u;
00164   i = bc & 0xffffu;
00165   j = ac >> 16u;
00166   k = ac & 0xffffu;
00167   result = (e+g+i + (1<<3)) >> 4u;  /* 1<<3 is for rounding */
00168   result += (f+h+k) << 12u;
00169   result += j << 28u;
00170   return (sign > 0) ? result : result * -1L;
00171 }
00172 
00173 #if 0
00174 SIGNED_QUAD axboverc (SIGNED_QUAD n1, SIGNED_QUAD n2, SIGNED_QUAD divide)
00175 {
00176   int sign = 1;
00177   unsigned long a, b, c, d, ad, bd, bc, ac, e, f, g, h, i, j, o;
00178   unsigned long high, low;
00179   SIGNED_QUAD result = 0;
00180   /*  Make positive. */
00181   if (n1 < 0) {
00182     sign = -sign;
00183     n1 = -n1;
00184   }
00185   if (n2 < 0) {
00186     sign = -sign;
00187     n2 = -n2;
00188   }
00189   if (divide < 0) {
00190     sign = -sign;
00191     divide = -divide;
00192   }
00193   a = ((unsigned long) n1) >> 16u;
00194   b = ((unsigned long) n1) & 0xffffu;
00195   c = ((unsigned long) n2) >> 16u;
00196   d = ((unsigned long) n2) & 0xffffu;
00197   ad = a*d; bd = b*d; bc = b*c; ac = a*c;
00198   e = bd >> 16u; f = bd & 0xffffu;
00199   g = ad >> 16u; h = ad & 0xffffu;
00200   i = bc >> 16u; j = bc & 0xffffu;
00201   o = e+h+j;
00202   high = g+i+(o>>16u)+ac; o &= 0xffffu;
00203   low = (o << 16) + f;
00204   if (high >= divide)
00205     ERROR ("Overflow in axboc");
00206   {
00207     int k;
00208     for (k=0; k<32; k++) {
00209       high *= 2;
00210       result *= 2;
00211       if (low >= 0x80000000) {
00212        low -= 0x80000000;
00213        high += 1;
00214       }
00215       low *= 2;
00216       if (high > divide) {
00217        high -= divide;
00218        result += 1;
00219       }
00220     }
00221   }
00222   high *= 2;
00223   if (high >= divide)
00224     result += 1;
00225   return (sign>0)?result:-result;
00226 }
00227 #endif
00228