summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2015-06-18 19:34:15 +0100
committerRobin Watts <robin.watts@artifex.com>2015-06-26 19:06:23 +0100
commit895b9cff172c28efdf2ec479b9f2fce1287acbc2 (patch)
treec1f0e5c0ad5b23becb3194f98d6058c240bb93f2
parent2b08c7f7ed2d4bc3874e5d2734c7d4a0ca3ad966 (diff)
downloadmupdf-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.h18
-rw-r--r--source/fitz/stream-read.c43
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);
+}