summaryrefslogtreecommitdiff
path: root/src/gd_io_file.c
blob: facd91fc6cd38ead38fa889ed88d9529df71386d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
 * io_file.c
 *
 * Implements the file interface.
 *
 * As will all I/O modules, most functions are for local use only (called
 * via function pointers in the I/O context).
 *
 * Most functions are just 'wrappers' for standard file functions.
 *
 * Written/Modified 1999, Philip Warner.
 *
 */

#ifdef HAVE_CONFIG_H
#	include "config.h"
#endif

/* For platforms with incomplete ANSI defines. Fortunately,
 * SEEK_SET is defined to be zero by the standard. */

#ifndef SEEK_SET
#	define SEEK_SET 0
#endif /* SEEK_SET */

#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 fileIOCtx {
	gdIOCtx ctx;
	FILE *f;
}
fileIOCtx;

gdIOCtxPtr newFileCtx(FILE *f);

static int fileGetbuf(gdIOCtxPtr, void *, int);
static int filePutbuf(gdIOCtxPtr, const void *, int);
static void filePutchar(gdIOCtxPtr, int);
static int fileGetchar(gdIOCtxPtr ctx);

static int fileSeek(gdIOCtxPtr, const int);
static long fileTell(gdIOCtxPtr);
static void gdFreeFileCtx(gdIOCtxPtr ctx);

/*
	Function: gdNewFileCtx

	Return data as a dynamic pointer.
*/
BGD_DECLARE(gdIOCtxPtr) gdNewFileCtx(FILE *f)
{
	fileIOCtx *ctx;

	if (f == NULL) return NULL;
	ctx = (fileIOCtx *)gdMalloc(sizeof(fileIOCtx));
	if(ctx == NULL) {
		return NULL;
	}

	ctx->f = f;

	ctx->ctx.getC = fileGetchar;
	ctx->ctx.putC = filePutchar;

	ctx->ctx.getBuf = fileGetbuf;
	ctx->ctx.putBuf = filePutbuf;

	ctx->ctx.tell = fileTell;
	ctx->ctx.seek = fileSeek;

	ctx->ctx.gd_free = gdFreeFileCtx;

	return (gdIOCtxPtr)ctx;
}

static void gdFreeFileCtx(gdIOCtxPtr ctx)
{
	gdFree(ctx);
}


static int filePutbuf(gdIOCtxPtr ctx, const void *buf, int size)
{
	fileIOCtx *fctx;
	fctx = (fileIOCtx *)ctx;

	return fwrite(buf, 1, size, fctx->f);
}

static int fileGetbuf(gdIOCtxPtr ctx, void *buf, int size)
{
	fileIOCtx *fctx;
	fctx = (fileIOCtx *)ctx;

	return (fread(buf, 1, size, fctx->f));
}

static void filePutchar(gdIOCtxPtr ctx, int a)
{
	unsigned char b;
	fileIOCtx *fctx;
	fctx = (fileIOCtx *)ctx;

	b = a;

	putc(b, fctx->f);
}

static int fileGetchar(gdIOCtxPtr ctx)
{
	fileIOCtx *fctx;
	fctx = (fileIOCtx *)ctx;

	return getc(fctx->f);
}

static int fileSeek(gdIOCtxPtr ctx, const int pos)
{
	fileIOCtx *fctx;
	fctx = (fileIOCtx *)ctx;
	return (fseek(fctx->f, pos, SEEK_SET) == 0);
}

static long fileTell(gdIOCtxPtr ctx)
{
	fileIOCtx *fctx;
	fctx = (fileIOCtx *)ctx;

	return ftell(fctx->f);
}