Coverage Report

Created: 2023-12-08 06:53

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