cidx_manager.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * $Id: cidx_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
  3. *
  4. * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
  5. * Copyright (c) 2002-2011, 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 write_cptr(int coff, int clen, opj_cio_t *cio);
  40. /*
  41. * Write main header index table (box)
  42. *
  43. * @param[in] coff offset of j2k codestream
  44. * @param[in] cstr_info codestream information
  45. * @param[in] cio file output handle
  46. * @return length of mainmhix box
  47. */
  48. int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
  49. /*
  50. * Check if EPH option is used
  51. *
  52. * @param[in] coff offset of j2k codestream
  53. * @param[in] markers marker information
  54. * @param[in] marknum number of markers
  55. * @param[in] cio file output handle
  56. * @return true if EPH is used
  57. */
  58. opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio);
  59. int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen)
  60. {
  61. int len, i, lenp;
  62. opj_jp2_box_t *box;
  63. int num_box = 0;
  64. opj_bool EPHused;
  65. (void)image; /* unused ? */
  66. lenp = -1;
  67. box = (opj_jp2_box_t *)opj_calloc( 32, sizeof(opj_jp2_box_t));
  68. for (i=0;i<2;i++){
  69. if(i)
  70. cio_seek( cio, lenp);
  71. lenp = cio_tell( cio);
  72. cio_skip( cio, 4); /* L [at the end] */
  73. cio_write( cio, JPIP_CIDX, 4); /* CIDX */
  74. write_cptr( offset, cstr_info.codestream_size, cio);
  75. write_manf( i, num_box, box, cio);
  76. num_box = 0;
  77. box[num_box].length = write_mainmhix( offset, cstr_info, cio);
  78. box[num_box].type = JPIP_MHIX;
  79. num_box++;
  80. box[num_box].length = write_tpix( offset, cstr_info, j2klen, cio);
  81. box[num_box].type = JPIP_TPIX;
  82. num_box++;
  83. box[num_box].length = write_thix( offset, cstr_info, cio);
  84. box[num_box].type = JPIP_THIX;
  85. num_box++;
  86. EPHused = check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio);
  87. box[num_box].length = write_ppix( offset, cstr_info, EPHused, j2klen, cio);
  88. box[num_box].type = JPIP_PPIX;
  89. num_box++;
  90. box[num_box].length = write_phix( offset, cstr_info, EPHused, j2klen, cio);
  91. box[num_box].type = JPIP_PHIX;
  92. num_box++;
  93. len = cio_tell( cio)-lenp;
  94. cio_seek( cio, lenp);
  95. cio_write( cio, len, 4); /* L */
  96. cio_seek( cio, lenp+len);
  97. }
  98. opj_free( box);
  99. return len;
  100. }
  101. void write_cptr(int coff, int clen, opj_cio_t *cio)
  102. {
  103. int len, lenp;
  104. lenp = cio_tell( cio);
  105. cio_skip( cio, 4); /* L [at the end] */
  106. cio_write( cio, JPIP_CPTR, 4); /* T */
  107. cio_write( cio, 0, 2); /* DR A PRECISER !! */
  108. cio_write( cio, 0, 2); /* CONT */
  109. cio_write( cio, coff, 8); /* COFF A PRECISER !! */
  110. cio_write( cio, clen, 8); /* CLEN */
  111. len = cio_tell( cio) - lenp;
  112. cio_seek( cio, lenp);
  113. cio_write( cio, len, 4); /* L */
  114. cio_seek( cio, lenp+len);
  115. }
  116. void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio)
  117. {
  118. int len, lenp, i;
  119. lenp = cio_tell( cio);
  120. cio_skip( cio, 4); /* L [at the end] */
  121. cio_write( cio, JPIP_MANF,4); /* T */
  122. if (second){ /* Write only during the second pass */
  123. for( i=0; i<v; i++){
  124. cio_write( cio, box[i].length, 4); /* Box length */
  125. cio_write( cio, box[i].type, 4); /* Box type */
  126. }
  127. }
  128. len = cio_tell( cio) - lenp;
  129. cio_seek( cio, lenp);
  130. cio_write( cio, len, 4); /* L */
  131. cio_seek( cio, lenp+len);
  132. }
  133. int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio)
  134. {
  135. int i;
  136. int len, lenp;
  137. lenp = cio_tell( cio);
  138. cio_skip( cio, 4); /* L [at the end] */
  139. cio_write( cio, JPIP_MHIX, 4); /* MHIX */
  140. cio_write( cio, cstr_info.main_head_end-cstr_info.main_head_start+1, 8); /* TLEN */
  141. for(i = 1; i < cstr_info.marknum; i++){ /* Marker restricted to 1 apparition, skip SOC marker */
  142. cio_write( cio, cstr_info.marker[i].type, 2);
  143. cio_write( cio, 0, 2);
  144. cio_write( cio, cstr_info.marker[i].pos-coff, 8);
  145. cio_write( cio, cstr_info.marker[i].len, 2);
  146. }
  147. len = cio_tell( cio) - lenp;
  148. cio_seek( cio, lenp);
  149. cio_write( cio, len, 4); /* L */
  150. cio_seek( cio, lenp+len);
  151. return len;
  152. }
  153. opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio)
  154. {
  155. opj_bool EPHused = OPJ_FALSE;
  156. int i=0;
  157. int org_pos;
  158. unsigned int Scod;
  159. for(i = 0; i < marknum; i++){
  160. if( markers[i].type == J2K_MS_COD){
  161. org_pos = cio_tell( cio);
  162. cio_seek( cio, coff+markers[i].pos+2);
  163. Scod = cio_read( cio, 1);
  164. if( ((Scod >> 2) & 1))
  165. EPHused = OPJ_TRUE;
  166. cio_seek( cio, org_pos);
  167. break;
  168. }
  169. }
  170. return EPHused;
  171. }