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