Reformat whole codebase with astyle.options (#128)
[openjpeg.git] / src / lib / openjp2 / cidx_manager.c
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
32 #include "opj_includes.h"
33
34
35 /*
36  * Write CPTR Codestream finder box
37  *
38  * @param[in] coff offset of j2k codestream
39  * @param[in] clen length of j2k codestream
40  * @param[in] cio  file output handle
41  */
42
43 void opj_write_cptr(int coff, int clen, opj_stream_private_t *cio,
44                     opj_event_mgr_t * p_manager);
45
46
47
48
49
50 int opj_write_cidx(int offset, opj_stream_private_t *cio,
51                    opj_codestream_info_t cstr_info, int j2klen,
52                    opj_event_mgr_t * p_manager)
53 {
54     int i;
55     OPJ_OFF_T lenp;
56     OPJ_UINT32 len;
57     opj_jp2_box_t *box;
58     int num_box = 0;
59     OPJ_BOOL  EPHused;
60     OPJ_BYTE l_data_header [4];
61
62     lenp = -1;
63     box = (opj_jp2_box_t *)opj_calloc(32, sizeof(opj_jp2_box_t));
64     if (box == NULL) {
65         return 0;
66     }
67     for (i = 0; i < 2; i++) {
68
69         if (i) {
70             opj_stream_seek(cio, lenp, p_manager);
71         }
72
73
74         lenp = opj_stream_tell(cio);
75
76         opj_stream_skip(cio, 4, p_manager); /* L [at the end] */
77
78         opj_write_bytes(l_data_header, JPIP_CIDX, 4); /* CIDX */
79         opj_stream_write_data(cio, l_data_header, 4, p_manager);
80
81         opj_write_cptr(offset, cstr_info.codestream_size, cio, p_manager);
82
83         opj_write_manf(i, num_box, box, cio, p_manager);
84
85         num_box = 0;
86         box[num_box].length = (OPJ_UINT32)opj_write_mainmhix(offset, cstr_info, cio,
87                               p_manager);
88         box[num_box].type = JPIP_MHIX;
89         num_box++;
90
91         box[num_box].length = (OPJ_UINT32)opj_write_tpix(offset, cstr_info, j2klen, cio,
92                               p_manager);
93         box[num_box].type = JPIP_TPIX;
94         num_box++;
95
96         box[num_box].length = (OPJ_UINT32)opj_write_thix(offset, cstr_info, cio,
97                               p_manager);
98         box[num_box].type = JPIP_THIX;
99         num_box++;
100
101         EPHused = opj_check_EPHuse(offset, cstr_info.marker, cstr_info.marknum, cio,
102                                    p_manager);
103
104         box[num_box].length = (OPJ_UINT32)opj_write_ppix(offset, cstr_info, EPHused,
105                               j2klen, cio, p_manager);
106         box[num_box].type = JPIP_PPIX;
107         num_box++;
108
109         box[num_box].length = (OPJ_UINT32)opj_write_phix(offset, cstr_info, EPHused,
110                               j2klen, cio, p_manager);
111         box[num_box].type = JPIP_PHIX;
112         num_box++;
113
114         len = (OPJ_UINT32)(opj_stream_tell(cio) - lenp);
115         opj_stream_seek(cio, lenp, p_manager);
116         opj_write_bytes(l_data_header, len, 4); /* L  */
117         opj_stream_write_data(cio, l_data_header, 4, p_manager);
118         opj_stream_seek(cio, lenp + len, p_manager);
119     }
120
121     opj_free(box);
122
123     return (int)len;
124 }
125
126
127
128 void opj_write_cptr(int coff, int clen, opj_stream_private_t *cio,
129                     opj_event_mgr_t * p_manager)
130 {
131     OPJ_BYTE l_data_header [3 * 8];
132     OPJ_UINT32 len;
133     OPJ_OFF_T lenp;
134
135
136     lenp = opj_stream_tell(cio);
137     opj_stream_skip(cio, 4, p_manager);                /* L [at the end]     */
138     opj_write_bytes(l_data_header, JPIP_CPTR, 4);    /* T                  */
139     opj_write_bytes(l_data_header + 4, 0, 2);          /* DR  A PRECISER !!  */
140     opj_write_bytes(l_data_header + 6, 0, 2);          /* CONT               */
141     opj_write_bytes(l_data_header + 8, (OPJ_UINT32)coff,
142                     8);   /* COFF A PRECISER !! */
143     opj_write_bytes(l_data_header + 16, (OPJ_UINT32)clen,
144                     8);   /* CLEN               */
145     opj_stream_write_data(cio, l_data_header, 3 * 8, p_manager);
146
147     len = (OPJ_UINT32)(opj_stream_tell(cio) - lenp);
148     opj_stream_seek(cio, lenp, p_manager);
149     opj_write_bytes(l_data_header, len, 4);         /* L                  */
150     opj_stream_write_data(cio, l_data_header, 4, p_manager);
151     opj_stream_seek(cio, lenp + len, p_manager);
152
153 }
154
155
156
157 void opj_write_manf(int second,
158                     int v,
159                     opj_jp2_box_t *box,
160                     opj_stream_private_t *cio,
161                     opj_event_mgr_t * p_manager)
162 {
163     OPJ_BYTE l_data_header [4];
164     int i;
165     OPJ_UINT32 len;
166     OPJ_OFF_T lenp;
167
168     lenp = opj_stream_tell(cio);
169     opj_stream_skip(cio, 4, p_manager);              /* L [at the end]     */
170     opj_write_bytes(l_data_header, JPIP_MANF, 4);    /* T                  */
171     opj_stream_write_data(cio, l_data_header, 4, p_manager);
172
173     if (second) {                         /* Write only during the second pass */
174         for (i = 0; i < v; i++) {
175             opj_write_bytes(l_data_header, box[i].length,
176                             4);  /* Box length                     */
177             opj_stream_write_data(cio, l_data_header, 4, p_manager);
178             opj_write_bytes(l_data_header, box[i].type,
179                             4);  /* Box type                       */
180             opj_stream_write_data(cio, l_data_header, 4, p_manager);
181         }
182     }
183
184     len = (OPJ_UINT32)(opj_stream_tell(cio) - lenp);
185     opj_stream_seek(cio, lenp, p_manager);
186     opj_write_bytes(l_data_header, len, 4);/* L                                 */
187     opj_stream_write_data(cio, l_data_header, 4, p_manager);
188     opj_stream_seek(cio, lenp + len, p_manager);
189 }
190
191
192 int opj_write_mainmhix(int coff, opj_codestream_info_t cstr_info,
193                        opj_stream_private_t *cio,
194                        opj_event_mgr_t * p_manager)
195 {
196     OPJ_BYTE l_data_header [8];
197     OPJ_UINT32 i;
198     OPJ_UINT32 len;
199     OPJ_OFF_T lenp;
200
201     lenp = opj_stream_tell(cio);
202     opj_stream_skip(cio, 4,
203                     p_manager);               /* L [at the end]                    */
204     opj_write_bytes(l_data_header, JPIP_MHIX,
205                     4);     /* MHIX                              */
206     opj_stream_write_data(cio, l_data_header, 4, p_manager);
207
208     opj_write_bytes(l_data_header,
209                     (OPJ_UINT32)(cstr_info.main_head_end - cstr_info.main_head_start + 1),
210                     8);        /* TLEN                              */
211     opj_stream_write_data(cio, l_data_header, 8, p_manager);
212
213     for (i = 1; i < (OPJ_UINT32)cstr_info.marknum;
214             i++) {  /* Marker restricted to 1 apparition, skip SOC marker */
215         opj_write_bytes(l_data_header, cstr_info.marker[i].type, 2);
216         opj_write_bytes(l_data_header + 2, 0, 2);
217         opj_stream_write_data(cio, l_data_header, 4, p_manager);
218         opj_write_bytes(l_data_header, (OPJ_UINT32)(cstr_info.marker[i].pos - coff), 8);
219         opj_stream_write_data(cio, l_data_header, 8, p_manager);
220         opj_write_bytes(l_data_header, (OPJ_UINT32)cstr_info.marker[i].len, 2);
221         opj_stream_write_data(cio, l_data_header, 2, p_manager);
222     }
223
224     len = (OPJ_UINT32)(opj_stream_tell(cio) - lenp);
225     opj_stream_seek(cio, lenp, p_manager);
226     opj_write_bytes(l_data_header, len, 4); /* L  */
227     opj_stream_write_data(cio, l_data_header, 4, p_manager);
228     opj_stream_seek(cio, lenp + len, p_manager);
229
230     return (int)len;
231 }
232
233 OPJ_BOOL opj_check_EPHuse(int coff, opj_marker_info_t *markers, int marknum,
234                           opj_stream_private_t *cio,
235                           opj_event_mgr_t * p_manager)
236 {
237     OPJ_BYTE l_data_header [4];
238     OPJ_BOOL EPHused = OPJ_FALSE;
239     int i = 0;
240     OPJ_OFF_T org_pos;
241     unsigned int Scod;
242
243     for (i = 0; i < marknum; i++) {
244         if (markers[i].type == J2K_MS_COD) {
245             org_pos = opj_stream_tell(cio);
246             opj_stream_seek(cio, coff + markers[i].pos + 2, p_manager);
247
248             opj_stream_read_data(cio, l_data_header, 1, p_manager);
249             opj_read_bytes(l_data_header, &Scod, 1);
250             if (((Scod >> 2) & 1)) {
251                 EPHused = OPJ_TRUE;
252             }
253             opj_stream_seek(cio, org_pos, p_manager);
254
255             break;
256         }
257     }
258     return EPHused;
259 }