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;
527 if (p_stream->m_bytes_in_buffer >= p_size) {
528 memcpy(p_buffer,p_stream->m_current_data,p_size);
529 p_stream->m_current_data += p_size;
530 p_stream->m_bytes_in_buffer -= p_size;
531 l_read_nb_bytes += p_size;
532 p_stream->m_byte_offset += p_size;
533 return l_read_nb_bytes;
536 /* we are now in the case when the remaining data if not sufficient */
537 if (p_stream->m_status & opj_stream_e_end) {
538 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
539 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
540 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
541 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
542 p_stream->m_bytes_in_buffer = 0;
543 return l_read_nb_bytes ? l_read_nb_bytes : -1;
546 /* the flag is not set, we copy data and then do an actual read on the stream */
547 if (p_stream->m_bytes_in_buffer) {
548 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
549 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
550 p_stream->m_current_data = p_stream->m_stored_data;
551 p_buffer += p_stream->m_bytes_in_buffer;
552 p_size -= p_stream->m_bytes_in_buffer;
553 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
554 p_stream->m_bytes_in_buffer = 0;
557 /* case where we are already at the end of the buffer
558 so reset the m_current_data to point to the start of the
559 stored buffer to get ready to read from disk*/
560 p_stream->m_current_data = p_stream->m_stored_data;
565 /* we should read less than a chunk -> read a chunk */
566 if (p_size < p_stream->m_buffer_size) {
567 /* we should do an actual read on the media */
568 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);
570 if (p_stream->m_bytes_in_buffer == -1) {
572 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
574 p_stream->m_bytes_in_buffer = 0;
575 p_stream->m_status |= opj_stream_e_end;
577 return l_read_nb_bytes ? l_read_nb_bytes : -1;
579 else if (p_stream->m_bytes_in_buffer < p_size) {
580 /* not enough data */
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;
590 l_read_nb_bytes += p_size;
591 memcpy(p_buffer,p_stream->m_current_data,p_size);
592 p_stream->m_current_data += p_size;
593 p_stream->m_bytes_in_buffer -= p_size;
594 p_stream->m_byte_offset += p_size;
595 return l_read_nb_bytes;
599 /* direct read on the dest buffer */
600 p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data);
602 if (p_stream->m_bytes_in_buffer == -1) {
604 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
606 p_stream->m_bytes_in_buffer = 0;
607 p_stream->m_status |= opj_stream_e_end;
609 return l_read_nb_bytes ? l_read_nb_bytes : -1;
611 else if (p_stream->m_bytes_in_buffer < p_size) {
612 /* not enough data */
613 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
614 p_stream->m_current_data = p_stream->m_stored_data;
615 p_buffer += p_stream->m_bytes_in_buffer;
616 p_size -= p_stream->m_bytes_in_buffer;
617 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
618 p_stream->m_bytes_in_buffer = 0;
621 /* we have read the exact size */
622 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
623 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
624 p_stream->m_current_data = p_stream->m_stored_data;
625 p_stream->m_bytes_in_buffer = 0;
626 return l_read_nb_bytes;
633 * Writes some bytes from the stream.
634 * @param p_stream the stream to write data to.
635 * @param p_buffer pointer to the data buffer holds the data to be writtent.
636 * @param p_size number of bytes to write.
637 * @param p_event_mgr the user event manager to be notified of special events.
638 * @return the number of bytes writtent, or -1 if an error occured.
640 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)
642 OPJ_UINT32 l_remaining_bytes = 0;
643 OPJ_UINT32 l_write_nb_bytes = 0;
646 (p_stream->m_status & opj_stream_e_error)
653 l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
654 // we have more memory than required
656 (l_remaining_bytes >= p_size)
658 memcpy(p_stream->m_current_data,p_buffer,p_size);
659 p_stream->m_current_data += p_size;
660 p_stream->m_bytes_in_buffer += p_size;
661 l_write_nb_bytes += p_size;
662 p_stream->m_byte_offset += p_size;
663 return l_write_nb_bytes;
666 // we copy data and then do an actual read on the stream
670 l_write_nb_bytes += l_remaining_bytes;
671 memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes);
672 p_stream->m_current_data = p_stream->m_stored_data;
673 p_buffer += l_remaining_bytes;
674 p_size -= l_remaining_bytes;
675 p_stream->m_bytes_in_buffer += l_remaining_bytes;
676 p_stream->m_byte_offset += l_remaining_bytes;
679 (! opj_stream_flush(p_stream, p_event_mgr))
688 * Writes the content of the stream buffer to the stream.
689 * @param p_stream the stream to write data to.
690 * @param p_event_mgr the user event manager to be notified of special events.
691 * @return the number of bytes written, or -1 if an error occured.
693 opj_bool opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr)
695 // the number of bytes written on the media.
696 OPJ_UINT32 l_current_write_nb_bytes = 0;
697 p_stream->m_current_data = p_stream->m_stored_data;
700 (p_stream->m_bytes_in_buffer)
702 // we should do an actual write on the media
703 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);
705 (l_current_write_nb_bytes == -1)
707 p_stream->m_status |= opj_stream_e_error;
708 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Error on writting stream!\n");
712 p_stream->m_current_data += l_current_write_nb_bytes;
713 p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
715 p_stream->m_current_data = p_stream->m_stored_data;
720 * Skips a number of bytes from the stream.
721 * @param p_stream the stream to skip data from.
722 * @param p_size the number of bytes to skip.
723 * @param p_event_mgr the user event manager to be notified of special events.
724 * @return the number of bytes skipped, or -1 if an error occured.
726 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)
728 OPJ_SIZE_T l_skip_nb_bytes = 0;
729 OPJ_SIZE_T l_current_skip_nb_bytes = 0;
732 (p_stream->m_bytes_in_buffer >= p_size)
734 p_stream->m_current_data += p_size;
735 p_stream->m_bytes_in_buffer -= p_size;
736 l_skip_nb_bytes += p_size;
737 p_stream->m_byte_offset += l_skip_nb_bytes;
738 return l_skip_nb_bytes;
741 // we are now in the case when the remaining data if not sufficient
743 (p_stream->m_status & opj_stream_e_end)
745 l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
746 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
747 p_stream->m_bytes_in_buffer = 0;
748 p_stream->m_byte_offset += l_skip_nb_bytes;
749 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
752 // the flag is not set, we copy data and then do an actual skip on the stream
754 (p_stream->m_bytes_in_buffer)
756 l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
757 p_stream->m_current_data = p_stream->m_stored_data;
758 p_size -= p_stream->m_bytes_in_buffer;
759 p_stream->m_bytes_in_buffer = 0;
765 // we should do an actual skip on the media
766 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
768 (l_current_skip_nb_bytes == (OPJ_SIZE_T) -1)
770 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
772 p_stream->m_status |= opj_stream_e_end;
773 p_stream->m_byte_offset += l_skip_nb_bytes;
775 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
777 p_size -= l_current_skip_nb_bytes;
778 l_skip_nb_bytes += l_current_skip_nb_bytes;
780 p_stream->m_byte_offset += l_skip_nb_bytes;
781 return l_skip_nb_bytes;
785 * Skips a number of bytes from the stream.
786 * @param p_stream the stream to skip data from.
787 * @param p_size the number of bytes to skip.
788 * @param p_event_mgr the user event manager to be notified of special events.
789 * @return the number of bytes skipped, or -1 if an error occured.
791 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)
793 opj_bool l_is_written = 0;
794 OPJ_SIZE_T l_current_skip_nb_bytes = 0;
795 OPJ_SIZE_T l_skip_nb_bytes = 0;
798 (p_stream->m_status & opj_stream_e_error)
800 return (OPJ_SIZE_T) -1;
803 // we should flush data
804 l_is_written = opj_stream_flush (p_stream, p_event_mgr);
808 p_stream->m_status |= opj_stream_e_error;
809 p_stream->m_bytes_in_buffer = 0;
810 p_stream->m_current_data = p_stream->m_current_data;
811 return (OPJ_SIZE_T) -1;
818 // we should do an actual skip on the media
819 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
821 (l_current_skip_nb_bytes == (OPJ_SIZE_T)-1)
823 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream error!\n");
825 p_stream->m_status |= opj_stream_e_error;
826 p_stream->m_byte_offset += l_skip_nb_bytes;
828 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T)-1;
830 p_size -= l_current_skip_nb_bytes;
831 l_skip_nb_bytes += l_current_skip_nb_bytes;
833 p_stream->m_byte_offset += l_skip_nb_bytes;
834 return l_skip_nb_bytes;
838 * Tells the byte offset on the stream (similar to ftell).
840 * @param p_stream the stream to get the information from.
842 * @return the current position of the stream.
844 OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream)
846 return p_stream->m_byte_offset;
851 * Get the number of bytes left before the end of the stream (similar to cio_numbytesleft).
853 * @param p_stream the stream to get the information from.
855 * @return Number of bytes left before the end of the stream.
857 OPJ_SIZE_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream)
859 return p_stream->m_user_data_length ?
860 p_stream->m_user_data_length - p_stream->m_byte_offset :
865 * Skips a number of bytes from the stream.
866 * @param p_stream the stream to skip data from.
867 * @param p_size the number of bytes to skip.
868 * @param p_event_mgr the user event manager to be notified of special events.
869 * @return the number of bytes skipped, or -1 if an error occured.
871 OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
873 return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr);
878 * Skips a number of bytes from the stream.
879 * @param p_stream the stream to skip data from.
880 * @param p_size the number of bytes to skip.
881 * @param p_event_mgr the user event manager to be notified of special events.
882 * @return the number of bytes skipped, or -1 if an error occured.
884 opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
886 p_stream->m_current_data = p_stream->m_stored_data;
887 p_stream->m_bytes_in_buffer = 0;
889 if( p_stream->m_seek_fn(p_size,p_stream->m_user_data)) {
890 p_stream->m_status |= opj_stream_e_end;
894 // reset stream status
895 p_stream->m_status &= (~opj_stream_e_end);
896 p_stream->m_byte_offset = p_size;
904 * Skips a number of bytes from the stream.
905 * @param p_stream the stream to skip data from.
906 * @param p_size the number of bytes to skip.
907 * @param p_event_mgr the user event manager to be notified of special events.
908 * @return the number of bytes skipped, or -1 if an error occured.
910 opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
913 (! opj_stream_flush(p_stream,p_event_mgr))
915 p_stream->m_status |= opj_stream_e_error;
919 p_stream->m_current_data = p_stream->m_stored_data;
920 p_stream->m_bytes_in_buffer = 0;
923 (! p_stream->m_seek_fn(p_size,p_stream->m_user_data))
925 p_stream->m_status |= opj_stream_e_error;
930 p_stream->m_byte_offset = p_size;
937 * Seeks a number of bytes from the stream.
938 * @param p_stream the stream to skip data from.
939 * @param p_size the number of bytes to skip.
940 * @param p_event_mgr the user event manager to be notified of special events.
941 * @return true if the stream is seekable.
943 opj_bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr)
945 return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr);
949 * Tells if the given stream is seekable.
951 opj_bool opj_stream_has_seek (const opj_stream_private_t * p_stream)
953 return p_stream->m_seek_fn != opj_stream_default_seek;
960 OPJ_UINT32 opj_stream_default_read (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
962 return (OPJ_UINT32) -1;
964 OPJ_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
966 return (OPJ_UINT32) -1;
968 OPJ_SIZE_T opj_stream_default_skip (OPJ_SIZE_T p_nb_bytes, void * p_user_data)
970 return (OPJ_SIZE_T) -1;
973 opj_bool opj_stream_default_seek (OPJ_SIZE_T p_nb_bytes, void * p_user_data)