comparison mupdf-source/source/fitz/random.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 // Copyright (C) 2004-2021 Artifex Software, Inc.
2 //
3 // This file is part of MuPDF.
4 //
5 // MuPDF is free software: you can redistribute it and/or modify it under the
6 // terms of the GNU Affero General Public License as published by the Free
7 // Software Foundation, either version 3 of the License, or (at your option)
8 // any later version.
9 //
10 // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU Affero General Public License
16 // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17 //
18 // Alternative licensing terms are available from the licensor.
19 // For commercial licensing, see <https://www.artifex.com/> or contact
20 // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21 // CA 94129, USA, for further information.
22
23 #include "mupdf/fitz.h"
24
25 /* The pseudo-random number generator in this file is based on the MIT licensed
26 * implementation in musl libc. */
27
28 #include <string.h>
29
30 /* The seed is initialized in context.c as follows:
31 * static uint16_t __seed48[7] = { 0, 0, 0, 0xe66d, 0xdeec, 0x5, 0xb };
32 */
33
34 static uint64_t fz_rand48_step(uint16_t *xi, uint16_t *lc)
35 {
36 uint64_t a, x;
37 x = xi[0] | (xi[1]+0U)<<16 | (xi[2]+0ULL)<<32;
38 a = lc[0] | (lc[1]+0U)<<16 | (lc[2]+0ULL)<<32;
39 x = a*x + lc[3];
40 xi[0] = x;
41 xi[1] = x>>16;
42 xi[2] = x>>32;
43 return x & 0xffffffffffffull;
44 }
45
46 double fz_erand48(fz_context *ctx, uint16_t s[3])
47 {
48 union {
49 uint64_t u;
50 double f;
51 } x = { 0x3ff0000000000000ULL | fz_rand48_step(s, ctx->seed48+3)<<4 };
52 return x.f - 1.0;
53 }
54
55 /*
56 Pseudo-random numbers using a linear congruential algorithm and 48-bit
57 integer arithmetic.
58 */
59 double fz_drand48(fz_context *ctx)
60 {
61 return fz_erand48(ctx, ctx->seed48);
62 }
63
64 int32_t fz_nrand48(fz_context *ctx, uint16_t s[3])
65 {
66 return fz_rand48_step(s, ctx->seed48+3) >> 17;
67 }
68
69 int32_t fz_lrand48(fz_context *ctx)
70 {
71 return fz_nrand48(ctx, ctx->seed48);
72 }
73
74 int32_t fz_jrand48(fz_context *ctx, uint16_t s[3])
75 {
76 return (int32_t)(fz_rand48_step(s, ctx->seed48+3) >> 16);
77 }
78
79 int32_t fz_mrand48(fz_context *ctx)
80 {
81 return fz_jrand48(ctx, ctx->seed48);
82 }
83
84 void fz_lcong48(fz_context *ctx, uint16_t p[7])
85 {
86 memcpy(ctx->seed48, p, sizeof ctx->seed48);
87 }
88
89 uint16_t *fz_seed48(fz_context *ctx, uint16_t *s)
90 {
91 static uint16_t p[3];
92 memcpy(p, ctx->seed48, sizeof p);
93 memcpy(ctx->seed48, s, sizeof p);
94 return p;
95 }
96
97 void fz_srand48(fz_context *ctx, int32_t seed)
98 {
99 uint16_t p[3] = { 0x330e, seed, seed>>16 };
100 fz_seed48(ctx, p);
101 }
102
103 void fz_memrnd(fz_context *ctx, unsigned char *data, int len)
104 {
105 #ifdef CLUSTER
106 memset(data, 0x55, len);
107 #else
108 while (len-- > 0)
109 *data++ = (unsigned char)fz_lrand48(ctx);
110 #endif
111 }