Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/base/ttcalc.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
18
/* Changes after FreeType: cut out the TrueType instruction interpreter. */
19
20
/*******************************************************************
21
 *
22
 *  ttcalc.c
23
 *
24
 *    Arithmetic Computations (body).
25
 *
26
 *  Copyright 1996-1998 by
27
 *  David Turner, Robert Wilhelm, and Werner Lemberg.
28
 *
29
 *  This file is part of the FreeType project, and may only be used
30
 *  modified and distributed under the terms of the FreeType project
31
 *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
32
 *  this file you indicate that you have read the license and
33
 *  understand and accept it fully.
34
 *
35
 ******************************************************************/
36
37
#include "ttmisc.h"
38
39
#include "ttcalc.h"
40
41
/* support for 1-complement arithmetic has been totally dropped in this */
42
/* release. You can still write your own code if you need it..          */
43
44
  static const long  Roots[63] =
45
  {
46
       1,    1,    2,     3,     4,     5,     8,    11,
47
      16,   22,   32,    45,    64,    90,   128,   181,
48
     256,  362,  512,   724,  1024,  1448,  2048,  2896,
49
    4096, 5892, 8192, 11585, 16384, 23170, 32768, 46340,
50
51
      65536,   92681,  131072,   185363,   262144,   370727,
52
     524288,  741455, 1048576,  1482910,  2097152,  2965820,
53
    4194304, 5931641, 8388608, 11863283, 16777216, 23726566,
54
55
      33554432,   47453132,   67108864,   94906265,
56
     134217728,  189812531,  268435456,  379625062,
57
     536870912,  759250125, 1073741824, 1518500250,
58
    2147483647
59
  };
60
61
#ifdef LONG64
62
63
  Int32  MulDiv( Int32  a, Int32  b, Int32  c )
64
51.0k
  {
65
51.0k
    Int32  s;
66
67
51.0k
    s  = a; a = ABS(a);
68
51.0k
    s ^= b; b = ABS(b);
69
51.0k
    s ^= c; c = ABS(c);
70
71
51.0k
    a = (Int64)a * b / c;
72
51.0k
    return ((s < 0) ? -a : a);
73
51.0k
  }
74
75
  Int32  MulDiv_Round( Int32  a, Int32  b, Int32  c )
76
6.75M
  {
77
6.75M
    int  s;
78
79
6.75M
    s  = a; a = ABS(a);
80
6.75M
    s ^= b; b = ABS(b);
81
6.75M
    s ^= c; c = ABS(c);
82
83
6.75M
    a = ((Int64)a * b + c/2) / c;
84
6.75M
    return ((s < 0) ? -a : a);
85
6.75M
  }
86
87
  static Int  Order64( Int64  z )
88
2.05k
  {
89
2.05k
    int  j = 0;
90
84.8k
    while ( z )
91
82.7k
    {
92
82.7k
      z = (unsigned INT64)z >> 1;
93
82.7k
      j++;
94
82.7k
    }
95
2.05k
    return j - 1;
96
2.05k
  }
97
98
  Int32  Sqrt64( Int64  l )
99
2.06k
  {
100
2.06k
    Int64  r, s;
101
102
2.06k
    if ( l <= 0 ) return 0;
103
2.05k
    if ( l == 1 ) return 1;
104
105
2.05k
    r = Roots[Order64( l )];
106
107
2.05k
    do
108
6.22k
    {
109
6.22k
      s = r;
110
6.22k
      r = ( r + l/r ) >> 1;
111
6.22k
    }
112
6.22k
    while ( r > s || r*r > l );
113
114
2.05k
    return r;
115
2.05k
  }
116
117
#else /* LONG64 */
118
119
  Int32  MulDiv( Int32  a, Int32  b, Int32  c )
120
  {
121
    Int64  temp;
122
    Int32  s;
123
124
    s  = a; a = ABS(a);
125
    s ^= b; b = ABS(b);
126
    s ^= c; c = ABS(c);
127
128
    MulTo64( a, b, &temp );
129
    a = Div64by32( &temp, c );
130
131
    return ((s < 0) ? -a : a);
132
  }
133
134
  Int32  MulDiv_Round( Int32  a, Int32  b, Int32  c )
135
  {
136
    Int64  temp, temp2;
137
    Int32  s;
138
139
    s  = a; a = ABS(a);
140
    s ^= b; b = ABS(b);
141
    s ^= c; c = ABS(c);
142
143
    MulTo64( a, b, &temp );
144
    temp2.hi = (Int32)(c >> 31);
145
    temp2.lo = (Word32)(c / 2);
146
    Add64( &temp, &temp2, &temp );
147
    a = Div64by32( &temp, c );
148
149
    return ((s < 0) ? -a : a);
150
  }
151
152
  static void  Neg64__( Int64*  x )
153
  {
154
    /* Remember that -(0x80000000) == 0x80000000 with 2-complement! */
155
    /* We take care of that here.                                   */
156
157
    x->hi ^= 0xFFFFFFFF;
158
    x->lo ^= 0xFFFFFFFF;
159
    x->lo++;
160
161
    if ( !x->lo )
162
    {
163
      x->hi++;
164
      if ( (Int32)x->hi == 0x80000000 )  /* Check -MaxInt32 - 1 */
165
      {
166
        x->lo--;
167
        x->hi--;  /* We return 0x7FFFFFFF! */
168
      }
169
    }
170
  }
171
172
  void  Add64( Int64*  x, Int64*  y, Int64*  z )
173
  {
174
    register Word32  lo, hi;
175
176
    hi = x->hi + y->hi;
177
    lo = x->lo + y->lo;
178
179
    if ( y->lo )
180
      if ( (Word32)x->lo >= (Word32)(-y->lo) ) hi++;
181
182
    z->lo = lo;
183
    z->hi = hi;
184
  }
185
186
  void  Sub64( Int64*  x, Int64*  y, Int64*  z )
187
  {
188
    register Word32  lo, hi;
189
190
    hi = x->hi - y->hi;
191
    lo = x->lo - y->lo;
192
193
    if ( x->lo < y->lo ) hi--;
194
195
    z->lo = lo;
196
    z->hi = hi;
197
  }
198
199
  void  MulTo64( Int32  x, Int32  y, Int64*  z )
200
  {
201
    Int32   s;
202
    Word32  lo1, hi1, lo2, hi2, lo, hi, i1, i2;
203
204
    s  = x; x = ABS(x);
205
    s ^= y; y = ABS(y);
206
207
    lo1 = x & 0x0000FFFF;  hi1 = x >> 16;
208
    lo2 = y & 0x0000FFFF;  hi2 = y >> 16;
209
210
    lo = lo1*lo2;
211
    i1 = lo1*hi2;
212
    i2 = lo2*hi1;
213
    hi = hi1*hi2;
214
215
    /* Check carry overflow of i1 + i2 */
216
217
    if ( i2 )
218
    {
219
      if ( i1 >= (Word32)-i2 ) hi += 1 << 16;
220
      i1 += i2;
221
    }
222
223
    i2 = i1 >> 16;
224
    i1 = i1 << 16;
225
226
    /* Check carry overflow of i1 + lo */
227
    if ( i1 )
228
    {
229
      if ( lo >= (Word32)-i1 ) hi++;
230
      lo += i1;
231
    }
232
233
    hi += i2;
234
235
    z->lo = lo;
236
    z->hi = hi;
237
238
    if (s < 0) Neg64__( z );
239
  }
240
241
  Int32  Div64by32( Int64*  x, Int32  y )
242
  {
243
    Int32   s;
244
    Word32  q, r, i, lo;
245
246
    s  = x->hi; if (s<0) Neg64__(x);
247
    s ^= y;     y = ABS(y);
248
249
    /* Shortcut */
250
    if ( x->hi == 0 )
251
    {
252
      q = x->lo / y;
253
      return ((s<0) ? -q : q);
254
    }
255
256
    r  = x->hi;
257
    lo = x->lo;
258
259
    if ( r >= (Word32)y )   /* we know y is to be treated as unsigned here */
260
      return ( (s<0) ? 0x80000001 : 0x7FFFFFFF );
261
                            /* Return Max/Min Int32 if divide overflow */
262
                            /* This includes division by zero!         */
263
    q = 0;
264
    for ( i = 0; i < 32; i++ )
265
    {
266
      r <<= 1;
267
      q <<= 1;
268
      r  |= lo >> 31;
269
270
      if ( r >= (Word32)y )
271
      {
272
        r -= y;
273
        q |= 1;
274
      }
275
      lo <<= 1;
276
    }
277
278
    return ( (s<0) ? -q : q );
279
  }
280
281
  Int  Order64( Int64*  z )
282
  {
283
    Word32  i;
284
    int     j;
285
286
    if ( z->hi )
287
    {
288
      i = z->hi;
289
      j = 32;
290
    }
291
    else
292
    {
293
      i = z->lo;
294
      j = 0;
295
    }
296
297
    while ( i > 0 )
298
    {
299
      i >>= 1;
300
      j++;
301
    }
302
    return j-1;
303
  }
304
305
  Int32  Sqrt64( Int64*  l )
306
  {
307
    Int64  l2;
308
    Int32  r, s;
309
310
    if ( (Int32)l->hi < 0          ||
311
        (l->hi == 0 && l->lo == 0) )  return 0;
312
313
    s = Order64( l );
314
    if ( s == 0 ) return 1;
315
316
    r = Roots[s];
317
    do
318
    {
319
      s = r;
320
      r = ( r + Div64by32(l,r) ) >> 1;
321
      MulTo64( r, r,   &l2 );
322
      Sub64  ( l, &l2, &l2 );
323
    }
324
    while ( r > s || (Int32)l2.hi < 0 );
325
326
    return r;
327
  }
328
329
#endif /* LONG64 */
330
331
#if 0  /* unused by the rest of the library */
332
333
  Int  Order32( Int32  z )
334
  {
335
    int j;
336
337
    j = 0;
338
    while ( z )
339
    {
340
      z = (Word32)z >> 1;
341
      j++;
342
    }
343
    return j - 1;
344
  }
345
346
  Int32  Sqrt32( Int32  l )
347
  {
348
    Int32  r, s;
349
350
    if ( l <= 0 ) return 0;
351
    if ( l == 1 ) return 1;
352
353
    r = Roots[Order32( l )];
354
    do
355
    {
356
      s = r;
357
      r = ( r + l/r ) >> 1;
358
    }
359
    while ( r > s || r*r > l );
360
    return r;
361
  }
362
363
#endif
364
365
/* END */