GFXprim
2D bitmap graphics library with emphasis on speed and correctness
Loading...
Searching...
No Matches
gp_io.h
1// SPDX-License-Identifier: LGPL-2.1-or-later
2/*
3 * Copyright (C) 2009-2014 Cyril Hrubis <metan@ucw.cz>
4 */
5
6 /*
7
8 I/O abstraction for gfxprim loaders.
9
10 */
11
12#ifndef LOADERS_GP_IO_H
13#define LOADERS_GP_IO_H
14
15#include <stdint.h>
16#include <sys/types.h>
17#include <utils/gp_seek.h>
18#include <loaders/gp_types.h>
19
20struct gp_io {
21 ssize_t (*read)(gp_io *self, void *buf, size_t size);
22 ssize_t (*write)(gp_io *self, const void *buf, size_t size);
23 off_t (*seek)(gp_io *self, off_t off, enum gp_seek_whence whence);
24 int (*close)(gp_io *self);
25
26 off_t mark;
27 char priv[];
28};
29
30#define GP_IO_PRIV(io) ((void *)(io)->priv)
31
32/*
33 * Just inline wrappers.
34 */
35static inline ssize_t gp_io_read(gp_io *io, void *buf, size_t size)
36{
37 return io->read(io, buf, size);
38}
39
40static inline ssize_t gp_io_write(gp_io *io, const void *buf, size_t size)
41{
42 return io->write(io, buf, size);
43}
44
45static inline int gp_io_close(gp_io *io)
46{
47 return io->close(io);
48}
49
50static inline off_t gp_io_seek(gp_io *io, off_t off, enum gp_seek_whence whence)
51{
52 return io->seek(io, off, whence);
53}
54
55/*
56 * PutC returns zero on success, non-zero on failure.
57 */
58static inline int gp_io_putc(gp_io *io, char c)
59{
60 return io->write(io, &c, 1) != 1;
61}
62
63static inline int gp_io_getb(gp_io *io)
64{
65 unsigned char c;
66
67 if (io->read(io, &c, 1) != 1)
68 return -1;
69
70 return c;
71}
72
73/*
74 * Returns current offset
75 */
76static inline off_t gp_io_tell(gp_io *io)
77{
78 return io->seek(io, 0, GP_SEEK_CUR);
79}
80
81/*
82 * Rewinds to start of the I/O stream.
83 */
84static inline off_t gp_io_rewind(gp_io *io)
85{
86 return io->seek(io, 0, GP_SEEK_SET);
87}
88
89static inline off_t gp_io_peek(gp_io *io, void *buf, size_t size)
90{
91 off_t cur_off = gp_io_tell(io);
92
93 if (gp_io_read(io, buf, size) != (ssize_t)size)
94 return -1;
95
96 return gp_io_seek(io, cur_off, GP_SEEK_SET);
97}
98
99
100/*
101 * Returns I/O stream size.
102 *
103 * May return (off_t)-1 in case that gp_io_SEEK_END is not possible.
104 */
105off_t gp_io_size(gp_io *io);
106
107/*
108 * Like a Read but either fills whole buffer or returns error.
109 *
110 * Returns zero on success non-zero on failure.
111 */
112int gp_io_fill(gp_io *io, void *buf, size_t size);
113
114/*
115 * Like Write but either writes whole buffer or retuns error.
116 *
117 * Returns zero on succes non-zero on failure.
118 */
119int gp_io_flush(gp_io *io, const void *buf, size_t size);
120
121/*
122 * Marks a current position, returns to mark in I/O stream.
123 */
124enum gp_io_mark_types {
125 GP_IO_MARK,
126 GP_IO_REWIND,
127};
128
129int gp_io_mark(gp_io *self, enum gp_io_mark_types type);
130
131/*
132 * Formatted read.
133 */
134enum gp_io_fmt_types {
135 /* Constant byte in lower half */
136 GP_IO_CONST = 0x0000,
137 /* Pointer to one byte */
138 GP_IO_BYTE = 0x0100,
139 /* Pointer to byte integer in litte endian */
140 GP_IO_L2 = 0x0200,
141 /* Poiter to four byte integer in litte endian */
142 GP_IO_L4 = 0x0300,
143 /* Pointer to two byte integer in big endian */
144 GP_IO_B2 = 0x0400,
145 /* Pointer to four byte integer in big endian */
146 GP_IO_B4 = 0x0500,
147 /* Pointer to byte array, size in lower half */
148 GP_IO_ARRAY = 0x0600,
149 /* Ignore bytes on read, size in lower half */
150 GP_IO_IGN = 0x0700,
151 GP_IO_I1 = GP_IO_IGN | 1,
152 GP_IO_I2 = GP_IO_IGN | 2,
153 GP_IO_I3 = GP_IO_IGN | 3,
154 GP_IO_I4 = GP_IO_IGN | 4,
155 /*
156 * Photoshop Pascal string
157 *
158 * first byte stores size and string is padded to even number bytes.
159 *
160 * The lower half stores passed buffer size.
161 *
162 * TODO: Unfinished
163 */
164 GP_IO_PPSTR = 0x0800,
165 /* End of the types array */
166 GP_IO_END = 0xff00,
167};
168
169#define GP_IO_TYPE_MASK 0xff00
170
171int gp_io_readf(gp_io *self, const uint16_t *types, ...);
172
173int gp_io_writef(gp_io *self, const uint16_t *types, ...);
174
175/*
176 * Printf like function.
177 *
178 * Returns zero on success, non-zero on failure.
179 */
180int gp_io_printf(gp_io *self, const char *fmt, ...)
181 __attribute__ ((format (printf, 2, 3)));
182
183/*
184 * gp_io_readf wrappers for convinient reading of single value
185 */
186int gp_io_read_b4(gp_io *io, uint32_t *val);
187
188int gp_io_read_b2(gp_io *io, uint16_t *val);
189
190enum gp_io_file_mode {
191 GP_IO_RDONLY = 0x00,
192 GP_IO_WRONLY = 0x01,
193 GP_IO_RDWR = 0x02,
194};
195
196/*
197 * Creates I/O from a file. On error NULL is returned and errno is set.
198 */
199gp_io *gp_io_file(const char *path, enum gp_io_file_mode mode);
200
201/*
202 * Creates I/O from a memory buffer.
203 *
204 * If free is not NULL, it's called on buf pointer on gp_ioClose().
205 */
206gp_io *gp_io_mem(void *buf, size_t size, void (*free)(void *));
207
208/*
209 * Create a sub I/O from an I/O.
210 *
211 * The sub I/O starts at current offset in the parent I/O (which is also point
212 * where gp_ioTell() for the new I/O will return zero) and continues for
213 * maximally size bytes in the parent I/O. Reads at the end of the Sub I/O will
214 * be truncated to the.
215 *
216 * WARNING: If you combine reading/writing in the Sub I/O and parent I/O the
217 * result is undefined.
218 */
219gp_io *gp_io_sub_io(gp_io *pio, size_t size);
220
221/*
222 * Creates a writeable buffered I/O on the top of the existing I/O.
223 *
224 * Passing zero as bsize select default buffer size.
225 */
226gp_io *gp_io_wbuffer(gp_io *pio, size_t bsize);
227
228#endif /* LOADERS_GP_IO_H */
Seek contants and transformations.
gp_seek_whence
Seek constants.
Definition gp_seek.h:24