diff options
author | Robin Watts <robin.watts@artifex.com> | 2015-06-18 19:34:15 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2015-06-26 19:06:23 +0100 |
commit | 895b9cff172c28efdf2ec479b9f2fce1287acbc2 (patch) | |
tree | c1f0e5c0ad5b23becb3194f98d6058c240bb93f2 | |
parent | 2b08c7f7ed2d4bc3874e5d2734c7d4a0ca3ad966 (diff) | |
download | mupdf-895b9cff172c28efdf2ec479b9f2fce1287acbc2.tar.xz |
Add stream functions for reading LE values of different sizes
fz_read_int16le, fz_read_int32le, fz_read_int64le.
-rw-r--r-- | include/mupdf/fitz/stream.h | 18 | ||||
-rw-r--r-- | source/fitz/stream-read.c | 43 |
2 files changed, 61 insertions, 0 deletions
diff --git a/include/mupdf/fitz/stream.h b/include/mupdf/fitz/stream.h index b07e7ce3..21958b8a 100644 --- a/include/mupdf/fitz/stream.h +++ b/include/mupdf/fitz/stream.h @@ -147,6 +147,24 @@ fz_buffer *fz_read_all(fz_context *ctx, fz_stream *stm, int initial); */ fz_buffer *fz_read_file(fz_context *ctx, const char *filename); +/* + fz_read_int16le: Read a 16bit little endian value from the stream. + Throws on failure. +*/ +int16_t fz_read_int16le(fz_context *ctx, fz_stream *stm); + +/* + fz_read_int32le: Read a 32bit little endian value from the stream. + Throws on failure. +*/ +int32_t fz_read_int32le(fz_context *ctx, fz_stream *stm); + +/* + fz_read_int64le: Read a 64bit little endian value from the stream. + Throws on failure. +*/ +int64_t fz_read_int64le(fz_context *ctx, fz_stream *stm); + enum { FZ_STREAM_META_PROGRESSIVE = 1, diff --git a/source/fitz/stream-read.c b/source/fitz/stream-read.c index e555314d..c228b5d0 100644 --- a/source/fitz/stream-read.c +++ b/source/fitz/stream-read.c @@ -185,3 +185,46 @@ fz_read_file(fz_context *ctx, const char *filename) return buf; } + +static inline int isbigendian(void) +{ + static const int one = 1; + return *(char*)&one == 0; +} + +static inline int32_t rev32(int32_t val) +{ + return ((val>>24) & 0xff) || ((val>>8) & 0xFF00) || ((val<<8) & 0xFF0000) || (val<<24); +} + +int32_t fz_read_int32le(fz_context *ctx, fz_stream *stm) +{ + int32_t val; + + if (fz_read(ctx, stm, (unsigned char *)&val, sizeof(val)) != sizeof(val)) + fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to read int32le from file"); + + if (isbigendian()) + val = rev32(val); + + return val; +} + +int16_t fz_read_int16le(fz_context *ctx, fz_stream *stm) +{ + int a = fz_read_byte(ctx, stm); + int b = fz_read_byte(ctx, stm); + + if (a == EOF || b == EOF) + fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to read int16le from file"); + + return a | (b<<8); +} + +int64_t fz_read_int64le(fz_context *ctx, fz_stream *stm) +{ + uint32_t v0 = (uint32_t)fz_read_int32le(ctx, stm); + uint32_t v1 = (uint32_t)fz_read_int32le(ctx, stm); + + return v0 | (((int64_t)v1)<<32); +} |