cio.c 24 KB

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