summaryrefslogtreecommitdiff
path: root/Build/source/libs/gd/libgd-src/src/gd_io_ss.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/gd/libgd-src/src/gd_io_ss.c')
-rw-r--r--Build/source/libs/gd/libgd-src/src/gd_io_ss.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/Build/source/libs/gd/libgd-src/src/gd_io_ss.c b/Build/source/libs/gd/libgd-src/src/gd_io_ss.c
new file mode 100644
index 00000000000..a0cf3918f91
--- /dev/null
+++ b/Build/source/libs/gd/libgd-src/src/gd_io_ss.c
@@ -0,0 +1,142 @@
+/*
+ * io_ss.c
+ *
+ * Implements the Source/Sink interface.
+ *
+ * As will all I/O modules, most functions are for local use only (called
+ * via function pointers in the I/O context).
+ *
+ * The Source/Sink model is the primary 'user' interface for alternate data
+ * sources; the IOCtx interface is intended (at least in version 1.5) to be
+ * used internally until it settles down a bit.
+ *
+ * This module just layers the Source/Sink interface on top of the IOCtx; no
+ * support is provided for tell/seek, so GD2 writing is not possible, and
+ * retrieving parts of GD2 files is also not possible.
+ *
+ * A new SS context does not need to be created with both a Source and a Sink.
+ *
+ * Written/Modified 1999, Philip Warner.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include "gd.h"
+#include "gdhelpers.h"
+
+/* this is used for creating images in main memory */
+
+typedef struct ssIOCtx {
+ gdIOCtx ctx;
+ gdSourcePtr src;
+ gdSinkPtr snk;
+}
+ssIOCtx;
+
+typedef struct ssIOCtx *ssIOCtxPtr;
+
+static int sourceGetbuf(gdIOCtx *, void *, int);
+static int sourceGetchar(gdIOCtx *ctx);
+static int sinkPutbuf(gdIOCtx *ctx, const void *buf, int size);
+static void sinkPutchar(gdIOCtx *ctx, int a);
+static void gdFreeSsCtx(gdIOCtx *ctx);
+
+/* return data as a dynamic pointer */
+BGD_DECLARE(gdIOCtx *) gdNewSSCtx(gdSourcePtr src, gdSinkPtr snk)
+{
+ ssIOCtxPtr ctx;
+
+ ctx = (ssIOCtxPtr)gdMalloc(sizeof (ssIOCtx));
+ if (ctx == NULL) {
+ return NULL;
+ }
+
+ ctx->src = src;
+ ctx->snk = snk;
+
+ ctx->ctx.getC = sourceGetchar;
+ ctx->ctx.getBuf = sourceGetbuf;
+
+ ctx->ctx.putC = sinkPutchar;
+ ctx->ctx.putBuf = sinkPutbuf;
+
+ ctx->ctx.tell = NULL;
+ ctx->ctx.seek = NULL;
+
+ ctx->ctx.gd_free = gdFreeSsCtx;
+
+ return (gdIOCtx *)ctx;
+}
+
+static void gdFreeSsCtx(gdIOCtx *ctx)
+{
+ gdFree(ctx);
+}
+
+static int sourceGetbuf(gdIOCtx *ctx, void *buf, int size)
+{
+ ssIOCtx *lctx;
+ int res;
+
+ lctx = (ssIOCtx *)ctx;
+
+ res = ((lctx->src->source)(lctx->src->context, buf, size));
+
+ /*
+ * Translate the return values from the Source object:
+ * 0 is EOF, -1 is error
+ */
+
+ if (res == 0) {
+ return 0;
+ } else if (res < 0) {
+ return 0;
+ } else {
+ return res;
+ }
+}
+
+static int sourceGetchar(gdIOCtx *ctx)
+{
+ int res;
+ unsigned char buf;
+
+ res = sourceGetbuf(ctx, &buf, 1);
+
+ if (res == 1) {
+ return buf;
+ } else {
+ return EOF;
+ }
+}
+
+static int sinkPutbuf(gdIOCtx *ctx, const void *buf, int size)
+{
+ ssIOCtxPtr lctx;
+ int res;
+
+ lctx = (ssIOCtx *)ctx;
+
+ res = (lctx->snk->sink)(lctx->snk->context, buf, size);
+
+ if (res <= 0) {
+ return 0;
+ } else {
+ return res;
+ }
+}
+
+static void sinkPutchar(gdIOCtx *ctx, int a)
+{
+ unsigned char b;
+
+ b = a;
+
+ sinkPutbuf(ctx, &b, 1);
+}