xref: /PHP-7.4/ext/gd/libgd/gd_io_ss.c (revision 36db28c8)
1 
2 /*
3    * io_ss.c
4    *
5    * Implements the Source/Sink interface.
6    *
7    * As will all I/O modules, most functions are for local use only (called
8    * via function pointers in the I/O context).
9    *
10    * The Source/Sink model is the primary 'user' interface for alternate data
11    * sources; the IOCtx interface is intended (at least in version 1.5) to be
12    * used internally until it settles down a bit.
13    *
14    * This module just layers the Source/Sink interface on top of the IOCtx; no
15    * support is provided for tell/seek, so GD2 writing is not possible, and
16    * retrieving parts of GD2 files is also not possible.
17    *
18    * A new SS context does not need to be created with both a Source and a Sink.
19    *
20    * Written/Modified 1999, Philip Warner.
21    *
22  */
23 
24 #include <math.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include "gd.h"
28 #include "gdhelpers.h"
29 
30 /* this is used for creating images in main memory */
31 
32 typedef struct ssIOCtx
33 {
34 	gdIOCtx ctx;
35 	gdSourcePtr src;
36 	gdSinkPtr snk;
37 } ssIOCtx;
38 
39 typedef struct ssIOCtx *ssIOCtxPtr;
40 
41 gdIOCtx *gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk);
42 
43 static int sourceGetbuf (gdIOCtx *, void *, int);
44 static int sourceGetchar (gdIOCtx * ctx);
45 static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size);
46 static void sinkPutchar (gdIOCtx * ctx, int a);
47 static void gdFreeSsCtx (gdIOCtx * ctx);
48 
49 /* return data as a dynamic pointer */
gdNewSSCtx(gdSourcePtr src,gdSinkPtr snk)50 gdIOCtx * gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk)
51 {
52 	ssIOCtxPtr ctx;
53 
54 	ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx));
55 
56 	ctx->src = src;
57 	ctx->snk = snk;
58 
59 	ctx->ctx.getC = sourceGetchar;
60 	ctx->ctx.getBuf = sourceGetbuf;
61 
62 	ctx->ctx.putC = sinkPutchar;
63 	ctx->ctx.putBuf = sinkPutbuf;
64 
65 	ctx->ctx.tell = NULL;
66 	ctx->ctx.seek = NULL;
67 
68 	ctx->ctx.gd_free = gdFreeSsCtx;
69 
70 	return (gdIOCtx *) ctx;
71 }
72 
gdFreeSsCtx(gdIOCtx * ctx)73 static void gdFreeSsCtx (gdIOCtx * ctx)
74 {
75 	gdFree(ctx);
76 }
77 
78 
sourceGetbuf(gdIOCtx * ctx,void * buf,int size)79 static int sourceGetbuf (gdIOCtx * ctx, void *buf, int size)
80 {
81 	ssIOCtx *lctx;
82 	int res;
83 
84 	lctx = (ssIOCtx *) ctx;
85 
86 	res = ((lctx->src->source) (lctx->src->context, buf, size));
87 
88 	/*
89 	 * Translate the return values from the Source object:
90 	 * 0 is EOF, -1 is error
91 	 */
92 
93 	if (res == 0) {
94 		return EOF;
95 	} else if (res < 0) {
96 		return 0;
97 	} else {
98 		return res;
99 	}
100 }
101 
sourceGetchar(gdIOCtx * ctx)102 static int sourceGetchar (gdIOCtx * ctx)
103 {
104 	int res;
105 	unsigned char buf;
106 
107 	res = sourceGetbuf (ctx, &buf, 1);
108 
109 	if (res == 1) {
110 		return buf;
111 	} else {
112 		return EOF;
113 	}
114 }
115 
sinkPutbuf(gdIOCtx * ctx,const void * buf,int size)116 static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size)
117 {
118 	ssIOCtxPtr lctx;
119 	int res;
120 
121 	lctx = (ssIOCtx *) ctx;
122 
123 	res = (lctx->snk->sink) (lctx->snk->context, buf, size);
124 
125 	if (res <= 0) {
126 		return 0;
127 	} else {
128 		return res;
129 	}
130 }
131 
sinkPutchar(gdIOCtx * ctx,int a)132 static void sinkPutchar (gdIOCtx * ctx, int a)
133 {
134 	unsigned char b;
135 
136 	b = a;
137 	sinkPutbuf (ctx, &b, 1);
138 }
139