summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/context.h20
-rw-r--r--platform/win32/libmupdf.vcproj4
-rw-r--r--scripts/cmapdump.c1
-rw-r--r--source/fitz/context.c19
-rw-r--r--source/fitz/random.c80
5 files changed, 124 insertions, 0 deletions
diff --git a/include/mupdf/fitz/context.h b/include/mupdf/fitz/context.h
index 5a88433f..caa22977 100644
--- a/include/mupdf/fitz/context.h
+++ b/include/mupdf/fitz/context.h
@@ -161,6 +161,7 @@ struct fz_context_s
fz_tuning_context *tuning;
fz_document_handler_context *handler;
fz_output_context *output;
+ uint16_t seed48[7];
};
/*
@@ -563,4 +564,23 @@ extern fz_alloc_context fz_alloc_default;
/* Default locks */
extern fz_locks_context fz_locks_default;
+/*
+ Pseudo-random numbers using a linear congruential algorithm and 48-bit
+ integer arithmetic.
+*/
+double fz_drand48(fz_context *ctx);
+int32_t fz_lrand48(fz_context *ctx);
+int32_t fz_mrand48(fz_context *ctx);
+double fz_erand48(fz_context *ctx, uint16_t xsubi[3]);
+int32_t fz_jrand48(fz_context *ctx, uint16_t xsubi[3]);
+int32_t fz_nrand48(fz_context *ctx, uint16_t xsubi[3]);
+void fz_lcong48(fz_context *ctx, uint16_t param[7]);
+uint16_t *fz_seed48(fz_context *ctx, uint16_t seed16v[3]);
+void fz_srand48(fz_context *ctx, int32_t seedval);
+
+/*
+ fz_memrnd: Fill block with len bytes of pseudo-randomness.
+*/
+void fz_memrnd(fz_context *ctx, uint8_t *block, int len);
+
#endif
diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj
index 024591db..573b0561 100644
--- a/platform/win32/libmupdf.vcproj
+++ b/platform/win32/libmupdf.vcproj
@@ -1861,6 +1861,10 @@
>
</File>
<File
+ RelativePath="..\..\source\fitz\random.c"
+ >
+ </File>
+ <File
RelativePath="..\..\source\fitz\separation.c"
>
</File>
diff --git a/scripts/cmapdump.c b/scripts/cmapdump.c
index a59532e8..b0705b80 100644
--- a/scripts/cmapdump.c
+++ b/scripts/cmapdump.c
@@ -19,6 +19,7 @@
#include "../source/fitz/context.c"
#include "../source/fitz/error.c"
#include "../source/fitz/memory.c"
+#include "../source/fitz/random.c"
#include "../source/fitz/output.c"
#include "../source/fitz/string.c"
#include "../source/fitz/buffer.c"
diff --git a/source/fitz/context.c b/source/fitz/context.c
index f4ebdc98..67fef05b 100644
--- a/source/fitz/context.c
+++ b/source/fitz/context.c
@@ -3,6 +3,7 @@
#include <assert.h>
#include <string.h>
#include <stdio.h>
+#include <time.h>
struct fz_id_context_s
{
@@ -132,6 +133,22 @@ void fz_tune_image_scale(fz_context *ctx, fz_tune_image_scale_fn *image_scale, v
ctx->tuning->image_scale_arg = arg;
}
+static void fz_init_random_context(fz_context *ctx)
+{
+ if (!ctx)
+ return;
+
+ ctx->seed48[0] = 0;
+ ctx->seed48[1] = 0;
+ ctx->seed48[2] = 0;
+ ctx->seed48[3] = 0xe66d;
+ ctx->seed48[4] = 0xdeec;
+ ctx->seed48[5] = 0x5;
+ ctx->seed48[6] = 0xb;
+
+ fz_srand48(ctx, (uint32_t)time(NULL));
+}
+
void
fz_drop_context(fz_context *ctx)
{
@@ -250,6 +267,7 @@ fz_new_context_imp(const fz_alloc_context *alloc, const fz_locks_context *locks,
fz_new_document_handler_context(ctx);
fz_new_style_context(ctx);
fz_new_tuning_context(ctx);
+ fz_init_random_context(ctx);
}
fz_catch(ctx)
{
@@ -304,6 +322,7 @@ fz_clone_context_internal(fz_context *ctx)
new_ctx->id = fz_keep_id_context(new_ctx);
new_ctx->tuning = ctx->tuning;
new_ctx->tuning = fz_keep_tuning_context(new_ctx);
+ memcpy(new_ctx->seed48, ctx->seed48, sizeof ctx->seed48);
new_ctx->handler = ctx->handler;
new_ctx->handler = fz_keep_document_handler_context(new_ctx);
diff --git a/source/fitz/random.c b/source/fitz/random.c
new file mode 100644
index 00000000..95e1990c
--- /dev/null
+++ b/source/fitz/random.c
@@ -0,0 +1,80 @@
+#include "mupdf/fitz.h"
+
+/* The pseudo-random number generator in this file is based on the MIT licensed
+ * implementation in musl libc. */
+
+#include <string.h>
+
+/* The seed is initialized in context.c as follows:
+ * static uint16_t __seed48[7] = { 0, 0, 0, 0xe66d, 0xdeec, 0x5, 0xb };
+ */
+
+static uint64_t fz_rand48_step(uint16_t *xi, uint16_t *lc)
+{
+ uint64_t a, x;
+ x = xi[0] | (xi[1]+0U)<<16 | (xi[2]+0ULL)<<32;
+ a = lc[0] | (lc[1]+0U)<<16 | (lc[2]+0ULL)<<32;
+ x = a*x + lc[3];
+ xi[0] = x;
+ xi[1] = x>>16;
+ xi[2] = x>>32;
+ return x & 0xffffffffffffull;
+}
+
+double fz_erand48(fz_context *ctx, uint16_t s[3])
+{
+ union {
+ uint64_t u;
+ double f;
+ } x = { 0x3ff0000000000000ULL | fz_rand48_step(s, ctx->seed48+3)<<4 };
+ return x.f - 1.0;
+}
+
+double fz_drand48(fz_context *ctx)
+{
+ return fz_erand48(ctx, ctx->seed48);
+}
+
+int32_t fz_nrand48(fz_context *ctx, uint16_t s[3])
+{
+ return fz_rand48_step(s, ctx->seed48+3) >> 17;
+}
+
+int32_t fz_lrand48(fz_context *ctx)
+{
+ return fz_nrand48(ctx, ctx->seed48);
+}
+
+int32_t fz_jrand48(fz_context *ctx, uint16_t s[3])
+{
+ return (int32_t)(fz_rand48_step(s, ctx->seed48+3) >> 16);
+}
+
+int32_t fz_mrand48(fz_context *ctx)
+{
+ return fz_jrand48(ctx, ctx->seed48);
+}
+
+void fz_lcong48(fz_context *ctx, uint16_t p[7])
+{
+ memcpy(ctx->seed48, p, sizeof ctx->seed48);
+}
+
+uint16_t *fz_seed48(fz_context *ctx, uint16_t *s)
+{
+ static uint16_t p[3];
+ memcpy(p, ctx->seed48, sizeof p);
+ memcpy(ctx->seed48, s, sizeof p);
+ return p;
+}
+
+void fz_srand48(fz_context *ctx, int32_t seed)
+{
+ fz_seed48(ctx, (uint16_t [3]){ 0x330e, seed, seed>>16 });
+}
+
+void fz_memrnd(fz_context *ctx, unsigned char *data, int len)
+{
+ while (len-- > 0)
+ *data++ = (unsigned char)fz_lrand48(ctx);
+}