cidx_manager.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. * $Id: cidx_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
  3. *
  4. * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
  5. * Copyright (c) 2002-2014, Professor Benoit Macq
  6. * Copyright (c) 2003-2004, Yannick Verschueren
  7. * Copyright (c) 2010-2011, Kaori Hagihara
  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. #include "opj_includes.h"
  32. /*
  33. * Write CPTR Codestream finder box
  34. *
  35. * @param[in] coff offset of j2k codestream
  36. * @param[in] clen length of j2k codestream
  37. * @param[in] cio file output handle
  38. */
  39. void opj_write_cptr(int coff, int clen, opj_stream_private_t *cio,
  40. opj_event_mgr_t * p_manager);
  41. int opj_write_cidx(int offset, opj_stream_private_t *cio,
  42. opj_codestream_info_t cstr_info, int j2klen,
  43. opj_event_mgr_t * p_manager)
  44. {
  45. int i;
  46. OPJ_OFF_T lenp;
  47. OPJ_UINT32 len;
  48. opj_jp2_box_t *box;
  49. int num_box = 0;
  50. OPJ_BOOL EPHused;
  51. OPJ_BYTE l_data_header [4];
  52. lenp = -1;
  53. box = (opj_jp2_box_t *)opj_calloc(32, sizeof(opj_jp2_box_t));
  54. if (box == NULL) {
  55. return 0;
  56. }
  57. for (i = 0; i < 2; i++) {
  58. if (i) {
  59. opj_stream_seek(cio, lenp, p_manager);
  60. }
  61. lenp = opj_stream_tell(cio);
  62. opj_stream_skip(cio, 4, p_manager); /* L [at the end] */
  63. opj_write_bytes(l_data_header, JPIP_CIDX, 4); /* CIDX */
  64. opj_stream_write_data(cio, l_data_header, 4, p_manager);
  65. opj_write_cptr(offset, cstr_info.codestream_size, cio, p_manager);
  66. opj_write_manf(i, num_box, box, cio, p_manager);
  67. num_box = 0;
  68. box[num_box].length = (OPJ_UINT32)opj_write_mainmhix(offset, cstr_info, cio,
  69. p_manager);
  70. box[num_box].type = JPIP_MHIX;
  71. num_box++;
  72. box[num_box].length = (OPJ_UINT32)opj_write_tpix(offset, cstr_info, j2klen, cio,
  73. p_manager);
  74. box[num_box].type = JPIP_TPIX;
  75. num_box++;
  76. box[num_box].length = (OPJ_UINT32)opj_write_thix(offset, cstr_info, cio,
  77. p_manager);
  78. box[num_box].type = JPIP_THIX;
  79. num_box++;
  80. EPHused = opj_check_EPHuse(offset, cstr_info.marker, cstr_info.marknum, cio,
  81. p_manager);
  82. box[num_box].length = (OPJ_UINT32)opj_write_ppix(offset, cstr_info, EPHused,
  83. j2klen, cio, p_manager);
  84. box[num_box].type = JPIP_PPIX;
  85. num_box++;
  86. box[num_box].length = (OPJ_UINT32)opj_write_phix(offset, cstr_info, EPHused,
  87. j2klen, cio, p_manager);
  88. box[num_box].type = JPIP_PHIX;
  89. num_box++;
  90. len = (OPJ_UINT32)(opj_stream_tell(cio) - lenp);
  91. opj_stream_seek(cio, lenp, p_manager);
  92. opj_write_bytes(l_data_header, len, 4); /* L */
  93. opj_stream_write_data(cio, l_data_header, 4, p_manager);
  94. opj_stream_seek(cio, lenp + len, p_manager);
  95. }
  96. opj_free(box);
  97. return (int)len;
  98. }
  99. void opj_write_cptr(int coff, int clen, opj_stream_private_t *cio,
  100. opj_event_mgr_t * p_manager)
  101. {
  102. OPJ_BYTE l_data_header [3 * 8];
  103. OPJ_UINT32 len;
  104. OPJ_OFF_T lenp;
  105. lenp = opj_stream_tell(cio);
  106. opj_stream_skip(cio, 4, p_manager); /* L [at the end] */
  107. opj_write_bytes(l_data_header, JPIP_CPTR, 4); /* T */
  108. opj_write_bytes(l_data_header + 4, 0, 2); /* DR A PRECISER !! */
  109. opj_write_bytes(l_data_header + 6, 0, 2); /* CONT */
  110. opj_write_bytes(l_data_header + 8, (OPJ_UINT32)coff,
  111. 8); /* COFF A PRECISER !! */
  112. opj_write_bytes(l_data_header + 16, (OPJ_UINT32)clen,
  113. 8); /* CLEN */
  114. opj_stream_write_data(cio, l_data_header, 3 * 8, p_manager);
  115. len = (OPJ_UINT32)(opj_stream_tell(cio) - lenp);
  116. opj_stream_seek(cio, lenp, p_manager);
  117. opj_write_bytes(l_data_header, len, 4); /* L */
  118. opj_stream_write_data(cio, l_data_header, 4, p_manager);
  119. opj_stream_seek(cio, lenp + len, p_manager);
  120. }
  121. void opj_write_manf(int second,
  122. int v,
  123. opj_jp2_box_t *box,
  124. opj_stream_private_t *cio,
  125. opj_event_mgr_t * p_manager)
  126. {
  127. OPJ_BYTE l_data_header [4];
  128. int i;
  129. OPJ_UINT32 len;
  130. OPJ_OFF_T lenp;
  131. lenp = opj_stream_tell(cio);
  132. opj_stream_skip(cio, 4, p_manager); /* L [at the end] */
  133. opj_write_bytes(l_data_header, JPIP_MANF, 4); /* T */
  134. opj_stream_write_data(cio, l_data_header, 4, p_manager);
  135. if (second) { /* Write only during the second pass */
  136. for (i = 0; i < v; i++) {
  137. opj_write_bytes(l_data_header, box[i].length,
  138. 4); /* Box length */
  139. opj_stream_write_data(cio, l_data_header, 4, p_manager);
  140. opj_write_bytes(l_data_header, box[i].type,
  141. 4); /* Box type */
  142. opj_stream_write_data(cio, l_data_header, 4, p_manager);
  143. }
  144. }
  145. len = (OPJ_UINT32)(opj_stream_tell(cio) - lenp);
  146. opj_stream_seek(cio, lenp, p_manager);
  147. opj_write_bytes(l_data_header, len, 4);/* L */
  148. opj_stream_write_data(cio, l_data_header, 4, p_manager);
  149. opj_stream_seek(cio, lenp + len, p_manager);
  150. }
  151. int opj_write_mainmhix(int coff, opj_codestream_info_t cstr_info,
  152. opj_stream_private_t *cio,
  153. opj_event_mgr_t * p_manager)
  154. {
  155. OPJ_BYTE l_data_header [8];
  156. OPJ_UINT32 i;
  157. OPJ_UINT32 len;
  158. OPJ_OFF_T lenp;
  159. lenp = opj_stream_tell(cio);
  160. opj_stream_skip(cio, 4,
  161. p_manager); /* L [at the end] */
  162. opj_write_bytes(l_data_header, JPIP_MHIX,
  163. 4); /* MHIX */
  164. opj_stream_write_data(cio, l_data_header, 4, p_manager);
  165. opj_write_bytes(l_data_header,
  166. (OPJ_UINT32)(cstr_info.main_head_end - cstr_info.main_head_start + 1),
  167. 8); /* TLEN */
  168. opj_stream_write_data(cio, l_data_header, 8, p_manager);
  169. for (i = 1; i < (OPJ_UINT32)cstr_info.marknum;
  170. i++) { /* Marker restricted to 1 apparition, skip SOC marker */
  171. opj_write_bytes(l_data_header, cstr_info.marker[i].type, 2);
  172. opj_write_bytes(l_data_header + 2, 0, 2);
  173. opj_stream_write_data(cio, l_data_header, 4, p_manager);
  174. opj_write_bytes(l_data_header, (OPJ_UINT32)(cstr_info.marker[i].pos - coff), 8);
  175. opj_stream_write_data(cio, l_data_header, 8, p_manager);
  176. opj_write_bytes(l_data_header, (OPJ_UINT32)cstr_info.marker[i].len, 2);
  177. opj_stream_write_data(cio, l_data_header, 2, p_manager);
  178. }
  179. len = (OPJ_UINT32)(opj_stream_tell(cio) - lenp);
  180. opj_stream_seek(cio, lenp, p_manager);
  181. opj_write_bytes(l_data_header, len, 4); /* L */
  182. opj_stream_write_data(cio, l_data_header, 4, p_manager);
  183. opj_stream_seek(cio, lenp + len, p_manager);
  184. return (int)len;
  185. }
  186. OPJ_BOOL opj_check_EPHuse(int coff, opj_marker_info_t *markers, int marknum,
  187. opj_stream_private_t *cio,
  188. opj_event_mgr_t * p_manager)
  189. {
  190. OPJ_BYTE l_data_header [4];
  191. OPJ_BOOL EPHused = OPJ_FALSE;
  192. int i = 0;
  193. OPJ_OFF_T org_pos;
  194. unsigned int Scod;
  195. for (i = 0; i < marknum; i++) {
  196. if (markers[i].type == J2K_MS_COD) {
  197. org_pos = opj_stream_tell(cio);
  198. opj_stream_seek(cio, coff + markers[i].pos + 2, p_manager);
  199. opj_stream_read_data(cio, l_data_header, 1, p_manager);
  200. opj_read_bytes(l_data_header, &Scod, 1);
  201. if (((Scod >> 2) & 1)) {
  202. EPHused = OPJ_TRUE;
  203. }
  204. opj_stream_seek(cio, org_pos, p_manager);
  205. break;
  206. }
  207. }
  208. return EPHused;
  209. }