]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/blob - QRScanner/mobile/jni/fitz/stream-open.c
Add MuPDF native source codes
[hornmich/skoda-qr-demo.git] / QRScanner / mobile / jni / fitz / stream-open.c
1 #include "mupdf/fitz.h"
2
3 void fz_rebind_stream(fz_stream *stm, fz_context *ctx)
4 {
5         if (stm == NULL || stm->ctx == ctx)
6                 return;
7         do {
8                 stm->ctx = ctx;
9                 stm = (stm->rebind == NULL ? NULL : stm->rebind(stm));
10         } while (stm != NULL);
11 }
12
13 fz_stream *
14 fz_new_stream(fz_context *ctx, void *state,
15         fz_stream_next_fn *next,
16         fz_stream_close_fn *close,
17         fz_stream_rebind_fn *rebind)
18 {
19         fz_stream *stm;
20
21         fz_try(ctx)
22         {
23                 stm = fz_malloc_struct(ctx, fz_stream);
24         }
25         fz_catch(ctx)
26         {
27                 close(ctx, state);
28                 fz_rethrow(ctx);
29         }
30
31         stm->refs = 1;
32         stm->error = 0;
33         stm->eof = 0;
34         stm->pos = 0;
35
36         stm->bits = 0;
37         stm->avail = 0;
38
39         stm->rp = NULL;
40         stm->wp = NULL;
41
42         stm->state = state;
43         stm->next = next;
44         stm->close = close;
45         stm->seek = NULL;
46         stm->rebind = rebind;
47         stm->ctx = ctx;
48
49         return stm;
50 }
51
52 fz_stream *
53 fz_keep_stream(fz_stream *stm)
54 {
55         if (stm)
56                 stm->refs ++;
57         return stm;
58 }
59
60 void
61 fz_close(fz_stream *stm)
62 {
63         if (!stm)
64                 return;
65         stm->refs --;
66         if (stm->refs == 0)
67         {
68                 if (stm->close)
69                         stm->close(stm->ctx, stm->state);
70                 fz_free(stm->ctx, stm);
71         }
72 }
73
74 /* File stream */
75
76 typedef struct fz_file_stream_s
77 {
78         int file;
79         unsigned char buffer[4096];
80 } fz_file_stream;
81
82 static int next_file(fz_stream *stm, int n)
83 {
84         fz_file_stream *state = stm->state;
85
86         /* n is only a hint, that we can safely ignore */
87         n = read(state->file, state->buffer, sizeof(state->buffer));
88         if (n < 0)
89                 fz_throw(stm->ctx, FZ_ERROR_GENERIC, "read error: %s", strerror(errno));
90         stm->rp = state->buffer;
91         stm->wp = state->buffer + n;
92         stm->pos += n;
93
94         if (n == 0)
95                 return EOF;
96         return *stm->rp++;
97 }
98
99 static void seek_file(fz_stream *stm, int offset, int whence)
100 {
101         fz_file_stream *state = stm->state;
102         int n = lseek(state->file, offset, whence);
103         if (n < 0)
104                 fz_throw(stm->ctx, FZ_ERROR_GENERIC, "cannot lseek: %s", strerror(errno));
105         stm->pos = n;
106         stm->rp = state->buffer;
107         stm->wp = state->buffer;
108 }
109
110 static void close_file(fz_context *ctx, void *state_)
111 {
112         fz_file_stream *state = state_;
113         int n = close(state->file);
114         if (n < 0)
115                 fz_warn(ctx, "close error: %s", strerror(errno));
116         fz_free(ctx, state);
117 }
118
119 fz_stream *
120 fz_open_fd(fz_context *ctx, int fd)
121 {
122         fz_stream *stm;
123         fz_file_stream *state = fz_malloc_struct(ctx, fz_file_stream);
124         state->file = fd;
125
126         fz_try(ctx)
127         {
128                 stm = fz_new_stream(ctx, state, next_file, close_file, NULL);
129         }
130         fz_catch(ctx)
131         {
132                 fz_free(ctx, state);
133                 fz_rethrow(ctx);
134         }
135         stm->seek = seek_file;
136
137         return stm;
138 }
139
140 fz_stream *
141 fz_open_file(fz_context *ctx, const char *name)
142 {
143 #ifdef _WIN32
144         char *s = (char*)name;
145         wchar_t *wname, *d;
146         int c, fd;
147         d = wname = fz_malloc(ctx, (strlen(name)+1) * sizeof(wchar_t));
148         while (*s) {
149                 s += fz_chartorune(&c, s);
150                 *d++ = c;
151         }
152         *d = 0;
153         fd = _wopen(wname, O_BINARY | O_RDONLY, 0);
154         fz_free(ctx, wname);
155 #else
156         int fd = open(name, O_BINARY | O_RDONLY, 0);
157 #endif
158         if (fd == -1)
159                 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open %s", name);
160         return fz_open_fd(ctx, fd);
161 }
162
163 #ifdef _WIN32
164 fz_stream *
165 fz_open_file_w(fz_context *ctx, const wchar_t *name)
166 {
167         int fd = _wopen(name, O_BINARY | O_RDONLY, 0);
168         if (fd == -1)
169                 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open file %ls", name);
170         return fz_open_fd(ctx, fd);
171 }
172 #endif
173
174 /* Memory stream */
175
176 static int next_buffer(fz_stream *stm, int max)
177 {
178         return EOF;
179 }
180
181 static void seek_buffer(fz_stream *stm, int offset, int whence)
182 {
183         int pos = stm->pos - (stm->wp - stm->rp);
184         /* Convert to absolute pos */
185         if (whence == 1)
186         {
187                 offset += pos; /* Was relative to current pos */
188         }
189         else if (whence == 2)
190         {
191                 offset += stm->pos; /* Was relative to end */
192         }
193
194         if (offset < 0)
195                 offset = 0;
196         if (offset > stm->pos)
197                 offset = stm->pos;
198         stm->rp += offset - pos;
199 }
200
201 static void close_buffer(fz_context *ctx, void *state_)
202 {
203         fz_buffer *state = (fz_buffer *)state_;
204         if (state)
205                 fz_drop_buffer(ctx, state);
206 }
207
208 fz_stream *
209 fz_open_buffer(fz_context *ctx, fz_buffer *buf)
210 {
211         fz_stream *stm;
212
213         fz_keep_buffer(ctx, buf);
214         stm = fz_new_stream(ctx, buf, next_buffer, close_buffer, NULL);
215         stm->seek = seek_buffer;
216
217         stm->rp = buf->data;
218         stm->wp = buf->data + buf->len;
219
220         stm->pos = buf->len;
221
222         return stm;
223 }
224
225 fz_stream *
226 fz_open_memory(fz_context *ctx, unsigned char *data, int len)
227 {
228         fz_stream *stm;
229
230         stm = fz_new_stream(ctx, NULL, next_buffer, close_buffer, NULL);
231         stm->seek = seek_buffer;
232
233         stm->rp = data;
234         stm->wp = data + len;
235
236         stm->pos = len;
237
238         return stm;
239 }