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) 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, SIZmarker_param_t *SIZ, CODmarker_param_t *COD)
54 if( *j2kstream++ != 0xff || *j2kstream++ != 0x4f){
55 fprintf( FCGI_stderr, "Error, j2kstream is not starting with SOC marker\n");
60 *SIZ = get_SIZmkrdata_from_j2kstream( j2kstream);
64 j2kstream += (SIZ->Lsiz+2);
69 j2kstream += (big2( j2kstream+2) + 2);
71 *COD = get_CODmkrdata_from_j2kstream( j2kstream);
78 SIZmarker_param_t get_SIZmkrdata_from_j2kstream( Byte_t *SIZstream)
80 SIZmarker_param_t SIZ;
83 if( *SIZstream++ != 0xff || *SIZstream++ != 0x51){
84 fprintf( FCGI_stderr, "Error, SIZ marker not found in the reconstructed j2kstream\n");
85 memset( &SIZ, 0, sizeof( SIZ ) );
89 SIZ.Lsiz = big2( SIZstream);
90 SIZ.Rsiz = big2( SIZstream+2);
91 SIZ.Xsiz = big4( SIZstream+4);
92 SIZ.Ysiz = big4( SIZstream+8);
93 SIZ.XOsiz = big4( SIZstream+12);
94 SIZ.YOsiz = big4( SIZstream+16);
95 SIZ.XTsiz = big4( SIZstream+20);
96 SIZ.YTsiz = big4( SIZstream+24);
97 SIZ.XTOsiz = big4( SIZstream+28);
98 SIZ.YTOsiz = big4( SIZstream+32);
99 SIZ.Csiz = big2( SIZstream+36);
101 SIZ.XTnum = ( SIZ.Xsiz-SIZ.XTOsiz+SIZ.XTsiz-1)/SIZ.XTsiz;
102 SIZ.YTnum = ( SIZ.Ysiz-SIZ.YTOsiz+SIZ.YTsiz-1)/SIZ.YTsiz;
104 for( i=0; i<(int)SIZ.Csiz; i++){
105 SIZ.Ssiz[i] = *(SIZstream+(38+i*3));
106 SIZ.XRsiz[i] = *(SIZstream+(39+i*3));
107 SIZ.YRsiz[i] = *(SIZstream+(40+i*3));
113 CODmarker_param_t get_CODmkrdata_from_j2kstream( Byte_t *CODstream)
115 CODmarker_param_t COD;
118 if( *CODstream++ != 0xff || *CODstream++ != 0x52){
119 fprintf( FCGI_stderr, "Error, COD marker not found in the reconstructed j2kstream\n");
123 COD.Lcod = big2( CODstream);
124 COD.Scod = *( CODstream+2);
125 COD.prog_order = *( CODstream+3);
126 COD.numOflayers = big2( CODstream+4);
127 COD.numOfdecomp = *( CODstream+7);
130 COD.XPsiz = (Byte4_t *)opj_malloc( (OPJ_SIZE_T)(COD.numOfdecomp+1)*sizeof(Byte4_t));
131 COD.YPsiz = (Byte4_t *)opj_malloc( (OPJ_SIZE_T)(COD.numOfdecomp+1)*sizeof(Byte4_t));
133 for( i=0; i<=COD.numOfdecomp; i++){
135 COD.XPsiz[i] = (Byte4_t)pow( 2, *( CODstream+12+i) & 0x0F);
136 COD.YPsiz[i] = (Byte4_t)pow( 2, (*( CODstream+12+i) & 0xF0) >> 4);
140 COD.XPsiz = (Byte4_t *)opj_malloc( sizeof(Byte4_t));
141 COD.YPsiz = (Byte4_t *)opj_malloc( sizeof(Byte4_t));
142 COD.XPsiz[0] = COD.YPsiz[0] = pow(2,15);
148 opj_bool modify_SIZmkrstream( SIZmarker_param_t SIZ, int difOfdecomplev, Byte_t *SIZstream);
149 Byte2_t modify_CODmkrstream( CODmarker_param_t COD, int numOfdecomp, Byte_t *CODstream);
151 opj_bool modify_mainheader( Byte_t *j2kstream, int numOfdecomp, SIZmarker_param_t SIZ, CODmarker_param_t COD, Byte8_t *j2klen)
155 if( *j2kstream++ != 0xff || *j2kstream++ != 0x4f){
156 fprintf( FCGI_stderr, "Error, j2kstream is not starting with SOC marker\n");
160 if(!modify_SIZmkrstream( SIZ, COD.numOfdecomp-numOfdecomp, j2kstream))
163 j2kstream += SIZ.Lsiz+2;
164 if( !(newLcod = modify_CODmkrstream( COD, numOfdecomp, j2kstream)))
167 memmove( j2kstream+2+newLcod, j2kstream+2+COD.Lcod, *j2klen - (Byte8_t)(SIZ.Lsiz+COD.Lcod+6));
168 *j2klen -= (Byte8_t)( COD.Lcod - newLcod);
173 opj_bool modify_SIZmkrstream( SIZmarker_param_t SIZ, int difOfdecomplev, Byte_t *SIZstream)
177 if( *SIZstream++ != 0xff || *SIZstream++ != 0x51){
178 fprintf( FCGI_stderr, "Error, SIZ marker not found in the reconstructed j2kstream\n");
182 for( i=0; i<difOfdecomplev; i++){
183 SIZ.Xsiz = (Byte4_t)ceil( (double)SIZ.Xsiz/2.0);
184 SIZ.Ysiz = (Byte4_t)ceil( (double)SIZ.Ysiz/2.0);
185 SIZ.XOsiz = (Byte4_t)ceil( (double)SIZ.XOsiz/2.0);
186 SIZ.YOsiz = (Byte4_t)ceil( (double)SIZ.YOsiz/2.0);
187 SIZ.XTsiz = (Byte4_t)ceil( (double)SIZ.XTsiz/2.0);
188 SIZ.YTsiz = (Byte4_t)ceil( (double)SIZ.YTsiz/2.0);
189 SIZ.XTOsiz = (Byte4_t)ceil( (double)SIZ.XTOsiz/2.0);
190 SIZ.YTOsiz = (Byte4_t)ceil( (double)SIZ.YTOsiz/2.0);
193 SIZstream += 4; /* skip Lsiz + Rsiz */
195 modify_4Bytecode( SIZ.Xsiz, SIZstream);
196 modify_4Bytecode( SIZ.Ysiz, SIZstream+4);
197 modify_4Bytecode( SIZ.XOsiz, SIZstream+8);
198 modify_4Bytecode( SIZ.YOsiz, SIZstream+12);
199 modify_4Bytecode( SIZ.XTsiz, SIZstream+16);
200 modify_4Bytecode( SIZ.YTsiz, SIZstream+20);
201 modify_4Bytecode( SIZ.XTOsiz, SIZstream+24);
202 modify_4Bytecode( SIZ.YTOsiz, SIZstream+28);
207 Byte2_t modify_CODmkrstream( CODmarker_param_t COD, int numOfdecomp, Byte_t *CODstream)
211 assert( numOfdecomp >= 0 || numOfdecomp <= 255 );
212 if( *CODstream++ != 0xff || *CODstream++ != 0x52){
213 fprintf( FCGI_stderr, "Error, COD marker not found in the reconstructed j2kstream\n");
217 if( COD.Scod & 0x01){
218 newLcod = (Byte2_t)(13+numOfdecomp);
220 *CODstream++ = (Byte_t)((Byte2_t)(newLcod & 0xff00) >> 8);
221 *CODstream++ = (Byte_t)(newLcod & 0x00ff);
228 CODstream += 5; /* skip Scod & SGcod */
231 *CODstream++ = (Byte_t) numOfdecomp;
236 opj_bool modify_COCmkrstream( int numOfdecomp, Byte_t *COCstream, Byte2_t Csiz, Byte2_t *oldLcoc, Byte2_t *newLcoc);
238 opj_bool modify_tileheader( Byte_t *j2kstream, Byte8_t SOToffset, int numOfdecomp, Byte2_t Csiz, Byte8_t *j2klen)
240 Byte4_t Psot; /* tile part length ref A.4.2 Start of tile-part SOT */
241 Byte_t *thstream, *SOTstream, *Psot_stream;
242 Byte2_t oldLcoc, newLcoc;
244 SOTstream = thstream = j2kstream+SOToffset;
246 if( *SOTstream++ != 0xff || *SOTstream++ != 0x90){
247 fprintf( FCGI_stderr, "Error, thstream is not starting with SOT marker\n");
251 SOTstream += 4; /* skip Lsot & Isot */
252 Psot = (Byte4_t)((SOTstream[0]<<24)+(SOTstream[1]<<16)+(SOTstream[2]<<8)+(SOTstream[3]));
253 Psot_stream = SOTstream;
255 thstream += 12; /* move to next marker (SOT always 12bytes) */
257 while( !( *thstream == 0xff && *(thstream+1) == 0x93)){ /* search SOD */
258 if( numOfdecomp != -1 && *thstream == 0xff && *(thstream+1) == 0x53){ /* COC */
259 if( !modify_COCmkrstream( numOfdecomp, thstream, Csiz, &oldLcoc, &newLcoc))
262 memmove( thstream+newLcoc+2, thstream+oldLcoc+2, *j2klen - (Byte8_t)(thstream-j2kstream+oldLcoc+2));
263 *j2klen -= (Byte8_t)( oldLcoc - newLcoc);
266 thstream += ((thstream[0]<<8)+(thstream[1])); /* marker length */
269 if( (*j2klen)-SOToffset != Psot){
270 Psot = (Byte4_t)((*j2klen)-SOToffset);
271 modify_4Bytecode( Psot, Psot_stream);
276 opj_bool modify_COCmkrstream( int numOfdecomp, Byte_t *COCstream, Byte2_t Csiz, Byte2_t *oldLcoc, Byte2_t *newLcoc)
278 if( numOfdecomp < 0 || numOfdecomp > 255 ) return OPJ_FALSE;
279 if( *COCstream++ != 0xff || *COCstream++ != 0x53){
280 fprintf( FCGI_stderr, "Error, COC marker not found in the reconstructed j2kstream\n");
284 *oldLcoc = big2( COCstream);
285 *newLcoc = (Byte2_t)((Csiz < 257 ? 10 : 11) + numOfdecomp);
286 *COCstream++ = (Byte_t)((Byte2_t)((*newLcoc) & 0xff00) >> 8);
287 *COCstream++ = (Byte_t)((*newLcoc) & 0x00ff);
289 if( Csiz < 257) COCstream +=2; /* skip Ccoc & Scoc */
292 *COCstream = (Byte_t)numOfdecomp;