2 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
\r
3 * Copyright (c) 2002-2007, Professor Benoit Macq
\r
4 * Copyright (c) 2001-2003, David Janssens
\r
5 * Copyright (c) 2002-2003, Yannick Verschueren
\r
6 * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
\r
7 * Copyright (c) 2005, Herve Drolon, FreeImage Team
\r
8 * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
\r
9 * All rights reserved.
\r
11 * Redistribution and use in source and binary forms, with or without
\r
12 * modification, are permitted provided that the following conditions
\r
14 * 1. Redistributions of source code must retain the above copyright
\r
15 * notice, this list of conditions and the following disclaimer.
\r
16 * 2. Redistributions in binary form must reproduce the above copyright
\r
17 * notice, this list of conditions and the following disclaimer in the
\r
18 * documentation and/or other materials provided with the distribution.
\r
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
\r
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\r
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
\r
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
\r
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
\r
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
\r
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
\r
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
\r
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
\r
30 * POSSIBILITY OF SUCH DAMAGE.
\r
34 #include "opj_includes.h"
\r
35 #include "opj_malloc.h"
\r
38 /* ----------------------------------------------------------------------- */
\r
42 * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
\r
43 * @param p_buffer pointer the data buffer to write data to.
\r
44 * @param p_value the value to write
\r
45 * @param p_nb_bytes the number of bytes to write
\r
47 void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
\r
49 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes;
\r
50 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
\r
51 memcpy(p_buffer,l_data_ptr,p_nb_bytes);
\r
55 * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
\r
56 * @param p_buffer pointer the data buffer to write data to.
\r
57 * @param p_value the value to write
\r
58 * @param p_nb_bytes the number of bytes to write
\r
59 * @return the number of bytes written or -1 if an error occured
\r
61 void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
\r
63 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes - 1;
\r
66 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
\r
68 (i=0;i<p_nb_bytes;++i)
\r
70 *(p_buffer++) = *(l_data_ptr--);
\r
75 * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
\r
76 * @param p_buffer pointer the data buffer to read data from.
\r
77 * @param p_value pointer to the value that will store the data.
\r
78 * @param p_nb_bytes the nb bytes to read.
\r
79 * @return the number of bytes read or -1 if an error occured.
\r
81 void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
\r
83 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
\r
84 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
\r
86 memcpy(l_data_ptr+4-p_nb_bytes,p_buffer,p_nb_bytes);
\r
90 * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
\r
91 * @param p_buffer pointer the data buffer to read data from.
\r
92 * @param p_value pointer to the value that will store the data.
\r
93 * @param p_nb_bytes the nb bytes to read.
\r
94 * @return the number of bytes read or -1 if an error occured.
\r
96 void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
\r
98 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + p_nb_bytes-1;
\r
101 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
\r
104 (i=0;i<p_nb_bytes;++i)
\r
106 *(l_data_ptr--) = *(p_buffer++);
\r
111 * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
\r
112 * @param p_buffer pointer the data buffer to write data to.
\r
113 * @param p_value the value to write
\r
114 * @return the number of bytes written or -1 if an error occured
\r
116 void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
\r
118 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
\r
119 memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT64));
\r
123 * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
\r
124 * @param p_buffer pointer the data buffer to write data to.
\r
125 * @param p_value the value to write
\r
127 void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
\r
129 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT64) - 1;
\r
132 (i=0;i<sizeof(OPJ_FLOAT64);++i)
\r
134 *(p_buffer++) = *(l_data_ptr--);
\r
139 * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
\r
140 * @param p_buffer pointer the data buffer to read data from.
\r
141 * @param p_value pointer to the value that will store the data.
\r
143 void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
\r
145 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
\r
146 memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT64));
\r
151 * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
\r
152 * @param p_buffer pointer the data buffer to read data from.
\r
153 * @param p_value pointer to the value that will store the data.
\r
155 void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
\r
157 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT64)-1;
\r
160 (i=0;i<sizeof(OPJ_FLOAT64);++i)
\r
162 *(l_data_ptr--) = *(p_buffer++);
\r
167 * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
\r
168 * @param p_buffer pointer the data buffer to write data to.
\r
169 * @param p_value the value to write
\r
170 * @return the number of bytes written or -1 if an error occured
\r
172 void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
\r
174 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
\r
175 memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT32));
\r
179 * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
\r
180 * @param p_buffer pointer the data buffer to write data to.
\r
181 * @param p_value the value to write
\r
183 void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
\r
185 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT32) - 1;
\r
188 (i=0;i<sizeof(OPJ_FLOAT32);++i)
\r
190 *(p_buffer++) = *(l_data_ptr--);
\r
195 * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
\r
196 * @param p_buffer pointer the data buffer to read data from.
\r
197 * @param p_value pointer to the value that will store the data.
\r
199 void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
\r
201 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
\r
202 memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT32));
\r
207 * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
\r
208 * @param p_buffer pointer the data buffer to read data from.
\r
209 * @param p_value pointer to the value that will store the data.
\r
211 void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
\r
213 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT32)-1;
\r
216 (i=0;i<sizeof(OPJ_FLOAT32);++i)
\r
218 *(l_data_ptr--) = *(p_buffer++);
\r
224 * Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream.
\r
225 * @return a stream object.
\r
227 opj_stream_t* opj_stream_create(OPJ_UINT32 p_size,bool l_is_input)
\r
229 opj_stream_private_t * l_stream = 00;
\r
230 l_stream = (opj_stream_private_t*) opj_malloc(sizeof(opj_stream_private_t));
\r
236 memset(l_stream,0,sizeof(opj_stream_private_t));
\r
237 l_stream->m_buffer_size = p_size;
\r
238 l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_size);
\r
240 (! l_stream->m_stored_data)
\r
242 opj_free(l_stream);
\r
245 l_stream->m_current_data = l_stream->m_stored_data;
\r
249 l_stream->m_status |= opj_stream_e_input;
\r
250 l_stream->m_opj_skip = opj_stream_read_skip;
\r
251 l_stream->m_opj_seek = opj_stream_read_seek;
\r
255 l_stream->m_status |= opj_stream_e_output;
\r
256 l_stream->m_opj_skip = opj_stream_write_skip;
\r
257 l_stream->m_opj_seek = opj_stream_write_seek;
\r
259 l_stream->m_read_fn = opj_stream_default_read;
\r
260 l_stream->m_write_fn = opj_stream_default_write;
\r
261 l_stream->m_skip_fn = opj_stream_default_skip;
\r
262 l_stream->m_seek_fn = opj_stream_default_seek;
\r
264 return (opj_stream_t *) l_stream;
\r
268 * Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream.
\r
269 * @return a stream object.
\r
271 opj_stream_t* opj_stream_default_create(bool l_is_input)
\r
273 return opj_stream_create(J2K_STREAM_CHUNK_SIZE,l_is_input);
\r
277 * Destroys a stream created by opj_create_stream. This function does NOT close the abstract stream. If needed the user must
\r
278 * close its own implementation of the stream.
\r
280 OPJ_API void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream)
\r
282 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
\r
286 opj_free(l_stream->m_stored_data);
\r
287 l_stream->m_stored_data = 00;
\r
288 opj_free(l_stream);
\r
294 * Sets the given function to be used as a read function.
\r
295 * @param p_stream the stream to modify
\r
296 * @param p_function the function to use a read function.
\r
298 OPJ_API void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function)
\r
300 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
\r
302 ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input)))
\r
306 l_stream->m_read_fn = p_function;
\r
309 OPJ_API void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function)
\r
311 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
\r
317 l_stream->m_seek_fn = p_function;
\r
321 * Sets the given function to be used as a write function.
\r
322 * @param p_stream the stream to modify
\r
323 * @param p_function the function to use a write function.
\r
325 OPJ_API void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function)
\r
327 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
\r
329 ((!l_stream )|| (! (l_stream->m_status & opj_stream_e_output)))
\r
333 l_stream->m_write_fn = p_function;
\r
337 * Sets the given function to be used as a skip function.
\r
338 * @param p_stream the stream to modify
\r
339 * @param p_function the function to use a skip function.
\r
341 OPJ_API void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function)
\r
343 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
\r
349 l_stream->m_skip_fn = p_function;
\r
353 * Sets the given data to be used as a user data for the stream.
\r
354 * @param p_stream the stream to modify
\r
355 * @param p_data the data to set.
\r
357 OPJ_API void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data)
\r
359 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
\r
360 l_stream->m_user_data = p_data;
\r
364 * Reads some bytes from the stream.
\r
365 * @param p_stream the stream to read data from.
\r
366 * @param p_buffer pointer to the data buffer that will receive the data.
\r
367 * @param p_size number of bytes to read.
\r
368 * @param p_event_mgr the user event manager to be notified of special events.
\r
369 * @return the number of bytes read, or -1 if an error occured or if the stream is at the end.
\r
371 OPJ_UINT32 opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_UINT32 p_size, opj_event_mgr_t * p_event_mgr)
\r
373 OPJ_UINT32 l_read_nb_bytes = 0;
\r
375 (p_stream->m_bytes_in_buffer >= p_size)
\r
377 memcpy(p_buffer,p_stream->m_current_data,p_size);
\r
378 p_stream->m_current_data += p_size;
\r
379 p_stream->m_bytes_in_buffer -= p_size;
\r
380 l_read_nb_bytes += p_size;
\r
381 p_stream->m_byte_offset += p_size;
\r
382 return l_read_nb_bytes;
\r
385 // we are now in the case when the remaining data if not sufficient
\r
387 (p_stream->m_status & opj_stream_e_end)
\r
389 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
\r
390 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
\r
391 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
\r
392 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
\r
393 p_stream->m_bytes_in_buffer = 0;
\r
394 return l_read_nb_bytes ? l_read_nb_bytes : -1;
\r
397 // the flag is not set, we copy data and then do an actual read on the stream
\r
399 (p_stream->m_bytes_in_buffer)
\r
401 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
\r
402 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
\r
403 p_stream->m_current_data = p_stream->m_stored_data;
\r
404 p_buffer += p_stream->m_bytes_in_buffer;
\r
405 p_size -= p_stream->m_bytes_in_buffer;
\r
406 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
\r
407 p_stream->m_bytes_in_buffer = 0;
\r
413 // we should read less than a chunk -> read a chunk
\r
415 (p_size < p_stream->m_buffer_size)
\r
417 // we should do an actual read on the media
\r
418 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);
\r
420 (p_stream->m_bytes_in_buffer == -1)
\r
423 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
\r
424 p_stream->m_bytes_in_buffer = 0;
\r
425 p_stream->m_status |= opj_stream_e_end;
\r
427 return l_read_nb_bytes ? l_read_nb_bytes : -1;
\r
430 (p_stream->m_bytes_in_buffer < p_size)
\r
433 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
\r
434 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
\r
435 p_stream->m_current_data = p_stream->m_stored_data;
\r
436 p_buffer += p_stream->m_bytes_in_buffer;
\r
437 p_size -= p_stream->m_bytes_in_buffer;
\r
438 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
\r
439 p_stream->m_bytes_in_buffer = 0;
\r
443 l_read_nb_bytes += p_size;
\r
444 memcpy(p_buffer,p_stream->m_current_data,p_size);
\r
445 p_stream->m_current_data += p_size;
\r
446 p_stream->m_bytes_in_buffer -= p_size;
\r
447 p_stream->m_byte_offset += p_size;
\r
448 return l_read_nb_bytes;
\r
453 // direct read on the dest buffer
\r
454 p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data);
\r
456 (p_stream->m_bytes_in_buffer == -1)
\r
459 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
\r
460 p_stream->m_bytes_in_buffer = 0;
\r
461 p_stream->m_status |= opj_stream_e_end;
\r
463 return l_read_nb_bytes ? l_read_nb_bytes : -1;
\r
466 (p_stream->m_bytes_in_buffer < p_size)
\r
469 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
\r
470 p_stream->m_current_data = p_stream->m_stored_data;
\r
471 p_buffer += p_stream->m_bytes_in_buffer;
\r
472 p_size -= p_stream->m_bytes_in_buffer;
\r
473 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
\r
474 p_stream->m_bytes_in_buffer = 0;
\r
478 // we have read the exact size
\r
479 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
\r
480 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
\r
481 p_stream->m_current_data = p_stream->m_stored_data;
\r
482 p_stream->m_bytes_in_buffer = 0;
\r
483 return l_read_nb_bytes;
\r
490 * Writes some bytes from the stream.
\r
491 * @param p_stream the stream to write data to.
\r
492 * @param p_buffer pointer to the data buffer holds the data to be writtent.
\r
493 * @param p_size number of bytes to write.
\r
494 * @param p_event_mgr the user event manager to be notified of special events.
\r
495 * @return the number of bytes writtent, or -1 if an error occured.
\r
497 OPJ_UINT32 opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer,OPJ_UINT32 p_size, opj_event_mgr_t * p_event_mgr)
\r
499 OPJ_UINT32 l_remaining_bytes = 0;
\r
500 OPJ_UINT32 l_write_nb_bytes = 0;
\r
503 (p_stream->m_status & opj_stream_e_error)
\r
511 l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
\r
512 // we have more memory than required
\r
514 (l_remaining_bytes >= p_size)
\r
516 memcpy(p_stream->m_current_data,p_buffer,p_size);
\r
517 p_stream->m_current_data += p_size;
\r
518 p_stream->m_bytes_in_buffer += p_size;
\r
519 l_write_nb_bytes += p_size;
\r
520 p_stream->m_byte_offset += p_size;
\r
521 return l_write_nb_bytes;
\r
524 // we copy data and then do an actual read on the stream
\r
526 (l_remaining_bytes)
\r
528 l_write_nb_bytes += l_remaining_bytes;
\r
529 memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes);
\r
530 p_stream->m_current_data = p_stream->m_stored_data;
\r
531 p_buffer += l_remaining_bytes;
\r
532 p_size -= l_remaining_bytes;
\r
533 p_stream->m_bytes_in_buffer += l_remaining_bytes;
\r
534 p_stream->m_byte_offset += l_remaining_bytes;
\r
537 (! opj_stream_flush(p_stream, p_event_mgr))
\r
546 * Writes the content of the stream buffer to the stream.
\r
547 * @param p_stream the stream to write data to.
\r
548 * @param p_event_mgr the user event manager to be notified of special events.
\r
549 * @return the number of bytes written, or -1 if an error occured.
\r
551 bool opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr)
\r
553 // the number of bytes written on the media.
\r
554 OPJ_UINT32 l_current_write_nb_bytes = 0;
\r
555 p_stream->m_current_data = p_stream->m_stored_data;
\r
558 (p_stream->m_bytes_in_buffer)
\r
560 // we should do an actual write on the media
\r
561 l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data,p_stream->m_bytes_in_buffer,p_stream->m_user_data);
\r
563 (l_current_write_nb_bytes == -1)
\r
565 p_stream->m_status |= opj_stream_e_error;
\r
566 opj_event_msg(p_event_mgr, EVT_INFO, "Error on writting stream!\n");
\r
569 p_stream->m_current_data += l_current_write_nb_bytes;
\r
570 p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
\r
572 p_stream->m_current_data = p_stream->m_stored_data;
\r
577 * Skips a number of bytes from the stream.
\r
578 * @param p_stream the stream to skip data from.
\r
579 * @param p_size the number of bytes to skip.
\r
580 * @param p_event_mgr the user event manager to be notified of special events.
\r
581 * @return the number of bytes skipped, or -1 if an error occured.
\r
583 OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
\r
585 OPJ_SIZE_T l_skip_nb_bytes = 0;
\r
586 OPJ_SIZE_T l_current_skip_nb_bytes = 0;
\r
589 (p_stream->m_bytes_in_buffer >= p_size)
\r
591 p_stream->m_current_data += p_size;
\r
592 p_stream->m_bytes_in_buffer -= p_size;
\r
593 l_skip_nb_bytes += p_size;
\r
594 p_stream->m_byte_offset += l_skip_nb_bytes;
\r
595 return l_skip_nb_bytes;
\r
598 // we are now in the case when the remaining data if not sufficient
\r
600 (p_stream->m_status & opj_stream_e_end)
\r
602 l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
\r
603 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
\r
604 p_stream->m_bytes_in_buffer = 0;
\r
605 p_stream->m_byte_offset += l_skip_nb_bytes;
\r
606 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
\r
609 // the flag is not set, we copy data and then do an actual skip on the stream
\r
611 (p_stream->m_bytes_in_buffer)
\r
613 l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
\r
614 p_stream->m_current_data = p_stream->m_stored_data;
\r
615 p_size -= p_stream->m_bytes_in_buffer;
\r
616 p_stream->m_bytes_in_buffer = 0;
\r
622 // we should do an actual skip on the media
\r
623 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
\r
625 (l_current_skip_nb_bytes == (OPJ_SIZE_T) -1)
\r
627 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
\r
628 p_stream->m_status |= opj_stream_e_end;
\r
629 p_stream->m_byte_offset += l_skip_nb_bytes;
\r
631 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
\r
633 p_size -= l_current_skip_nb_bytes;
\r
634 l_skip_nb_bytes += l_current_skip_nb_bytes;
\r
636 p_stream->m_byte_offset += l_skip_nb_bytes;
\r
637 return l_skip_nb_bytes;
\r
641 * Skips a number of bytes from the stream.
\r
642 * @param p_stream the stream to skip data from.
\r
643 * @param p_size the number of bytes to skip.
\r
644 * @param p_event_mgr the user event manager to be notified of special events.
\r
645 * @return the number of bytes skipped, or -1 if an error occured.
\r
647 OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
\r
649 bool l_is_written = 0;
\r
650 OPJ_SIZE_T l_current_skip_nb_bytes = 0;
\r
651 OPJ_SIZE_T l_skip_nb_bytes = 0;
\r
654 (p_stream->m_status & opj_stream_e_error)
\r
656 return (OPJ_SIZE_T) -1;
\r
659 // we should flush data
\r
660 l_is_written = opj_stream_flush (p_stream, p_event_mgr);
\r
664 p_stream->m_status |= opj_stream_e_error;
\r
665 p_stream->m_bytes_in_buffer = 0;
\r
666 p_stream->m_current_data = p_stream->m_current_data;
\r
667 return (OPJ_SIZE_T) -1;
\r
674 // we should do an actual skip on the media
\r
675 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
\r
677 (l_current_skip_nb_bytes == (OPJ_SIZE_T)-1)
\r
679 opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n");
\r
680 p_stream->m_status |= opj_stream_e_error;
\r
681 p_stream->m_byte_offset += l_skip_nb_bytes;
\r
683 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T)-1;
\r
685 p_size -= l_current_skip_nb_bytes;
\r
686 l_skip_nb_bytes += l_current_skip_nb_bytes;
\r
688 p_stream->m_byte_offset += l_skip_nb_bytes;
\r
689 return l_skip_nb_bytes;
\r
693 * Tells the byte offset on the stream (similar to ftell).
\r
695 * @param p_stream the stream to get the information from.
\r
697 * @return the current position o fthe stream.
\r
699 OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream)
\r
701 return p_stream->m_byte_offset;
\r
705 * Skips a number of bytes from the stream.
\r
706 * @param p_stream the stream to skip data from.
\r
707 * @param p_size the number of bytes to skip.
\r
708 * @param p_event_mgr the user event manager to be notified of special events.
\r
709 * @return the number of bytes skipped, or -1 if an error occured.
\r
711 OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
\r
713 return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr);
\r
718 * Skips a number of bytes from the stream.
\r
719 * @param p_stream the stream to skip data from.
\r
720 * @param p_size the number of bytes to skip.
\r
721 * @param p_event_mgr the user event manager to be notified of special events.
\r
722 * @return the number of bytes skipped, or -1 if an error occured.
\r
724 bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
\r
726 p_stream->m_current_data = p_stream->m_stored_data;
\r
727 p_stream->m_bytes_in_buffer = 0;
\r
729 (! p_stream->m_seek_fn(p_size,p_stream->m_user_data))
\r
731 p_stream->m_status |= opj_stream_e_end;
\r
736 // reset stream status
\r
737 p_stream->m_status &= (~opj_stream_e_end);
\r
738 p_stream->m_byte_offset = p_size;
\r
745 * Skips a number of bytes from the stream.
\r
746 * @param p_stream the stream to skip data from.
\r
747 * @param p_size the number of bytes to skip.
\r
748 * @param p_event_mgr the user event manager to be notified of special events.
\r
749 * @return the number of bytes skipped, or -1 if an error occured.
\r
751 bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
\r
754 (! opj_stream_flush(p_stream,p_event_mgr))
\r
756 p_stream->m_status |= opj_stream_e_error;
\r
760 p_stream->m_current_data = p_stream->m_stored_data;
\r
761 p_stream->m_bytes_in_buffer = 0;
\r
764 (! p_stream->m_seek_fn(p_size,p_stream->m_user_data))
\r
766 p_stream->m_status |= opj_stream_e_error;
\r
771 p_stream->m_byte_offset = p_size;
\r
778 * Seeks a number of bytes from the stream.
\r
779 * @param p_stream the stream to skip data from.
\r
780 * @param p_size the number of bytes to skip.
\r
781 * @param p_event_mgr the user event manager to be notified of special events.
\r
782 * @return true if the stream is seekable.
\r
784 bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr)
\r
786 return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr);
\r
790 * Tells if the given stream is seekable.
\r
792 bool opj_stream_has_seek (const opj_stream_private_t * p_stream)
\r
794 return p_stream->m_seek_fn != opj_stream_default_seek;
\r
801 OPJ_UINT32 opj_stream_default_read (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
\r
803 return (OPJ_UINT32) -1;
\r
805 OPJ_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
\r
807 return (OPJ_UINT32) -1;
\r
809 OPJ_SIZE_T opj_stream_default_skip (OPJ_SIZE_T p_nb_bytes, void * p_user_data)
\r
811 return (OPJ_SIZE_T) -1;
\r
814 bool opj_stream_default_seek (OPJ_SIZE_T p_nb_bytes, void * p_user_data)
\r