diff options
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.c | 142 |
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); +} |