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, OPJ_UINT32 p_nb_bytes) 48 { 49 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value)+sizeof(OPJ_UINT32)-p_nb_bytes; 50 51 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32)); 52 53 memcpy(p_buffer,l_data_ptr,p_nb_bytes); 54 } 55 56 void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes) 57 { 58 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes - 1; 59 OPJ_UINT32 i; 60 61 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32)); 62 63 for (i=0;i<p_nb_bytes;++i) { 64 *(p_buffer++) = *(l_data_ptr--); 65 } 66 } 67 68 void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes) 69 { 70 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value); 71 72 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32)); 73 74 *p_value = 0; 75 memcpy(l_data_ptr+sizeof(OPJ_UINT32)-p_nb_bytes,p_buffer,p_nb_bytes); 76 } 77 78 void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes) 79 { 80 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + p_nb_bytes-1; 81 OPJ_UINT32 i; 82 83 assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32)); 84 85 *p_value = 0; 86 for (i=0;i<p_nb_bytes;++i) { 87 *(l_data_ptr--) = *(p_buffer++); 88 } 89 } 90 91 void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value) 92 { 93 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value); 94 memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT64)); 95 } 96 97 void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value) 98 { 99 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT64) - 1; 100 OPJ_UINT32 i; 101 for (i=0;i<sizeof(OPJ_FLOAT64);++i) { 102 *(p_buffer++) = *(l_data_ptr--); 103 } 104 } 105 106 void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value) 107 { 108 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value); 109 memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT64)); 110 } 111 112 void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value) 113 { 114 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT64)-1; 115 OPJ_UINT32 i; 116 for (i=0;i<sizeof(OPJ_FLOAT64);++i) { 117 *(l_data_ptr--) = *(p_buffer++); 118 } 119 } 120 121 void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value) 122 { 123 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value); 124 memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT32)); 125 } 126 127 void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value) 128 { 129 const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT32) - 1; 130 OPJ_UINT32 i; 131 for (i=0;i<sizeof(OPJ_FLOAT32);++i) { 132 *(p_buffer++) = *(l_data_ptr--); 133 } 134 } 135 136 void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value) 137 { 138 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value); 139 memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT32)); 140 } 141 142 void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value) 143 { 144 OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT32)-1; 145 OPJ_UINT32 i; 146 for (i=0;i<sizeof(OPJ_FLOAT32);++i) { 147 *(l_data_ptr--) = *(p_buffer++); 148 } 149 } 150 151 opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_SIZE_T p_buffer_size,OPJ_BOOL l_is_input) 152 { 153 opj_stream_private_t * l_stream = 00; 154 l_stream = (opj_stream_private_t*) opj_calloc(1,sizeof(opj_stream_private_t)); 155 if (! l_stream) { 156 return 00; 157 } 158 159 l_stream->m_buffer_size = p_buffer_size; 160 l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_buffer_size); 161 if (! l_stream->m_stored_data) { 162 opj_free(l_stream); 163 return 00; 164 } 165 166 l_stream->m_current_data = l_stream->m_stored_data; 167 168 if (l_is_input) { 169 l_stream->m_status |= opj_stream_e_input; 170 l_stream->m_opj_skip = opj_stream_read_skip; 171 l_stream->m_opj_seek = opj_stream_read_seek; 172 } 173 else { 174 l_stream->m_status |= opj_stream_e_output; 175 l_stream->m_opj_skip = opj_stream_write_skip; 176 l_stream->m_opj_seek = opj_stream_write_seek; 177 } 178 179 l_stream->m_read_fn = opj_stream_default_read; 180 l_stream->m_write_fn = opj_stream_default_write; 181 l_stream->m_skip_fn = opj_stream_default_skip; 182 l_stream->m_seek_fn = opj_stream_default_seek; 183 184 return (opj_stream_t *) l_stream; 185 } 186 187 opj_stream_t* OPJ_CALLCONV opj_stream_default_create(OPJ_BOOL l_is_input) 188 { 189 return opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE,l_is_input); 190 } 191 192 void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream) 193 { 194 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 195 196 if (l_stream) { 197 if (l_stream->m_free_user_data_fn) { 198 l_stream->m_free_user_data_fn(l_stream->m_user_data); 199 } 200 opj_free(l_stream->m_stored_data); 201 l_stream->m_stored_data = 00; 202 opj_free(l_stream); 203 } 204 } 205 206 void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function) 207 { 208 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 209 210 if ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input))) { 211 return; 212 } 213 214 l_stream->m_read_fn = p_function; 215 } 216 217 void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function) 218 { 219 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 220 221 if (!l_stream) { 222 return; 223 } 224 l_stream->m_seek_fn = p_function; 225 } 226 227 void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function) 228 { 229 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 230 231 if ((!l_stream )|| (! (l_stream->m_status & opj_stream_e_output))) { 232 return; 233 } 234 235 l_stream->m_write_fn = p_function; 236 } 237 238 void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function) 239 { 240 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 241 242 if (! l_stream) { 243 return; 244 } 245 246 l_stream->m_skip_fn = p_function; 247 } 248 249 void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data, opj_stream_free_user_data_fn p_function) 250 { 251 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 252 if (!l_stream) 253 return; 254 l_stream->m_user_data = p_data; 255 l_stream->m_free_user_data_fn = p_function; 256 } 257 258 void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT64 data_length) 259 { 260 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 261 if (!l_stream) 262 return; 263 l_stream->m_user_data_length = data_length; 264 } 265 266 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) 267 { 268 OPJ_SIZE_T l_read_nb_bytes = 0; 269 if (p_stream->m_bytes_in_buffer >= p_size) { 270 memcpy(p_buffer,p_stream->m_current_data,p_size); 271 p_stream->m_current_data += p_size; 272 p_stream->m_bytes_in_buffer -= p_size; 273 l_read_nb_bytes += p_size; 274 p_stream->m_byte_offset += (OPJ_OFF_T)p_size; 275 return l_read_nb_bytes; 276 } 277 278 /* we are now in the case when the remaining data if not sufficient */ 279 if (p_stream->m_status & opj_stream_e_end) { 280 l_read_nb_bytes += p_stream->m_bytes_in_buffer; 281 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer); 282 p_stream->m_current_data += p_stream->m_bytes_in_buffer; 283 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 284 p_stream->m_bytes_in_buffer = 0; 285 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1; 286 } 287 288 /* the flag is not set, we copy data and then do an actual read on the stream */ 289 if (p_stream->m_bytes_in_buffer) { 290 l_read_nb_bytes += p_stream->m_bytes_in_buffer; 291 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer); 292 p_stream->m_current_data = p_stream->m_stored_data; 293 p_buffer += p_stream->m_bytes_in_buffer; 294 p_size -= p_stream->m_bytes_in_buffer; 295 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 296 p_stream->m_bytes_in_buffer = 0; 297 } 298 else { 299 /* case where we are already at the end of the buffer 300 so reset the m_current_data to point to the start of the 301 stored buffer to get ready to read from disk*/ 302 p_stream->m_current_data = p_stream->m_stored_data; 303 } 304 305 for (;;) { 306 /* we should read less than a chunk -> read a chunk */ 307 if (p_size < p_stream->m_buffer_size) { 308 /* we should do an actual read on the media */ 309 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); 310 311 if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T)-1) { 312 /* end of stream */ 313 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n"); 314 315 p_stream->m_bytes_in_buffer = 0; 316 p_stream->m_status |= opj_stream_e_end; 317 /* end of stream */ 318 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1; 319 } 320 else if (p_stream->m_bytes_in_buffer < p_size) { 321 /* not enough data */ 322 l_read_nb_bytes += p_stream->m_bytes_in_buffer; 323 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer); 324 p_stream->m_current_data = p_stream->m_stored_data; 325 p_buffer += p_stream->m_bytes_in_buffer; 326 p_size -= p_stream->m_bytes_in_buffer; 327 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 328 p_stream->m_bytes_in_buffer = 0; 329 } 330 else { 331 l_read_nb_bytes += p_size; 332 memcpy(p_buffer,p_stream->m_current_data,p_size); 333 p_stream->m_current_data += p_size; 334 p_stream->m_bytes_in_buffer -= p_size; 335 p_stream->m_byte_offset += (OPJ_OFF_T)p_size; 336 return l_read_nb_bytes; 337 } 338 } 339 else { 340 /* direct read on the dest buffer */ 341 p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data); 342 343 if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T)-1) { 344 /* end of stream */ 345 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n"); 346 347 p_stream->m_bytes_in_buffer = 0; 348 p_stream->m_status |= opj_stream_e_end; 349 /* end of stream */ 350 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1; 351 } 352 else if (p_stream->m_bytes_in_buffer < p_size) { 353 /* not enough data */ 354 l_read_nb_bytes += p_stream->m_bytes_in_buffer; 355 p_stream->m_current_data = p_stream->m_stored_data; 356 p_buffer += p_stream->m_bytes_in_buffer; 357 p_size -= p_stream->m_bytes_in_buffer; 358 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 359 p_stream->m_bytes_in_buffer = 0; 360 } 361 else { 362 /* we have read the exact size */ 363 l_read_nb_bytes += p_stream->m_bytes_in_buffer; 364 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 365 p_stream->m_current_data = p_stream->m_stored_data; 366 p_stream->m_bytes_in_buffer = 0; 367 return l_read_nb_bytes; 368 } 369 } 370 } 371 } 372 373 OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream, 374 const OPJ_BYTE * p_buffer, 375 OPJ_SIZE_T p_size, 376 opj_event_mgr_t * p_event_mgr) 377 { 378 OPJ_SIZE_T l_remaining_bytes = 0; 379 OPJ_SIZE_T l_write_nb_bytes = 0; 380 381 if (p_stream->m_status & opj_stream_e_error) { 382 return (OPJ_SIZE_T)-1; 383 } 384 385 for (;;) { 386 l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer; 387 388 /* we have more memory than required */ 389 if (l_remaining_bytes >= p_size) { 390 memcpy(p_stream->m_current_data, p_buffer, p_size); 391 392 p_stream->m_current_data += p_size; 393 p_stream->m_bytes_in_buffer += p_size; 394 l_write_nb_bytes += p_size; 395 p_stream->m_byte_offset += (OPJ_OFF_T)p_size; 396 397 return l_write_nb_bytes; 398 } 399 400 /* we copy data and then do an actual read on the stream */ 401 if (l_remaining_bytes) { 402 l_write_nb_bytes += l_remaining_bytes; 403 404 memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes); 405 406 p_stream->m_current_data = p_stream->m_stored_data; 407 408 p_buffer += l_remaining_bytes; 409 p_size -= l_remaining_bytes; 410 p_stream->m_bytes_in_buffer += l_remaining_bytes; 411 p_stream->m_byte_offset += (OPJ_OFF_T)l_remaining_bytes; 412 } 413 414 if (! opj_stream_flush(p_stream, p_event_mgr)) { 415 return (OPJ_SIZE_T)-1; 416 } 417 } 418 419 } 420 421 OPJ_BOOL opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr) 422 { 423 /* the number of bytes written on the media. */ 424 OPJ_SIZE_T l_current_write_nb_bytes = 0; 425 426 p_stream->m_current_data = p_stream->m_stored_data; 427 428 while (p_stream->m_bytes_in_buffer) { 429 /* we should do an actual write on the media */ 430 l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data, 431 p_stream->m_bytes_in_buffer, 432 p_stream->m_user_data); 433 434 if (l_current_write_nb_bytes == (OPJ_SIZE_T)-1) { 435 p_stream->m_status |= opj_stream_e_error; 436 opj_event_msg(p_event_mgr, EVT_INFO, "Error on writing stream!\n"); 437 438 return OPJ_FALSE; 439 } 440 441 p_stream->m_current_data += l_current_write_nb_bytes; 442 p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes; 443 } 444 445 p_stream->m_current_data = p_stream->m_stored_data; 446 447 return OPJ_TRUE; 448 } 449 450 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) 451 { 452 OPJ_OFF_T l_skip_nb_bytes = 0; 453 OPJ_OFF_T l_current_skip_nb_bytes = 0; 454 455 assert( p_size >= 0 ); 456 457 if (p_stream->m_bytes_in_buffer >= (OPJ_SIZE_T)p_size) { 458 p_stream->m_current_data += p_size; 459 /* it is safe to cast p_size to OPJ_SIZE_T since it is <= m_bytes_in_buffer 460 which is of type OPJ_SIZE_T */ 461 p_stream->m_bytes_in_buffer -= (OPJ_SIZE_T)p_size; 462 l_skip_nb_bytes += p_size; 463 p_stream->m_byte_offset += l_skip_nb_bytes; 464 return l_skip_nb_bytes; 465 } 466 467 /* we are now in the case when the remaining data if not sufficient */ 468 if (p_stream->m_status & opj_stream_e_end) { 469 l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 470 p_stream->m_current_data += p_stream->m_bytes_in_buffer; 471 p_stream->m_bytes_in_buffer = 0; 472 p_stream->m_byte_offset += l_skip_nb_bytes; 473 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1; 474 } 475 476 /* the flag is not set, we copy data and then do an actual skip on the stream */ 477 if (p_stream->m_bytes_in_buffer) { 478 l_skip_nb_bytes += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 479 p_stream->m_current_data = p_stream->m_stored_data; 480 p_size -= (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 481 p_stream->m_bytes_in_buffer = 0; 482 } 483 484 while (p_size > 0) { 485 /* we should do an actual skip on the media */ 486 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data); 487 if (l_current_skip_nb_bytes == (OPJ_OFF_T) -1) { 488 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n"); 489 490 p_stream->m_status |= opj_stream_e_end; 491 p_stream->m_byte_offset += l_skip_nb_bytes; 492 /* end if stream */ 493 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1; 494 } 495 p_size -= l_current_skip_nb_bytes; 496 l_skip_nb_bytes += l_current_skip_nb_bytes; 497 } 498 499 p_stream->m_byte_offset += l_skip_nb_bytes; 500 501 return l_skip_nb_bytes; 502 } 503 504 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) 505 { 506 OPJ_BOOL l_is_written = 0; 507 OPJ_OFF_T l_current_skip_nb_bytes = 0; 508 OPJ_OFF_T l_skip_nb_bytes = 0; 509 510 if (p_stream->m_status & opj_stream_e_error) { 511 return (OPJ_OFF_T) -1; 512 } 513 514 /* we should flush data */ 515 l_is_written = opj_stream_flush (p_stream, p_event_mgr); 516 if (! l_is_written) { 517 p_stream->m_status |= opj_stream_e_error; 518 p_stream->m_bytes_in_buffer = 0; 519 return (OPJ_OFF_T) -1; 520 } 521 /* then skip */ 522 523 while (p_size > 0) { 524 /* we should do an actual skip on the media */ 525 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data); 526 527 if (l_current_skip_nb_bytes == (OPJ_OFF_T)-1) { 528 opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n"); 529 530 p_stream->m_status |= opj_stream_e_error; 531 p_stream->m_byte_offset += l_skip_nb_bytes; 532 /* end if stream */ 533 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T)-1; 534 } 535 p_size -= l_current_skip_nb_bytes; 536 l_skip_nb_bytes += l_current_skip_nb_bytes; 537 } 538 539 p_stream->m_byte_offset += l_skip_nb_bytes; 540 541 return l_skip_nb_bytes; 542 } 543 544 OPJ_OFF_T opj_stream_tell (const opj_stream_private_t * p_stream) 545 { 546 return p_stream->m_byte_offset; 547 } 548 549 OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream) 550 { 551 assert( p_stream->m_byte_offset >= 0 ); 552 assert( p_stream->m_user_data_length >= (OPJ_UINT64)p_stream->m_byte_offset); 553 return p_stream->m_user_data_length ? 554 (OPJ_OFF_T)(p_stream->m_user_data_length) - p_stream->m_byte_offset : 555 0; 556 } 557 558 OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr) 559 { 560 assert(p_size >= 0); 561 return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr); 562 } 563 564 OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr) 565 { 566 OPJ_ARG_NOT_USED(p_event_mgr); 567 p_stream->m_current_data = p_stream->m_stored_data; 568 p_stream->m_bytes_in_buffer = 0; 569 570 if( !(p_stream->m_seek_fn(p_size,p_stream->m_user_data)) ) { 571 p_stream->m_status |= opj_stream_e_end; 572 return OPJ_FALSE; 573 } 574 else { 575 /* reset stream status */ 576 p_stream->m_status &= (~opj_stream_e_end); 577 p_stream->m_byte_offset = p_size; 578 579 } 580 581 return OPJ_TRUE; 582 } 583 584 OPJ_BOOL opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr) 585 { 586 if (! opj_stream_flush(p_stream,p_event_mgr)) { 587 p_stream->m_status |= opj_stream_e_error; 588 return OPJ_FALSE; 589 } 590 591 p_stream->m_current_data = p_stream->m_stored_data; 592 p_stream->m_bytes_in_buffer = 0; 593 594 if (! p_stream->m_seek_fn(p_size,p_stream->m_user_data)) { 595 p_stream->m_status |= opj_stream_e_error; 596 return OPJ_FALSE; 597 } 598 else { 599 p_stream->m_byte_offset = p_size; 600 } 601 602 return OPJ_TRUE; 603 } 604 605 OPJ_BOOL opj_stream_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr) 606 { 607 assert(p_size >= 0); 608 return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr); 609 } 610 611 OPJ_BOOL opj_stream_has_seek (const opj_stream_private_t * p_stream) 612 { 613 return p_stream->m_seek_fn != opj_stream_default_seek; 614 } 615 616 OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) 617 { 618 OPJ_ARG_NOT_USED(p_buffer); 619 OPJ_ARG_NOT_USED(p_nb_bytes); 620 OPJ_ARG_NOT_USED(p_user_data); 621 return (OPJ_SIZE_T) -1; 622 } 623 624 OPJ_SIZE_T opj_stream_default_write (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) 625 { 626 OPJ_ARG_NOT_USED(p_buffer); 627 OPJ_ARG_NOT_USED(p_nb_bytes); 628 OPJ_ARG_NOT_USED(p_user_data); 629 return (OPJ_SIZE_T) -1; 630 } 631 632 OPJ_OFF_T opj_stream_default_skip (OPJ_OFF_T p_nb_bytes, void * p_user_data) 633 { 634 OPJ_ARG_NOT_USED(p_nb_bytes); 635 OPJ_ARG_NOT_USED(p_user_data); 636 return (OPJ_OFF_T) -1; 637 } 638 639 OPJ_BOOL opj_stream_default_seek (OPJ_OFF_T p_nb_bytes, void * p_user_data) 640 { 641 OPJ_ARG_NOT_USED(p_nb_bytes); 642 OPJ_ARG_NOT_USED(p_user_data); 643 return OPJ_FALSE; 644 } 645