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 if ((!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 * Sets the given data to be used as a user data for the stream.
506 * @param p_stream the stream to modify
507 * @param p_data the data to set.
509 OPJ_API void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT32 data_length)
511 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
513 l_stream->m_user_data_length = data_length;
517 * Reads some bytes from the stream.
518 * @param p_stream the stream to read data from.
519 * @param p_buffer pointer to the data buffer that will receive the data.
520 * @param p_size number of bytes to read.
521 * @param p_event_mgr the user event manager to be notified of special events.
522 * @return the number of bytes read, or -1 if an error occured or if the stream is at the end.
524 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)
526 OPJ_UINT32 l_read_nb_bytes = 0;
528 (p_stream->m_bytes_in_buffer >= p_size)
530 memcpy(p_buffer,p_stream->m_current_data,p_size);
531 p_stream->m_current_data += p_size;
532 p_stream->m_bytes_in_buffer -= p_size;
533 l_read_nb_bytes += p_size;
534 p_stream->m_byte_offset += p_size;
535 return l_read_nb_bytes;
538 // we are now in the case when the remaining data if not sufficient
540 (p_stream->m_status & opj_stream_e_end)
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_bytes_in_buffer;
545 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
546 p_stream->m_bytes_in_buffer = 0;
547 return l_read_nb_bytes ? l_read_nb_bytes : -1;
550 // the flag is not set, we copy data and then do an actual read on the stream
552 (p_stream->m_bytes_in_buffer)
554 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
555 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
556 p_stream->m_current_data = p_stream->m_stored_data;
557 p_buffer += p_stream->m_bytes_in_buffer;
558 p_size -= p_stream->m_bytes_in_buffer;
559 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
560 p_stream->m_bytes_in_buffer = 0;
564 /* case where we are already at the end of the buffer
565 so reset the m_current_data to point to the start of the
566 stored buffer to get ready to read from disk*/
567 p_stream->m_current_data = p_stream->m_stored_data;
572 // we should read less than a chunk -> read a chunk
574 (p_size < p_stream->m_buffer_size)
576 // we should do an actual read on the media
577 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);
579 (p_stream->m_bytes_in_buffer == -1)
582 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
584 p_stream->m_bytes_in_buffer = 0;
585 p_stream->m_status |= opj_stream_e_end;
587 return l_read_nb_bytes ? l_read_nb_bytes : -1;
590 (p_stream->m_bytes_in_buffer < p_size)
593 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
594 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
595 p_stream->m_current_data = p_stream->m_stored_data;
596 p_buffer += p_stream->m_bytes_in_buffer;
597 p_size -= p_stream->m_bytes_in_buffer;
598 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
599 p_stream->m_bytes_in_buffer = 0;
603 l_read_nb_bytes += p_size;
604 memcpy(p_buffer,p_stream->m_current_data,p_size);
605 p_stream->m_current_data += p_size;
606 p_stream->m_bytes_in_buffer -= p_size;
607 p_stream->m_byte_offset += p_size;
608 return l_read_nb_bytes;
613 // direct read on the dest buffer
614 p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data);
616 (p_stream->m_bytes_in_buffer == -1)
619 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
621 p_stream->m_bytes_in_buffer = 0;
622 p_stream->m_status |= opj_stream_e_end;
624 return l_read_nb_bytes ? l_read_nb_bytes : -1;
627 (p_stream->m_bytes_in_buffer < p_size)
630 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
631 p_stream->m_current_data = p_stream->m_stored_data;
632 p_buffer += p_stream->m_bytes_in_buffer;
633 p_size -= p_stream->m_bytes_in_buffer;
634 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
635 p_stream->m_bytes_in_buffer = 0;
639 // we have read the exact size
640 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
641 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
642 p_stream->m_current_data = p_stream->m_stored_data;
643 p_stream->m_bytes_in_buffer = 0;
644 return l_read_nb_bytes;
651 * Writes some bytes from the stream.
652 * @param p_stream the stream to write data to.
653 * @param p_buffer pointer to the data buffer holds the data to be writtent.
654 * @param p_size number of bytes to write.
655 * @param p_event_mgr the user event manager to be notified of special events.
656 * @return the number of bytes writtent, or -1 if an error occured.
658 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)
660 OPJ_UINT32 l_remaining_bytes = 0;
661 OPJ_UINT32 l_write_nb_bytes = 0;
664 (p_stream->m_status & opj_stream_e_error)
671 l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
672 // we have more memory than required
674 (l_remaining_bytes >= p_size)
676 memcpy(p_stream->m_current_data,p_buffer,p_size);
677 p_stream->m_current_data += p_size;
678 p_stream->m_bytes_in_buffer += p_size;
679 l_write_nb_bytes += p_size;
680 p_stream->m_byte_offset += p_size;
681 return l_write_nb_bytes;
684 // we copy data and then do an actual read on the stream
688 l_write_nb_bytes += l_remaining_bytes;
689 memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes);
690 p_stream->m_current_data = p_stream->m_stored_data;
691 p_buffer += l_remaining_bytes;
692 p_size -= l_remaining_bytes;
693 p_stream->m_bytes_in_buffer += l_remaining_bytes;
694 p_stream->m_byte_offset += l_remaining_bytes;
697 (! opj_stream_flush(p_stream, p_event_mgr))
706 * Writes the content of the stream buffer to the stream.
707 * @param p_stream the stream to write data to.
708 * @param p_event_mgr the user event manager to be notified of special events.
709 * @return the number of bytes written, or -1 if an error occured.
711 opj_bool opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr)
713 // the number of bytes written on the media.
714 OPJ_UINT32 l_current_write_nb_bytes = 0;
715 p_stream->m_current_data = p_stream->m_stored_data;
718 (p_stream->m_bytes_in_buffer)
720 // we should do an actual write on the media
721 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);
723 (l_current_write_nb_bytes == -1)
725 p_stream->m_status |= opj_stream_e_error;
726 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Error on writting stream!\n");
730 p_stream->m_current_data += l_current_write_nb_bytes;
731 p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
733 p_stream->m_current_data = p_stream->m_stored_data;
738 * Skips a number of bytes from the stream.
739 * @param p_stream the stream to skip data from.
740 * @param p_size the number of bytes to skip.
741 * @param p_event_mgr the user event manager to be notified of special events.
742 * @return the number of bytes skipped, or -1 if an error occured.
744 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)
746 OPJ_SIZE_T l_skip_nb_bytes = 0;
747 OPJ_SIZE_T l_current_skip_nb_bytes = 0;
750 (p_stream->m_bytes_in_buffer >= p_size)
752 p_stream->m_current_data += p_size;
753 p_stream->m_bytes_in_buffer -= p_size;
754 l_skip_nb_bytes += p_size;
755 p_stream->m_byte_offset += l_skip_nb_bytes;
756 return l_skip_nb_bytes;
759 // we are now in the case when the remaining data if not sufficient
761 (p_stream->m_status & opj_stream_e_end)
763 l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
764 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
765 p_stream->m_bytes_in_buffer = 0;
766 p_stream->m_byte_offset += l_skip_nb_bytes;
767 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
770 // the flag is not set, we copy data and then do an actual skip on the stream
772 (p_stream->m_bytes_in_buffer)
774 l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
775 p_stream->m_current_data = p_stream->m_stored_data;
776 p_size -= p_stream->m_bytes_in_buffer;
777 p_stream->m_bytes_in_buffer = 0;
783 // we should do an actual skip on the media
784 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
786 (l_current_skip_nb_bytes == (OPJ_SIZE_T) -1)
788 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
790 p_stream->m_status |= opj_stream_e_end;
791 p_stream->m_byte_offset += l_skip_nb_bytes;
793 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
795 p_size -= l_current_skip_nb_bytes;
796 l_skip_nb_bytes += l_current_skip_nb_bytes;
798 p_stream->m_byte_offset += l_skip_nb_bytes;
799 return l_skip_nb_bytes;
803 * Skips a number of bytes from the stream.
804 * @param p_stream the stream to skip data from.
805 * @param p_size the number of bytes to skip.
806 * @param p_event_mgr the user event manager to be notified of special events.
807 * @return the number of bytes skipped, or -1 if an error occured.
809 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)
811 opj_bool l_is_written = 0;
812 OPJ_SIZE_T l_current_skip_nb_bytes = 0;
813 OPJ_SIZE_T l_skip_nb_bytes = 0;
816 (p_stream->m_status & opj_stream_e_error)
818 return (OPJ_SIZE_T) -1;
821 // we should flush data
822 l_is_written = opj_stream_flush (p_stream, p_event_mgr);
826 p_stream->m_status |= opj_stream_e_error;
827 p_stream->m_bytes_in_buffer = 0;
828 p_stream->m_current_data = p_stream->m_current_data;
829 return (OPJ_SIZE_T) -1;
836 // we should do an actual skip on the media
837 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
839 (l_current_skip_nb_bytes == (OPJ_SIZE_T)-1)
841 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream error!\n");
843 p_stream->m_status |= opj_stream_e_error;
844 p_stream->m_byte_offset += l_skip_nb_bytes;
846 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T)-1;
848 p_size -= l_current_skip_nb_bytes;
849 l_skip_nb_bytes += l_current_skip_nb_bytes;
851 p_stream->m_byte_offset += l_skip_nb_bytes;
852 return l_skip_nb_bytes;
856 * Tells the byte offset on the stream (similar to ftell).
858 * @param p_stream the stream to get the information from.
860 * @return the current position of the stream.
862 OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream)
864 return p_stream->m_byte_offset;
869 * Get the number of bytes left before the end of the stream (similar to cio_numbytesleft).
871 * @param p_stream the stream to get the information from.
873 * @return Number of bytes left before the end of the stream.
875 OPJ_SIZE_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream)
877 return p_stream->m_user_data_length ?
878 p_stream->m_user_data_length - p_stream->m_byte_offset :
883 * Skips a number of bytes from the stream.
884 * @param p_stream the stream to skip data from.
885 * @param p_size the number of bytes to skip.
886 * @param p_event_mgr the user event manager to be notified of special events.
887 * @return the number of bytes skipped, or -1 if an error occured.
889 OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
891 return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr);
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_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
904 p_stream->m_current_data = p_stream->m_stored_data;
905 p_stream->m_bytes_in_buffer = 0;
907 (! p_stream->m_seek_fn(p_size,p_stream->m_user_data))
909 p_stream->m_status |= opj_stream_e_end;
914 // reset stream status
915 p_stream->m_status &= (~opj_stream_e_end);
916 p_stream->m_byte_offset = p_size;
923 * Skips a number of bytes from the stream.
924 * @param p_stream the stream to skip data from.
925 * @param p_size the number of bytes to skip.
926 * @param p_event_mgr the user event manager to be notified of special events.
927 * @return the number of bytes skipped, or -1 if an error occured.
929 opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
932 (! opj_stream_flush(p_stream,p_event_mgr))
934 p_stream->m_status |= opj_stream_e_error;
938 p_stream->m_current_data = p_stream->m_stored_data;
939 p_stream->m_bytes_in_buffer = 0;
942 (! p_stream->m_seek_fn(p_size,p_stream->m_user_data))
944 p_stream->m_status |= opj_stream_e_error;
949 p_stream->m_byte_offset = p_size;
956 * Seeks a number of bytes from the stream.
957 * @param p_stream the stream to skip data from.
958 * @param p_size the number of bytes to skip.
959 * @param p_event_mgr the user event manager to be notified of special events.
960 * @return true if the stream is seekable.
962 opj_bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr)
964 return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr);
968 * Tells if the given stream is seekable.
970 opj_bool opj_stream_has_seek (const opj_stream_private_t * p_stream)
972 return p_stream->m_seek_fn != opj_stream_default_seek;
979 OPJ_UINT32 opj_stream_default_read (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
981 return (OPJ_UINT32) -1;
983 OPJ_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
985 return (OPJ_UINT32) -1;
987 OPJ_SIZE_T opj_stream_default_skip (OPJ_SIZE_T p_nb_bytes, void * p_user_data)
989 return (OPJ_SIZE_T) -1;
992 opj_bool opj_stream_default_seek (OPJ_SIZE_T p_nb_bytes, void * p_user_data)