/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 */ |