1 /*
2 * The copyright in this software is being made available under the 2-clauses
3 * BSD License, included below. This software may be subject to other third
4 * party and contributor rights, including patent rights, and no such rights
5 * are granted under this license.
6 *
7 * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8 * Copyright (c) 2002-2014, Professor Benoit Macq
9 * Copyright (c) 2001-2003, David Janssens
10 * Copyright (c) 2002-2003, Yannick Verschueren
11 * Copyright (c) 2003-2007, Francois-Olivier Devaux
12 * Copyright (c) 2003-2014, Antonin Descampe
13 * Copyright (c) 2005, Herve Drolon, FreeImage Team
14 * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
15 * Copyright (c) 2012, CS Systemes d'Information, France
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #include "opj_includes.h"
41
42 /* ----------------------------------------------------------------------- */
43
44
45 /* ----------------------------------------------------------------------- */
46
opj_write_bytes_BE(OPJ_BYTE * p_buffer,OPJ_UINT32 p_value,OPJ_UINT32 p_nb_bytes)47 void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
48 {
49 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes;
50
51 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
52
53 memcpy(p_buffer,l_data_ptr,p_nb_bytes);
54 }
55
opj_write_bytes_LE(OPJ_BYTE * p_buffer,OPJ_UINT32 p_value,OPJ_UINT32 p_nb_bytes)56 void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
57 {
58 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes - 1;
59 OPJ_UINT32 i;
60
61 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
62
63 for (i=0;i<p_nb_bytes;++i) {
64 *(p_buffer++) = *(l_data_ptr--);
65 }
66 }
67
opj_read_bytes_BE(const OPJ_BYTE * p_buffer,OPJ_UINT32 * p_value,OPJ_UINT32 p_nb_bytes)68 void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
69 {
70 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
71
72 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
73
74 *p_value = 0;
75 memcpy(l_data_ptr+4-p_nb_bytes,p_buffer,p_nb_bytes);
76 }
77
opj_read_bytes_LE(const OPJ_BYTE * p_buffer,OPJ_UINT32 * p_value,OPJ_UINT32 p_nb_bytes)78 void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
79 {
80 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + p_nb_bytes-1;
81 OPJ_UINT32 i;
82
83 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
84
85 *p_value = 0;
86 for (i=0;i<p_nb_bytes;++i) {
87 *(l_data_ptr--) = *(p_buffer++);
88 }
89 }
90
opj_write_double_BE(OPJ_BYTE * p_buffer,OPJ_FLOAT64 p_value)91 void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
92 {
93 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
94 memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT64));
95 }
96
opj_write_double_LE(OPJ_BYTE * p_buffer,OPJ_FLOAT64 p_value)97 void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
98 {
99 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT64) - 1;
100 OPJ_UINT32 i;
101 for (i=0;i<sizeof(OPJ_FLOAT64);++i) {
102 *(p_buffer++) = *(l_data_ptr--);
103 }
104 }
105
opj_read_double_BE(const OPJ_BYTE * p_buffer,OPJ_FLOAT64 * p_value)106 void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
107 {
108 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
109 memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT64));
110 }
111
opj_read_double_LE(const OPJ_BYTE * p_buffer,OPJ_FLOAT64 * p_value)112 void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
113 {
114 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT64)-1;
115 OPJ_UINT32 i;
116 for (i=0;i<sizeof(OPJ_FLOAT64);++i) {
117 *(l_data_ptr--) = *(p_buffer++);
118 }
119 }
120
opj_write_float_BE(OPJ_BYTE * p_buffer,OPJ_FLOAT32 p_value)121 void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
122 {
123 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
124 memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT32));
125 }
126
opj_write_float_LE(OPJ_BYTE * p_buffer,OPJ_FLOAT32 p_value)127 void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
128 {
129 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT32) - 1;
130 OPJ_UINT32 i;
131 for (i=0;i<sizeof(OPJ_FLOAT32);++i) {
132 *(p_buffer++) = *(l_data_ptr--);
133 }
134 }
135
opj_read_float_BE(const OPJ_BYTE * p_buffer,OPJ_FLOAT32 * p_value)136 void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
137 {
138 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
139 memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT32));
140 }
141
opj_read_float_LE(const OPJ_BYTE * p_buffer,OPJ_FLOAT32 * p_value)142 void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
143 {
144 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT32)-1;
145 OPJ_UINT32 i;
146 for (i=0;i<sizeof(OPJ_FLOAT32);++i) {
147 *(l_data_ptr--) = *(p_buffer++);
148 }
149 }
150
opj_stream_create(OPJ_SIZE_T p_buffer_size,OPJ_BOOL l_is_input)151 opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size,OPJ_BOOL l_is_input)
152 {
153 opj_stream_private_t * l_stream = 00;
154 l_stream = (opj_stream_private_t*) opj_malloc(sizeof(opj_stream_private_t));
155 if (! l_stream) {
156 return 00;
157 }
158
159 memset(l_stream,0,sizeof(opj_stream_private_t));
160 l_stream->m_buffer_size = p_buffer_size;
161 l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_buffer_size);
162 if (! l_stream->m_stored_data) {
163 opj_free(l_stream);
164 return 00;
165 }
166
167 l_stream->m_current_data = l_stream->m_stored_data;
168
169 if (l_is_input) {
170 l_stream->m_status |= opj_stream_e_input;
171 l_stream->m_opj_skip = opj_stream_read_skip;
172 l_stream->m_opj_seek = opj_stream_read_seek;
173 }
174 else {
175 l_stream->m_status |= opj_stream_e_output;
176 l_stream->m_opj_skip = opj_stream_write_skip;
177 l_stream->m_opj_seek = opj_stream_write_seek;
178 }
179
180 l_stream->m_read_fn = opj_stream_default_read;
181 l_stream->m_write_fn = opj_stream_default_write;
182 l_stream->m_skip_fn = opj_stream_default_skip;
183 l_stream->m_seek_fn = opj_stream_default_seek;
184
185 return (opj_stream_t *) l_stream;
186 }
187
opj_stream_default_create(OPJ_BOOL l_is_input)188 opj_stream_t* OPJ_CALLCONV opj_stream_default_create(OPJ_BOOL l_is_input)
189 {
190 return opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE,l_is_input);
191 }
192
opj_stream_destroy(opj_stream_t * p_stream)193 void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream)
194 {
195 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
196
197 if (l_stream) {
198 if (l_stream->m_free_user_data_fn) {
199 l_stream->m_free_user_data_fn(l_stream->m_user_data);
200 }
201 opj_free(l_stream->m_stored_data);
202 l_stream->m_stored_data = 00;
203 opj_free(l_stream);
204 }
205 }
206
opj_stream_destroy_v3(opj_stream_t * p_stream)207 void OPJ_CALLCONV opj_stream_destroy_v3(opj_stream_t* p_stream)
208 {
209 opj_stream_destroy(p_stream);
210 }
211
opj_stream_set_read_function(opj_stream_t * p_stream,opj_stream_read_fn p_function)212 void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function)
213 {
214 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
215
216 if ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input))) {
217 return;
218 }
219
220 l_stream->m_read_fn = p_function;
221 }
222
opj_stream_set_seek_function(opj_stream_t * p_stream,opj_stream_seek_fn p_function)223 void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function)
224 {
225 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
226
227 if (!l_stream) {
228 return;
229 }
230 l_stream->m_seek_fn = p_function;
231 }
232
opj_stream_set_write_function(opj_stream_t * p_stream,opj_stream_write_fn p_function)233 void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function)
234 {
235 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
236
237 if ((!l_stream )|| (! (l_stream->m_status & opj_stream_e_output))) {
238 return;
239 }
240
241 l_stream->m_write_fn = p_function;
242 }
243
opj_stream_set_skip_function(opj_stream_t * p_stream,opj_stream_skip_fn p_function)244 void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function)
245 {
246 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
247
248 if (! l_stream) {
249 return;
250 }
251
252 l_stream->m_skip_fn = p_function;
253 }
254
opj_stream_set_user_data(opj_stream_t * p_stream,void * p_data)255 void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data)
256 {
257 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
258 if (!l_stream)
259 return;
260 l_stream->m_user_data = p_data;
261 }
262
opj_stream_set_user_data_v3(opj_stream_t * p_stream,void * p_data,opj_stream_free_user_data_fn p_function)263 void OPJ_CALLCONV opj_stream_set_user_data_v3(opj_stream_t* p_stream, void * p_data, opj_stream_free_user_data_fn p_function)
264 {
265 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
266 if (!l_stream)
267 return;
268 l_stream->m_user_data = p_data;
269 l_stream->m_free_user_data_fn = p_function;
270 }
271
opj_stream_set_user_data_length(opj_stream_t * p_stream,OPJ_UINT64 data_length)272 void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT64 data_length)
273 {
274 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
275 if (!l_stream)
276 return;
277 l_stream->m_user_data_length = data_length;
278 }
279
opj_stream_read_data(opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer,OPJ_SIZE_T p_size,opj_event_mgr_t * p_event_mgr)280 OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
281 {
282 OPJ_SIZE_T l_read_nb_bytes = 0;
283 if (p_stream->m_bytes_in_buffer >= p_size) {
284 memcpy(p_buffer,p_stream->m_current_data,p_size);
285 p_stream->m_current_data += p_size;
286 p_stream->m_bytes_in_buffer -= p_size;
287 l_read_nb_bytes += p_size;
288 p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
289 return l_read_nb_bytes;
290 }
291
292 /* we are now in the case when the remaining data if not sufficient */
293 if (p_stream->m_status & opj_stream_e_end) {
294 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
295 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
296 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
297 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
298 p_stream->m_bytes_in_buffer = 0;
299 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
300 }
301
302 /* the flag is not set, we copy data and then do an actual read on the stream */
303 if (p_stream->m_bytes_in_buffer) {
304 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
305 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
306 p_stream->m_current_data = p_stream->m_stored_data;
307 p_buffer += p_stream->m_bytes_in_buffer;
308 p_size -= p_stream->m_bytes_in_buffer;
309 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
310 p_stream->m_bytes_in_buffer = 0;
311 }
312 else {
313 /* case where we are already at the end of the buffer
314 so reset the m_current_data to point to the start of the
315 stored buffer to get ready to read from disk*/
316 p_stream->m_current_data = p_stream->m_stored_data;
317 }
318
319 while(1){
320 /* we should read less than a chunk -> read a chunk */
321 if (p_size < p_stream->m_buffer_size) {
322 /* we should do an actual read on the media */
323 p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_stream->m_stored_data,p_stream->m_buffer_size,p_stream->m_user_data);
324
325 if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T)-1) {
326 /* end of stream */
327 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
328
329 p_stream->m_bytes_in_buffer = 0;
330 p_stream->m_status |= opj_stream_e_end;
331 /* end of stream */
332 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
333 }
334 else if (p_stream->m_bytes_in_buffer < p_size) {
335 /* not enough data */
336 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
337 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
338 p_stream->m_current_data = p_stream->m_stored_data;
339 p_buffer += p_stream->m_bytes_in_buffer;
340 p_size -= p_stream->m_bytes_in_buffer;
341 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
342 p_stream->m_bytes_in_buffer = 0;
343 }
344 else {
345 l_read_nb_bytes += p_size;
346 memcpy(p_buffer,p_stream->m_current_data,p_size);
347 p_stream->m_current_data += p_size;
348 p_stream->m_bytes_in_buffer -= p_size;
349 p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
350 return l_read_nb_bytes;
351 }
352 }
353 else {
354 /* direct read on the dest buffer */
355 p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data);
356
357 if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T)-1) {
358 /* end of stream */
359 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
360
361 p_stream->m_bytes_in_buffer = 0;
362 p_stream->m_status |= opj_stream_e_end;
363 /* end of stream */
364 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1;
365 }
366 else if (p_stream->m_bytes_in_buffer < p_size) {
367 /* not enough data */
368 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
369 p_stream->m_current_data = p_stream->m_stored_data;
370 p_buffer += p_stream->m_bytes_in_buffer;
371 p_size -= p_stream->m_bytes_in_buffer;
372 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
373 p_stream->m_bytes_in_buffer = 0;
374 }
375 else {
376 /* we have read the exact size */
377 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
378 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
379 p_stream->m_current_data = p_stream->m_stored_data;
380 p_stream->m_bytes_in_buffer = 0;
381 return l_read_nb_bytes;
382 }
383 }
384 }
385 }
386
opj_stream_write_data(opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer,OPJ_SIZE_T p_size,opj_event_mgr_t * p_event_mgr)387 OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,
388 const OPJ_BYTE * p_buffer,
389 OPJ_SIZE_T p_size,
390 opj_event_mgr_t * p_event_mgr)
391 {
392 OPJ_SIZE_T l_remaining_bytes = 0;
393 OPJ_SIZE_T l_write_nb_bytes = 0;
394
395 if (p_stream->m_status & opj_stream_e_error) {
396 return (OPJ_SIZE_T)-1;
397 }
398
399 while(1) {
400 l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
401
402 /* we have more memory than required */
403 if (l_remaining_bytes >= p_size) {
404 memcpy(p_stream->m_current_data, p_buffer, p_size);
405
406 p_stream->m_current_data += p_size;
407 p_stream->m_bytes_in_buffer += p_size;
408 l_write_nb_bytes += p_size;
409 p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
410
411 return l_write_nb_bytes;
412 }
413
414 /* we copy data and then do an actual read on the stream */
415 if (l_remaining_bytes) {
416 l_write_nb_bytes += l_remaining_bytes;
417
418 memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes);
419
420 p_stream->m_current_data = p_stream->m_stored_data;
421
422 p_buffer += l_remaining_bytes;
423 p_size -= l_remaining_bytes;
424 p_stream->m_bytes_in_buffer += l_remaining_bytes;
425 p_stream->m_byte_offset += (OPJ_OFF_T)l_remaining_bytes;
426 }
427
428 if (! opj_stream_flush(p_stream, p_event_mgr)) {
429 return (OPJ_SIZE_T)-1;
430 }
431 }
432
433 }
434
opj_stream_flush(opj_stream_private_t * p_stream,opj_event_mgr_t * p_event_mgr)435 OPJ_BOOL opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr)
436 {
437 /* the number of bytes written on the media. */
438 OPJ_SIZE_T l_current_write_nb_bytes = 0;
439
440 p_stream->m_current_data = p_stream->m_stored_data;
441
442 while (p_stream->m_bytes_in_buffer) {
443 /* we should do an actual write on the media */
444 l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data,
445 p_stream->m_bytes_in_buffer,
446 p_stream->m_user_data);
447
448 if (l_current_write_nb_bytes == (OPJ_SIZE_T)-1) {
449 p_stream->m_status |= opj_stream_e_error;
450 opj_event_msg(p_event_mgr, EVT_INFO, "Error on writing stream!\n");
451
452 return OPJ_FALSE;
453 }
454
455 p_stream->m_current_data += l_current_write_nb_bytes;
456 p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
457 }
458
459 p_stream->m_current_data = p_stream->m_stored_data;
460
461 return OPJ_TRUE;
462 }
463
opj_stream_read_skip(opj_stream_private_t * p_stream,OPJ_OFF_T p_size,opj_event_mgr_t * p_event_mgr)464 OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
465 {
466 OPJ_OFF_T l_skip_nb_bytes = 0;
467 OPJ_OFF_T l_current_skip_nb_bytes = 0;
468
469 assert( p_size >= 0 );
470
471 if (p_stream->m_bytes_in_buffer >= (OPJ_SIZE_T)p_size) {
472 p_stream->m_current_data += p_size;
473 /* it is safe to cast p_size to OPJ_SIZE_T since it is <= m_bytes_in_buffer
474 which is of type OPJ_SIZE_T */
475 p_stream->m_bytes_in_buffer -= (OPJ_SIZE_T)p_size;
476 l_skip_nb_bytes += p_size;
477 p_stream->m_byte_offset += l_skip_nb_bytes;
478 return l_skip_nb_bytes;
479 }
480
481 /* we are now in the case when the remaining data if not sufficient */
482 if (p_stream->m_status & opj_stream_e_end) {
483 l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
484 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
485 p_stream->m_bytes_in_buffer = 0;
486 p_stream->m_byte_offset += l_skip_nb_bytes;
487 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
488 }
489
490 /* the flag is not set, we copy data and then do an actual skip on the stream */
491 if (p_stream->m_bytes_in_buffer) {
492 l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
493 p_stream->m_current_data = p_stream->m_stored_data;
494 p_size -= (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
495 p_stream->m_bytes_in_buffer = 0;
496 }
497
498 while (p_size > 0) {
499 /* we should do an actual skip on the media */
500 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
501 if (l_current_skip_nb_bytes == (OPJ_OFF_T) -1) {
502 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
503
504 p_stream->m_status |= opj_stream_e_end;
505 p_stream->m_byte_offset += l_skip_nb_bytes;
506 /* end if stream */
507 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
508 }
509 p_size -= l_current_skip_nb_bytes;
510 l_skip_nb_bytes += l_current_skip_nb_bytes;
511 }
512
513 p_stream->m_byte_offset += l_skip_nb_bytes;
514
515 return l_skip_nb_bytes;
516 }
517
opj_stream_write_skip(opj_stream_private_t * p_stream,OPJ_OFF_T p_size,opj_event_mgr_t * p_event_mgr)518 OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
519 {
520 OPJ_BOOL l_is_written = 0;
521 OPJ_OFF_T l_current_skip_nb_bytes = 0;
522 OPJ_OFF_T l_skip_nb_bytes = 0;
523
524 if (p_stream->m_status & opj_stream_e_error) {
525 return (OPJ_OFF_T) -1;
526 }
527
528 /* we should flush data */
529 l_is_written = opj_stream_flush (p_stream, p_event_mgr);
530 if (! l_is_written) {
531 p_stream->m_status |= opj_stream_e_error;
532 p_stream->m_bytes_in_buffer = 0;
533 return (OPJ_OFF_T) -1;
534 }
535 /* then skip */
536
537 while (p_size > 0) {
538 /* we should do an actual skip on the media */
539 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
540
541 if (l_current_skip_nb_bytes == (OPJ_OFF_T)-1) {
542 opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n");
543
544 p_stream->m_status |= opj_stream_e_error;
545 p_stream->m_byte_offset += l_skip_nb_bytes;
546 /* end if stream */
547 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T)-1;
548 }
549 p_size -= l_current_skip_nb_bytes;
550 l_skip_nb_bytes += l_current_skip_nb_bytes;
551 }
552
553 p_stream->m_byte_offset += l_skip_nb_bytes;
554
555 return l_skip_nb_bytes;
556 }
557
opj_stream_tell(const opj_stream_private_t * p_stream)558 OPJ_OFF_T opj_stream_tell (const opj_stream_private_t * p_stream)
559 {
560 return p_stream->m_byte_offset;
561 }
562
opj_stream_get_number_byte_left(const opj_stream_private_t * p_stream)563 OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream)
564 {
565 assert( p_stream->m_byte_offset >= 0 );
566 assert( p_stream->m_user_data_length >= (OPJ_UINT64)p_stream->m_byte_offset);
567 return p_stream->m_user_data_length ?
568 (OPJ_OFF_T)(p_stream->m_user_data_length) - p_stream->m_byte_offset :
569 0;
570 }
571
opj_stream_skip(opj_stream_private_t * p_stream,OPJ_OFF_T p_size,opj_event_mgr_t * p_event_mgr)572 OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
573 {
574 assert(p_size >= 0);
575 return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr);
576 }
577
opj_stream_read_seek(opj_stream_private_t * p_stream,OPJ_OFF_T p_size,opj_event_mgr_t * p_event_mgr)578 OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
579 {
580 OPJ_ARG_NOT_USED(p_event_mgr);
581 p_stream->m_current_data = p_stream->m_stored_data;
582 p_stream->m_bytes_in_buffer = 0;
583
584 if( !(p_stream->m_seek_fn(p_size,p_stream->m_user_data)) ) {
585 p_stream->m_status |= opj_stream_e_end;
586 return OPJ_FALSE;
587 }
588 else {
589 /* reset stream status */
590 p_stream->m_status &= (~opj_stream_e_end);
591 p_stream->m_byte_offset = p_size;
592
593 }
594
595 return OPJ_TRUE;
596 }
597
opj_stream_write_seek(opj_stream_private_t * p_stream,OPJ_OFF_T p_size,opj_event_mgr_t * p_event_mgr)598 OPJ_BOOL opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
599 {
600 if (! opj_stream_flush(p_stream,p_event_mgr)) {
601 p_stream->m_status |= opj_stream_e_error;
602 return OPJ_FALSE;
603 }
604
605 p_stream->m_current_data = p_stream->m_stored_data;
606 p_stream->m_bytes_in_buffer = 0;
607
608 if (! p_stream->m_seek_fn(p_size,p_stream->m_user_data)) {
609 p_stream->m_status |= opj_stream_e_error;
610 return OPJ_FALSE;
611 }
612 else {
613 p_stream->m_byte_offset = p_size;
614 }
615
616 return OPJ_TRUE;
617 }
618
opj_stream_seek(opj_stream_private_t * p_stream,OPJ_OFF_T p_size,struct opj_event_mgr * p_event_mgr)619 OPJ_BOOL opj_stream_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr)
620 {
621 assert(p_size >= 0);
622 return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr);
623 }
624
opj_stream_has_seek(const opj_stream_private_t * p_stream)625 OPJ_BOOL opj_stream_has_seek (const opj_stream_private_t * p_stream)
626 {
627 return p_stream->m_seek_fn != opj_stream_default_seek;
628 }
629
opj_stream_default_read(void * p_buffer,OPJ_SIZE_T p_nb_bytes,void * p_user_data)630 OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
631 {
632 OPJ_ARG_NOT_USED(p_buffer);
633 OPJ_ARG_NOT_USED(p_nb_bytes);
634 OPJ_ARG_NOT_USED(p_user_data);
635 return (OPJ_SIZE_T) -1;
636 }
637
opj_stream_default_write(void * p_buffer,OPJ_SIZE_T p_nb_bytes,void * p_user_data)638 OPJ_SIZE_T opj_stream_default_write (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
639 {
640 OPJ_ARG_NOT_USED(p_buffer);
641 OPJ_ARG_NOT_USED(p_nb_bytes);
642 OPJ_ARG_NOT_USED(p_user_data);
643 return (OPJ_SIZE_T) -1;
644 }
645
opj_stream_default_skip(OPJ_OFF_T p_nb_bytes,void * p_user_data)646 OPJ_OFF_T opj_stream_default_skip (OPJ_OFF_T p_nb_bytes, void * p_user_data)
647 {
648 OPJ_ARG_NOT_USED(p_nb_bytes);
649 OPJ_ARG_NOT_USED(p_user_data);
650 return (OPJ_OFF_T) -1;
651 }
652
opj_stream_default_seek(OPJ_OFF_T p_nb_bytes,void * p_user_data)653 OPJ_BOOL opj_stream_default_seek (OPJ_OFF_T p_nb_bytes, void * p_user_data)
654 {
655 OPJ_ARG_NOT_USED(p_nb_bytes);
656 OPJ_ARG_NOT_USED(p_user_data);
657 return OPJ_FALSE;
658 }
659