Home | History | Annotate | Download | only in libopenjpeg20
      1 /*
      2  * The copyright in this software is being made available under the 2-clauses
      3  * BSD License, included below. This software may be subject to other third
      4  * party and contributor rights, including patent rights, and no such rights
      5  * are granted under this license.
      6  *
      7  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
      8  * Copyright (c) 2002-2014, Professor Benoit Macq
      9  * Copyright (c) 2001-2003, David Janssens
     10  * Copyright (c) 2002-2003, Yannick Verschueren
     11  * Copyright (c) 2003-2007, Francois-Olivier Devaux
     12  * Copyright (c) 2003-2014, Antonin Descampe
     13  * Copyright (c) 2005, Herve Drolon, FreeImage Team
     14  * Copyright (c) 2008, 2011-2012, Centre National d'Etudes Spatiales (CNES), FR
     15  * Copyright (c) 2012, CS Systemes d'Information, France
     16  * All rights reserved.
     17  *
     18  * Redistribution and use in source and binary forms, with or without
     19  * modification, are permitted provided that the following conditions
     20  * are met:
     21  * 1. Redistributions of source code must retain the above copyright
     22  *    notice, this list of conditions and the following disclaimer.
     23  * 2. Redistributions in binary form must reproduce the above copyright
     24  *    notice, this list of conditions and the following disclaimer in the
     25  *    documentation and/or other materials provided with the distribution.
     26  *
     27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
     28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37  * POSSIBILITY OF SUCH DAMAGE.
     38  */
     39 
     40 #include "opj_includes.h"
     41 
     42 /* ----------------------------------------------------------------------- */
     43 
     44 
     45 /* ----------------------------------------------------------------------- */
     46 
     47 void opj_write_bytes_BE(OPJ_BYTE * p_buffer, OPJ_UINT32 p_value,
     48                         OPJ_UINT32 p_nb_bytes)
     49 {
     50     const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(
     51                                       OPJ_UINT32) - p_nb_bytes;
     52 
     53     assert(p_nb_bytes > 0 && p_nb_bytes <=  sizeof(OPJ_UINT32));
     54 
     55     memcpy(p_buffer, l_data_ptr, p_nb_bytes);
     56 }
     57 
     58 void opj_write_bytes_LE(OPJ_BYTE * p_buffer, OPJ_UINT32 p_value,
     59                         OPJ_UINT32 p_nb_bytes)
     60 {
     61     const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes - 1;
     62     OPJ_UINT32 i;
     63 
     64     assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
     65 
     66     for (i = 0; i < p_nb_bytes; ++i) {
     67         *(p_buffer++) = *(l_data_ptr--);
     68     }
     69 }
     70 
     71 void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value,
     72                        OPJ_UINT32 p_nb_bytes)
     73 {
     74     OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
     75 
     76     assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
     77 
     78     *p_value = 0;
     79     memcpy(l_data_ptr + sizeof(OPJ_UINT32) - p_nb_bytes, p_buffer, p_nb_bytes);
     80 }
     81 
     82 void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value,
     83                        OPJ_UINT32 p_nb_bytes)
     84 {
     85     OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + p_nb_bytes - 1;
     86     OPJ_UINT32 i;
     87 
     88     assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
     89 
     90     *p_value = 0;
     91     for (i = 0; i < p_nb_bytes; ++i) {
     92         *(l_data_ptr--) = *(p_buffer++);
     93     }
     94 }
     95 
     96 void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
     97 {
     98     const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
     99     memcpy(p_buffer, l_data_ptr, sizeof(OPJ_FLOAT64));
    100 }
    101 
    102 void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
    103 {
    104     const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(
    105                                       OPJ_FLOAT64) - 1;
    106     OPJ_UINT32 i;
    107     for (i = 0; i < sizeof(OPJ_FLOAT64); ++i) {
    108         *(p_buffer++) = *(l_data_ptr--);
    109     }
    110 }
    111 
    112 void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
    113 {
    114     OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
    115     memcpy(l_data_ptr, p_buffer, sizeof(OPJ_FLOAT64));
    116 }
    117 
    118 void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
    119 {
    120     OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT64) - 1;
    121     OPJ_UINT32 i;
    122     for (i = 0; i < sizeof(OPJ_FLOAT64); ++i) {
    123         *(l_data_ptr--) = *(p_buffer++);
    124     }
    125 }
    126 
    127 void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
    128 {
    129     const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
    130     memcpy(p_buffer, l_data_ptr, sizeof(OPJ_FLOAT32));
    131 }
    132 
    133 void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
    134 {
    135     const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(
    136                                       OPJ_FLOAT32) - 1;
    137     OPJ_UINT32 i;
    138     for (i = 0; i < sizeof(OPJ_FLOAT32); ++i) {
    139         *(p_buffer++) = *(l_data_ptr--);
    140     }
    141 }
    142 
    143 void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
    144 {
    145     OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
    146     memcpy(l_data_ptr, p_buffer, sizeof(OPJ_FLOAT32));
    147 }
    148 
    149 void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
    150 {
    151     OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT32) - 1;
    152     OPJ_UINT32 i;
    153     for (i = 0; i < sizeof(OPJ_FLOAT32); ++i) {
    154         *(l_data_ptr--) = *(p_buffer++);
    155     }
    156 }
    157 
    158 opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size,
    159         OPJ_BOOL l_is_input)
    160 {
    161     opj_stream_private_t * l_stream = 00;
    162     l_stream = (opj_stream_private_t*) opj_calloc(1, sizeof(opj_stream_private_t));
    163     if (! l_stream) {
    164         return 00;
    165     }
    166 
    167     l_stream->m_buffer_size = p_buffer_size;
    168     l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_buffer_size);
    169     if (! l_stream->m_stored_data) {
    170         opj_free(l_stream);
    171         return 00;
    172     }
    173 
    174     l_stream->m_current_data = l_stream->m_stored_data;
    175 
    176     if (l_is_input) {
    177         l_stream->m_status |= OPJ_STREAM_STATUS_INPUT;
    178         l_stream->m_opj_skip = opj_stream_read_skip;
    179         l_stream->m_opj_seek = opj_stream_read_seek;
    180     } else {
    181         l_stream->m_status |= OPJ_STREAM_STATUS_OUTPUT;
    182         l_stream->m_opj_skip = opj_stream_write_skip;
    183         l_stream->m_opj_seek = opj_stream_write_seek;
    184     }
    185 
    186     l_stream->m_read_fn = opj_stream_default_read;
    187     l_stream->m_write_fn = opj_stream_default_write;
    188     l_stream->m_skip_fn = opj_stream_default_skip;
    189     l_stream->m_seek_fn = opj_stream_default_seek;
    190 
    191     return (opj_stream_t *) l_stream;
    192 }
    193 
    194 opj_stream_t* OPJ_CALLCONV opj_stream_default_create(OPJ_BOOL l_is_input)
    195 {
    196     return opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, l_is_input);
    197 }
    198 
    199 void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream)
    200 {
    201     opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
    202 
    203     if (l_stream) {
    204         if (l_stream->m_free_user_data_fn) {
    205             l_stream->m_free_user_data_fn(l_stream->m_user_data);
    206         }
    207         opj_free(l_stream->m_stored_data);
    208         l_stream->m_stored_data = 00;
    209         opj_free(l_stream);
    210     }
    211 }
    212 
    213 void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream,
    214         opj_stream_read_fn p_function)
    215 {
    216     opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
    217 
    218     if ((!l_stream) || (!(l_stream->m_status & OPJ_STREAM_STATUS_INPUT))) {
    219         return;
    220     }
    221 
    222     l_stream->m_read_fn = p_function;
    223 }
    224 
    225 void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream,
    226         opj_stream_seek_fn p_function)
    227 {
    228     opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
    229 
    230     if (!l_stream) {
    231         return;
    232     }
    233     l_stream->m_seek_fn = p_function;
    234 }
    235 
    236 void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream,
    237         opj_stream_write_fn p_function)
    238 {
    239     opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
    240 
    241     if ((!l_stream) || (!(l_stream->m_status & OPJ_STREAM_STATUS_OUTPUT))) {
    242         return;
    243     }
    244 
    245     l_stream->m_write_fn = p_function;
    246 }
    247 
    248 void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream,
    249         opj_stream_skip_fn p_function)
    250 {
    251     opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
    252 
    253     if (! l_stream) {
    254         return;
    255     }
    256 
    257     l_stream->m_skip_fn = p_function;
    258 }
    259 
    260 void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream,
    261         void * p_data, opj_stream_free_user_data_fn p_function)
    262 {
    263     opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
    264     if (!l_stream) {
    265         return;
    266     }
    267     l_stream->m_user_data = p_data;
    268     l_stream->m_free_user_data_fn = p_function;
    269 }
    270 
    271 void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream,
    272         OPJ_UINT64 data_length)
    273 {
    274     opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
    275     if (!l_stream) {
    276         return;
    277     }
    278     l_stream->m_user_data_length = data_length;
    279 }
    280 
    281 OPJ_SIZE_T opj_stream_read_data(opj_stream_private_t * p_stream,
    282                                 OPJ_BYTE * p_buffer, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
    283 {
    284     OPJ_SIZE_T l_read_nb_bytes = 0;
    285     if (p_stream->m_bytes_in_buffer >= p_size) {
    286         memcpy(p_buffer, p_stream->m_current_data, p_size);
    287         p_stream->m_current_data += p_size;
    288         p_stream->m_bytes_in_buffer -= p_size;
    289         l_read_nb_bytes += p_size;
    290         p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
    291         return l_read_nb_bytes;
    292     }
    293 
    294     /* we are now in the case when the remaining data if not sufficient */
    295     if (p_stream->m_status & OPJ_STREAM_STATUS_END) {
    296         l_read_nb_bytes += p_stream->m_bytes_in_buffer;
    297         memcpy(p_buffer, p_stream->m_current_data, p_stream->m_bytes_in_buffer);
    298         p_stream->m_current_data += p_stream->m_bytes_in_buffer;
    299         p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
    300         p_stream->m_bytes_in_buffer = 0;
    301         return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T) - 1;
    302     }
    303 
    304     /* the flag is not set, we copy data and then do an actual read on the stream */
    305     if (p_stream->m_bytes_in_buffer) {
    306         l_read_nb_bytes += p_stream->m_bytes_in_buffer;
    307         memcpy(p_buffer, p_stream->m_current_data, p_stream->m_bytes_in_buffer);
    308         p_stream->m_current_data = p_stream->m_stored_data;
    309         p_buffer += p_stream->m_bytes_in_buffer;
    310         p_size -= p_stream->m_bytes_in_buffer;
    311         p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
    312         p_stream->m_bytes_in_buffer = 0;
    313     } else {
    314         /* case where we are already at the end of the buffer
    315            so reset the m_current_data to point to the start of the
    316            stored buffer to get ready to read from disk*/
    317         p_stream->m_current_data = p_stream->m_stored_data;
    318     }
    319 
    320     for (;;) {
    321         /* we should read less than a chunk -> read a chunk */
    322         if (p_size < p_stream->m_buffer_size) {
    323             /* we should do an actual read on the media */
    324             p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_stream->m_stored_data,
    325                                           p_stream->m_buffer_size, p_stream->m_user_data);
    326 
    327             if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T) - 1) {
    328                 /* end of stream */
    329                 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
    330 
    331                 p_stream->m_bytes_in_buffer = 0;
    332                 p_stream->m_status |= OPJ_STREAM_STATUS_END;
    333                 /* end of stream */
    334                 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T) - 1;
    335             } else if (p_stream->m_bytes_in_buffer < p_size) {
    336                 /* not enough data */
    337                 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
    338                 memcpy(p_buffer, p_stream->m_current_data, p_stream->m_bytes_in_buffer);
    339                 p_stream->m_current_data = p_stream->m_stored_data;
    340                 p_buffer += p_stream->m_bytes_in_buffer;
    341                 p_size -= p_stream->m_bytes_in_buffer;
    342                 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
    343                 p_stream->m_bytes_in_buffer = 0;
    344             } else {
    345                 l_read_nb_bytes += p_size;
    346                 memcpy(p_buffer, p_stream->m_current_data, p_size);
    347                 p_stream->m_current_data += p_size;
    348                 p_stream->m_bytes_in_buffer -= p_size;
    349                 p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
    350                 return l_read_nb_bytes;
    351             }
    352         } else {
    353             /* direct read on the dest buffer */
    354             p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer, p_size,
    355                                           p_stream->m_user_data);
    356 
    357             if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T) - 1) {
    358                 /*  end of stream */
    359                 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
    360 
    361                 p_stream->m_bytes_in_buffer = 0;
    362                 p_stream->m_status |= OPJ_STREAM_STATUS_END;
    363                 /* end of stream */
    364                 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T) - 1;
    365             } else if (p_stream->m_bytes_in_buffer < p_size) {
    366                 /* not enough data */
    367                 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
    368                 p_stream->m_current_data = p_stream->m_stored_data;
    369                 p_buffer += p_stream->m_bytes_in_buffer;
    370                 p_size -= p_stream->m_bytes_in_buffer;
    371                 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
    372                 p_stream->m_bytes_in_buffer = 0;
    373             } else {
    374                 /* we have read the exact size */
    375                 l_read_nb_bytes += p_stream->m_bytes_in_buffer;
    376                 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
    377                 p_stream->m_current_data = p_stream->m_stored_data;
    378                 p_stream->m_bytes_in_buffer = 0;
    379                 return l_read_nb_bytes;
    380             }
    381         }
    382     }
    383 }
    384 
    385 OPJ_SIZE_T opj_stream_write_data(opj_stream_private_t * p_stream,
    386                                  const OPJ_BYTE * p_buffer,
    387                                  OPJ_SIZE_T p_size,
    388                                  opj_event_mgr_t * p_event_mgr)
    389 {
    390     OPJ_SIZE_T l_remaining_bytes = 0;
    391     OPJ_SIZE_T l_write_nb_bytes = 0;
    392 
    393     if (p_stream->m_status & OPJ_STREAM_STATUS_ERROR) {
    394         return (OPJ_SIZE_T) - 1;
    395     }
    396 
    397     for (;;) {
    398         l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
    399 
    400         /* we have more memory than required */
    401         if (l_remaining_bytes >= p_size) {
    402             memcpy(p_stream->m_current_data, p_buffer, p_size);
    403 
    404             p_stream->m_current_data += p_size;
    405             p_stream->m_bytes_in_buffer += p_size;
    406             l_write_nb_bytes += p_size;
    407             p_stream->m_byte_offset += (OPJ_OFF_T)p_size;
    408 
    409             return l_write_nb_bytes;
    410         }
    411 
    412         /* we copy data and then do an actual read on the stream */
    413         if (l_remaining_bytes) {
    414             l_write_nb_bytes += l_remaining_bytes;
    415 
    416             memcpy(p_stream->m_current_data, p_buffer, l_remaining_bytes);
    417 
    418             p_stream->m_current_data = p_stream->m_stored_data;
    419 
    420             p_buffer += l_remaining_bytes;
    421             p_size -= l_remaining_bytes;
    422             p_stream->m_bytes_in_buffer += l_remaining_bytes;
    423             p_stream->m_byte_offset += (OPJ_OFF_T)l_remaining_bytes;
    424         }
    425 
    426         if (! opj_stream_flush(p_stream, p_event_mgr)) {
    427             return (OPJ_SIZE_T) - 1;
    428         }
    429     }
    430 
    431 }
    432 
    433 OPJ_BOOL opj_stream_flush(opj_stream_private_t * p_stream,
    434                           opj_event_mgr_t * p_event_mgr)
    435 {
    436     /* the number of bytes written on the media. */
    437     OPJ_SIZE_T l_current_write_nb_bytes = 0;
    438 
    439     p_stream->m_current_data = p_stream->m_stored_data;
    440 
    441     while (p_stream->m_bytes_in_buffer) {
    442         /* we should do an actual write on the media */
    443         l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data,
    444                                    p_stream->m_bytes_in_buffer,
    445                                    p_stream->m_user_data);
    446 
    447         if (l_current_write_nb_bytes == (OPJ_SIZE_T) - 1) {
    448             p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
    449             opj_event_msg(p_event_mgr, EVT_INFO, "Error on writing stream!\n");
    450 
    451             return OPJ_FALSE;
    452         }
    453 
    454         p_stream->m_current_data += l_current_write_nb_bytes;
    455         p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
    456     }
    457 
    458     p_stream->m_current_data = p_stream->m_stored_data;
    459 
    460     return OPJ_TRUE;
    461 }
    462 
    463 OPJ_OFF_T opj_stream_read_skip(opj_stream_private_t * p_stream,
    464                                OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
    465 {
    466     OPJ_OFF_T l_skip_nb_bytes = 0;
    467     OPJ_OFF_T l_current_skip_nb_bytes = 0;
    468 
    469     assert(p_size >= 0);
    470 
    471     if (p_stream->m_bytes_in_buffer >= (OPJ_SIZE_T)p_size) {
    472         p_stream->m_current_data += p_size;
    473         /* it is safe to cast p_size to OPJ_SIZE_T since it is <= m_bytes_in_buffer
    474         which is of type OPJ_SIZE_T */
    475         p_stream->m_bytes_in_buffer -= (OPJ_SIZE_T)p_size;
    476         l_skip_nb_bytes += p_size;
    477         p_stream->m_byte_offset += l_skip_nb_bytes;
    478         return l_skip_nb_bytes;
    479     }
    480 
    481     /* we are now in the case when the remaining data if not sufficient */
    482     if (p_stream->m_status & OPJ_STREAM_STATUS_END) {
    483         l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
    484         p_stream->m_current_data += p_stream->m_bytes_in_buffer;
    485         p_stream->m_bytes_in_buffer = 0;
    486         p_stream->m_byte_offset += l_skip_nb_bytes;
    487         return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) - 1;
    488     }
    489 
    490     /* the flag is not set, we copy data and then do an actual skip on the stream */
    491     if (p_stream->m_bytes_in_buffer) {
    492         l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
    493         p_stream->m_current_data = p_stream->m_stored_data;
    494         p_size -= (OPJ_OFF_T)p_stream->m_bytes_in_buffer;
    495         p_stream->m_bytes_in_buffer = 0;
    496     }
    497 
    498     while (p_size > 0) {
    499         /* Check if we are going beyond the end of file. Most skip_fn do not */
    500         /* check that, but we must be careful not to advance m_byte_offset */
    501         /* beyond m_user_data_length, otherwise */
    502         /* opj_stream_get_number_byte_left() will assert. */
    503         if ((OPJ_UINT64)(p_stream->m_byte_offset + l_skip_nb_bytes + p_size) >
    504                 p_stream->m_user_data_length) {
    505             opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
    506 
    507             p_stream->m_byte_offset += l_skip_nb_bytes;
    508             l_skip_nb_bytes = (OPJ_OFF_T)(p_stream->m_user_data_length -
    509                                           (OPJ_UINT64)p_stream->m_byte_offset);
    510 
    511             opj_stream_read_seek(p_stream, (OPJ_OFF_T)p_stream->m_user_data_length,
    512                                  p_event_mgr);
    513             p_stream->m_status |= OPJ_STREAM_STATUS_END;
    514 
    515             /* end if stream */
    516             return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) - 1;
    517         }
    518 
    519         /* we should do an actual skip on the media */
    520         l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
    521         if (l_current_skip_nb_bytes == (OPJ_OFF_T) - 1) {
    522             opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
    523 
    524             p_stream->m_status |= OPJ_STREAM_STATUS_END;
    525             p_stream->m_byte_offset += l_skip_nb_bytes;
    526             /* end if stream */
    527             return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) - 1;
    528         }
    529         p_size -= l_current_skip_nb_bytes;
    530         l_skip_nb_bytes += l_current_skip_nb_bytes;
    531     }
    532 
    533     p_stream->m_byte_offset += l_skip_nb_bytes;
    534 
    535     return l_skip_nb_bytes;
    536 }
    537 
    538 OPJ_OFF_T opj_stream_write_skip(opj_stream_private_t * p_stream,
    539                                 OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
    540 {
    541     OPJ_BOOL l_is_written = 0;
    542     OPJ_OFF_T l_current_skip_nb_bytes = 0;
    543     OPJ_OFF_T l_skip_nb_bytes = 0;
    544 
    545     if (p_stream->m_status & OPJ_STREAM_STATUS_ERROR) {
    546         return (OPJ_OFF_T) - 1;
    547     }
    548 
    549     /* we should flush data */
    550     l_is_written = opj_stream_flush(p_stream, p_event_mgr);
    551     if (! l_is_written) {
    552         p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
    553         p_stream->m_bytes_in_buffer = 0;
    554         return (OPJ_OFF_T) - 1;
    555     }
    556     /* then skip */
    557 
    558     while (p_size > 0) {
    559         /* we should do an actual skip on the media */
    560         l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
    561 
    562         if (l_current_skip_nb_bytes == (OPJ_OFF_T) - 1) {
    563             opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n");
    564 
    565             p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
    566             p_stream->m_byte_offset += l_skip_nb_bytes;
    567             /* end if stream */
    568             return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) - 1;
    569         }
    570         p_size -= l_current_skip_nb_bytes;
    571         l_skip_nb_bytes += l_current_skip_nb_bytes;
    572     }
    573 
    574     p_stream->m_byte_offset += l_skip_nb_bytes;
    575 
    576     return l_skip_nb_bytes;
    577 }
    578 
    579 OPJ_OFF_T opj_stream_tell(const opj_stream_private_t * p_stream)
    580 {
    581     return p_stream->m_byte_offset;
    582 }
    583 
    584 OPJ_OFF_T opj_stream_get_number_byte_left(const opj_stream_private_t * p_stream)
    585 {
    586     assert(p_stream->m_byte_offset >= 0);
    587     assert(p_stream->m_user_data_length >= (OPJ_UINT64)p_stream->m_byte_offset);
    588     return p_stream->m_user_data_length ?
    589            (OPJ_OFF_T)(p_stream->m_user_data_length) - p_stream->m_byte_offset :
    590            0;
    591 }
    592 
    593 OPJ_OFF_T opj_stream_skip(opj_stream_private_t * p_stream, OPJ_OFF_T p_size,
    594                           opj_event_mgr_t * p_event_mgr)
    595 {
    596     assert(p_size >= 0);
    597     return p_stream->m_opj_skip(p_stream, p_size, p_event_mgr);
    598 }
    599 
    600 OPJ_BOOL opj_stream_read_seek(opj_stream_private_t * p_stream, OPJ_OFF_T p_size,
    601                               opj_event_mgr_t * p_event_mgr)
    602 {
    603     OPJ_ARG_NOT_USED(p_event_mgr);
    604     p_stream->m_current_data = p_stream->m_stored_data;
    605     p_stream->m_bytes_in_buffer = 0;
    606 
    607     if (!(p_stream->m_seek_fn(p_size, p_stream->m_user_data))) {
    608         p_stream->m_status |= OPJ_STREAM_STATUS_END;
    609         return OPJ_FALSE;
    610     } else {
    611         /* reset stream status */
    612         p_stream->m_status &= (~OPJ_STREAM_STATUS_END);
    613         p_stream->m_byte_offset = p_size;
    614 
    615     }
    616 
    617     return OPJ_TRUE;
    618 }
    619 
    620 OPJ_BOOL opj_stream_write_seek(opj_stream_private_t * p_stream,
    621                                OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr)
    622 {
    623     if (! opj_stream_flush(p_stream, p_event_mgr)) {
    624         p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
    625         return OPJ_FALSE;
    626     }
    627 
    628     p_stream->m_current_data = p_stream->m_stored_data;
    629     p_stream->m_bytes_in_buffer = 0;
    630 
    631     if (! p_stream->m_seek_fn(p_size, p_stream->m_user_data)) {
    632         p_stream->m_status |= OPJ_STREAM_STATUS_ERROR;
    633         return OPJ_FALSE;
    634     } else {
    635         p_stream->m_byte_offset = p_size;
    636     }
    637 
    638     return OPJ_TRUE;
    639 }
    640 
    641 OPJ_BOOL opj_stream_seek(opj_stream_private_t * p_stream, OPJ_OFF_T p_size,
    642                          struct opj_event_mgr * p_event_mgr)
    643 {
    644     assert(p_size >= 0);
    645     return p_stream->m_opj_seek(p_stream, p_size, p_event_mgr);
    646 }
    647 
    648 OPJ_BOOL opj_stream_has_seek(const opj_stream_private_t * p_stream)
    649 {
    650     return p_stream->m_seek_fn != opj_stream_default_seek;
    651 }
    652 
    653 OPJ_SIZE_T opj_stream_default_read(void * p_buffer, OPJ_SIZE_T p_nb_bytes,
    654                                    void * p_user_data)
    655 {
    656     OPJ_ARG_NOT_USED(p_buffer);
    657     OPJ_ARG_NOT_USED(p_nb_bytes);
    658     OPJ_ARG_NOT_USED(p_user_data);
    659     return (OPJ_SIZE_T) - 1;
    660 }
    661 
    662 OPJ_SIZE_T opj_stream_default_write(void * p_buffer, OPJ_SIZE_T p_nb_bytes,
    663                                     void * p_user_data)
    664 {
    665     OPJ_ARG_NOT_USED(p_buffer);
    666     OPJ_ARG_NOT_USED(p_nb_bytes);
    667     OPJ_ARG_NOT_USED(p_user_data);
    668     return (OPJ_SIZE_T) - 1;
    669 }
    670 
    671 OPJ_OFF_T opj_stream_default_skip(OPJ_OFF_T p_nb_bytes, void * p_user_data)
    672 {
    673     OPJ_ARG_NOT_USED(p_nb_bytes);
    674     OPJ_ARG_NOT_USED(p_user_data);
    675     return (OPJ_OFF_T) - 1;
    676 }
    677 
    678 OPJ_BOOL opj_stream_default_seek(OPJ_OFF_T p_nb_bytes, void * p_user_data)
    679 {
    680     OPJ_ARG_NOT_USED(p_nb_bytes);
    681     OPJ_ARG_NOT_USED(p_user_data);
    682     return OPJ_FALSE;
    683 }
    684