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