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) + 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+4-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_malloc(sizeof(opj_stream_private_t)); 155 if (! l_stream) { 156 return 00; 157 } 158 159 memset(l_stream,0,sizeof(opj_stream_private_t)); 160 l_stream->m_buffer_size = p_buffer_size; 161 l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_buffer_size); 162 if (! l_stream->m_stored_data) { 163 opj_free(l_stream); 164 return 00; 165 } 166 167 l_stream->m_current_data = l_stream->m_stored_data; 168 169 if (l_is_input) { 170 l_stream->m_status |= opj_stream_e_input; 171 l_stream->m_opj_skip = opj_stream_read_skip; 172 l_stream->m_opj_seek = opj_stream_read_seek; 173 } 174 else { 175 l_stream->m_status |= opj_stream_e_output; 176 l_stream->m_opj_skip = opj_stream_write_skip; 177 l_stream->m_opj_seek = opj_stream_write_seek; 178 } 179 180 l_stream->m_read_fn = opj_stream_default_read; 181 l_stream->m_write_fn = opj_stream_default_write; 182 l_stream->m_skip_fn = opj_stream_default_skip; 183 l_stream->m_seek_fn = opj_stream_default_seek; 184 185 return (opj_stream_t *) l_stream; 186 } 187 188 opj_stream_t* OPJ_CALLCONV opj_stream_default_create(OPJ_BOOL l_is_input) 189 { 190 return opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE,l_is_input); 191 } 192 193 void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream) 194 { 195 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 196 197 if (l_stream) { 198 if (l_stream->m_free_user_data_fn) { 199 l_stream->m_free_user_data_fn(l_stream->m_user_data); 200 } 201 opj_free(l_stream->m_stored_data); 202 l_stream->m_stored_data = 00; 203 opj_free(l_stream); 204 } 205 } 206 207 void OPJ_CALLCONV opj_stream_destroy_v3(opj_stream_t* p_stream) 208 { 209 opj_stream_destroy(p_stream); 210 } 211 212 void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function) 213 { 214 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 215 216 if ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input))) { 217 return; 218 } 219 220 l_stream->m_read_fn = p_function; 221 } 222 223 void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function) 224 { 225 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 226 227 if (!l_stream) { 228 return; 229 } 230 l_stream->m_seek_fn = p_function; 231 } 232 233 void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function) 234 { 235 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 236 237 if ((!l_stream )|| (! (l_stream->m_status & opj_stream_e_output))) { 238 return; 239 } 240 241 l_stream->m_write_fn = p_function; 242 } 243 244 void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function) 245 { 246 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 247 248 if (! l_stream) { 249 return; 250 } 251 252 l_stream->m_skip_fn = p_function; 253 } 254 255 void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data) 256 { 257 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 258 if (!l_stream) 259 return; 260 l_stream->m_user_data = p_data; 261 } 262 263 void OPJ_CALLCONV opj_stream_set_user_data_v3(opj_stream_t* p_stream, void * p_data, opj_stream_free_user_data_fn p_function) 264 { 265 opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; 266 if (!l_stream) 267 return; 268 l_stream->m_user_data = p_data; 269 l_stream->m_free_user_data_fn = p_function; 270 } 271 272 void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, 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 l_stream->m_user_data_length = data_length; 278 } 279 280 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) 281 { 282 OPJ_SIZE_T l_read_nb_bytes = 0; 283 if (p_stream->m_bytes_in_buffer >= p_size) { 284 memcpy(p_buffer,p_stream->m_current_data,p_size); 285 p_stream->m_current_data += p_size; 286 p_stream->m_bytes_in_buffer -= p_size; 287 l_read_nb_bytes += p_size; 288 p_stream->m_byte_offset += (OPJ_OFF_T)p_size; 289 return l_read_nb_bytes; 290 } 291 292 /* we are now in the case when the remaining data if not sufficient */ 293 if (p_stream->m_status & opj_stream_e_end) { 294 l_read_nb_bytes += p_stream->m_bytes_in_buffer; 295 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer); 296 p_stream->m_current_data += p_stream->m_bytes_in_buffer; 297 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 298 p_stream->m_bytes_in_buffer = 0; 299 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1; 300 } 301 302 /* the flag is not set, we copy data and then do an actual read on the stream */ 303 if (p_stream->m_bytes_in_buffer) { 304 l_read_nb_bytes += p_stream->m_bytes_in_buffer; 305 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer); 306 p_stream->m_current_data = p_stream->m_stored_data; 307 p_buffer += p_stream->m_bytes_in_buffer; 308 p_size -= p_stream->m_bytes_in_buffer; 309 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 310 p_stream->m_bytes_in_buffer = 0; 311 } 312 else { 313 /* case where we are already at the end of the buffer 314 so reset the m_current_data to point to the start of the 315 stored buffer to get ready to read from disk*/ 316 p_stream->m_current_data = p_stream->m_stored_data; 317 } 318 319 while(1){ 320 /* we should read less than a chunk -> read a chunk */ 321 if (p_size < p_stream->m_buffer_size) { 322 /* we should do an actual read on the media */ 323 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); 324 325 if (p_stream->m_bytes_in_buffer == (OPJ_SIZE_T)-1) { 326 /* end of stream */ 327 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n"); 328 329 p_stream->m_bytes_in_buffer = 0; 330 p_stream->m_status |= opj_stream_e_end; 331 /* end of stream */ 332 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1; 333 } 334 else if (p_stream->m_bytes_in_buffer < p_size) { 335 /* not enough data */ 336 l_read_nb_bytes += p_stream->m_bytes_in_buffer; 337 memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer); 338 p_stream->m_current_data = p_stream->m_stored_data; 339 p_buffer += p_stream->m_bytes_in_buffer; 340 p_size -= p_stream->m_bytes_in_buffer; 341 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 342 p_stream->m_bytes_in_buffer = 0; 343 } 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 } 353 else { 354 /* direct read on the dest buffer */ 355 p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,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_e_end; 363 /* end of stream */ 364 return l_read_nb_bytes ? l_read_nb_bytes : (OPJ_SIZE_T)-1; 365 } 366 else if (p_stream->m_bytes_in_buffer < p_size) { 367 /* not enough data */ 368 l_read_nb_bytes += p_stream->m_bytes_in_buffer; 369 p_stream->m_current_data = p_stream->m_stored_data; 370 p_buffer += p_stream->m_bytes_in_buffer; 371 p_size -= p_stream->m_bytes_in_buffer; 372 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 373 p_stream->m_bytes_in_buffer = 0; 374 } 375 else { 376 /* we have read the exact size */ 377 l_read_nb_bytes += p_stream->m_bytes_in_buffer; 378 p_stream->m_byte_offset += (OPJ_OFF_T)p_stream->m_bytes_in_buffer; 379 p_stream->m_current_data = p_stream->m_stored_data; 380 p_stream->m_bytes_in_buffer = 0; 381 return l_read_nb_bytes; 382 } 383 } 384 } 385 } 386 387 OPJ_SIZE_T opj_stream_write_data (opj_stream_private_t * p_stream, 388 const OPJ_BYTE * p_buffer, 389 OPJ_SIZE_T p_size, 390 opj_event_mgr_t * p_event_mgr) 391 { 392 OPJ_SIZE_T l_remaining_bytes = 0; 393 OPJ_SIZE_T l_write_nb_bytes = 0; 394 395 if (p_stream->m_status & opj_stream_e_error) { 396 return (OPJ_SIZE_T)-1; 397 } 398 399 while(1) { 400 l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer; 401 402 /* we have more memory than required */ 403 if (l_remaining_bytes >= p_size) { 404 memcpy(p_stream->m_current_data, p_buffer, p_size); 405 406 p_stream->m_current_data += p_size; 407 p_stream->m_bytes_in_buffer += p_size; 408 l_write_nb_bytes += p_size; 409 p_stream->m_byte_offset += (OPJ_OFF_T)p_size; 410 411 return l_write_nb_bytes; 412 } 413 414 /* we copy data and then do an actual read on the stream */ 415 if (l_remaining_bytes) { 416 l_write_nb_bytes += l_remaining_bytes; 417 418 memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes); 419 420 p_stream->m_current_data = p_stream->m_stored_data; 421 422 p_buffer += l_remaining_bytes; 423 p_size -= l_remaining_bytes; 424 p_stream->m_bytes_in_buffer += l_remaining_bytes; 425 p_stream->m_byte_offset += (OPJ_OFF_T)l_remaining_bytes; 426 } 427 428 if (! opj_stream_flush(p_stream, p_event_mgr)) { 429 return (OPJ_SIZE_T)-1; 430 } 431 } 432 433 } 434 435 OPJ_BOOL opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr) 436 { 437 /* the number of bytes written on the media. */ 438 OPJ_SIZE_T l_current_write_nb_bytes = 0; 439 440 p_stream->m_current_data = p_stream->m_stored_data; 441 442 while (p_stream->m_bytes_in_buffer) { 443 /* we should do an actual write on the media */ 444 l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data, 445 p_stream->m_bytes_in_buffer, 446 p_stream->m_user_data); 447 448 if (l_current_write_nb_bytes == (OPJ_SIZE_T)-1) { 449 p_stream->m_status |= opj_stream_e_error; 450 opj_event_msg(p_event_mgr, EVT_INFO, "Error on writing stream!\n"); 451 452 return OPJ_FALSE; 453 } 454 455 p_stream->m_current_data += l_current_write_nb_bytes; 456 p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes; 457 } 458 459 p_stream->m_current_data = p_stream->m_stored_data; 460 461 return OPJ_TRUE; 462 } 463 464 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) 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_e_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 /* we should do an actual skip on the media */ 500 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data); 501 if (l_current_skip_nb_bytes == (OPJ_OFF_T) -1) { 502 opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n"); 503 504 p_stream->m_status |= opj_stream_e_end; 505 p_stream->m_byte_offset += l_skip_nb_bytes; 506 /* end if stream */ 507 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) -1; 508 } 509 p_size -= l_current_skip_nb_bytes; 510 l_skip_nb_bytes += l_current_skip_nb_bytes; 511 } 512 513 p_stream->m_byte_offset += l_skip_nb_bytes; 514 515 return l_skip_nb_bytes; 516 } 517 518 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) 519 { 520 OPJ_BOOL l_is_written = 0; 521 OPJ_OFF_T l_current_skip_nb_bytes = 0; 522 OPJ_OFF_T l_skip_nb_bytes = 0; 523 524 if (p_stream->m_status & opj_stream_e_error) { 525 return (OPJ_OFF_T) -1; 526 } 527 528 /* we should flush data */ 529 l_is_written = opj_stream_flush (p_stream, p_event_mgr); 530 if (! l_is_written) { 531 p_stream->m_status |= opj_stream_e_error; 532 p_stream->m_bytes_in_buffer = 0; 533 return (OPJ_OFF_T) -1; 534 } 535 /* then skip */ 536 537 while (p_size > 0) { 538 /* we should do an actual skip on the media */ 539 l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data); 540 541 if (l_current_skip_nb_bytes == (OPJ_OFF_T)-1) { 542 opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n"); 543 544 p_stream->m_status |= opj_stream_e_error; 545 p_stream->m_byte_offset += l_skip_nb_bytes; 546 /* end if stream */ 547 return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T)-1; 548 } 549 p_size -= l_current_skip_nb_bytes; 550 l_skip_nb_bytes += l_current_skip_nb_bytes; 551 } 552 553 p_stream->m_byte_offset += l_skip_nb_bytes; 554 555 return l_skip_nb_bytes; 556 } 557 558 OPJ_OFF_T opj_stream_tell (const opj_stream_private_t * p_stream) 559 { 560 return p_stream->m_byte_offset; 561 } 562 563 OPJ_OFF_T opj_stream_get_number_byte_left (const opj_stream_private_t * p_stream) 564 { 565 assert( p_stream->m_byte_offset >= 0 ); 566 assert( p_stream->m_user_data_length >= (OPJ_UINT64)p_stream->m_byte_offset); 567 return p_stream->m_user_data_length ? 568 (OPJ_OFF_T)(p_stream->m_user_data_length) - p_stream->m_byte_offset : 569 0; 570 } 571 572 OPJ_OFF_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr) 573 { 574 assert(p_size >= 0); 575 return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr); 576 } 577 578 OPJ_BOOL opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr) 579 { 580 OPJ_ARG_NOT_USED(p_event_mgr); 581 p_stream->m_current_data = p_stream->m_stored_data; 582 p_stream->m_bytes_in_buffer = 0; 583 584 if( !(p_stream->m_seek_fn(p_size,p_stream->m_user_data)) ) { 585 p_stream->m_status |= opj_stream_e_end; 586 return OPJ_FALSE; 587 } 588 else { 589 /* reset stream status */ 590 p_stream->m_status &= (~opj_stream_e_end); 591 p_stream->m_byte_offset = p_size; 592 593 } 594 595 return OPJ_TRUE; 596 } 597 598 OPJ_BOOL opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, opj_event_mgr_t * p_event_mgr) 599 { 600 if (! opj_stream_flush(p_stream,p_event_mgr)) { 601 p_stream->m_status |= opj_stream_e_error; 602 return OPJ_FALSE; 603 } 604 605 p_stream->m_current_data = p_stream->m_stored_data; 606 p_stream->m_bytes_in_buffer = 0; 607 608 if (! p_stream->m_seek_fn(p_size,p_stream->m_user_data)) { 609 p_stream->m_status |= opj_stream_e_error; 610 return OPJ_FALSE; 611 } 612 else { 613 p_stream->m_byte_offset = p_size; 614 } 615 616 return OPJ_TRUE; 617 } 618 619 OPJ_BOOL opj_stream_seek (opj_stream_private_t * p_stream, OPJ_OFF_T p_size, struct opj_event_mgr * p_event_mgr) 620 { 621 assert(p_size >= 0); 622 return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr); 623 } 624 625 OPJ_BOOL opj_stream_has_seek (const opj_stream_private_t * p_stream) 626 { 627 return p_stream->m_seek_fn != opj_stream_default_seek; 628 } 629 630 OPJ_SIZE_T opj_stream_default_read (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) 631 { 632 OPJ_ARG_NOT_USED(p_buffer); 633 OPJ_ARG_NOT_USED(p_nb_bytes); 634 OPJ_ARG_NOT_USED(p_user_data); 635 return (OPJ_SIZE_T) -1; 636 } 637 638 OPJ_SIZE_T opj_stream_default_write (void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) 639 { 640 OPJ_ARG_NOT_USED(p_buffer); 641 OPJ_ARG_NOT_USED(p_nb_bytes); 642 OPJ_ARG_NOT_USED(p_user_data); 643 return (OPJ_SIZE_T) -1; 644 } 645 646 OPJ_OFF_T opj_stream_default_skip (OPJ_OFF_T p_nb_bytes, void * p_user_data) 647 { 648 OPJ_ARG_NOT_USED(p_nb_bytes); 649 OPJ_ARG_NOT_USED(p_user_data); 650 return (OPJ_OFF_T) -1; 651 } 652 653 OPJ_BOOL opj_stream_default_seek (OPJ_OFF_T p_nb_bytes, void * p_user_data) 654 { 655 OPJ_ARG_NOT_USED(p_nb_bytes); 656 OPJ_ARG_NOT_USED(p_user_data); 657 return OPJ_FALSE; 658 } 659