4 * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
5 * Copyright (c) 2002-2014, Professor Benoit Macq
6 * Copyright (c) 2010-2011, Kaori Hagihara
7 * Copyright (c) 2011, Lucian Corlaciu, GSoC
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
37 #include "j2kheader_manager.h"
40 #include "fcgi_stdio.h"
41 #define logstream FCGI_stdout
43 #define FCGI_stdout stdout
44 #define FCGI_stderr stderr
45 #define logstream stderr
49 SIZmarker_param_t get_SIZmkrdata_from_j2kstream(Byte_t *SIZstream);
50 CODmarker_param_t get_CODmkrdata_from_j2kstream(Byte_t *CODstream);
52 OPJ_BOOL get_mainheader_from_j2kstream(Byte_t *j2kstream,
53 SIZmarker_param_t *SIZ, CODmarker_param_t *COD)
55 if (*j2kstream++ != 0xff || *j2kstream++ != 0x4f) {
56 fprintf(FCGI_stderr, "Error, j2kstream is not starting with SOC marker\n");
61 *SIZ = get_SIZmkrdata_from_j2kstream(j2kstream);
66 j2kstream += (SIZ->Lsiz + 2);
71 j2kstream += (big2(j2kstream + 2) + 2);
74 *COD = get_CODmkrdata_from_j2kstream(j2kstream);
82 SIZmarker_param_t get_SIZmkrdata_from_j2kstream(Byte_t *SIZstream)
84 SIZmarker_param_t SIZ;
87 if (*SIZstream++ != 0xff || *SIZstream++ != 0x51) {
89 "Error, SIZ marker not found in the reconstructed j2kstream\n");
90 memset(&SIZ, 0, sizeof(SIZ));
94 SIZ.Lsiz = big2(SIZstream);
95 SIZ.Rsiz = big2(SIZstream + 2);
96 SIZ.Xsiz = big4(SIZstream + 4);
97 SIZ.Ysiz = big4(SIZstream + 8);
98 SIZ.XOsiz = big4(SIZstream + 12);
99 SIZ.YOsiz = big4(SIZstream + 16);
100 SIZ.XTsiz = big4(SIZstream + 20);
101 SIZ.YTsiz = big4(SIZstream + 24);
102 SIZ.XTOsiz = big4(SIZstream + 28);
103 SIZ.YTOsiz = big4(SIZstream + 32);
104 SIZ.Csiz = big2(SIZstream + 36);
106 SIZ.XTnum = (SIZ.Xsiz - SIZ.XTOsiz + SIZ.XTsiz - 1) / SIZ.XTsiz;
107 SIZ.YTnum = (SIZ.Ysiz - SIZ.YTOsiz + SIZ.YTsiz - 1) / SIZ.YTsiz;
109 for (i = 0; i < (int)SIZ.Csiz; i++) {
110 SIZ.Ssiz[i] = *(SIZstream + (38 + i * 3));
111 SIZ.XRsiz[i] = *(SIZstream + (39 + i * 3));
112 SIZ.YRsiz[i] = *(SIZstream + (40 + i * 3));
118 CODmarker_param_t get_CODmkrdata_from_j2kstream(Byte_t *CODstream)
120 CODmarker_param_t COD;
123 if (*CODstream++ != 0xff || *CODstream++ != 0x52) {
125 "Error, COD marker not found in the reconstructed j2kstream\n");
126 memset(&COD, 0, sizeof(COD));
130 COD.Lcod = big2(CODstream);
131 COD.Scod = *(CODstream + 2);
132 COD.prog_order = *(CODstream + 3);
133 COD.numOflayers = big2(CODstream + 4);
134 COD.numOfdecomp = *(CODstream + 7);
136 if (COD.Scod & 0x01) {
137 COD.XPsiz = (Byte4_t *)opj_malloc((OPJ_SIZE_T)(COD.numOfdecomp + 1) * sizeof(
139 COD.YPsiz = (Byte4_t *)opj_malloc((OPJ_SIZE_T)(COD.numOfdecomp + 1) * sizeof(
142 for (i = 0; i <= COD.numOfdecomp; i++) {
144 COD.XPsiz[i] = (Byte4_t)pow(2, *(CODstream + 12 + i) & 0x0F);
145 COD.YPsiz[i] = (Byte4_t)pow(2, (*(CODstream + 12 + i) & 0xF0) >> 4);
148 COD.XPsiz = (Byte4_t *)opj_malloc(sizeof(Byte4_t));
149 COD.YPsiz = (Byte4_t *)opj_malloc(sizeof(Byte4_t));
150 COD.XPsiz[0] = COD.YPsiz[0] = 1 << 15; /*pow(2,15)*/
156 OPJ_BOOL modify_SIZmkrstream(SIZmarker_param_t SIZ, int difOfdecomplev,
158 Byte2_t modify_CODmkrstream(CODmarker_param_t COD, int numOfdecomp,
161 OPJ_BOOL modify_mainheader(Byte_t *j2kstream, int numOfdecomp,
162 SIZmarker_param_t SIZ, CODmarker_param_t COD, Byte8_t *j2klen)
166 if (*j2kstream++ != 0xff || *j2kstream++ != 0x4f) {
167 fprintf(FCGI_stderr, "Error, j2kstream is not starting with SOC marker\n");
171 if (!modify_SIZmkrstream(SIZ, COD.numOfdecomp - numOfdecomp, j2kstream)) {
175 j2kstream += SIZ.Lsiz + 2;
176 if (!(newLcod = modify_CODmkrstream(COD, numOfdecomp, j2kstream))) {
180 memmove(j2kstream + 2 + newLcod, j2kstream + 2 + COD.Lcod,
181 *j2klen - (Byte8_t)(SIZ.Lsiz + COD.Lcod + 6));
182 *j2klen -= (Byte8_t)(COD.Lcod - newLcod);
187 OPJ_BOOL modify_SIZmkrstream(SIZmarker_param_t SIZ, int difOfdecomplev,
192 if (*SIZstream++ != 0xff || *SIZstream++ != 0x51) {
194 "Error, SIZ marker not found in the reconstructed j2kstream\n");
198 for (i = 0; i < difOfdecomplev; i++) {
199 SIZ.Xsiz = (Byte4_t)ceil((double)SIZ.Xsiz / 2.0);
200 SIZ.Ysiz = (Byte4_t)ceil((double)SIZ.Ysiz / 2.0);
201 SIZ.XOsiz = (Byte4_t)ceil((double)SIZ.XOsiz / 2.0);
202 SIZ.YOsiz = (Byte4_t)ceil((double)SIZ.YOsiz / 2.0);
203 SIZ.XTsiz = (Byte4_t)ceil((double)SIZ.XTsiz / 2.0);
204 SIZ.YTsiz = (Byte4_t)ceil((double)SIZ.YTsiz / 2.0);
205 SIZ.XTOsiz = (Byte4_t)ceil((double)SIZ.XTOsiz / 2.0);
206 SIZ.YTOsiz = (Byte4_t)ceil((double)SIZ.YTOsiz / 2.0);
209 SIZstream += 4; /* skip Lsiz + Rsiz */
211 modify_4Bytecode(SIZ.Xsiz, SIZstream);
212 modify_4Bytecode(SIZ.Ysiz, SIZstream + 4);
213 modify_4Bytecode(SIZ.XOsiz, SIZstream + 8);
214 modify_4Bytecode(SIZ.YOsiz, SIZstream + 12);
215 modify_4Bytecode(SIZ.XTsiz, SIZstream + 16);
216 modify_4Bytecode(SIZ.YTsiz, SIZstream + 20);
217 modify_4Bytecode(SIZ.XTOsiz, SIZstream + 24);
218 modify_4Bytecode(SIZ.YTOsiz, SIZstream + 28);
223 Byte2_t modify_CODmkrstream(CODmarker_param_t COD, int numOfdecomp,
228 assert(numOfdecomp >= 0 || numOfdecomp <= 255);
229 if (*CODstream++ != 0xff || *CODstream++ != 0x52) {
231 "Error, COD marker not found in the reconstructed j2kstream\n");
235 if (COD.Scod & 0x01) {
236 newLcod = (Byte2_t)(13 + numOfdecomp);
238 *CODstream++ = (Byte_t)((Byte2_t)(newLcod & 0xff00) >> 8);
239 *CODstream++ = (Byte_t)(newLcod & 0x00ff);
245 CODstream += 5; /* skip Scod & SGcod */
248 *CODstream++ = (Byte_t) numOfdecomp;
253 OPJ_BOOL modify_COCmkrstream(int numOfdecomp, Byte_t *COCstream, Byte2_t Csiz,
254 Byte2_t *oldLcoc, Byte2_t *newLcoc);
256 OPJ_BOOL modify_tileheader(Byte_t *j2kstream, Byte8_t SOToffset,
257 int numOfdecomp, Byte2_t Csiz, Byte8_t *j2klen)
259 Byte4_t Psot; /* tile part length ref A.4.2 Start of tile-part SOT */
260 Byte_t *thstream, *SOTstream, *Psot_stream;
261 Byte2_t oldLcoc, newLcoc;
263 SOTstream = thstream = j2kstream + SOToffset;
265 if (*SOTstream++ != 0xff || *SOTstream++ != 0x90) {
266 fprintf(FCGI_stderr, "Error, thstream is not starting with SOT marker\n");
270 SOTstream += 4; /* skip Lsot & Isot */
271 Psot = (Byte4_t)((SOTstream[0] << 24) + (SOTstream[1] << 16) +
272 (SOTstream[2] << 8) + (SOTstream[3]));
273 Psot_stream = SOTstream;
275 thstream += 12; /* move to next marker (SOT always 12bytes) */
277 while (!(*thstream == 0xff && *(thstream + 1) == 0x93)) { /* search SOD */
278 if (numOfdecomp != -1 && *thstream == 0xff &&
279 *(thstream + 1) == 0x53) { /* COC */
280 if (!modify_COCmkrstream(numOfdecomp, thstream, Csiz, &oldLcoc, &newLcoc)) {
284 memmove(thstream + newLcoc + 2, thstream + oldLcoc + 2,
285 *j2klen - (Byte8_t)(thstream - j2kstream + oldLcoc + 2));
286 *j2klen -= (Byte8_t)(oldLcoc - newLcoc);
289 thstream += ((thstream[0] << 8) + (thstream[1])); /* marker length */
292 if ((*j2klen) - SOToffset != Psot) {
293 Psot = (Byte4_t)((*j2klen) - SOToffset);
294 modify_4Bytecode(Psot, Psot_stream);
299 OPJ_BOOL modify_COCmkrstream(int numOfdecomp, Byte_t *COCstream, Byte2_t Csiz,
300 Byte2_t *oldLcoc, Byte2_t *newLcoc)
302 if (numOfdecomp < 0 || numOfdecomp > 255) {
305 if (*COCstream++ != 0xff || *COCstream++ != 0x53) {
307 "Error, COC marker not found in the reconstructed j2kstream\n");
311 *oldLcoc = big2(COCstream);
312 *newLcoc = (Byte2_t)((Csiz < 257 ? 10 : 11) + numOfdecomp);
313 *COCstream++ = (Byte_t)((Byte2_t)((*newLcoc) & 0xff00) >> 8);
314 *COCstream++ = (Byte_t)((*newLcoc) & 0x00ff);
317 COCstream += 2; /* skip Ccoc & Scoc */
322 *COCstream = (Byte_t)numOfdecomp;