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_SIZE_T p_buffer_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_buffer_size;
384 l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_buffer_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_UINT64 data_length)
511 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
512 l_stream->m_user_data_length = data_length;
516 * Reads some bytes from the stream.
517 * @param p_stream the stream to read data from.
518 * @param p_buffer pointer to the data buffer that will receive the data.
519 * @param p_size number of bytes to read.
520 * @param p_event_mgr the user event manager to be notified of special events.
521 * @return the number of bytes read, or -1 if an error occured or if the stream is at the end.
523 OPJ_SIZE_T opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
525 OPJ_SIZE_T l_read_nb_bytes = 0;
526 if (p_stream->m_bytes_in_buffer >= p_size) {
527 memcpy(p_buffer,p_stream->m_current_data,p_size);
528 p_stream->m_current_data += p_size;
529 p_stream->m_bytes_in_buffer -= p_size;
530 l_read_nb_bytes += p_size;
531 p_stream->m_byte_offset += p_size;
532 return l_read_nb_bytes;
535 /* we are now in the case when the remaining data if not sufficient */
536 if (p_stream->m_status & opj_stream_e_end) {
537 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
538 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
539 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
540 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
541 p_stream->m_bytes_in_buffer = 0;
542 return l_read_nb_bytes ? l_read_nb_bytes : -1;
545 /* the flag is not set, we copy data and then do an actual read on the stream */
546 if (p_stream->m_bytes_in_buffer) {
547 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
548 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
549 p_stream->m_current_data = p_stream->m_stored_data;
550 p_buffer += p_stream->m_bytes_in_buffer;
551 p_size -= p_stream->m_bytes_in_buffer;
552 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
553 p_stream->m_bytes_in_buffer = 0;
556 /* case where we are already at the end of the buffer
557 so reset the m_current_data to point to the start of the
558 stored buffer to get ready to read from disk*/
559 p_stream->m_current_data = p_stream->m_stored_data;
564 /* we should read less than a chunk -> read a chunk */
565 if (p_size < p_stream->m_buffer_size) {
566 /* we should do an actual read on the media */
567 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);
569 if (p_stream->m_bytes_in_buffer == -1) {
571 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
573 p_stream->m_bytes_in_buffer = 0;
574 p_stream->m_status |= opj_stream_e_end;
576 return l_read_nb_bytes ? l_read_nb_bytes : -1;
578 else if (p_stream->m_bytes_in_buffer < p_size) {
579 /* not enough data */
580 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
581 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
582 p_stream->m_current_data = p_stream->m_stored_data;
583 p_buffer += p_stream->m_bytes_in_buffer;
584 p_size -= p_stream->m_bytes_in_buffer;
585 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
586 p_stream->m_bytes_in_buffer = 0;
589 l_read_nb_bytes += p_size;
590 memcpy(p_buffer,p_stream->m_current_data,p_size);
591 p_stream->m_current_data += p_size;
592 p_stream->m_bytes_in_buffer -= p_size;
593 p_stream->m_byte_offset += p_size;
594 return l_read_nb_bytes;
598 /* direct read on the dest buffer */
599 p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data);
601 if (p_stream->m_bytes_in_buffer == -1) {
603 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
605 p_stream->m_bytes_in_buffer = 0;
606 p_stream->m_status |= opj_stream_e_end;
608 return l_read_nb_bytes ? l_read_nb_bytes : -1;
610 else if (p_stream->m_bytes_in_buffer < p_size) {
611 /* not enough data */
612 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
613 p_stream->m_current_data = p_stream->m_stored_data;
614 p_buffer += p_stream->m_bytes_in_buffer;
615 p_size -= p_stream->m_bytes_in_buffer;
616 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
617 p_stream->m_bytes_in_buffer = 0;
620 /* we have read the exact size */
621 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
622 p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
623 p_stream->m_current_data = p_stream->m_stored_data;
624 p_stream->m_bytes_in_buffer = 0;
625 return l_read_nb_bytes;
632 * Writes some bytes from the stream.
633 * @param p_stream the stream to write data to.
634 * @param p_buffer pointer to the data buffer holds the data to be writtent.
635 * @param p_size number of bytes to write.
636 * @param p_event_mgr the user event manager to be notified of special events.
637 * @return the number of bytes writtent, or -1 if an error occured.
639 OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer,OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
641 OPJ_SIZE_T l_remaining_bytes = 0;
642 OPJ_SIZE_T l_write_nb_bytes = 0;
645 (p_stream->m_status & opj_stream_e_error)
652 l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
653 /* we have more memory than required */
655 (l_remaining_bytes >= p_size)
657 memcpy(p_stream->m_current_data,p_buffer,p_size);
658 p_stream->m_current_data += p_size;
659 p_stream->m_bytes_in_buffer += p_size;
660 l_write_nb_bytes += p_size;
661 p_stream->m_byte_offset += p_size;
662 return l_write_nb_bytes;
665 /* we copy data and then do an actual read on the stream */
669 l_write_nb_bytes += l_remaining_bytes;
670 memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes);
671 p_stream->m_current_data = p_stream->m_stored_data;
672 p_buffer += l_remaining_bytes;
673 p_size -= l_remaining_bytes;
674 p_stream->m_bytes_in_buffer += l_remaining_bytes;
675 p_stream->m_byte_offset += l_remaining_bytes;
678 (! opj_stream_flush(p_stream, p_event_mgr))
687 * Writes the content of the stream buffer to the stream.
688 * @param p_stream the stream to write data to.
689 * @param p_event_mgr the user event manager to be notified of special events.
690 * @return the number of bytes written, or -1 if an error occured.
692 opj_bool opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr)
694 // the number of bytes written on the media.
695 OPJ_SIZE_T l_current_write_nb_bytes = 0;
696 p_stream->m_current_data = p_stream->m_stored_data;
699 (p_stream->m_bytes_in_buffer)
701 // we should do an actual write on the media
702 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);
704 (l_current_write_nb_bytes == -1)
706 p_stream->m_status |= opj_stream_e_error;
707 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Error on writting stream!\n");
711 p_stream->m_current_data += l_current_write_nb_bytes;
712 p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
714 p_stream->m_current_data = p_stream->m_stored_data;
719 * Skips a number of bytes from the stream.
720 * @param p_stream the stream to skip data from.
721 * @param p_size the number of bytes to skip.
722 * @param p_event_mgr the user event manager to be notified of special events.
723 * @return the number of bytes skipped, or -1 if an error occured.
725 OPJ_OFF_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
727 OPJ_OFF_T l_skip_nb_bytes = 0;
728 OPJ_OFF_T l_current_skip_nb_bytes = 0;
731 (p_stream->m_bytes_in_buffer >= p_size)
733 p_stream->m_current_data += p_size;
734 // it is safe to cast p_size to OPJ_SIZE_T since it is <= m_bytes_in_buffer
735 // which is of type OPJ_SIZE_T
736 p_stream->m_bytes_in_buffer -= (OPJ_SIZE_T)p_size;
737 l_skip_nb_bytes += p_size;
738 p_stream->m_byte_offset += l_skip_nb_bytes;
739 return l_skip_nb_bytes;
742 // we are now in the case when the remaining data if not sufficient
744 (p_stream->m_status & opj_stream_e_end)
746 l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
747 p_stream->m_current_data += p_stream->m_bytes_in_buffer;
748 p_stream->m_bytes_in_buffer = 0;
749 p_stream->m_byte_offset += l_skip_nb_bytes;
750 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
753 // the flag is not set, we copy data and then do an actual skip on the stream
755 (p_stream->m_bytes_in_buffer)
757 l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
758 p_stream->m_current_data = p_stream->m_stored_data;
759 p_size -= p_stream->m_bytes_in_buffer;
760 p_stream->m_bytes_in_buffer = 0;
766 // we should do an actual skip on the media
767 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
769 (l_current_skip_nb_bytes == (OPJ_OFF_T) -1)
771 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
773 p_stream->m_status |= opj_stream_e_end;
774 p_stream->m_byte_offset += l_skip_nb_bytes;
776 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1;
778 p_size -= l_current_skip_nb_bytes;
779 l_skip_nb_bytes += l_current_skip_nb_bytes;
781 p_stream->m_byte_offset += l_skip_nb_bytes;
782 return l_skip_nb_bytes;
786 * Skips a number of bytes from the stream.
787 * @param p_stream the stream to skip data from.
788 * @param p_size the number of bytes to skip.
789 * @param p_event_mgr the user event manager to be notified of special events.
790 * @return the number of bytes skipped, or -1 if an error occured.
792 OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
794 opj_bool l_is_written = 0;
795 OPJ_OFF_T l_current_skip_nb_bytes = 0;
796 OPJ_OFF_T l_skip_nb_bytes = 0;
799 (p_stream->m_status & opj_stream_e_error)
801 return (OPJ_OFF_T) -1;
804 // we should flush data
805 l_is_written = opj_stream_flush (p_stream, p_event_mgr);
809 p_stream->m_status |= opj_stream_e_error;
810 p_stream->m_bytes_in_buffer = 0;
811 p_stream->m_current_data = p_stream->m_current_data;
812 return (OPJ_OFF_T) -1;
819 // we should do an actual skip on the media
820 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
822 (l_current_skip_nb_bytes == (OPJ_OFF_T)-1)
824 opj_event_msg_v2(p_event_mgr, EVT_INFO, "Stream error!\n");
826 p_stream->m_status |= opj_stream_e_error;
827 p_stream->m_byte_offset += l_skip_nb_bytes;
829 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T)-1;
831 p_size -= l_current_skip_nb_bytes;
832 l_skip_nb_bytes += l_current_skip_nb_bytes;
834 p_stream->m_byte_offset += l_skip_nb_bytes;
835 return l_skip_nb_bytes;
839 * Tells the byte offset on the stream (similar to ftell).
841 * @param p_stream the stream to get the information from.
843 * @return the current position of the stream.
845 OPJ_OFF_T opj_stream_tell (const opj_stream_private_t * p_stream)
847 return p_stream->m_byte_offset;
852 * Get the number of bytes left before the end of the stream (similar to cio_numbytesleft).
854 * @param p_stream the stream to get the information from.
856 * @return Number of bytes left before the end of the stream.
858 OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream)
860 return p_stream->m_user_data_length ?
861 p_stream->m_user_data_length - p_stream->m_byte_offset :
866 * Skips a number of bytes from the stream.
867 * @param p_stream the stream to skip data from.
868 * @param p_size the number of bytes to skip.
869 * @param p_event_mgr the user event manager to be notified of special events.
870 * @return the number of bytes skipped, or -1 if an error occured.
872 OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
875 return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr);
880 * Skips a number of bytes from the stream.
881 * @param p_stream the stream to skip data from.
882 * @param p_size the number of bytes to skip.
883 * @param p_event_mgr the user event manager to be notified of special events.
884 * @return the number of bytes skipped, or -1 if an error occured.
886 opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
888 OPJ_ARG_NOT_USED(p_event_mgr);
889 p_stream->m_current_data = p_stream->m_stored_data;
890 p_stream->m_bytes_in_buffer = 0;
892 if( p_stream->m_seek_fn(p_size,p_stream->m_user_data)) {
893 p_stream->m_status |= opj_stream_e_end;
897 // reset stream status
898 p_stream->m_status &= (~opj_stream_e_end);
899 p_stream->m_byte_offset = p_size;
907 * Skips a number of bytes from the stream.
908 * @param p_stream the stream to skip data from.
909 * @param p_size the number of bytes to skip.
910 * @param p_event_mgr the user event manager to be notified of special events.
911 * @return the number of bytes skipped, or -1 if an error occured.
913 opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
916 (! opj_stream_flush(p_stream,p_event_mgr))
918 p_stream->m_status |= opj_stream_e_error;
922 p_stream->m_current_data = p_stream->m_stored_data;
923 p_stream->m_bytes_in_buffer = 0;
926 (! p_stream->m_seek_fn(p_size,p_stream->m_user_data))
928 p_stream->m_status |= opj_stream_e_error;
933 p_stream->m_byte_offset = p_size;
940 * Seeks a number of bytes from the stream.
941 * @param p_stream the stream to skip data from.
942 * @param p_size the number of bytes to skip.
943 * @param p_event_mgr the user event manager to be notified of special events.
944 * @return true if the stream is seekable.
946 opj_bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr)
949 return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr);
953 * Tells if the given stream is seekable.
955 opj_bool opj_stream_has_seek (const opj_stream_private_t * p_stream)
957 return p_stream->m_seek_fn != opj_stream_default_seek;
960 OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
962 OPJ_ARG_NOT_USED(p_buffer);
963 OPJ_ARG_NOT_USED(p_nb_bytes);
964 OPJ_ARG_NOT_USED(p_user_data);
965 return (OPJ_SIZE_T) -1;
968 OPJ_SIZE_T opj_stream_default_write (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
970 OPJ_ARG_NOT_USED(p_buffer);
971 OPJ_ARG_NOT_USED(p_nb_bytes);
972 OPJ_ARG_NOT_USED(p_user_data);
973 return (OPJ_SIZE_T) -1;
976 OPJ_OFF_T opj_stream_default_skip (OPJ_OFF_T p_nb_bytes, void * p_user_data)
978 OPJ_ARG_NOT_USED(p_nb_bytes);
979 OPJ_ARG_NOT_USED(p_user_data);
980 return (OPJ_OFF_T) -1;
983 opj_bool opj_stream_default_seek (OPJ_OFF_T p_nb_bytes, void * p_user_data)
985 OPJ_ARG_NOT_USED(p_nb_bytes);
986 OPJ_ARG_NOT_USED(p_user_data);