2 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3 * Copyright (c) 2002-2007, Professor Benoit Macq
4 * Copyright (c) 2001-2003, David Janssens
5 * Copyright (c) 2002-2003, Yannick Verschueren
6 * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
7 * Copyright (c) 2005, Herve Drolon, FreeImage Team
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include "opj_includes.h"
34 /* ----------------------------------------------------------------------- */
36 opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length) {
38 opj_cio_t *cio = (opj_cio_t*)opj_malloc(sizeof(opj_cio_t));
41 if(buffer && length) {
42 /* wrap a user buffer containing the encoded image */
43 cio->openmode = OPJ_STREAM_READ;
47 else if(!buffer && !length && cinfo) {
48 /* allocate a buffer for the encoded image */
49 cio->openmode = OPJ_STREAM_WRITE;
50 switch(cinfo->codec_format) {
52 cp = ((opj_j2k_t*)cinfo->j2k_handle)->cp;
55 cp = ((opj_jp2_t*)cinfo->jp2_handle)->j2k->cp;
61 cio->length = (unsigned int) (0.1625 * cp->img_size + 2000); /* 0.1625 = 1.3/8 and 2000 bytes as a minimum for headers */
62 cio->buffer = (unsigned char *)opj_malloc(cio->length);
64 opj_event_msg(cio->cinfo, EVT_ERROR, "Error allocating memory for compressed bitstream\n");
74 /* Initialize byte IO */
75 cio->start = cio->buffer;
76 cio->end = cio->buffer + cio->length;
77 cio->bp = cio->buffer;
82 void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio) {
84 if(cio->openmode == OPJ_STREAM_WRITE) {
85 /* destroy the allocated buffer */
86 opj_free(cio->buffer);
94 /* ----------------------------------------------------------------------- */
97 * Get position in byte stream.
99 int OPJ_CALLCONV cio_tell(opj_cio_t *cio) {
100 return cio->bp - cio->start;
104 * Set position in byte stream.
106 * pos : position, in number of bytes, from the beginning of the stream
108 void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) {
109 cio->bp = cio->start + pos;
113 * Number of bytes left before the end of the stream.
115 int cio_numbytesleft(opj_cio_t *cio) {
116 return cio->end - cio->bp;
120 * Get pointer to the current position in the stream.
122 unsigned char *cio_getbp(opj_cio_t *cio) {
129 opj_bool cio_byteout(opj_cio_t *cio, unsigned char v) {
130 if (cio->bp >= cio->end) {
131 opj_event_msg(cio->cinfo, EVT_ERROR, "write error\n");
141 unsigned char cio_bytein(opj_cio_t *cio) {
142 if (cio->bp >= cio->end) {
143 opj_event_msg(cio->cinfo, EVT_ERROR, "read error: passed the end of the codestream (start = %d, current = %d, end = %d\n", cio->start, cio->bp, cio->end);
153 * n : number of bytes to write
155 unsigned int cio_write(opj_cio_t *cio, unsigned long long int v, int n) {
157 for (i = n - 1; i >= 0; i--) {
158 if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) )
167 * n : number of bytes to read
169 * return : value of the n bytes read
171 unsigned int cio_read(opj_cio_t *cio, int n) {
175 for (i = n - 1; i >= 0; i--) {
176 v += cio_bytein(cio) << (i << 3);
184 * n : number of bytes to skip
186 void cio_skip(opj_cio_t *cio, int n) {
191 /* ----------------------------------------------------------------------- */
195 * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
196 * @param p_buffer pointer the data buffer to write data to.
197 * @param p_value the value to write
198 * @param p_nb_bytes the number of bytes to write
200 void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
202 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes;
204 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
206 memcpy(p_buffer,l_data_ptr,p_nb_bytes);
210 * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
211 * @param p_buffer pointer the data buffer to write data to.
212 * @param p_value the value to write
213 * @param p_nb_bytes the number of bytes to write
214 * @return the number of bytes written or -1 if an error occured
216 void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
218 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes - 1;
221 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
223 for (i=0;i<p_nb_bytes;++i) {
224 *(p_buffer++) = *(l_data_ptr--);
229 * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
230 * @param p_buffer pointer the data buffer to read data from.
231 * @param p_value pointer to the value that will store the data.
232 * @param p_nb_bytes the nb bytes to read.
233 * @return the number of bytes read or -1 if an error occured.
235 void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
237 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
239 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
242 memcpy(l_data_ptr+4-p_nb_bytes,p_buffer,p_nb_bytes);
246 * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
247 * @param p_buffer pointer the data buffer to read data from.
248 * @param p_value pointer to the value that will store the data.
249 * @param p_nb_bytes the nb bytes to read.
250 * @return the number of bytes read or -1 if an error occured.
252 void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
254 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + p_nb_bytes-1;
257 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
260 for (i=0;i<p_nb_bytes;++i) {
261 *(l_data_ptr--) = *(p_buffer++);
266 * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
267 * @param p_buffer pointer the data buffer to write data to.
268 * @param p_value the value to write
269 * @return the number of bytes written or -1 if an error occured
271 void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
273 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
274 memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT64));
278 * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
279 * @param p_buffer pointer the data buffer to write data to.
280 * @param p_value the value to write
282 void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
284 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT64) - 1;
286 for (i=0;i<sizeof(OPJ_FLOAT64);++i) {
287 *(p_buffer++) = *(l_data_ptr--);
292 * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
293 * @param p_buffer pointer the data buffer to read data from.
294 * @param p_value pointer to the value that will store the data.
296 void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
298 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
299 memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT64));
304 * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
305 * @param p_buffer pointer the data buffer to read data from.
306 * @param p_value pointer to the value that will store the data.
308 void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
310 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT64)-1;
312 for (i=0;i<sizeof(OPJ_FLOAT64);++i) {
313 *(l_data_ptr--) = *(p_buffer++);
318 * Write some bytes to the given data buffer, this function is used in Big Endian cpus.
319 * @param p_buffer pointer the data buffer to write data to.
320 * @param p_value the value to write
321 * @return the number of bytes written or -1 if an error occured
323 void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
325 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
326 memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT32));
330 * Write some bytes to the given data buffer, this function is used in Little Endian cpus.
331 * @param p_buffer pointer the data buffer to write data to.
332 * @param p_value the value to write
334 void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
336 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT32) - 1;
338 for (i=0;i<sizeof(OPJ_FLOAT32);++i) {
339 *(p_buffer++) = *(l_data_ptr--);
344 * Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
345 * @param p_buffer pointer the data buffer to read data from.
346 * @param p_value pointer to the value that will store the data.
348 void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
350 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
351 memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT32));
356 * Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
357 * @param p_buffer pointer the data buffer to read data from.
358 * @param p_value pointer to the value that will store the data.
360 void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
362 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT32)-1;
364 for (i=0;i<sizeof(OPJ_FLOAT32);++i) {
365 *(l_data_ptr--) = *(p_buffer++);
371 * Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream.
372 * @return a stream object.
374 opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_UINT32 p_size,opj_bool l_is_input)
376 opj_stream_private_t * l_stream = 00;
377 l_stream = (opj_stream_private_t*) opj_malloc(sizeof(opj_stream_private_t));
382 memset(l_stream,0,sizeof(opj_stream_private_t));
383 l_stream->m_buffer_size = p_size;
384 l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_size);
385 if (! l_stream->m_stored_data) {
390 l_stream->m_current_data = l_stream->m_stored_data;
393 l_stream->m_status |= opj_stream_e_input;
394 l_stream->m_opj_skip = opj_stream_read_skip;
395 l_stream->m_opj_seek = opj_stream_read_seek;
398 l_stream->m_status |= opj_stream_e_output;
399 l_stream->m_opj_skip = opj_stream_write_skip;
400 l_stream->m_opj_seek = opj_stream_write_seek;
403 l_stream->m_read_fn = opj_stream_default_read;
404 l_stream->m_write_fn = opj_stream_default_write;
405 l_stream->m_skip_fn = opj_stream_default_skip;
406 l_stream->m_seek_fn = opj_stream_default_seek;
408 return (opj_stream_t *) l_stream;
412 * Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream.
413 * @return a stream object.
415 opj_stream_t* OPJ_CALLCONV opj_stream_default_create(opj_bool l_is_input)
417 return opj_stream_create(J2K_STREAM_CHUNK_SIZE,l_is_input);
421 * Destroys a stream created by opj_create_stream. This function does NOT close the abstract stream. If needed the user must
422 * close its own implementation of the stream.
424 OPJ_API void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream)
426 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
428 opj_free(l_stream->m_stored_data);
429 l_stream->m_stored_data = 00;
435 * Sets the given function to be used as a read function.
436 * @param p_stream the stream to modify
437 * @param p_function the function to use a read function.
439 OPJ_API void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function)
441 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
443 ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input)))
447 l_stream->m_read_fn = p_function;
450 OPJ_API void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function)
452 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
458 l_stream->m_seek_fn = p_function;
462 * Sets the given function to be used as a write function.
463 * @param p_stream the stream to modify
464 * @param p_function the function to use a write function.
466 OPJ_API void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function)
468 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
470 ((!l_stream )|| (! (l_stream->m_status & opj_stream_e_output)))
474 l_stream->m_write_fn = p_function;
478 * Sets the given function to be used as a skip function.
479 * @param p_stream the stream to modify
480 * @param p_function the function to use a skip function.
482 OPJ_API void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function)
484 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
490 l_stream->m_skip_fn = p_function;
494 * Sets the given data to be used as a user data for the stream.
495 * @param p_stream the stream to modify
496 * @param p_data the data to set.
498 OPJ_API void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data)
500 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
501 l_stream->m_user_data = p_data;
505 * Reads some bytes from the stream.
506 * @param p_stream the stream to read data from.
507 * @param p_buffer pointer to the data buffer that will receive the data.
508 * @param p_size number of bytes to read.
509 * @param p_event_mgr the user event manager to be notified of special events.
510 * @return the number of bytes read, or -1 if an error occured or if the stream is at the end.
512 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)
514 OPJ_UINT32 l_read_nb_bytes = 0;
516 (p_stream->m_bytes_in_buffer >= p_size)
518 memcpy(p_buffer,p_stream->m_current_data,p_size);
519 p_stream->m_current_data += p_size;
520 p_stream->m_bytes_in_buffer -= p_size;
521 l_read_nb_bytes += p_size;
522 p_stream->m_byte_offset += p_size;
523 return l_read_nb_bytes;
526 // we are now in the case when the remaining data if not sufficient
528 (p_stream->m_status & opj_stream_e_end)
530 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
531 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
532 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
533 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
534 p_stream->m_bytes_in_buffer = 0;
535 return l_read_nb_bytes ? l_read_nb_bytes : -1;
538 // the flag is not set, we copy data and then do an actual read on the stream
540 (p_stream->m_bytes_in_buffer)
542 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
543 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
544 p_stream->m_current_data = p_stream->m_stored_data;
545 p_buffer += p_stream->m_bytes_in_buffer;
546 p_size -= p_stream->m_bytes_in_buffer;
547 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
548 p_stream->m_bytes_in_buffer = 0;
552 /* case where we are already at the end of the buffer
553 so reset the m_current_data to point to the start of the
554 stored buffer to get ready to read from disk*/
555 p_stream->m_current_data = p_stream->m_stored_data;
560 // we should read less than a chunk -> read a chunk
562 (p_size < p_stream->m_buffer_size)
564 // we should do an actual read on the media
565 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);
567 (p_stream->m_bytes_in_buffer == -1)
570 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
572 p_stream->m_bytes_in_buffer = 0;
573 p_stream->m_status |= opj_stream_e_end;
575 return l_read_nb_bytes ? l_read_nb_bytes : -1;
578 (p_stream->m_bytes_in_buffer < p_size)
581 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
582 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
583 p_stream->m_current_data = p_stream->m_stored_data;
584 p_buffer += p_stream->m_bytes_in_buffer;
585 p_size -= p_stream->m_bytes_in_buffer;
586 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
587 p_stream->m_bytes_in_buffer = 0;
591 l_read_nb_bytes += p_size;
592 memcpy(p_buffer,p_stream->m_current_data,p_size);
593 p_stream->m_current_data += p_size;
594 p_stream->m_bytes_in_buffer -= p_size;
595 p_stream->m_byte_offset += p_size;
596 return l_read_nb_bytes;
601 // direct read on the dest buffer
602 p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data);
604 (p_stream->m_bytes_in_buffer == -1)
607 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
609 p_stream->m_bytes_in_buffer = 0;
610 p_stream->m_status |= opj_stream_e_end;
612 return l_read_nb_bytes ? l_read_nb_bytes : -1;
615 (p_stream->m_bytes_in_buffer < p_size)
618 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
619 p_stream->m_current_data = p_stream->m_stored_data;
620 p_buffer += p_stream->m_bytes_in_buffer;
621 p_size -= p_stream->m_bytes_in_buffer;
622 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
623 p_stream->m_bytes_in_buffer = 0;
627 // we have read the exact size
628 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
629 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
630 p_stream->m_current_data = p_stream->m_stored_data;
631 p_stream->m_bytes_in_buffer = 0;
632 return l_read_nb_bytes;
639 * Writes some bytes from the stream.
640 * @param p_stream the stream to write data to.
641 * @param p_buffer pointer to the data buffer holds the data to be writtent.
642 * @param p_size number of bytes to write.
643 * @param p_event_mgr the user event manager to be notified of special events.
644 * @return the number of bytes writtent, or -1 if an error occured.
646 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)
648 OPJ_UINT32 l_remaining_bytes = 0;
649 OPJ_UINT32 l_write_nb_bytes = 0;
652 (p_stream->m_status & opj_stream_e_error)
659 l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
660 // we have more memory than required
662 (l_remaining_bytes >= p_size)
664 memcpy(p_stream->m_current_data,p_buffer,p_size);
665 p_stream->m_current_data += p_size;
666 p_stream->m_bytes_in_buffer += p_size;
667 l_write_nb_bytes += p_size;
668 p_stream->m_byte_offset += p_size;
669 return l_write_nb_bytes;
672 // we copy data and then do an actual read on the stream
676 l_write_nb_bytes += l_remaining_bytes;
677 memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes);
678 p_stream->m_current_data = p_stream->m_stored_data;
679 p_buffer += l_remaining_bytes;
680 p_size -= l_remaining_bytes;
681 p_stream->m_bytes_in_buffer += l_remaining_bytes;
682 p_stream->m_byte_offset += l_remaining_bytes;
685 (! opj_stream_flush(p_stream, p_event_mgr))
694 * Writes the content of the stream buffer to the stream.
695 * @param p_stream the stream to write data to.
696 * @param p_event_mgr the user event manager to be notified of special events.
697 * @return the number of bytes written, or -1 if an error occured.
699 opj_bool opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr)
701 // the number of bytes written on the media.
702 OPJ_UINT32 l_current_write_nb_bytes = 0;
703 p_stream->m_current_data = p_stream->m_stored_data;
706 (p_stream->m_bytes_in_buffer)
708 // we should do an actual write on the media
709 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);
711 (l_current_write_nb_bytes == -1)
713 p_stream->m_status |= opj_stream_e_error;
714 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Error on writting stream!\n");
718 p_stream->m_current_data += l_current_write_nb_bytes;
719 p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
721 p_stream->m_current_data = p_stream->m_stored_data;
726 * Skips a number of bytes from the stream.
727 * @param p_stream the stream to skip data from.
728 * @param p_size the number of bytes to skip.
729 * @param p_event_mgr the user event manager to be notified of special events.
730 * @return the number of bytes skipped, or -1 if an error occured.
732 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)
734 OPJ_SIZE_T l_skip_nb_bytes = 0;
735 OPJ_SIZE_T l_current_skip_nb_bytes = 0;
738 (p_stream->m_bytes_in_buffer >= p_size)
740 p_stream->m_current_data += p_size;
741 p_stream->m_bytes_in_buffer -= p_size;
742 l_skip_nb_bytes += p_size;
743 p_stream->m_byte_offset += l_skip_nb_bytes;
744 return l_skip_nb_bytes;
747 // we are now in the case when the remaining data if not sufficient
749 (p_stream->m_status & opj_stream_e_end)
751 l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
752 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
753 p_stream->m_bytes_in_buffer = 0;
754 p_stream->m_byte_offset += l_skip_nb_bytes;
755 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
758 // the flag is not set, we copy data and then do an actual skip on the stream
760 (p_stream->m_bytes_in_buffer)
762 l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
763 p_stream->m_current_data = p_stream->m_stored_data;
764 p_size -= p_stream->m_bytes_in_buffer;
765 p_stream->m_bytes_in_buffer = 0;
771 // we should do an actual skip on the media
772 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
774 (l_current_skip_nb_bytes == (OPJ_SIZE_T) -1)
776 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
778 p_stream->m_status |= opj_stream_e_end;
779 p_stream->m_byte_offset += l_skip_nb_bytes;
781 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
783 p_size -= l_current_skip_nb_bytes;
784 l_skip_nb_bytes += l_current_skip_nb_bytes;
786 p_stream->m_byte_offset += l_skip_nb_bytes;
787 return l_skip_nb_bytes;
791 * Skips a number of bytes from the stream.
792 * @param p_stream the stream to skip data from.
793 * @param p_size the number of bytes to skip.
794 * @param p_event_mgr the user event manager to be notified of special events.
795 * @return the number of bytes skipped, or -1 if an error occured.
797 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)
799 opj_bool l_is_written = 0;
800 OPJ_SIZE_T l_current_skip_nb_bytes = 0;
801 OPJ_SIZE_T l_skip_nb_bytes = 0;
804 (p_stream->m_status & opj_stream_e_error)
806 return (OPJ_SIZE_T) -1;
809 // we should flush data
810 l_is_written = opj_stream_flush (p_stream, p_event_mgr);
814 p_stream->m_status |= opj_stream_e_error;
815 p_stream->m_bytes_in_buffer = 0;
816 p_stream->m_current_data = p_stream->m_current_data;
817 return (OPJ_SIZE_T) -1;
824 // we should do an actual skip on the media
825 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
827 (l_current_skip_nb_bytes == (OPJ_SIZE_T)-1)
829 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream error!\n");
831 p_stream->m_status |= opj_stream_e_error;
832 p_stream->m_byte_offset += l_skip_nb_bytes;
834 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T)-1;
836 p_size -= l_current_skip_nb_bytes;
837 l_skip_nb_bytes += l_current_skip_nb_bytes;
839 p_stream->m_byte_offset += l_skip_nb_bytes;
840 return l_skip_nb_bytes;
844 * Tells the byte offset on the stream (similar to ftell).
846 * @param p_stream the stream to get the information from.
848 * @return the current position of the stream.
850 OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream)
852 return p_stream->m_byte_offset;
856 * Skips a number of bytes from the stream.
857 * @param p_stream the stream to skip data from.
858 * @param p_size the number of bytes to skip.
859 * @param p_event_mgr the user event manager to be notified of special events.
860 * @return the number of bytes skipped, or -1 if an error occured.
862 OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
864 return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr);
869 * Skips a number of bytes from the stream.
870 * @param p_stream the stream to skip data from.
871 * @param p_size the number of bytes to skip.
872 * @param p_event_mgr the user event manager to be notified of special events.
873 * @return the number of bytes skipped, or -1 if an error occured.
875 opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
877 p_stream->m_current_data = p_stream->m_stored_data;
878 p_stream->m_bytes_in_buffer = 0;
880 (! p_stream->m_seek_fn(p_size,p_stream->m_user_data))
882 p_stream->m_status |= opj_stream_e_end;
887 // reset stream status
888 p_stream->m_status &= (~opj_stream_e_end);
889 p_stream->m_byte_offset = p_size;
896 * Skips a number of bytes from the stream.
897 * @param p_stream the stream to skip data from.
898 * @param p_size the number of bytes to skip.
899 * @param p_event_mgr the user event manager to be notified of special events.
900 * @return the number of bytes skipped, or -1 if an error occured.
902 opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
905 (! opj_stream_flush(p_stream,p_event_mgr))
907 p_stream->m_status |= opj_stream_e_error;
911 p_stream->m_current_data = p_stream->m_stored_data;
912 p_stream->m_bytes_in_buffer = 0;
915 (! p_stream->m_seek_fn(p_size,p_stream->m_user_data))
917 p_stream->m_status |= opj_stream_e_error;
922 p_stream->m_byte_offset = p_size;
929 * Seeks a number of bytes from the stream.
930 * @param p_stream the stream to skip data from.
931 * @param p_size the number of bytes to skip.
932 * @param p_event_mgr the user event manager to be notified of special events.
933 * @return true if the stream is seekable.
935 opj_bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr)
937 return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr);
941 * Tells if the given stream is seekable.
943 opj_bool opj_stream_has_seek (const opj_stream_private_t * p_stream)
945 return p_stream->m_seek_fn != opj_stream_default_seek;
952 OPJ_UINT32 opj_stream_default_read (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
954 return (OPJ_UINT32) -1;
956 OPJ_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
958 return (OPJ_UINT32) -1;
960 OPJ_SIZE_T opj_stream_default_skip (OPJ_SIZE_T p_nb_bytes, void * p_user_data)
962 return (OPJ_SIZE_T) -1;
965 opj_bool opj_stream_default_seek (OPJ_SIZE_T p_nb_bytes, void * p_user_data)