Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

549 lines
14 KiB

  1. /* @(#)CM_VerSion xcf_fp.c atm09 1.3 16499.eco sum= 31680 atm09.002 */
  2. /* @(#)CM_VerSion xcf_fp.c atm08 1.3 16343.eco sum= 19313 atm08.005 */
  3. /***********************************************************************/
  4. /* */
  5. /* Copyright 1990-1996 Adobe Systems Incorporated. */
  6. /* All rights reserved. */
  7. /* */
  8. /* Patents Pending */
  9. /* */
  10. /* NOTICE: All information contained herein is the property of Adobe */
  11. /* Systems Incorporated. Many of the intellectual and technical */
  12. /* concepts contained herein are proprietary to Adobe, are protected */
  13. /* as trade secrets, and are made available only to Adobe licensees */
  14. /* for their internal use. Any reproduction or dissemination of this */
  15. /* software is strictly forbidden unless prior written permission is */
  16. /* obtained from Adobe. */
  17. /* */
  18. /* PostScript and Display PostScript are trademarks of Adobe Systems */
  19. /* Incorporated or its subsidiaries and may be registered in certain */
  20. /* jurisdictions. */
  21. /* */
  22. /***********************************************************************
  23. * SCCS Id: %W%
  24. * Changed: %G% %U%
  25. ***********************************************************************/
  26. /*
  27. * Fixed point multiply, divide, and conversions.
  28. * The double-to-int conversion is assumed to truncate rather than round;
  29. * this is specified by the C language manual. The direction of truncation
  30. * is machine-dependent, but is toward zero rather than toward minus
  31. * infinity on the Vax and Sun. This explains the peculiar way in which
  32. * fixmul and fixdiv do rounding.
  33. */
  34. #include "xcf_priv.h"
  35. #if (USE_FIXMUL == USE_HWFP)
  36. Fixed XCF_FixMul(Fixed x, Fixed y) /* returns x*y */
  37. {
  38. double d = (double) x * (double) y / fixedScale;
  39. d += (d < 0)? -0.5 : 0.5;
  40. if (d >= FixedPosInf) return FixedPosInf;
  41. if (d <= FixedNegInf) return FixedNegInf;
  42. return (Fixed) d;
  43. }
  44. #endif
  45. #if (USE_FIXMUL == USE_SWFP)
  46. Fixed XCF_SWFixMul(Fixed x, Fixed y);
  47. Fixed XCF_SWFixMul(Fixed x, Fixed y) /* returns x*y */
  48. {
  49. Int32 xu, yu, up, sign;
  50. if (x && y) {
  51. sign = x ^ y;
  52. if (x < 0) x = -x;
  53. if (y < 0) y = -y;
  54. xu = x >> 16; x = x & 0xffff;
  55. yu = y >> 16; y = y & 0xffff;
  56. up = (xu * yu);
  57. if (!(up >> 15)) { /* overflow */
  58. x = (x * yu) + (xu * y) + (up << 16) +
  59. ((((unsigned int)(x * y) >> 15) + 1) >> 1);
  60. if (x >= 0) return (sign < 0) ? -x : x;
  61. }
  62. return (sign < 0) ? FixedNegInf : FixedPosInf;
  63. }
  64. return 0;
  65. }
  66. #endif
  67. #if (USE_FIXDIV == USE_HWFP)
  68. Fixed XCF_FixDiv(Fixed x, Fixed y) /* returns x/y */
  69. {
  70. double d;
  71. if (y == 0) return (x < 0)? FixedNegInf : FixedPosInf;
  72. d = (double) x / (double) y * fixedScale;
  73. d += (d < 0)? -0.5 : 0.5;
  74. if (d >= FixedPosInf) return FixedPosInf;
  75. if (d <= FixedNegInf) return FixedNegInf;
  76. return (Fixed) d;
  77. }
  78. #endif
  79. #if (USE_FIXDIV == USE_SWFP)
  80. Fixed XCF_SWFixDiv(Fixed i, Fixed j);
  81. Fixed XCF_SWFixDiv(Fixed i, Fixed j)
  82. {
  83. Int32 q,m;
  84. unsigned int sign = (unsigned int)((i ^ j) >> 31) & 1; /* should not need & */
  85. if (i) { /* zero divided by anything is zero */
  86. if (j) { /* divide by zero is infinity */
  87. if (i < 0) i = -i; /* get absolute value for unsigned divide */
  88. if (j < 0) j = -j; /* get absolute value for unsigned divide */
  89. q = i / j; /* do the divide */
  90. m = i % j; /* and remainder -- same operation? */
  91. if (!(q >> 15)) { /* otherwise it's overflow */
  92. q = q << 16;
  93. if (m) { /* otherwise no remainder -- we're done */
  94. if (m >> 15) { /* sigh. Do this the hard way */
  95. m = m << 1; if (m > j) { q += 0x8000; m -= j;};
  96. m = m << 1; if (m > j) { q += 0x4000; m -= j;};
  97. m = m << 1; if (m > j) { q += 0x2000; m -= j;};
  98. m = m << 1; if (m > j) { q += 0x1000; m -= j;};
  99. m = m << 1; if (m > j) { q += 0x800; m -= j;};
  100. m = m << 1; if (m > j) { q += 0x400; m -= j;};
  101. m = m << 1; if (m > j) { q += 0x200; m -= j;};
  102. m = m << 1; if (m > j) { q += 0x100; m -= j;};
  103. m = m << 1; if (m > j) { q += 0x80; m -= j;};
  104. m = m << 1; if (m > j) { q += 0x40; m -= j;};
  105. m = m << 1; if (m > j) { q += 0x20; m -= j;};
  106. m = m << 1; if (m > j) { q += 0x10; m -= j;};
  107. m = m << 1; if (m > j) { q += 0x8; m -= j;};
  108. m = m << 1; if (m > j) { q += 0x4; m -= j;};
  109. m = m << 1; if (m > j) { q += 0x2; m -= j;};
  110. m = m << 1; if (m > j) { q += 0x1; m -= j;};
  111. if ((m << 1) > j) q += 1; /* round the result */
  112. return ((sign)? -q : q);
  113. } else { /* oh, good -- we can use another divide */
  114. m = m << 16;
  115. q += m / j;
  116. m = m % j;
  117. if ((m << 1) > j) q += 1; /* round the result */
  118. return ((sign)? -q : q);
  119. }
  120. }
  121. return ((sign)? -q : q);
  122. }
  123. } return (sign + FixedPosInf);
  124. } return ((j) ? 0 : FixedPosInf);
  125. }
  126. #endif
  127. #if (USE_FRACMUL == USE_HWFP)
  128. Frac XCF_FracMul(Frac x, Frac y)
  129. {
  130. Int32 sign = x ^ y;
  131. double d = (double) x * (double) y / fracScale;
  132. if (sign >= 0) { /* positive result */
  133. d += 0.5;
  134. if (d < (double)FixedPosInf) return (Fixed) d;
  135. return FixedPosInf;
  136. }
  137. /* result is negative */
  138. d -= 0.5;
  139. if(d > (double)FixedNegInf) return (Fixed) d;
  140. return FixedNegInf;
  141. }
  142. #endif
  143. #if (USE_FRACMUL == USE_SWFP)
  144. Frac XCF_SWFracMul(Frac x, Frac y);
  145. Frac XCF_SWFracMul(Frac x, Frac y)
  146. {
  147. Int32 xu, yu, up, sign;
  148. if (x && y) {
  149. sign = x ^ y;
  150. if (x < 0) x = -x;
  151. if (y < 0) y = -y;
  152. xu = x >> 16; x = x & 0xffff;
  153. yu = y >> 16; y = y & 0xffff;
  154. up = (xu * yu);
  155. if (!(up >> 29)) { /* overflow */
  156. x = (x * yu) + (xu * y) + ((unsigned int)(x * y) >> 16) + 0x2000;
  157. x = (x >> 14) & 0x3ffff;
  158. x += (up << 2);
  159. if (x >= 0) return (sign < 0) ? -x : x;
  160. }
  161. return (sign < 0) ? FixedNegInf : FixedPosInf;
  162. }
  163. return 0;
  164. }
  165. #endif
  166. static long convFract[] =
  167. {
  168. 65536L,
  169. 6553L,
  170. 655L,
  171. 66L,
  172. 6L
  173. };
  174. /* Converts a number in Fixed format to a string and stores it in s. */
  175. void XCF_Fixed2CString(Fixed f, char PTR_PREFIX *s, short precision,
  176. boolean fracType)
  177. {
  178. char u[12];
  179. char PTR_PREFIX *t;
  180. short v;
  181. char sign;
  182. Card32 frac;
  183. long fracPrec = (precision <= 4) ? convFract[precision] : 0L;
  184. if ((sign = f < 0) != 0)
  185. f = -f;
  186. /* If f started out as fixedMax or -fixedMax, the precision adjustment
  187. puts it out of bounds. Reset it correctly. */
  188. if (f >= 0x7FFF7FFF)
  189. f =(Fixed)0x7fffffff;
  190. else
  191. f += fracType ? 0x03 : (fracPrec + 1) >> 1;
  192. v = fracType ? (short)(f >> 30) : (short)(f >> 16);
  193. f &= fracType ? 0x3fffffff : 0x0000ffff;
  194. if (sign && (v || f >= fracPrec))
  195. *s++ = '-';
  196. t = u;
  197. do
  198. {
  199. *t++ = v % 10 + '0';
  200. v /= 10;
  201. } while (v);
  202. for (; t > u;)
  203. *s++ = *--t;
  204. if (f >= fracPrec)
  205. {
  206. /* If this is a fracType then shift the value right by 2 so we don't
  207. have to worry about overflow. If the current callers request
  208. more than 9 significant digits then we'll have to re-evaluate
  209. this to make sure we don't lose any precision. */
  210. frac = fracType ? f >> 2 : f;
  211. *s++ = '.';
  212. for (v = precision; v-- && frac;)
  213. {
  214. frac = (frac << 3) + (frac << 1); /* multiply by 10 */
  215. *s++ = fracType ? (char)((frac >> 28) + '0') : (char)((frac >> 16) + '0');
  216. frac &= fracType ? 0x0fffffff : 0x0000ffff;
  217. }
  218. for (; *--s == '0';)
  219. ;
  220. if (*s != '.')
  221. s++;
  222. }
  223. *s = '\0';
  224. }
  225. #if USE_FXL
  226. static Fxl powersof10[MAXEXP - MINEXP + 1] = {
  227. { 1441151880, -27 },
  228. { 1801439850, -24 },
  229. { 1125899906, -20 },
  230. { 1407374883, -17 },
  231. { 1759218604, -14 },
  232. { 1099511627, -10 },
  233. { 1374389534, -7 },
  234. { 1717986918, -4 },
  235. { 1073741824, 0 },
  236. { 1342177280, 3 },
  237. { 1677721600, 6 },
  238. { 2097152000, 9 },
  239. { 1310720000, 13 }
  240. };
  241. #define Odd(x) ((x) & 1)
  242. #define isdigit(c) ((c) >= '0' && (c) <= '9')
  243. /* mkfxl -- create a normalized Fxl from mantissa and exponent */
  244. static Fxl mkfxl(Frac mantissa, Int32 exp)
  245. {
  246. Fxl fxl;
  247. if (mantissa == 0)
  248. exp = 0;
  249. else {
  250. boolean neg;
  251. if (mantissa >= 0)
  252. neg = 0;
  253. else {
  254. mantissa = -mantissa;
  255. neg = 1;
  256. }
  257. for (; (mantissa & mostSigBit) == 0; exp--)
  258. mantissa <<= 1;
  259. if (neg)
  260. mantissa = -mantissa;
  261. }
  262. fxl.mantissa = mantissa;
  263. fxl.exp = exp;
  264. return fxl;
  265. }
  266. static Fxl fxladd (Fxl a, Fxl b)
  267. {
  268. Frac mantissa, fa, fb;
  269. Int32 shift, exp;
  270. if (FxlIsZero(a))
  271. return b;
  272. if (FxlIsZero(b))
  273. return a;
  274. shift = a.exp - b.exp;
  275. if (shift < 0) {
  276. Fxl t;
  277. t = a;
  278. a = b;
  279. b = t;
  280. shift = -shift;
  281. }
  282. exp = a.exp;
  283. fa = a.mantissa;
  284. fb = b.mantissa;
  285. if (shift > 0)
  286. if (fb >= 0) {
  287. fb >>= (shift - 1);
  288. fb = (fb >> 1) + Odd(fb);
  289. }
  290. else {
  291. fb = (-fb) >> (shift - 1);
  292. fb = -((fb >> 1) + Odd(fb));
  293. }
  294. if ((fa < 0) == (fb < 0)) { /* signs alike */
  295. boolean neg = (fa < 0) ? 1 : 0;
  296. unsigned long f;
  297. if (neg) {
  298. fa = -fa;
  299. fb = -fb;
  300. }
  301. f = fa + fb;
  302. if (f >= (Card32) 0x80000000l) { /* overflow */
  303. mantissa = (f >> 1) + Odd(f);
  304. exp++;
  305. } else
  306. mantissa = f;
  307. if (neg)
  308. mantissa = -mantissa;
  309. } else
  310. mantissa = fa + fb;
  311. return mkfxl(mantissa, exp);
  312. }
  313. static Fxl fxlmul(Fxl a, Fxl b)
  314. {
  315. Frac f;
  316. /* Force a to be in [.5 .. 1) (as Frac!) to keep in range */
  317. if (a.mantissa >= 0)
  318. f = (a.mantissa >> 1) + Odd(a.mantissa);
  319. else
  320. f = -(((-a.mantissa) >> 1) + Odd(a.mantissa));
  321. return mkfxl(XCF_FracMul(f, b.mantissa), a.exp + b.exp + 1);
  322. }
  323. static Fxl fxlpow10 (Fxl f, IntX n)
  324. {
  325. if (n < 0) {
  326. for (; n < MINEXP; n -= MINEXP)
  327. f = fxlmul(f, powersof10[0]);
  328. f = fxlmul(f, powersof10[n - MINEXP]);
  329. }
  330. else if (n > 0) {
  331. for (; n > MAXEXP; n -= MAXEXP)
  332. f = fxlmul(f, powersof10[MAXEXP - MINEXP]);
  333. f = fxlmul(f, powersof10[n - MINEXP]);
  334. }
  335. return f;
  336. }
  337. #if 0
  338. static Fxl FixedToFxl (Fixed f)
  339. {
  340. return mkfxl(f, expFixed);
  341. }
  342. #endif
  343. static Fxl Int32ToFxl (Int32 i)
  344. {
  345. return mkfxl(i, expInteger);
  346. }
  347. /*
  348. * strtofxl
  349. * convert a PostScript numeric token to a Fxl. we have to accept
  350. * three formats: (see pslrm 2, pp 27-28)
  351. * integers: [+-]?[0-9]+
  352. * reals: [+-]?[0-9]*('.'[0-9]*)?([eE][+-]?[0-9]+)?
  353. * radix numbers: [0-9]+'#'[0-9a-zA-Z]+
  354. * note that this routine is a bit more forgiving than PostScript itself.
  355. */
  356. static Fxl strtofxl(XCF_Handle h, Card8 PTR_PREFIX *token)
  357. {
  358. long c;
  359. Card8 PTR_PREFIX *s;
  360. boolean neg;
  361. Fxl f;
  362. c = *token;
  363. if (c == '-') {
  364. neg = 1;
  365. token++;
  366. }
  367. else {
  368. neg = 0;
  369. if (c == '+')
  370. token++;
  371. }
  372. for (c = *(s = token); isdigit(c); c = *++s);
  373. if (c == '#')
  374. if (s == token)
  375. goto INVALID;
  376. else {
  377. unsigned long radix = h->callbacks.atoi((char *) token);
  378. if (radix > 36)
  379. goto INVALID;
  380. else {
  381. char *t;
  382. long number = h->callbacks.strtol((char *) s + 1, &t, (int) radix);
  383. if (*t != '\0')
  384. goto INVALID;
  385. return Int32ToFxl(neg ? -number : number);
  386. }
  387. }
  388. f = Int32ToFxl(h->callbacks.strtol((char *) token, NULL, 10));
  389. if (c == '.') {
  390. for (c = *(token = ++s); isdigit(c); c = *++s);
  391. if (s != token)
  392. f = fxladd(f, fxlpow10(Int32ToFxl(h->callbacks.strtol((char *) token, NULL, 10)), (IntX)(token - s)));
  393. }
  394. if (c == 'e' || c == 'E') {
  395. token = ++s;
  396. c = *s;
  397. if (c == '+' || c == '-')
  398. c = *++s;
  399. for (; isdigit(c); c = *++s);
  400. f = fxlpow10(f, h->callbacks.atoi((char *) token));
  401. }
  402. if (neg)
  403. f.mantissa = -f.mantissa;
  404. if (c == '\0')
  405. return f;
  406. INVALID:
  407. f.mantissa = 1;
  408. f.exp = 30000; /* big enough to overflow, always */
  409. return f;
  410. }
  411. static Fixed FxlToFixed (Fxl fxl)
  412. {
  413. Fixed f = fxl.mantissa;
  414. Int32 shift = fxl.exp - expFixed;
  415. boolean neg = false;
  416. if (f == 0 || shift == 0)
  417. return f;
  418. else if (shift < 0)
  419. {
  420. Fixed tempF = f >> (-shift - 1);
  421. if (tempF < 0) {
  422. neg = true;
  423. tempF = -tempF;
  424. }
  425. f = (tempF >> 1) + (tempF & 1);
  426. return neg ? -f : f;
  427. } else
  428. return (fxl.mantissa < 0) ? FixedNegInf : FixedPosInf;
  429. }
  430. static Frac FxlToFrac (Fxl fxl)
  431. {
  432. Fixed f = fxl.mantissa;
  433. Int32 shift = fxl.exp;
  434. boolean neg = false;
  435. if (f == 0 || shift == 0)
  436. return f;
  437. else if (shift < 0) {
  438. Fixed tempF = f >> (-shift - 1);
  439. if (tempF < 0) {
  440. neg = 1;
  441. tempF = -tempF;
  442. }
  443. f = (tempF >> 1) + (tempF & 1);
  444. return neg ? -f : f;
  445. } else
  446. return (fxl.mantissa < 0) ? FixedNegInf : FixedPosInf;
  447. }
  448. /* ConvertFixed -- takes an ascii token and converts to a 16.16 fixed */
  449. Fixed XCF_ConvertFixed (XCF_Handle h, char *s)
  450. {
  451. Fxl f;
  452. f = strtofxl(h, (unsigned char *) s);
  453. return FxlToFixed(f);
  454. }
  455. /* ConvertFrac -- takes an ascii token and converts to a 2.30 frac */
  456. Frac XCF_ConvertFrac (XCF_Handle h, char *s)
  457. {
  458. Fxl f;
  459. f = strtofxl(h, (unsigned char *) s);
  460. return FxlToFrac(f);
  461. }
  462. #endif