~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/third_party/BaseClasses/arithutil.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//------------------------------------------------------------------------------
 
2
// File: ArithUtil.cpp
 
3
//
 
4
// Desc: DirectShow base classes - implements helper classes for building
 
5
//       multimedia filters.
 
6
//
 
7
// Copyright (c) 1992-2004 Microsoft Corporation.  All rights reserved.
 
8
//------------------------------------------------------------------------------
 
9
 
 
10
#include <pjmedia-videodev/config.h>
 
11
 
 
12
#if defined(PJMEDIA_VIDEO_DEV_HAS_DSHOW) && PJMEDIA_VIDEO_DEV_HAS_DSHOW != 0
 
13
 
 
14
#include <streams.h>
 
15
 
 
16
//
 
17
//  Declare function from largeint.h we need so that PPC can build
 
18
//
 
19
 
 
20
//
 
21
// Enlarged integer divide - 64-bits / 32-bits > 32-bits
 
22
//
 
23
 
 
24
#ifndef _X86_
 
25
 
 
26
#define LLtoU64(x) (*(unsigned __int64*)(void*)(&(x)))
 
27
 
 
28
__inline
 
29
ULONG
 
30
WINAPI
 
31
EnlargedUnsignedDivide (
 
32
    IN ULARGE_INTEGER Dividend,
 
33
    IN ULONG Divisor,
 
34
    IN PULONG Remainder
 
35
    )
 
36
{
 
37
        // return remainder if necessary
 
38
        if (Remainder != NULL)
 
39
                *Remainder = (ULONG)(LLtoU64(Dividend) % Divisor);
 
40
        return (ULONG)(LLtoU64(Dividend) / Divisor);
 
41
}
 
42
 
 
43
#else
 
44
__inline
 
45
ULONG
 
46
WINAPI
 
47
EnlargedUnsignedDivide (
 
48
    IN ULARGE_INTEGER Dividend,
 
49
    IN ULONG Divisor,
 
50
    IN PULONG Remainder
 
51
    )
 
52
{
 
53
    ULONG ulResult;
 
54
    _asm {
 
55
        mov eax,Dividend.LowPart
 
56
        mov edx,Dividend.HighPart
 
57
        mov ecx,Remainder
 
58
        div Divisor
 
59
        or  ecx,ecx
 
60
        jz  short label
 
61
        mov [ecx],edx
 
62
label:
 
63
        mov ulResult,eax
 
64
    }
 
65
    return ulResult;
 
66
}
 
67
#endif
 
68
 
 
69
 
 
70
/*  Arithmetic functions to help with time format conversions
 
71
*/
 
72
 
 
73
#ifdef _M_ALPHA
 
74
// work around bug in version 12.00.8385 of the alpha compiler where
 
75
// UInt32x32To64 sign-extends its arguments (?)
 
76
#undef UInt32x32To64
 
77
#define UInt32x32To64(a, b) (((ULONGLONG)((ULONG)(a)) & 0xffffffff) * ((ULONGLONG)((ULONG)(b)) & 0xffffffff))
 
78
#endif
 
79
 
 
80
/*   Compute (a * b + d) / c */
 
81
LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG d)
 
82
{
 
83
    /*  Compute the absolute values to avoid signed arithmetic problems */
 
84
    ULARGE_INTEGER ua, ub;
 
85
    DWORDLONG uc;
 
86
 
 
87
    ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a);
 
88
    ub.QuadPart = (DWORDLONG)(b >= 0 ? b : -b);
 
89
    uc          = (DWORDLONG)(c >= 0 ? c : -c);
 
90
    BOOL bSign = (a < 0) ^ (b < 0);
 
91
 
 
92
    /*  Do long multiplication */
 
93
    ULARGE_INTEGER p[2];
 
94
    p[0].QuadPart  = UInt32x32To64(ua.LowPart, ub.LowPart);
 
95
 
 
96
    /*  This next computation cannot overflow into p[1].HighPart because
 
97
        the max number we can compute here is:
 
98
 
 
99
                 (2 ** 32 - 1) * (2 ** 32 - 1) +  // ua.LowPart * ub.LowPart
 
100
    (2 ** 32) *  (2 ** 31) * (2 ** 32 - 1) * 2    // x.LowPart * y.HighPart * 2
 
101
 
 
102
    == 2 ** 96 - 2 ** 64 + (2 ** 64 - 2 ** 33 + 1)
 
103
    == 2 ** 96 - 2 ** 33 + 1
 
104
    < 2 ** 96
 
105
    */
 
106
 
 
107
    ULARGE_INTEGER x;
 
108
    x.QuadPart     = UInt32x32To64(ua.LowPart, ub.HighPart) +
 
109
                     UInt32x32To64(ua.HighPart, ub.LowPart) +
 
110
                     p[0].HighPart;
 
111
    p[0].HighPart  = x.LowPart;
 
112
    p[1].QuadPart  = UInt32x32To64(ua.HighPart, ub.HighPart) + x.HighPart;
 
113
 
 
114
    if (d != 0) {
 
115
        ULARGE_INTEGER ud[2];
 
116
        if (bSign) {
 
117
            ud[0].QuadPart = (DWORDLONG)(-d);
 
118
            if (d > 0) {
 
119
                /*  -d < 0 */
 
120
                ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1;
 
121
            } else {
 
122
                ud[1].QuadPart = (DWORDLONG)0;
 
123
            }
 
124
        } else {
 
125
            ud[0].QuadPart = (DWORDLONG)d;
 
126
            if (d < 0) {
 
127
                ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1;
 
128
            } else {
 
129
                ud[1].QuadPart = (DWORDLONG)0;
 
130
            }
 
131
        }
 
132
        /*  Now do extended addition */
 
133
        ULARGE_INTEGER uliTotal;
 
134
 
 
135
        /*  Add ls DWORDs */
 
136
        uliTotal.QuadPart  = (DWORDLONG)ud[0].LowPart + p[0].LowPart;
 
137
        p[0].LowPart       = uliTotal.LowPart;
 
138
 
 
139
        /*  Propagate carry */
 
140
        uliTotal.LowPart   = uliTotal.HighPart;
 
141
        uliTotal.HighPart  = 0;
 
142
 
 
143
        /*  Add 2nd most ls DWORDs */
 
144
        uliTotal.QuadPart += (DWORDLONG)ud[0].HighPart + p[0].HighPart;
 
145
        p[0].HighPart      = uliTotal.LowPart;
 
146
 
 
147
        /*  Propagate carry */
 
148
        uliTotal.LowPart   = uliTotal.HighPart;
 
149
        uliTotal.HighPart  = 0;
 
150
 
 
151
        /*  Add MS DWORDLONGs - no carry expected */
 
152
        p[1].QuadPart     += ud[1].QuadPart + uliTotal.QuadPart;
 
153
 
 
154
        /*  Now see if we got a sign change from the addition */
 
155
        if ((LONG)p[1].HighPart < 0) {
 
156
            bSign = !bSign;
 
157
 
 
158
            /*  Negate the current value (ugh!) */
 
159
            p[0].QuadPart  = ~p[0].QuadPart;
 
160
            p[1].QuadPart  = ~p[1].QuadPart;
 
161
            p[0].QuadPart += 1;
 
162
            p[1].QuadPart += (p[0].QuadPart == 0);
 
163
        }
 
164
    }
 
165
 
 
166
    /*  Now for the division */
 
167
    if (c < 0) {
 
168
        bSign = !bSign;
 
169
    }
 
170
 
 
171
 
 
172
    /*  This will catch c == 0 and overflow */
 
173
    if (uc <= p[1].QuadPart) {
 
174
        return bSign ? (LONGLONG)0x8000000000000000 :
 
175
                       (LONGLONG)0x7FFFFFFFFFFFFFFF;
 
176
    }
 
177
 
 
178
    DWORDLONG ullResult;
 
179
 
 
180
    /*  Do the division */
 
181
    /*  If the dividend is a DWORD_LONG use the compiler */
 
182
    if (p[1].QuadPart == 0) {
 
183
        ullResult = p[0].QuadPart / uc;
 
184
        return bSign ? -(LONGLONG)ullResult : (LONGLONG)ullResult;
 
185
    }
 
186
 
 
187
    /*  If the divisor is a DWORD then its simpler */
 
188
    ULARGE_INTEGER ulic;
 
189
    ulic.QuadPart = uc;
 
190
    if (ulic.HighPart == 0) {
 
191
        ULARGE_INTEGER uliDividend;
 
192
        ULARGE_INTEGER uliResult;
 
193
        DWORD dwDivisor = (DWORD)uc;
 
194
        // ASSERT(p[1].HighPart == 0 && p[1].LowPart < dwDivisor);
 
195
        uliDividend.HighPart = p[1].LowPart;
 
196
        uliDividend.LowPart = p[0].HighPart;
 
197
#ifndef USE_LARGEINT
 
198
        uliResult.HighPart = (DWORD)(uliDividend.QuadPart / dwDivisor);
 
199
        p[0].HighPart = (DWORD)(uliDividend.QuadPart % dwDivisor);
 
200
        uliResult.LowPart = 0;
 
201
        uliResult.QuadPart = p[0].QuadPart / dwDivisor + uliResult.QuadPart;
 
202
#else
 
203
        /*  NOTE - this routine will take exceptions if
 
204
            the result does not fit in a DWORD
 
205
        */
 
206
        if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) {
 
207
            uliResult.HighPart = EnlargedUnsignedDivide(
 
208
                                     uliDividend,
 
209
                                     dwDivisor,
 
210
                                     &p[0].HighPart);
 
211
        } else {
 
212
            uliResult.HighPart = 0;
 
213
        }
 
214
        uliResult.LowPart = EnlargedUnsignedDivide(
 
215
                                 p[0],
 
216
                                 dwDivisor,
 
217
                                 NULL);
 
218
#endif
 
219
        return bSign ? -(LONGLONG)uliResult.QuadPart :
 
220
                        (LONGLONG)uliResult.QuadPart;
 
221
    }
 
222
 
 
223
 
 
224
    ullResult = 0;
 
225
 
 
226
    /*  OK - do long division */
 
227
    for (int i = 0; i < 64; i++) {
 
228
        ullResult <<= 1;
 
229
 
 
230
        /*  Shift 128 bit p left 1 */
 
231
        p[1].QuadPart <<= 1;
 
232
        if ((p[0].HighPart & 0x80000000) != 0) {
 
233
            p[1].LowPart++;
 
234
        }
 
235
        p[0].QuadPart <<= 1;
 
236
 
 
237
        /*  Compare */
 
238
        if (uc <= p[1].QuadPart) {
 
239
            p[1].QuadPart -= uc;
 
240
            ullResult += 1;
 
241
        }
 
242
    }
 
243
 
 
244
    return bSign ? - (LONGLONG)ullResult : (LONGLONG)ullResult;
 
245
}
 
246
 
 
247
LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG d)
 
248
{
 
249
    ULARGE_INTEGER ua;
 
250
    DWORD ub;
 
251
    DWORD uc;
 
252
 
 
253
    /*  Compute the absolute values to avoid signed arithmetic problems */
 
254
    ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a);
 
255
    ub = (DWORD)(b >= 0 ? b : -b);
 
256
    uc = (DWORD)(c >= 0 ? c : -c);
 
257
    BOOL bSign = (a < 0) ^ (b < 0);
 
258
 
 
259
    /*  Do long multiplication */
 
260
    ULARGE_INTEGER p0;
 
261
    DWORD p1;
 
262
    p0.QuadPart  = UInt32x32To64(ua.LowPart, ub);
 
263
 
 
264
    if (ua.HighPart != 0) {
 
265
        ULARGE_INTEGER x;
 
266
        x.QuadPart     = UInt32x32To64(ua.HighPart, ub) + p0.HighPart;
 
267
        p0.HighPart  = x.LowPart;
 
268
        p1   = x.HighPart;
 
269
    } else {
 
270
        p1 = 0;
 
271
    }
 
272
 
 
273
    if (d != 0) {
 
274
        ULARGE_INTEGER ud0;
 
275
        DWORD ud1;
 
276
 
 
277
        if (bSign) {
 
278
            //
 
279
            //  Cast d to LONGLONG first otherwise -0x80000000 sign extends
 
280
            //  incorrectly
 
281
            //
 
282
            ud0.QuadPart = (DWORDLONG)(-(LONGLONG)d);
 
283
            if (d > 0) {
 
284
                /*  -d < 0 */
 
285
                ud1 = (DWORD)-1;
 
286
            } else {
 
287
                ud1 = (DWORD)0;
 
288
            }
 
289
        } else {
 
290
            ud0.QuadPart = (DWORDLONG)d;
 
291
            if (d < 0) {
 
292
                ud1 = (DWORD)-1;
 
293
            } else {
 
294
                ud1 = (DWORD)0;
 
295
            }
 
296
        }
 
297
        /*  Now do extended addition */
 
298
        ULARGE_INTEGER uliTotal;
 
299
 
 
300
        /*  Add ls DWORDs */
 
301
        uliTotal.QuadPart  = (DWORDLONG)ud0.LowPart + p0.LowPart;
 
302
        p0.LowPart       = uliTotal.LowPart;
 
303
 
 
304
        /*  Propagate carry */
 
305
        uliTotal.LowPart   = uliTotal.HighPart;
 
306
        uliTotal.HighPart  = 0;
 
307
 
 
308
        /*  Add 2nd most ls DWORDs */
 
309
        uliTotal.QuadPart += (DWORDLONG)ud0.HighPart + p0.HighPart;
 
310
        p0.HighPart      = uliTotal.LowPart;
 
311
 
 
312
        /*  Add MS DWORDLONGs - no carry expected */
 
313
        p1 += ud1 + uliTotal.HighPart;
 
314
 
 
315
        /*  Now see if we got a sign change from the addition */
 
316
        if ((LONG)p1 < 0) {
 
317
            bSign = !bSign;
 
318
 
 
319
            /*  Negate the current value (ugh!) */
 
320
            p0.QuadPart  = ~p0.QuadPart;
 
321
            p1 = ~p1;
 
322
            p0.QuadPart += 1;
 
323
            p1 += (p0.QuadPart == 0);
 
324
        }
 
325
    }
 
326
 
 
327
    /*  Now for the division */
 
328
    if (c < 0) {
 
329
        bSign = !bSign;
 
330
    }
 
331
 
 
332
 
 
333
    /*  This will catch c == 0 and overflow */
 
334
    if (uc <= p1) {
 
335
        return bSign ? (LONGLONG)0x8000000000000000 :
 
336
                       (LONGLONG)0x7FFFFFFFFFFFFFFF;
 
337
    }
 
338
 
 
339
    /*  Do the division */
 
340
 
 
341
    /*  If the divisor is a DWORD then its simpler */
 
342
    ULARGE_INTEGER uliDividend;
 
343
    ULARGE_INTEGER uliResult;
 
344
    DWORD dwDivisor = uc;
 
345
    uliDividend.HighPart = p1;
 
346
    uliDividend.LowPart = p0.HighPart;
 
347
    /*  NOTE - this routine will take exceptions if
 
348
        the result does not fit in a DWORD
 
349
    */
 
350
    if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) {
 
351
        uliResult.HighPart = EnlargedUnsignedDivide(
 
352
                                 uliDividend,
 
353
                                 dwDivisor,
 
354
                                 &p0.HighPart);
 
355
    } else {
 
356
        uliResult.HighPart = 0;
 
357
    }
 
358
    uliResult.LowPart = EnlargedUnsignedDivide(
 
359
                             p0,
 
360
                             dwDivisor,
 
361
                             NULL);
 
362
    return bSign ? -(LONGLONG)uliResult.QuadPart :
 
363
                    (LONGLONG)uliResult.QuadPart;
 
364
}
 
365
 
 
366
#endif /* PJMEDIA_VIDEO_DEV_HAS_DSHOW */