diff options
-rw-r--r-- | include/mupdf/fitz/context.h | 20 | ||||
-rw-r--r-- | platform/win32/libmupdf.vcproj | 4 | ||||
-rw-r--r-- | scripts/cmapdump.c | 1 | ||||
-rw-r--r-- | source/fitz/context.c | 19 | ||||
-rw-r--r-- | source/fitz/random.c | 80 |
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); +} |