~ubuntu-branches/ubuntu/wily/sflphone/wily

« 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): Francois Marier, Francois Marier, Mark Purcell
  • Date: 2014-10-18 15:08:50 UTC
  • mfrom: (1.1.12)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20141018150850-2exfk34ckb15pcwi
Tags: 1.4.1-0.1
[ Francois Marier ]
* Non-maintainer upload
* New upstream release (closes: #759576, #741130)
  - debian/rules +PJPROJECT_VERSION := 2.2.1
  - add upstream patch to fix broken TLS support
  - add patch to fix pjproject regression

[ Mark Purcell ]
* Build-Depends:
  - sflphone-daemon + libavformat-dev, libavcodec-dev, libswscale-dev,
  libavdevice-dev, libavutil-dev
  - sflphone-gnome + libclutter-gtk-1.0-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 */