Initial revision
[openjpeg.git] / jpwl / encoder / libopenjpeg / jpw.c
1 /*
2  * Copyright 2004-2005 Andrea Betti and Michele Massarelli
3  * Copyright 2004-2005 DIEI, University of Perugia
4  *
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27
28
29 /* questa � un' estensione della libreria dell'openjpeg in grado di implementare
30  * la parte 11 dello standard JPEG2000 ossia il JPWL
31  */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <setjmp.h>
37 #include <conio.h>
38 #include <math.h>
39 #include "j2k.h"
40 #include "cio.h"
41 #include "jpw.h"
42 #include "rs.h"
43
44 // JPWL MARKERS 
45 #define JPWL_MS_EPC 0xff68
46 #define JPWL_MS_EPB 0xff66
47 #define JPWL_MS_ESD 0xff67
48 #define JPWL_MS_RED 0xff69
49
50
51 //stati del codec
52 #define J2K_STATE_MHSOC 0x0001
53 #define J2K_STATE_MHSIZ 0x0002
54 #define J2K_STATE_MH 0x0004
55 #define J2K_STATE_TPHSOT 0x0008
56 #define J2K_STATE_TPH 0x0010
57 #define J2K_STATE_MT 0x0020
58 #define J2K_STATE_NEOC 0x0040
59 #define J2K_STATE_MHEPB 0x0080
60 #define J2K_STATE_TPHEPB 0x0100
61
62 //carica la struttura relativa ai parametri JPWL
63 extern JPWL_cp_t jpwl_cp;
64 extern int j2k_state;
65 extern j2k_cp_t *j2k_cp;
66 extern info_image info_IM;
67
68 static long crcSum;
69 static long pepbs[1000];
70 static int cont_epb=0;
71 static int scavalcato=0;
72
73 static int CrcT16[256] =
74 {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
75 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
76 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
77 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
78 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
79 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
80 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
81 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
82 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
83 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
84 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
85 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
86 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
87 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
88 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
89 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
90 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
91 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
92 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
93 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
94 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
95 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
96 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
97 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
98 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
99 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
100 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
101 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
102 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
103 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
104 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
105 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
106
107 static long CrcT32[256] = {0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
108 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
109 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
110 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
111 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
112 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
113 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
114 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
115 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
116 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
117 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
118 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
119 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
120 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
121 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
122 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
123 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
124 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
125 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
126 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
127 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
128 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
129 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
130 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
131 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
132 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
133 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
134 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
135 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
136 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
137 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
138 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
139 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
140 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
141 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
142 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
143 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
144 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
145 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
146 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
147 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
148 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
149 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
150 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
151 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
152 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
153 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
154 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
155 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
156 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
157 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
158 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
159 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
160 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
161 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
162 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
163 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
164 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
165 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
166 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
167 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
168 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
169 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
170 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
171
172
173 /* inizializza i parametri relativi al JPWL *
174  * disabilitando le funzionalit�            */
175
176 void jpwl_cp_init(JPWL_cp_t *jpwl_cp){
177         jpwl_cp->JPWL_on = 0;
178         jpwl_cp->EPB_on = 0;
179         jpwl_cp->ESD_on = 0;
180         jpwl_cp->RED_on = 0;
181         jpwl_cp->info_tech_on = 0;
182 }
183
184 /****************************************************************************************
185  *                                                                                                                                                                              *
186  *                                                                  Marker JPWL                                                                                 *
187  *                                                                                                                                                                              *
188  ****************************************************************************************/
189
190 /* Scrive il marker segment EPC
191    version 0.1: in questa prima fase questo andr� subito dopo il SIZ */
192
193 void jpwl_write_EPC(){
194         int lenp, len, i;
195         char c, P_EPC = 0;
196         cio_write(JPWL_MS_EPC, 2);
197         lenp = cio_tell();
198         cio_skip(2);
199         // calcola il crc
200         cio_skip(2);
201         // per adesso lascio uno spazio vuoto (16 bit)
202         // CL settore di 32bit che indica la lungheza della codestream:
203         // per ora metto tutto uguale a zero (info non disponibile)
204         cio_write(0, 4);
205         // P_EPC indica se nella codestream saranno usati gli altri 
206         // marker segment oppure tecniche informative aggiuntive 
207         if (jpwl_cp.ESD_on)
208                 P_EPC += 0x10;
209         if (jpwl_cp.RED_on)
210                 P_EPC += 0x20;
211         if (jpwl_cp.EPB_on)
212                 P_EPC += 0x40;
213         if (jpwl_cp.info_tech_on)
214                 P_EPC += 0x80;
215         cio_write(P_EPC, 1);
216         //scrivo i Pepb
217
218         if(jpwl_cp.EPB_on)
219                 JPWL_write_Pepbs(NULL,0);
220
221
222
223
224         /* Al momento non esistono tecniche informative aggiuntive per richiamarle
225          * opereremo in questo modo:
226          * 0) dovr� inserire nella struttura jpwl_cp_t un campo contenente un puntatore
227          *    ad un array che conterr� gli ID delle tecniche informative da usare;
228          * 1) conrollo il campo info_tech_on;
229          * 2) eseguo delle funzioni da inserire nel file jpw.c e jpw.h relative alle 
230          *    tecniche informative desiderate; tali funzioni dovranno preoccuparsi di
231          *    creare i campi corretti nel marker segment.
232          *  if( jpwl_cp->info_tech_on){
233          *      qui inserir� i comandi desiderati
234          *  }
235          */
236     len = cio_tell() - lenp;
237         cio_seek(lenp);
238         cio_write(len, 2);
239         // calcola il crc
240         cio_skip(-4);
241         ResetCRC();
242         for (i=0; i<4; i++){
243                 c = cio_read(1);
244                 UpdateCRC16(c); 
245         }
246         cio_skip(2);
247         for (i=6; i<(len + 2); i++){
248                 c = cio_read(1);
249                 UpdateCRC16(c); 
250         }
251         cio_seek(lenp + 2);
252         cio_write(crcSum, 2);
253         cio_seek(lenp + len);
254
255 }
256
257
258 void jpwl_write_EPC_fin(unsigned long CL, long *pepbs, int num_epb){
259         int lenp, len, i;
260         unsigned long len_codestr;
261         char c, P_EPC = 0;
262         cio_write(JPWL_MS_EPC, 2);
263         lenp = cio_tell();
264         cio_skip(2);
265         // calcola il crc
266         cio_skip(2);
267         // per adesso lascio uno spazio vuoto (16 bit)
268         // CL settore di 32bit che indica la lungheza della codestream:
269         // per ora metto tutto uguale a zero (info non disponibile)
270         cio_write(0, 4);
271         // P_EPC indica se nella codestream saranno usati gli altri 
272         // marker segment oppure tecniche informative aggiuntive 
273         if (jpwl_cp.ESD_on)
274                 P_EPC += 0x10;
275         if (jpwl_cp.RED_on)
276                 P_EPC += 0x20;
277         if (jpwl_cp.EPB_on)
278                 P_EPC += 0x40;
279         if (jpwl_cp.info_tech_on)
280                 P_EPC += 0x80;
281         cio_write(P_EPC, 1);
282         //scrivo i Pepb
283
284         if(jpwl_cp.EPB_on)
285                 JPWL_write_Pepbs(pepbs, num_epb);
286
287
288
289
290         /* Al momento non esistono tecniche informative aggiuntive per richiamarle
291          * opereremo in questo modo:
292          * 0) dovr� inserire nella struttura jpwl_cp_t un campo contenente un puntatore
293          *    ad un array che conterr� gli ID delle tecniche informative da usare;
294          * 1) conrollo il campo info_tech_on;
295          * 2) eseguo delle funzioni da inserire nel file jpw.c e jpw.h relative alle 
296          *    tecniche informative desiderate; tali funzioni dovranno preoccuparsi di
297          *    creare i campi corretti nel marker segment.
298          *  if( jpwl_cp->info_tech_on){
299          *      qui inserir� i comandi desiderati
300          *  }
301          */
302     len = cio_tell() - lenp;
303         cio_seek(lenp);
304         cio_write(len, 2);
305         //scrivo la lunghezza della codestream
306         cio_skip(2);
307         len_codestr = CL + len + 2;
308         cio_write(len_codestr, 4);
309         // calcola il crc
310         cio_skip(-10);
311         ResetCRC();
312         for (i=0; i<4; i++){
313                 c = cio_read(1);
314                 UpdateCRC16(c); 
315         }
316         cio_skip(2);
317         for (i=6; i<(len + 2); i++){
318                 c = cio_read(1);
319                 UpdateCRC16(c); 
320         }
321         cio_seek(lenp + 2);
322         cio_write(crcSum, 2);
323         cio_seek(lenp + len);
324
325 }
326
327
328
329 void JPWL_write_EPB(char *buf, unsigned long LDPepb, unsigned long Pepb, unsigned char Depb){
330         int *alpha_to, *index_of, *gg, *data_, *bb;
331         unsigned long i=0;
332         unsigned int len = 11, lenp, scrivi_pb, cont, leggi, tenta=0;
333         char pos_epb;
334         unsigned data_unprot = 0, RS = 0;
335         int n1, n2, k1, k2, j, n=255, k, CRC = 0, go_back;      // 0 = disabilitato, 1 = CRC CCITT 16 bit, 2 = Ethernet CRC 32 bit 
336         //prova
337         /*FILE *f;
338         FILE *fp;*/
339
340
341         cio_write(JPWL_MS_EPB, 2);
342         lenp = cio_tell();
343         /* determino len_epb e i parametri di codifica*/
344         pos_epb= Depb & 0x3F;
345         if ((j2k_state == J2K_STATE_MH) && !(pos_epb)){  // sto scrivendo il primo epb del mh
346                 
347                 n1=160;
348                 k1=64;
349                 go_back =lenp + 11;
350                 len += (n1 - k1)*(unsigned int)ceil((double)go_back/k1);
351         } else {if ((j2k_state == J2K_STATE_TPH) && !(pos_epb)&& !(scavalcato)){                // primo epb di un tph
352                                 n1=80;
353                                 k1=go_back=25;
354                                 len += 55;
355                                 
356                         } else {                    // altro epb
357                                 n1=40;
358                                 k1=go_back=13;
359                                 len += 27;
360                                 //tenta=1;
361                         }
362         }
363         if (!Pepb) {               // per codificare i dati seguenti uso lo stesso codice di prima
364                 RS = 1;
365                 n2 = n1;
366                 k2 = k1;
367             len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
368
369         } else{
370                 if (Pepb == 0xffffffff)    
371                         data_unprot=1;
372                 else {if ((Pepb >> 28)== 1){
373                                 if ((Pepb & 0x00000001)){
374                                         CRC = 2;
375                                         len += 4;
376                                 } else {
377                                         CRC = 1;
378                                         len +=2;
379                                 }
380                         } else {if ((Pepb >> 28)== 2){
381                                                 n2 = ((Pepb & 0x0000ff00)>> 8);
382                                                 k2 = (Pepb & 0x000000ff);
383                                                 RS = 1;
384                                                 len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
385                                                 }
386                                         }
387                         }
388         }
389         cio_write(len, 2);    // Lepb
390         cio_write(Depb, 1);             //Depb
391         cio_write((LDPepb & 0xffff0000) >> 16, 2);  //LDPepb
392     cio_write((LDPepb & 0x0000ffff), 2);
393         cio_write((Pepb & 0xffff0000) >> 16, 2);  //Pepb
394     cio_write((Pepb & 0x0000ffff), 2);
395         //printf("start\n");
396
397         // devi implementare il codice rs per la protezione dell'epb
398         // cio_write(0, (int) ceil((lenp+11)*(n1 - k1)/k1));
399         if(!(alpha_to=(int *) calloc(256,sizeof(int))))
400              printf("Non pu� essere allocata memoria per eseguire il programma1\n ");
401
402     if(!(index_of=(int *) calloc(256,sizeof(int))))
403              printf("Non pu� essere allocata memoria per eseguire il programma2\n ");
404         
405         if(!(gg=(int *) calloc((n1 - k1 +1),sizeof(int))))
406              printf("Non pu� essere allocata memoria per eseguire il programma3\n ");
407         
408         k = 255-(n1-k1);
409
410         if(!(data_=(int *) calloc(k, sizeof(int))))
411              printf("Non pu� essere allocata memoria per eseguire il programma4\n ");
412
413         if(!(bb=(int *) calloc((n1 - k1),sizeof(int))))
414              printf("Non pu� essere allocata memoria per eseguire il programma5\n ");
415         
416         generate_gf(alpha_to, index_of);
417
418         gen_poly(k, alpha_to, index_of, gg);
419
420         scrivi_pb = cio_tell();
421
422         //prova
423         
424
425         cio_skip(-go_back);
426         for (cont = 0; cont < (unsigned int) ceil((double)go_back/k1); cont++) {
427                 for (j=0; j<k1; j++){
428                         if (j+(cont*k1) <(unsigned int) go_back)
429                                 data_[j]= cio_read(1);
430                         else data_[j] = 0;              //padding
431                 }
432                 for (j=k1; j<k; j++) data_[j] = 0; // padding per la gestione di codici "accorciati"
433                 
434                 leggi = cio_tell();
435                 encode_rs(k,alpha_to, index_of, gg, bb, data_);
436                 
437                 cio_seek(scrivi_pb);
438                 for (j=0; j<(n1-k1); j++)
439                         cio_write(bb[j], 1);
440                 scrivi_pb = cio_tell();
441                 cio_seek(leggi);
442         }
443         cio_seek(scrivi_pb);
444         
445         free(alpha_to);
446         free(index_of);
447         free(gg);
448         free(data_);
449         free(bb);
450
451         /* protezione dei dati seguenti */
452         
453         
454         if (!data_unprot) {
455                 if (CRC == 1){                  //crc ccitt 16 bit questo � l'algo
456                         ResetCRC();
457                         for (i=0; i < LDPepb; i++){
458                                 UpdateCRC16(buf[i]);    
459                         }
460                         cio_write(crcSum & 0xffff, 2);
461         }
462                 if (CRC == 2){  
463                         /*per fare il crc32 occorre invertire i byte in ingresso, invertire il crc calcolato
464                           e farne il complemento a 1*/
465                         ResetCRC();
466                         for (i=0; i < LDPepb; i++){
467                                 UpdateCRC32(reflectByte(buf[i]));       
468                         }
469                         reflectCRC32();
470                         crcSum ^= 0xffffffff;           
471             cio_write((crcSum & 0xffff0000) >> 16, 2);
472                         cio_write((crcSum & 0x0000ffff), 2);
473         } 
474                 if (RS) {
475                         //printf("n2, k2: %d %d\n", n2, k2);
476                         k = 255-(n2-k2);
477
478                         if(!(alpha_to=(int *) malloc(256*sizeof(int))))
479                                 printf("Non pu� essere allocata memoria per eseguire il programma1\n ");
480
481                         if(!(index_of=(int *) malloc(256*sizeof(int))))
482                                 printf("Non pu� essere allocata memoria per eseguire il programma2\n ");
483         
484                         if(!(gg=(int *) malloc((n2 - k2 +1)*sizeof(int))))
485                                 printf("Non pu� essere allocata memoria per eseguire il programma3\n ");        
486                                 
487                         if(!(data_=(int *) malloc(k*sizeof(int))))
488                                 printf("Non pu� essere allocata memoria per eseguire il programma4\n ");
489
490                         if(!(bb=(int *) malloc((n2 - k2)*sizeof(int))))
491                                 printf("Non pu� essere allocata memoria per eseguire il programma5\n ");
492                         
493                         generate_gf(alpha_to, index_of);
494
495                         gen_poly(k, alpha_to, index_of, gg);
496                         //printf("num blocchi: %f\n", ceil((double)LDPepb/k2));
497                         //printf("resto: %d\n", LDPepb%k2);
498
499                         for (cont = 0; cont < (unsigned int)ceil((double)LDPepb/k2); cont++) {
500
501                                 for (j=0; j<k2; j++){
502                                         if (j+(cont*k2) < LDPepb)
503                                                 data_[j]= 0x000000ff & buf[j+(cont*k2)];  //qualcuno dovr� spiegarmi il perch�!!!!
504                                         else data_[j] = 0;              //padding
505                                 }
506                                 
507                                 for (j=k2; j<k; j++) data_[j] = 0; // padding per la gestione di codici "accorciati"
508                                 //prova
509                                 /*if ((cont==(unsigned int)ceil((double)LDPepb/k2)-1)&&(tenta)){
510                                         f=fopen("data.txt","wb");
511                                         for(j=0; j<k; j++) fputc(data_[j], f);
512                                         fclose(f);
513                                 }*/
514                                 
515                                 encode_rs(k, alpha_to, index_of, gg, bb, data_);
516                                 //prova
517                                 /*if ((cont==(unsigned int)ceil((double)LDPepb/k2)-1)&&(tenta)){
518                                         fp=fopen("parity.txt","wb");
519                                         for(j=0; j<(n2-k2); j++) fputc(bb[j], fp);
520                                         fclose(fp);
521                                 }*/
522                                 
523                                 for (j=0; j<(n2-k2); j++){
524                                         cio_write(bb[j], 1);
525                                         }
526                                 
527                         }
528
529                         free(alpha_to);
530                         free(index_of);
531                         free(gg);
532                         free(data_);
533                         free(bb);
534
535                         
536
537                         
538                 }
539         }
540 }
541
542
543 void jpwl_write_ESD(char Pesd, int notil){
544         int i, ult, set, nb_pos, nb_sv, metric, mode, cont=0, npix, lev, start, end, temp, len, npack;
545         double **dMSE, **dPSNR, maxMSE, **PSNR, M, val, x;
546
547         //nuova versione!!
548         cio_write(JPWL_MS_ESD,2);
549         set = cio_tell();
550         cio_skip(2);   //len
551         // faccio solo un esd medio relativo a tutte le componenti
552         if(info_IM.Comp < 257)
553                 cio_write(0,1);         //Cesd
554         else cio_write(0x0000,2);
555         cio_write(Pesd,1);
556         //determino i parametri per scrivere i dati dell'esd
557         nb_pos = (((Pesd & 0x02)>>1)==0) ? 2 : 4;
558         nb_sv = (((Pesd & 0x04)>>2)==0) ? 1 : 2;
559         metric = ((Pesd & 0x38)>>3);
560         mode = ((Pesd & 0xC0)>>6);
561         M = 65025;
562         // creo le matrici che conterranno i valori di deltaMSE e deltaPSNR
563         // in realt� spreco un po' di memoria nel caso in cui la scrivo nei tile...
564         dMSE = (double **) malloc(j2k_cp->th * j2k_cp->tw * sizeof(double));
565         for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
566                 dMSE[i]=(double*) malloc(info_IM.num *sizeof(double));
567         dPSNR = (double **) malloc(j2k_cp->th * j2k_cp->tw * sizeof(double));
568         for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
569                 dPSNR[i]=(double*) malloc(info_IM.num *sizeof(double));
570         PSNR = (double **) malloc(j2k_cp->th * j2k_cp->tw * sizeof(double));
571         for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
572                 PSNR[i]=(double*) malloc(info_IM.num * sizeof(double));
573
574         // a questo punto se notil=0 vuol dire che scrivo l'esd nel main header
575         // altrimenti notil indica il tile a cui mi riferisco
576         ult = (notil == 0) ? j2k_cp->th * j2k_cp->tw : notil;
577         if (notil != 0) notil--; 
578         
579         // calcolo di dPSNR, dMSE e PSNR 
580         // nuova routine pi� snella!!
581         for (i = notil; i < ult; i++){
582                 val = 0;
583                 npix = info_IM.tile[i].nbpix;
584                 maxMSE = info_IM.tile[i].distotile / npix;
585                 for(npack=0; npack < (info_IM.num); npack++){
586                         dMSE[i][npack] = info_IM.tile[i].packet[npack].disto / npix;
587                         if (dMSE[i][npack]!=0){
588                                 val += dMSE[i][npack];
589                                 PSNR[i][npack] = (10 * log10(M/(maxMSE - val)));
590                                 x = (npack==0) ? 0 : PSNR[i][npack-1];
591                                 dPSNR[i][npack] = PSNR[i][npack] - x;
592                         }
593                         else {
594                                 dPSNR[i][npack] = 0;
595                                 PSNR[i][npack] = PSNR[i][npack-1];
596                         }
597                 } 
598         }
599         
600         //ora scrivo i valori di sensibilit� in base alla metrica scelta
601         switch (metric){
602                         case 0:
603                                 //relative error sensitivity: i lvelli di sensibilit� coincidono con i layer (livello 0 = header) 
604                                 //uso sette livelli di sensibilit� relativa
605                                 switch (mode){
606                                         case 0:
607                                                 //packet mode
608                                                 
609                                                 for (i = notil; i < ult; i++){
610                                                         for (npack=0; npack < (info_IM.num); npack++){
611                                                                 if (dPSNR[i][npack]>10)
612                                                                         cio_write(1, 1);
613                                                                 else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8))
614                                                                         cio_write(2,1);
615                                                                 else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6))
616                                                                         cio_write(3,1);
617                                                                 else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5))
618                                                                         cio_write(4,1);
619                                                                 else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3))
620                                                                         cio_write(5,1);
621                                                                 else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7))
622                                                                         cio_write(6,1);
623                                                                 else
624                                                                         //(dPSNR[i][npack]<=1.7)
625                                                                         cio_write(7,1);
626                                                         }       
627                                                 }
628
629                                                 break;
630
631                                         case 1:
632                                                 //byte range mode
633                                                 for (i = notil; i < ult; i++){
634                                                         //inizializzazioni
635                                                         lev = 0;
636                                                         start = 0;
637                                                         end = 1;
638                                                         for (npack=0; npack < (info_IM.num); npack++){
639                                                                 temp=lev;
640                                                                 //determinazione dei livelli 
641                                                                 if (dPSNR[i][npack]>10)
642                                                                         lev = 1;
643                                                                 else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8))
644                                                                         lev = 2;
645                                                                 else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6))
646                                                                         lev = 3;
647                                                                 else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5))
648                                                                         lev = 4;
649                                                                 else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3))
650                                                                         lev = 5;
651                                                                 else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7))
652                                                                         lev = 6;
653                                                                 else 
654                                                                         //(dPSNR[i][npack]<=1.7)
655                                                                         lev = 7;
656                                                                 if (lev == temp){
657                                                                         end++;
658                                                                         continue;
659                                                                 } else {
660                                                                         cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
661                                                                         cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
662                                                                         cio_write(lev, nb_sv);
663                                                                         start = end;
664                                                                         end++;
665                                                                 }
666                                                         }
667                                                         cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
668                                                         cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
669                                                         cio_write(lev, nb_sv);
670                                                 } 
671                                                 break;
672
673                                         case 2:
674                                                 //packet range mode
675                                                 for (i = notil; i < ult; i++){
676                                                         //inizializzazioni
677                                                         lev = 0;
678                                                         start = 0;
679                                                         end = 1;
680                                                         for (npack=0; npack < (info_IM.num); npack++){
681                                                                 temp=lev;
682                                                                 //determinazione dei livelli (catena di if-else-if)
683                                                                 if (dPSNR[i][npack]>10)
684                                                                         lev = 1;
685                                                                 else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8))
686                                                                         lev = 2;
687                                                                 else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6))
688                                                                         lev = 3;
689                                                                 else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5))
690                                                                         lev = 4;
691                                                                 else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3))
692                                                                         lev = 5;
693                                                                 else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7))
694                                                                         lev = 6;
695                                                                 else 
696                                                                         //(dPSNR[i][npack]<=1.7)
697                                                                         lev = 7;
698                                                                 if (lev == temp){
699                                                                         end++;
700                                                                         continue;
701                                                                 } else {
702                                                                         cio_write(start, nb_pos);
703                                                                         cio_write(end-1, nb_pos);
704                                                                         cio_write(lev, nb_sv);
705                                                                         start = end;
706                                                                         end++;
707                                                                 }
708                                                         }
709                                                         cio_write(start, nb_pos);
710                                                         cio_write(end - 1, nb_pos);
711                                                         cio_write(lev, nb_sv);
712                                                 } 
713                                                 
714                                                 break;
715                                         default:
716                                                 printf("errore\n");
717                                 }
718                                 break;
719                         case 1:
720                                 // MSE
721                                 switch (mode){
722                                         case 0:
723                                                 //packet mode
724                                                 for (i = notil; i < ult; i++){
725                                                         npix = info_IM.tile[i].nbpix;
726                                                         val = info_IM.tile[i].distotile / npix;
727                                                         cio_write(d2pfp(val), nb_sv);
728                                                         for (npack=0; npack < (info_IM.num); npack++){
729                                                                 val -= dMSE[i][npack];
730                                                                 cio_write(d2pfp(val), nb_sv);
731                                                         }
732                                                 }
733                                                 break;
734                                         case 1:
735                                                 //byte range mode
736                                                 //divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano
737                                                 for (i = notil; i < ult; i++){
738                                                         npix = info_IM.tile[i].nbpix;
739                                                         val = info_IM.tile[i].distotile / npix;
740                                                         start = 0;
741                                                         end = 0;
742                                                         for (npack=0; npack < (info_IM.num); npack++){
743                                                                 val -= dMSE[i][npack];
744                                                                 if (((npack+1) % 10)==0){
745                                                                         cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
746                                                                         cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos);
747                                                                         cio_write(d2pfp(val), nb_sv);
748                                                                         start = end+1;
749                                                                 }
750                                                                 end++;
751                                                         }
752                                                         if (start != end){
753                                                                 cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
754                                                                 cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
755                                                                 cio_write(d2pfp(val), nb_sv);
756                                                         }
757                                                 }
758
759                                                 break;
760                                         case 2:
761                                                 //packet range mode
762                                                 //divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano
763                                                 for (i = notil; i < ult; i++){
764                                                         npix = info_IM.tile[i].nbpix;
765                                                         val = info_IM.tile[i].distotile / npix;
766                                                         start = 0;
767                                                         end = 0;
768                                                         for (npack=0; npack < (info_IM.num); npack++){
769                                                                 val -= dMSE[i][npack];
770                                                                 if (((npack+1) % 10)==0){
771                                                                         cio_write(start, nb_pos);
772                                                                         cio_write(end, nb_pos);
773                                                                         cio_write(d2pfp(val), nb_sv);
774                                                                         start = end+1;
775                                                                 }
776                                                                 end++;
777                                                         }
778                                                         if (start != end){
779                                                                 cio_write(start, nb_pos);
780                                                                 cio_write(end-1, nb_pos);
781                                                                 cio_write(d2pfp(val), nb_sv);
782                                                         }
783                                                 }
784                                                 break;
785                                         default:
786                                                 printf("errore\n");
787                                 }
788
789                                 break;
790                         case 2:
791                                 // MSE reduction
792                                 switch (mode){
793                                         case 0:
794                                                 //packet mode
795                                                 for (i = notil; i < ult; i++)
796                                                         for (npack=0; npack < (info_IM.num); npack++)
797                                                                 cio_write(d2pfp(dMSE[i][npack]), nb_sv);
798                                                 
799                                                 break;
800                                         case 1:
801                                                 //byte range mode
802                                                 //scrivo la mse reduction media relativa ad un blocco di dieci pacchetti
803                                                 for (i = notil; i < ult; i++){
804                                                         val = 0;
805                                                         start = 0;
806                                                         end = 0;
807                                                         for (npack=0; npack < (info_IM.num); npack++){
808                                                                 val += dMSE[i][npack];
809                                                                 if (((npack+1) % 10)==0){
810                                                                         val /= 10;
811                                                                         cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
812                                                                         cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos);
813                                                                         cio_write(d2pfp(val), nb_sv);
814                                                                         start = end+1;
815                                                                         val = 0;
816                                                                 }
817                                                                 end++;
818                                                         }
819                                                         if (start != end){
820                                                                 val /= npack%10;
821                                                                 cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
822                                                                 cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
823                                                                 cio_write(d2pfp(val), nb_sv);
824                                                         }
825                                                 }
826                                                 break;
827                                         case 2:
828                                                 //packet range mode
829                                                 //scrivo la mse reduction media relativa ad un blocco di dieci pacchetti
830                                                 for (i = notil; i < ult; i++){
831                                                         val = 0;
832                                                         start = 0;
833                                                         end = 0;
834                                                         for (npack=0; npack < (info_IM.num); npack++){
835                                                                 val += dMSE[i][npack];
836                                                                 if (((npack+1) % 10)==0){
837                                                                         val /= 10;
838                                                                         cio_write(start, nb_pos);
839                                                                         cio_write(end, nb_pos);
840                                                                         cio_write(d2pfp(val), nb_sv);
841                                                                         start = end+1;
842                                                                         val = 0;
843                                                                 }
844                                                                 end++;
845                                                         }
846                                                         if (start != end){
847                                                                 val /= npack%10;
848                                                                 cio_write(start, nb_pos);
849                                                                 cio_write(end-1, nb_pos);
850                                                                 cio_write(d2pfp(val), nb_sv);
851                                                         }
852                                                 }
853                                                 break;
854                                         default:
855                                                 printf("errore\n");
856                                 }
857
858                                 break;
859                         case 3:
860                                 //PSNR
861
862                                 switch (mode){
863                                         case 0:
864                                                 //packet mode   
865                                                 for (i = notil; i < ult; i++)
866                                                         for (npack=0; npack < (info_IM.num); npack++)
867                                                                 cio_write(d2pfp(PSNR[i][npack]),nb_sv);
868                                                 break;
869                                         case 1:
870                                                 //byte range mode
871                                                 //divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano
872                                                 for (i = notil; i < ult; i++){
873                                                         start = 0;
874                                                         end = 0;
875                                                         for (npack=0; npack < (info_IM.num); npack++){
876                                                                 if (((npack+1) % 10)==0){
877                                                                         cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
878                                                                         //printf("start: %d\n",info_IM.tile[i].packet[start].start_pos);
879                                                                         cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos);
880                                                                         //printf("end: %d\n", info_IM.tile[i].packet[end].end_pos);
881                                                                         cio_write(d2pfp(PSNR[i][npack]), nb_sv);
882                                                                         start = end+1;
883                                                                 }
884                                                                 end++;
885                                                         }
886                                                         if (start != end){
887                                                                 cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
888                                                                 //printf("start: %d\n",info_IM.tile[i].packet[start].start_pos);
889                                                                 cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
890                                                                 //printf("end: %d\n", info_IM.tile[i].packet[end-1].end_pos);
891                                                                 cio_write(d2pfp(PSNR[i][end-1]), nb_sv);
892                                                         }
893                                                 }
894                                                 break;
895                                         case 2:
896                                                 //packet range mode
897                                                 //divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano
898                                                 for (i = notil; i < ult; i++){
899                                                         start = 0;
900                                                         end = 0;
901                                                         for (npack=0; npack < (info_IM.num); npack++){
902                                                                 if (((npack+1) % 10)==0){
903                                                                         cio_write(start, nb_pos);
904                                                                         cio_write(end, nb_pos);
905                                                                         cio_write(d2pfp(PSNR[i][npack]), nb_sv);
906                                                                         start = end+1;
907                                                                 }
908                                                                 end++;
909                                                         }
910                                                         if (start != end){
911                                                                 cio_write(start, nb_pos);
912                                                                 cio_write(end-1, nb_pos);
913                                                                 cio_write(d2pfp(PSNR[i][end-1]), nb_sv);
914                                                         }
915                                                 }
916
917                                                 break;
918                                         default:
919                                                 printf("errore\n");
920                                 }
921
922                                 break;
923                         case 4:
924                                 //PSNR increases
925
926                                 switch (mode){
927                                         case 0:
928                                                 //packet mode
929                                                 for (i = notil; i < ult; i++)
930                                                         for (npack=0; npack < (info_IM.num); npack++)
931                                                                 cio_write(d2pfp(dPSNR[i][npack]), nb_sv);
932                                                 break;
933                                         case 1:
934                                                 //byte range mode
935                                                 //scrivo il psnr increase medio relativo ad un blocco di dieci pacchetti
936                                                 for (i = notil; i < ult; i++){
937                                                         val = 0;
938                                                         start = 0;
939                                                         end = 0;
940                                                         for (npack=0; npack < (info_IM.num); npack++){
941                                                                 val += dPSNR[i][npack];
942                                                                 if (((npack+1) % 10)==0){
943                                                                         val /= 10;
944                                                                         cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
945                                                                         cio_write(info_IM.tile[i].packet[end].end_pos, nb_pos);
946                                                                         cio_write(d2pfp(val), nb_sv);
947                                                                         start = end+1;
948                                                                         val = 0;
949                                                                 }
950                                                                 end++;
951                                                         }
952                                                         if (start != end){
953                                                                 val /= npack%10;
954                                                                 cio_write(info_IM.tile[i].packet[start].start_pos, nb_pos);
955                                                                 cio_write(info_IM.tile[i].packet[end-1].end_pos, nb_pos);
956                                                                 cio_write(d2pfp(val), nb_sv);
957                                                         }
958                                                 }
959                                                 break;
960                                         case 2:
961                                                 //packet range mode
962                                                 //scrivo il psnr increase medio relativo ad un blocco di dieci pacchetti
963                                                 for (i = notil; i < ult; i++){
964                                                         val = 0;
965                                                         start = 0;
966                                                         end = 0;
967                                                         for (npack=0; npack < (info_IM.num); npack++){
968                                                                 val += dPSNR[i][npack];
969                                                                 if (((npack+1) % 10)==0){
970                                                                         val /= 10;
971                                                                         cio_write(start, nb_pos);
972                                                                         cio_write(end, nb_pos);
973                                                                         cio_write(d2pfp(val), nb_sv);
974                                                                         start = end+1;
975                                                                         val = 0;
976                                                                 }
977                                                                 end++;
978                                                         }
979                                                         if (start != end){
980                                                                 val /= npack%10;
981                                                                 cio_write(start, nb_pos);
982                                                                 cio_write(end-1, nb_pos);
983                                                                 cio_write(d2pfp(val), nb_sv);
984                                                         }
985                                                 }
986                                                 break;
987                                         default:
988                                                 printf("errore\n");
989                                 }
990
991                                 break;
992                         case 5:
993                                 //MAXERR
994                                 printf("Opzione MAXERR non supportata\n");
995                                 break;
996                         default:
997                                 printf("opzione riservata per uso futuro\n");
998                 }
999         for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
1000                 free(PSNR[i]);
1001         free(PSNR);
1002         for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
1003                 free(dPSNR[i]);
1004         free(dPSNR);
1005         for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
1006                 free(dMSE[i]);
1007         free(dMSE);
1008
1009         len = cio_tell() - set;
1010         cio_seek(set);
1011         cio_write(len, 2);
1012         cio_skip(len - 2);
1013 }
1014
1015
1016 int JPWL_len_EPB(unsigned int LDPepb, unsigned int Pepb, unsigned char Depb){
1017         unsigned int len = 11, n1, n2, k1, k2, lenp;
1018         char pos_epb;
1019         
1020         
1021         lenp = cio_tell();
1022         /* determino len_epb e i parametri di codifica*/
1023         pos_epb= Depb & 0x3F;
1024         if ((j2k_state == J2K_STATE_MH) && !(pos_epb)){  // sto scrivendo il primo epb del mh
1025                 n1=160;
1026                 k1=64;
1027                 len += (n1 - k1)*(unsigned int)ceil((double)(lenp + 11)/k1);
1028         } else {if ((j2k_state == J2K_STATE_TPH) && !(pos_epb)){                // primo epb di un tph
1029                                 n1=80;
1030                                 k1=25;
1031                                 len += 55;
1032                         } else {                    // altro epb
1033                                 n1=40;
1034                                 k1=13;
1035                                 len += 27;
1036                         }
1037         }
1038         if (!Pepb) {               // per codificare i dati seguenti uso lo stesso codice di prima
1039                 n2 = n1;
1040                 k2 = k1;
1041             len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
1042
1043         } else{
1044                 if (Pepb == 0xffffffff)   
1045                         1;
1046
1047                 else {if ((Pepb >> 28)== 1){
1048                                 if ((Pepb & 0x00000001)){
1049                                         len += 4;
1050                                 } else {
1051                                         len +=2;
1052                                 }
1053                         } else {if ((Pepb >> 28)== 2){
1054                                                 n2 = ((Pepb & 0x0000ff00)>> 8);
1055                                                 k2 = (Pepb & 0x000000ff);
1056                                                 len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
1057                                                 }
1058                                         }
1059                         }
1060         }
1061
1062         
1063         return len;
1064
1065 }
1066
1067 void jpwl_write_RED(){
1068         //questa funzione scrive un marker RED di test vuoto
1069         cio_write(JPWL_MS_RED,2);
1070         //gi� scrivo la len(non metto informazioni nel marker, poich� la codestream sar� corretta)
1071         cio_write(3,2);
1072         cio_write(jpwl_cp.pred,1);
1073 }
1074
1075
1076
1077
1078
1079 void JPWL_write_Pepbs(long *pepbs, int num_epb){
1080         int i, lenp, pos;
1081         
1082         cio_write(0,2);                 // id relativo all'uso degli epb
1083         cio_skip(2);
1084         lenp=cio_tell();
1085         /*
1086                 Qui in base a come decider� di far operare l'encoder dovr� trovare il modo di inserire
1087                 i Pepb relativi alla struttura; In questo caso uso una struttura fissa che prevede un 
1088                 solo epb nel main header che usa lo stesso codice relativo al primo epb e pi� epb per 
1089                 ogni tile part header, il primo che protegge tutto il tph con lo stesso codice relativo 
1090                 al primo epb del tile part,  gli altri a protezione dei dati con un codice rs specificato
1091         */
1092         for (i=0; i<num_epb; i++)
1093                 cio_write(pepbs[i],4);
1094         // scrivo la Lid
1095         pos=cio_tell();
1096         cio_seek(lenp-2);
1097         cio_write(pos-lenp,2);
1098         cio_seek(pos);
1099 }
1100
1101 void correggi_esd(int offset, int len_esd, int Pesd){
1102         //nel caso in cui i dati dell'esd sono posti in byte range mode, devo correggere con l'offset
1103         //pari alla somma della lunghezza del primo epb e dell'epc
1104         int nb_pos, nb_sv, start, end, set, p;
1105         p=cio_tell();
1106         //mi metto all'inizio dei dati dell'esd
1107         cio_skip(6);
1108         //printf("marker: %x\n", cio_read(2));
1109         //printf("len: %x\n", cio_read(2));
1110         //printf("info: %x\n", cio_read(2));
1111         //determino i parametri con cui sono scritti i dati
1112         nb_pos = (((Pesd & 0x02)>>1)==0) ? 2 : 4;
1113         nb_sv = (((Pesd & 0x04)>>2)==0) ? 1 : 2;
1114         //printf("offset: %x\n",offset);
1115         //printf("len_esd: %d\n", len_esd);
1116         //procedo alla correzione
1117         while ((cio_tell()-p)<len_esd) {
1118                 set=cio_tell();
1119                 start = cio_read(nb_pos);
1120                 //printf("start: %d\n", start);
1121                 end = cio_read(nb_pos);
1122                 //printf("end: %d\n", end);
1123                 cio_seek(set);
1124                 cio_write(start + offset, nb_pos);
1125                 cio_write(end + offset, nb_pos);
1126                 cio_skip(nb_sv);
1127                 //printf("pos: %d\n", cio_tell());
1128         }
1129
1130 }
1131
1132 int pianifica_epb(unsigned int LDPepb, unsigned int Pepb, int *n_epb ){
1133         int len_max, *num_epb, n2, k2;
1134         //serve per pianificare il numero di epb necessari per proteggere i dati
1135         num_epb = n_epb;
1136         if ((Pepb >> 28)== 2){
1137                 n2 = ((Pepb & 0x0000ff00)>> 8);
1138                 k2 = (Pepb & 0x000000ff);
1139                 len_max = 0xFF80 * k2 / (n2 - k2);
1140                 *num_epb = (int) ceil((double) LDPepb / len_max);
1141         } else if (!Pepb){
1142                 n2 = 40;
1143                 k2 = 13;
1144                 len_max = 0xFF80 * k2 / (n2 - k2);
1145                 *num_epb = (int) ceil((double) LDPepb / len_max);
1146         } else {
1147                 *num_epb = 1;
1148                 len_max = LDPepb+2;
1149         }
1150         return len_max;
1151 }
1152
1153
1154
1155 int uep(int notil, char *bs, char *header, int len_header){
1156         //questa funzione ritorna il valore di psot_corr
1157         double maxMSE, val, dMSE, M;
1158         int depb, mask, corr=0, len_til, npix, lung=0, i, h=0, k, l=0, npack, start[6], end[6], fa=0, pkt=0, Psot_cor=0, lmax[6], no_epb[6], len[6], set, cont, tot_epb=0;
1159         char *data;
1160         double *PSNR; 
1161         
1162         PSNR = (double *) malloc(info_IM.num*sizeof(double));
1163         //printf("uep\n");
1164
1165         //mi piazzo alla fine di SOT
1166         set=cio_tell();
1167
1168         //determino il psnr che si raggiunge con ogni pacchetto
1169         M = 65025;
1170         //printf("M: %f\n",M);
1171         val = 0;
1172         npix = info_IM.tile[notil-1].nbpix;
1173         maxMSE = info_IM.tile[notil-1].distotile / npix;
1174         //printf("max mse:%f\n", maxMSE);
1175         for(npack=0; npack < (info_IM.num); npack++){
1176                 dMSE = info_IM.tile[notil-1].packet[npack].disto / npix;
1177                 //printf("dmse: %f\n", dMSE);
1178                 if (dMSE!=0){
1179                         val += dMSE;
1180                         PSNR[npack] = (10 * log10(M/(maxMSE - val)));   
1181                 }
1182                 else {
1183                         PSNR[npack] = PSNR[npack-1];
1184                 }
1185                 printf("psnr %d: %f\n ", npack, PSNR[npack] );
1186         }
1187         
1188         //a questo punto determino le fasce
1189         npack=0;
1190         
1191         //inizializzo le posizioni
1192         for (i=0;i<6;i++){
1193                 start[i]=-1;
1194                 end[i]=-1;
1195         }
1196         start[0]=0;
1197         while (npack<info_IM.num){
1198                 //printf("conta: %d\n", npack);
1199                 if (PSNR[npack]<20){
1200                         npack++;
1201                 }
1202                 else if ((PSNR[npack]>=20)&&(PSNR[npack]<23)){
1203                         if (fa!=1){
1204                                 fa=1;
1205                                 end[0]=npack++;
1206                                 start[1]=npack;
1207                         }
1208                         else
1209                                 npack++;
1210                 
1211                 }
1212                 else if ((PSNR[npack]>=23)&&(PSNR[npack]<26)){
1213                         if (fa!=2){
1214                                 end[fa]=npack++;
1215                                 start[2]=npack;
1216                                 fa=2;
1217                         }
1218                         else
1219                                 npack++;
1220                 
1221                 }
1222                 else if ((PSNR[npack]>=26)&&(PSNR[npack]<35)){
1223                         if (fa!=3){
1224                                 end[fa]=npack++;
1225                                 start[3]=npack;
1226                                 fa=3;
1227                         }
1228                         else
1229                                 npack++;
1230                 
1231                 }
1232                 else if ((PSNR[npack]>=35)&&(PSNR[npack]<37)){
1233                         if (fa!=4){
1234                                 end[fa]=npack++;
1235                                 start[4]=npack;
1236                                 fa=4;
1237                         }
1238                         else
1239                                 npack++;
1240
1241                 }
1242                 else{
1243                         end[fa]=info_IM.num-1;
1244                         npack=info_IM.num;
1245                         fa=5;
1246                 
1247                 }
1248         
1249         }
1250         // devo mettere la fine all'ultima fascia abilitata
1251         if (fa!=5){
1252                 //risolvo un bug!!
1253                 if(start[fa] == info_IM.num){
1254                         //disattivo l'ultima fascia se non correttamente abilitata
1255                         start[fa] = -1;
1256                         fa--;
1257                 }
1258                 else
1259                         end[fa]=info_IM.num-1;
1260         }
1261         printf("livello   start    end\n");
1262         for (i=0;i<6;i++)
1263                 printf("%d\t%d\t%d\n", i, start[i], end[i]);
1264
1265         for (i=0;i<6;i++)
1266                 printf("pepb[%d]: %x\n", i, jpwl_cp.pepb[i]);
1267
1268         //determino anticipatamente le lunghezze degli epb
1269         if (len_header)
1270                 Psot_cor += JPWL_len_EPB((len_header), jpwl_cp.pepb[0], 0) + 2;
1271         fa=0;
1272         //devo calcolare le lunghezze degli epb necessari per ogni fascia
1273         for(i=0;i<5;i++){
1274                 len[i]=0;
1275                 if ((start[i]!=-1)&&(end[i]!=-1)){
1276                         len[i]= (info_IM.tile[notil-1].packet[end[i]].end_pos) - info_IM.tile[notil-1].packet[start[i]].start_pos +1;
1277                         /*printf("len[%d]: %d\n",i, len[i]); */
1278                         if (i==0)
1279                                 //poich� non viene considerato il marker SOD
1280                                 len[i]+=2;
1281                         lmax[i] = pianifica_epb(len[i], jpwl_cp.pepb[i+1], &no_epb[i]);
1282                         /*printf("lmax[%d]: %d\n", i, lmax[i]);*/
1283                         tot_epb+=no_epb[i];
1284                         /*printf("num epb[%d]: %d\n",i, no_epb[i]);*/
1285                         if(no_epb[i] > 1){
1286                                 if ((!(len_header))&&(i==1))
1287                                         Psot_cor += JPWL_len_EPB(lmax[i], jpwl_cp.pepb[i+1], 0) + (no_epb[i]-2)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41);
1288                                 else
1289                                         Psot_cor += (no_epb[i]-1)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41);
1290                         }
1291                         else{
1292                                 if ((!(len_header))&&(i==1))
1293                                         Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x0);
1294                                 else
1295                                         Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x41);
1296                         }
1297
1298                         Psot_cor += 2*(no_epb[i]);
1299                         fa=i;
1300
1301
1302                 }
1303         }
1304         /*printf("fa: %d\n", fa);
1305         printf("psot_cor: %d\n", Psot_cor);
1306         printf("tot_epb: %d\n", tot_epb);*/
1307         /*len[5]=0;
1308         for(i=0;i<5;i++){
1309                 len[5]+=len[i];
1310         }*/
1311         /*printf("lendata: %d\n", len[5]);*/
1312         cio_seek(set - 6);
1313         len_til=cio_read(4);
1314         cio_skip(-4);
1315         cio_write(Psot_cor + len_til,4);
1316
1317         cio_seek(set);
1318         //correzione index
1319         if (info_IM.index_on){
1320                 corr += Psot_cor;
1321                 info_IM.tile[notil-1].end_header += corr;
1322                 info_IM.tile[notil-1].end_pos += corr;
1323                 if (notil < j2k_cp->tw * j2k_cp->th)
1324                         info_IM.tile[notil].start_pos += corr;
1325                 pack_corr(corr, notil-1);
1326         }
1327         //scrivo gli EPB e riporto i buffer
1328         if (len_header){
1329                 JPWL_write_EPB(header, len_header, jpwl_cp.pepb[0], 0);
1330                 h=1;
1331                 pepbs[cont_epb++]=jpwl_cp.pepb[0];
1332         }
1333         for (i = 0; i < len_header; i++)
1334                 cio_write(header[i],1);
1335         free(header);
1336         mask = (tot_epb == 1) ? 0x40 : 0x80;
1337         for(i=0;i<5;i++){
1338                 if ((start[i]!=-1)&&(end[i]!=-1)){
1339                         data = (unsigned char *)malloc(lmax[i]*sizeof(unsigned char));
1340                         for (k=0; k < no_epb[i]; k++){
1341                                 cont=0;
1342                                 depb = mask | ((l+h)&0x3F);
1343                                 
1344                                 while (((cont + k*lmax[i])< len[i])&&(cont < lmax[i])){
1345                                         data[cont] = bs[cont + k*lmax[i] + lung];
1346                                         cont++;
1347                                 }
1348                                 if ((cont < lmax[i])&&(i==fa))
1349                                         depb |= 0x40;
1350                                 /*printf("depb[%d]: %x\n",i, depb);*/
1351                                 JPWL_write_EPB(data, cont, jpwl_cp.pepb[i+1], depb);
1352                                 pepbs[cont_epb++]=jpwl_cp.pepb[i+1];
1353                                 if (l==1)
1354                                         scavalcato=1;
1355                                 l++;
1356                         }
1357                         free(data);
1358                         lung+=len[i];
1359                 }
1360         }
1361
1362         /*printf("lung: %d\n", lung );*/
1363         return Psot_cor;
1364
1365 }
1366
1367
1368
1369 int uep_lay(int notil, char *bs, char *header, int len_header){
1370         //questa funzione ritorna il valore di psot_corr
1371         int depb, mask, corr=0, len_til, n_lay, lung=0, i, h=0, k, l=0, npack, Psot_cor=0, set, cont, tot_epb=0;
1372         char *data;
1373         int *lmax, *no_epb, *len;
1374         
1375         //determino il numero dei layer
1376         n_lay = info_IM.Layer;
1377
1378         //determino il numero di pacchetti per layer
1379         npack = info_IM.num / n_lay;
1380
1381         //preparo i vettori necessari
1382
1383         if(!(lmax=(int *) malloc(n_lay * sizeof(int))))
1384              printf("Non pu� essere allocata memoria per eseguire il programma3\n ");
1385         if(!(no_epb=(int *) malloc(n_lay * sizeof(int))))
1386              printf("Non pu� essere allocata memoria per eseguire il programma3\n ");
1387         if(!(len=(int *) malloc(n_lay * sizeof(int))))
1388              printf("Non pu� essere allocata memoria per eseguire il programma3\n ");
1389
1390         //mi piazzo alla fine di SOT
1391         set=cio_tell();
1392
1393
1394         //determino anticipatamente le lunghezze degli epb
1395         if (len_header)
1396                 Psot_cor += JPWL_len_EPB((len_header), jpwl_cp.pepb[0], 0) + 2;
1397
1398         //devo calcolare le lunghezze degli epb necessari per ogni fascia
1399         for(i=0;i<n_lay;i++){
1400                 //determino le lunghezze dei layer
1401                 len[i] = (info_IM.tile[notil-1].packet[((i+1) * npack) - 1].end_pos) - info_IM.tile[notil-1].packet[i * npack].start_pos +1;
1402                 /*printf("len[%d]: %d\n",i, len[i]); */
1403                 if (i==0)
1404                         //poich� non viene considerato il marker SOD
1405                         len[i]+=2;
1406                 lmax[i] = pianifica_epb(len[i], jpwl_cp.pepb[i+1], &no_epb[i]);
1407                 /*printf("lmax[%d]: %d\n", i, lmax[i]);*/
1408                 tot_epb+=no_epb[i];
1409                 /*printf("num epb[%d]: %d\n",i, no_epb[i]);*/
1410                 if(no_epb[i] > 1){
1411                         if ((!(len_header))&&(i==1))
1412                                 Psot_cor += JPWL_len_EPB(lmax[i], jpwl_cp.pepb[i+1], 0) + (no_epb[i]-2)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41);
1413                         else
1414                                 Psot_cor += (no_epb[i]-1)*JPWL_len_EPB((lmax[i]), jpwl_cp.pepb[i+1], 0x41) + JPWL_len_EPB((len[i] % lmax[i]), jpwl_cp.pepb[i+1], 0x41);
1415                 }
1416                 else{
1417                         if ((!(len_header))&&(i==1))
1418                                 Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x0);
1419                         else
1420                                 Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x41);
1421                 }
1422
1423                 Psot_cor += 2*(no_epb[i]);
1424         }
1425
1426         //correzione di psot
1427         cio_seek(set - 6);
1428         len_til=cio_read(4);
1429         cio_skip(-4);
1430         cio_write(Psot_cor + len_til,4);
1431         cio_seek(set);
1432
1433         //correzione index
1434         if (info_IM.index_on){
1435                 corr += Psot_cor;
1436                 info_IM.tile[notil-1].end_header += corr;
1437                 info_IM.tile[notil-1].end_pos += corr;
1438                 if (notil < j2k_cp->tw * j2k_cp->th)
1439                         info_IM.tile[notil].start_pos += corr;
1440                 pack_corr(corr, notil-1);
1441         }
1442
1443         //scrivo gli EPB e riporto i buffer
1444         if (len_header){
1445                 JPWL_write_EPB(header, len_header, jpwl_cp.pepb[0], 0);
1446                 h=1;
1447                 pepbs[cont_epb++]=jpwl_cp.pepb[0];
1448         }
1449         for (i = 0; i < len_header; i++)
1450                 cio_write(header[i],1);
1451         free(header);
1452
1453         //EPB a protezione della bitstream
1454         mask = (tot_epb == 1) ? 0x40 : 0x80;
1455         for(i=0;i<n_lay;i++){
1456                 //preparo il buffer con i dati da proteggere
1457                 data = (unsigned char *)malloc(lmax[i]*sizeof(unsigned char));
1458                 for (k=0; k < no_epb[i]; k++){
1459                         cont=0;
1460                         depb = mask | ((l+h)&0x3F);
1461                         
1462                         while (((cont + k*lmax[i])< len[i])&&(cont < lmax[i])){
1463                                 data[cont] = bs[cont + k*lmax[i] + lung];
1464                                 cont++;
1465                         }
1466                         if ((cont < lmax[i]) && (i == (n_lay-1)))
1467                                 depb |= 0x40;
1468                         /*printf("depb[%d]: %x\n",i, depb);*/
1469                         JPWL_write_EPB(data, cont, jpwl_cp.pepb[i+1], depb);
1470                         pepbs[cont_epb++]=jpwl_cp.pepb[i+1];
1471                         if (l==1)
1472                                 scavalcato=1;
1473                         l++;
1474                 }
1475                 free(data);
1476                 lung+=len[i];
1477                 
1478         }
1479         free(len);
1480         free(no_epb);
1481         free(lmax);
1482         /*printf("lung: %d\n", lung );*/
1483         return Psot_cor;
1484
1485 }
1486
1487
1488 int jpwl_encode(char *input, char * output, unsigned long CL){
1489         long len_tot, len_primo_epb, len_til, Psot_cor;
1490         unsigned char *buf1, *buf2, *buf3, *data;
1491         int h=0,pos, end_siz, i, depb, len_SIZ, notil, len_mar, len_red, mark, set, end_tph, len_data1, len_data2, len_data3, cur_pos, fine_mh, len_epc, corr=0, len_esd=0, lmax, no_epb, cont, mask;
1492         
1493         
1494         // controllo se devo usare gli epb
1495         if (jpwl_cp.EPB_on){
1496                 
1497                 //parser, serve a determinare le lunghezze degli epb e scrivere quelli nei tile part
1498                 cio_init(input, CL*4);
1499                 len_tot=CL;
1500                 cio_skip(4);
1501                 len_mar = cio_read(2);
1502                 cio_skip(len_mar-2);
1503                 end_siz=cio_tell();
1504                 j2k_state = J2K_STATE_MH;
1505                 mark = cio_read(2);
1506                 //printf("mark: %x\n",mark);
1507                 while (mark!=0xff90){
1508                         len_mar = cio_read(2);
1509                         cio_skip(len_mar-2);
1510                         mark = cio_read(2);
1511                         //printf("mark: %x\n",mark);
1512                 }
1513                 fine_mh=cio_tell()-2;
1514                 cont_epb=1;
1515                 pepbs[0]=jpwl_cp.pepb[0];
1516
1517                 j2k_state = J2K_STATE_TPH;
1518                 for (notil=1; notil <= j2k_cp->tw * j2k_cp->th; notil++){
1519                         Psot_cor = 0;
1520                         //trucco per non fare sbagliare nella scrittura di pi� di 64 epb
1521                         scavalcato=0;
1522                         cio_skip(4);
1523                         len_til = cio_read(4);
1524                         cio_skip(2);
1525                         set = cio_tell();
1526                         mark = cio_read(2);
1527                         //printf("mark: %x\n",mark);
1528                         while (mark!=0xff93){
1529                                 len_mar = cio_read(2);
1530                                 cio_skip(len_mar-2);
1531                                 mark = cio_read(2);
1532                                 //printf("mark: %x\n",mark);
1533                         }
1534                         end_tph = cio_tell()-2;
1535                         len_data1= end_tph - set;
1536                         len_data2= len_til+set-end_tph-12;
1537                         /*printf("lendata2: %d\n",len_data2);*/
1538                         buf1 = (unsigned char *) malloc(len_data1*sizeof(unsigned char));
1539                         buf2 = (unsigned char *) malloc(len_data2*sizeof(unsigned char));
1540                     cio_seek(set);
1541                         for (i=0; i<len_data1; i++)
1542                                 buf1[i]=cio_read(1);
1543                         for (i=0; i<len_data2; i++)
1544                                 buf2[i]=cio_read(1);
1545                         cur_pos=cio_tell();
1546                         len_data3 = len_tot-cur_pos;
1547                         buf3 = (unsigned char *) malloc((len_data3)*sizeof(unsigned char));
1548                         for (i=0; i< len_data3; i++)
1549                                 buf3[i]=cio_read(1);
1550                         //uep
1551                         if (jpwl_cp.UEP_on){
1552                                 cio_seek(set);
1553                                 Psot_cor=uep_lay(notil,buf2,buf1,len_data1);
1554                                 //free(buf1);
1555                                 len_tot += Psot_cor;
1556                         }
1557                         else{
1558                                 //correzione Psot
1559                                 if (len_data1)
1560                                         Psot_cor += JPWL_len_EPB((len_data1), jpwl_cp.pepb[0], 0) + 2;
1561                                 lmax = pianifica_epb(len_data2, jpwl_cp.pepb[1], &no_epb);
1562                                 //printf("num epb: %d\n", no_epb);
1563                                 if(no_epb > 1){
1564                                         if (len_data1)
1565                                                 Psot_cor += (no_epb-1)*JPWL_len_EPB((lmax), jpwl_cp.pepb[1], 0x41) + JPWL_len_EPB((len_data2 % lmax), jpwl_cp.pepb[1], 0x41);
1566                                         else
1567                                                 Psot_cor += JPWL_len_EPB(lmax, jpwl_cp.pepb[1], 0) + (no_epb-2)*JPWL_len_EPB((lmax), jpwl_cp.pepb[1], 0x41) + JPWL_len_EPB((len_data2 % lmax), jpwl_cp.pepb[1], 0x41);
1568                                 }
1569                                 else{
1570                                         if (len_data1)
1571                                                 Psot_cor += JPWL_len_EPB((len_data2), jpwl_cp.pepb[1], 0x41);
1572                                         else
1573                                                 Psot_cor += JPWL_len_EPB((len_data2), jpwl_cp.pepb[1], 0x0);
1574                                 }
1575                                 Psot_cor += 2*(no_epb);
1576                                 len_tot += Psot_cor;
1577                                 //Psot_cor += len_til;
1578                                 cio_seek(set - 6);
1579                                 cio_write(Psot_cor + len_til,4);
1580
1581                                 cio_seek(set);
1582                                 //correzione index
1583                                 if (info_IM.index_on){
1584                                         corr += Psot_cor;
1585                                         info_IM.tile[notil-1].end_header += corr;
1586                                         info_IM.tile[notil-1].end_pos += corr;
1587                                         if (notil < j2k_cp->tw * j2k_cp->th)
1588                                                 info_IM.tile[notil].start_pos += corr;
1589                                         pack_corr(corr, notil-1);
1590                                 }
1591                                 //scrivo gli EPB e riporto i buffer
1592                                 if (len_data1){
1593                                         JPWL_write_EPB(buf1, len_data1, jpwl_cp.pepb[0], 0);
1594                                         h=1;
1595                                         pepbs[cont_epb++]=jpwl_cp.pepb[0];
1596                                 }
1597                                 for (i = 0; i < len_data1; i++)
1598                                         cio_write(buf1[i],1);
1599                                 free(buf1);
1600                                 mask = (no_epb == 1) ? 0x40 : 0x80;
1601                                 data = (unsigned char *)malloc(lmax*sizeof(unsigned char));
1602                                 for (i=0; i < no_epb; i++){
1603                                         cont=0;
1604                                         depb = mask | ((i+h)&0x3F);
1605                                         while (((cont + i*lmax)< len_data2)&&(cont < lmax)){
1606                                                 data[cont] = buf2[cont + i*lmax];
1607                                                 cont++;
1608                                         }
1609                                         if (cont < lmax)
1610                                                 depb |= 0x40;
1611                                         JPWL_write_EPB(data, cont, jpwl_cp.pepb[1], depb);
1612                                         pepbs[cont_epb++]=jpwl_cp.pepb[1];
1613                                         if (i==1)
1614                                                 scavalcato=1;
1615                                 }
1616                                 free(data);
1617                         }
1618                         for (i = 0; i < len_data2; i++)
1619                                 cio_write(buf2[i],1);
1620                         cur_pos=cio_tell();
1621                         free(buf2);
1622                         for (i=0; i < len_data3; i++)
1623                                 cio_write(buf3[i],1);
1624                         free(buf3);
1625                         cio_seek(cur_pos);
1626                         mark = cio_read(2);
1627
1628                 }
1629
1630                 //ora mi trovo alla fine della codestream
1631                 len_tot=cio_tell();
1632                 // controllo se devo inserire l'esd (non lo devo inserire qui se � attivo il packet range mode)
1633                 if ((jpwl_cp.ESD_on)&(!(((jpwl_cp.pesd & 0xC0)>>6)==2))){
1634                         cio_seek(end_siz);
1635                         len_data1 = len_tot - end_siz;
1636                         buf1 = (unsigned char *) malloc(len_data1 * sizeof(unsigned char));
1637                         for (i = 0; i < len_data1; i++){
1638                                 buf1[i] = cio_read(1);
1639                         }
1640                         //printf("%x%x\n", buf1[len_tot - set - 2], buf1[len_tot - set -1]);
1641                         cio_seek(end_siz);
1642                         jpwl_write_ESD(jpwl_cp.pesd, 0);
1643                         len_esd = cio_tell() - end_siz;
1644                         //printf("len esd: %d\n",len_esd);
1645                         len_tot += len_esd;
1646                         for (i = 0; i < len_data1; i++){
1647                                 cio_write(buf1[i],1);
1648                         }
1649                         free(buf1);
1650                 }
1651
1652                 //scrivo l'epc ed il primo epb
1653                 cio_init(output, len_tot*2);
1654                 j2k_state = J2K_STATE_MH;
1655                 for (i=0; i< 6; i++){
1656                         output[i]=input[i];
1657                 }
1658                 cio_skip(4);
1659                 len_SIZ = cio_read(2);
1660                 for (i=6; i< 4+len_SIZ; i++){
1661                 output[i]=input[i];
1662                 }
1663                 cio_skip(len_SIZ-2);
1664                 set = cio_tell();
1665                 len_epc = 15 + cont_epb*4;
1666                 len_primo_epb=JPWL_len_EPB(fine_mh - set + len_epc, jpwl_cp.pepb[0], 0);
1667                 len_red=(jpwl_cp.RED_on)? 5 : 0; 
1668                 if (info_IM.index_on){
1669                         corr=len_epc + len_primo_epb + 2 + len_esd + len_red;
1670                         info_IM.Main_head_end += corr;
1671                         //printf("fine_mh: %d\n",info_IM.Main_head_end);
1672                         //printf("%d\n", info_IM.tile[0].start_pos);
1673                         info_IM.tile[0].start_pos += corr;
1674                         for (i=0; i < j2k_cp->th * j2k_cp->tw; i++){
1675                                 info_IM.tile[i].end_header += corr;
1676                                 info_IM.tile[i].end_pos += corr;
1677                                 if (i <  j2k_cp->tw * j2k_cp->th)
1678                                         info_IM.tile[i+1].start_pos += corr;
1679                                 pack_corr(corr, i);
1680                         } 
1681                 } 
1682
1683                 jpwl_write_EPC_fin(len_tot+len_primo_epb+2+len_esd+len_red, pepbs, cont_epb);
1684                 //controllo se devo inserire la red (solo test)
1685                 if (jpwl_cp.RED_on) 
1686                         jpwl_write_RED();
1687                 pos=cio_tell();
1688                 //scrivo da input il main header
1689                 for (i=4+len_SIZ; i<fine_mh+len_esd; i++){
1690                         cio_write(input[i],1);
1691                 }
1692                 cur_pos = cio_tell();
1693                 //se l'esd � presente ed � in byte range mode devo correggere la posizioni
1694                 if (jpwl_cp.ESD_on && (((jpwl_cp.pesd & 0xC0)>>6)==1) ){
1695                         cio_seek(pos);
1696                         correggi_esd(corr, len_esd, jpwl_cp.pesd);
1697                 }
1698                 
1699                 len_data1=cur_pos-set;
1700                 buf1= (unsigned char *) malloc((len_data1)*sizeof(unsigned char));
1701                 cio_seek(set);
1702                 for (i=0; i< len_data1; i++){
1703                         buf1[i]=cio_read(1);
1704                 }
1705                 cio_seek(set);
1706                 JPWL_write_EPB(buf1, len_data1, jpwl_cp.pepb[0], 0x40);
1707                 for (i = 0; i < len_data1; i++)
1708                         cio_write(buf1[i],1);
1709                 free(buf1);
1710                 for (i = fine_mh+len_esd; i < len_tot; i++)
1711                         cio_write(input[i],1);
1712                 
1713                 
1714         }
1715         
1716         
1717         // se devo inserire l'epc da solo lo posiziono subito dopo SIZ
1718         else {
1719                 len_esd=0;
1720                 cio_init(output, CL*2);
1721                 for (i=0; i< 6; i++){
1722                         output[i]=input[i];
1723                 }
1724                 cio_skip(4);
1725                 len_SIZ = cio_read(2);
1726                 for (i=6; i< 4+len_SIZ; i++){
1727                         output[i]=input[i];
1728                 }
1729                 cio_skip(len_SIZ-2);
1730                 set = cio_tell();
1731                 // controllo se devo inserire l'esd 
1732                 if ((jpwl_cp.ESD_on)&(!(((jpwl_cp.pesd & 0xC0)>>6)==2))){
1733                         jpwl_write_ESD(jpwl_cp.pesd, 0);
1734                         len_esd = cio_tell() - set;
1735                         cio_seek(set);
1736                         buf1 = (unsigned char *) malloc(len_esd * sizeof(unsigned char));
1737                         for (i = 0; i < len_esd; i++){
1738                                 buf1[i] = cio_read(1);
1739                         }
1740                         cio_seek(set);
1741                         len_red=(jpwl_cp.RED_on)? 5 : 0;
1742                         corr=len_esd+11+len_red;
1743                         //correzione delle posizioni dei pack nella struttura info image da fare nel caso di esd nel main header
1744                         if (info_IM.index_on){
1745                                 info_IM.Main_head_end += corr;
1746                                 //printf("fine_mh: %d\n",info_IM.Main_head_end);
1747                                 info_IM.tile[0].start_pos += corr;
1748                                 for (i=0; i < j2k_cp->th * j2k_cp->tw; i++){
1749                                         info_IM.tile[i].end_header += corr;
1750                                         info_IM.tile[i].end_pos += corr;
1751                                         if (i <  j2k_cp->tw * j2k_cp->th)
1752                                                 info_IM.tile[i+1].start_pos += corr;
1753                                         pack_corr(corr, i);
1754                                 } 
1755                         } 
1756                 }
1757                 jpwl_write_EPC_fin(CL + len_esd, NULL, 0);
1758                 //controllo se devo inserire la red (solo test)
1759                 if (jpwl_cp.RED_on) 
1760                         jpwl_write_RED();
1761                 set=cio_tell();
1762                 if (jpwl_cp.ESD_on){
1763                         for (i = 0; i < len_esd; i++){
1764                                         cio_write(buf1[i],1);
1765                                 }
1766                         free(buf1);
1767                         if (((jpwl_cp.pesd & 0xC0)>>6)==1) {
1768                                 cio_seek(set);
1769                                 correggi_esd(corr, len_esd, jpwl_cp.pesd);
1770                         }
1771                 }
1772                 for (i=4+len_SIZ; i < CL; i++){
1773                         cio_write(input[i],1);
1774                 }
1775         }
1776
1777         
1778         return cio_tell();
1779
1780 }
1781
1782 void get_jpwl_cp(j2k_cp_t *cp){
1783         char risp, scelta,choose;
1784         int out = 0;
1785         unsigned long n;
1786         j2k_cp_t *param;
1787         
1788         param = cp;
1789         printf("You have chosen to activate JPWL techniques. EPC will be inserted\n");
1790         if (param->intermed_file){
1791                 printf("Since intermed file option is active, EPC will not contain any information on the");
1792                 printf("codestream length: eventual ESDs will be written in tile part headers.\n\n\n");
1793         }
1794         printf("Do you want to use EPBs (y/n)?: ");
1795         risp = (char) _getche();
1796         printf("\n\n\n");
1797         do {
1798                 switch (risp){
1799                         case 'y':
1800                                 jpwl_cp.EPB_on = 1;
1801                                 do{
1802                                         printf("UEP or EEP (u,e)?: ");
1803                                         choose = (char) _getche();
1804                                         printf("\n\n\n");
1805                                 }while(!strchr("ue",choose));
1806                                 if (choose=='e'){
1807                                                 do{
1808                                                         printf("Header protecting EPBs settings\n");
1809                                                         printf("1) Adopt the same RS code used for the EPB;\n");
1810                                                         printf("2) Enter a RS(n,32) code;\n");
1811                                                         printf("3) Use CRC-16(CCITT);\n");
1812                                                         printf("4) Use CRC-32(ETHERNET);\n");
1813                                                         printf("5) No protection at all.\n\n\n");
1814                                                         scelta = (char) _getche();
1815                                                         printf("\n\n");
1816                                                 }while(!strchr("12345",scelta));
1817                                                 if (scelta == '1')
1818                                                         jpwl_cp.pepb[0]=0x00000000;
1819                                                 if (scelta == '2'){
1820                                                         do {
1821                                                         printf("Enter the desired n value (k=32 as standard; n between 37 and 128): ");
1822                                                         scanf("%d", &n);
1823                                                         printf("\n\n\n");
1824                                                         } while ((n<37)||(n>128));
1825                                                         jpwl_cp.pepb[0] = ( n & 0x000000FF)<<8;
1826                                                         jpwl_cp.pepb[0] |= 0x20000020;
1827                                                 }
1828                                                 if (scelta == '3')
1829                                                         jpwl_cp.pepb[0] = 0x10000000;
1830                                                 if (scelta == '4')
1831                                                         jpwl_cp.pepb[0] = 0x10000001;
1832                                                 if (scelta == '5')
1833                                                         jpwl_cp.pepb[0] = 0xFFFFFFFF;
1834                                                 printf("pepb1: %x\n", jpwl_cp.pepb[0]);
1835                                                 do{
1836                                                         printf("Data protecting EPBs settings\n");
1837                                                         printf("1) Adopt the same RS code used for the EPB;\n");
1838                                                         printf("2) Enter a RS(n,32) code;\n");
1839                                                         printf("3) Use CRC-16(CCITT);\n");
1840                                                         printf("4) Use CRC-32(ETHERNET);\n");
1841                                                         printf("5) No protection at all.\n\n\n");
1842                                                         scelta = (char) _getche();
1843                                                         printf("\n\n");
1844                                                 }while(!strchr("12345",scelta));
1845                                                 if (scelta == '1')
1846                                                         jpwl_cp.pepb[1]=0x00000000;
1847                                                 if (scelta == '2'){
1848                                                         do {
1849                                                                 printf("Enter the desired n value (k=32 as standard; n between 37 and 128): ");
1850                                                         scanf("%d", &n);
1851                                                         printf("\n\n\n");
1852                                                         } while ((n<37)||(n>128));
1853                                                         jpwl_cp.pepb[1] = ( n & 0x000000FF)<<8;
1854                                                         jpwl_cp.pepb[1] |= 0x20000020;
1855                                                 }
1856                                                 if (scelta == '3')
1857                                                         jpwl_cp.pepb[1] = 0x10000000;
1858                                                 if (scelta == '4')
1859                                                         jpwl_cp.pepb[1] = 0x10000001;
1860                                                 if (scelta == '5')
1861                                                         jpwl_cp.pepb[1] = 0xFFFFFFFF;
1862                                                 printf("pepb2: %x\n", jpwl_cp.pepb[1]);
1863                                                 out=1;
1864                                 }
1865                                 if (choose=='u'){
1866                                         printf("N.B.: layer number must be less than or equal to five\n");
1867                                         param->index_on = 1;
1868                                         jpwl_cp.UEP_on = 1;
1869                                         jpwl_cp.pepb[0] = 0x20008020;
1870                                         jpwl_cp.pepb[1] = 0x20005520;
1871                                         jpwl_cp.pepb[2] = 0x20004B20;
1872                                         jpwl_cp.pepb[3] = 0x20002520;
1873                                         jpwl_cp.pepb[4] = 0x20002520;
1874                                         jpwl_cp.pepb[5] = 0x20002520;
1875                                         out=1;
1876                                 }
1877
1878                                 break;
1879                         case 'n':
1880                                 out=1;
1881                                 break;
1882                         default:
1883                                 printf("Error in answer.\n");
1884                                 printf("Do you want to use EPBs (y/n)?: ");
1885                                 risp = (char) _getche();
1886                                 printf("\n\n\n");
1887                 }
1888         }while (!out);
1889         out = 0;
1890         printf("Do you want to use ESD (y/n)?: ");
1891         risp = (char) _getche();
1892         printf("\n\n\n");
1893         do {
1894                 switch(risp){
1895                         case 'y':
1896                                 jpwl_cp.ESD_on = 1;
1897                                 param->index_on = 1;
1898                                 jpwl_cp.pesd = 0x01;
1899                                 do{
1900                                         printf("Enter representation mode:\n");
1901                                         printf("1) Packet mode;\n");
1902                                         printf("2) Byte range mode;\n");
1903                                         printf("3) Packet range mode.\n");
1904                                         scelta = (char) _getche();
1905                                         printf("\n\n");
1906                                 }while(!strchr("123",scelta));
1907                                 if (scelta =='1')
1908                                         jpwl_cp.pesd |= 0x00;
1909                                 if (scelta =='2')
1910                                         jpwl_cp.pesd |= 0x42;
1911                                 if (scelta =='3')
1912                                         jpwl_cp.pesd |= 0x80;
1913                                 do{
1914                                         printf("Enter metrics:\n");
1915                                         printf("1) Relative error sensitivity;\n");
1916                                         printf("2) MSE;\n");
1917                                         printf("3) MSE reduction;\n");
1918                                         printf("4) PSNR;\n");
1919                                         printf("5) PSNR increase.\n");
1920                                         scelta = (char) _getche();
1921                                         printf("\n\n");
1922                                 }while(!strchr("12345",scelta));
1923                                 if (scelta =='1')
1924                                         jpwl_cp.pesd |= 0x00;
1925                                 if (scelta =='2')
1926                                         jpwl_cp.pesd |= 0x0C;
1927                                 if (scelta =='3')
1928                                         jpwl_cp.pesd |= 0x14;
1929                                 if (scelta =='4')
1930                                         jpwl_cp.pesd |= 0x1C;
1931                                 if (scelta =='5')
1932                                         jpwl_cp.pesd |= 0x24;
1933                                 printf("pesd: %x\n", jpwl_cp.pesd);
1934                                 out=1;
1935                                 break;
1936                         case 'n':
1937                                 out=1;
1938                                 break;
1939                         default:
1940                                 printf("Error entering the answer.\n");
1941                                 printf("Do you want to use ESD (y/n)?: ");
1942                                 risp = (char) _getche();
1943                                 printf("\n\n\n");
1944                 }
1945         }while (!out);
1946         out = 0;
1947         printf("Do you want to use RED (y/n)?: ");
1948         risp = (char) _getche();
1949         printf("\n\n\n");
1950         do {
1951                 switch(risp){
1952                         case 'y':
1953                                 jpwl_cp.RED_on = 1;
1954                                 //suppongo che la codestream sia corretta => b0=0 e b5b4b3=000
1955                                 jpwl_cp.pred = 0x00;
1956                                 do{
1957                                         printf("Enter representation mode:\n");
1958                                         printf("1) Packet mode;\n");
1959                                         printf("2) Byte range mode;\n");
1960                                         printf("3) Packet range mode.\n");
1961                                         scelta = (char) _getche();
1962                                         printf("\n\n");
1963                                 }while(!strchr("123",scelta));
1964                                 if (scelta =='1')
1965                                         jpwl_cp.pred |= 0x00;
1966                                 if (scelta =='2')
1967                                         jpwl_cp.pred |= 0x42;
1968                                 if (scelta =='3')
1969                                         jpwl_cp.pred |= 0x80;
1970                                 printf("pred: %x\n", jpwl_cp.pred);
1971                                 out=1;
1972                                 break;
1973                         case 'n':
1974                                 out=1;
1975                                 break;
1976                         default:
1977                                 printf("Error entering the answer.\n");
1978                                 printf("Do you want to use RED (y/n)?: ");
1979                                 risp = (char) _getche();
1980                                 printf("\n\n\n");
1981                 }
1982         }while (!out);
1983
1984 }
1985
1986
1987
1988 void ResetCRC()
1989 {
1990         crcSum = 0xffffffff;
1991 }
1992
1993
1994 void UpdateCRC16(char x)
1995 {
1996         int tmp;
1997         tmp = ((x ^ (crcSum >> 8)) & 0xff);
1998         crcSum = ((crcSum << 8) ^ CrcT16[tmp]) & 0xffff;
1999 }
2000
2001 void UpdateCRC32(char x)
2002 {
2003         int tmp;
2004         tmp = ((x ^ (crcSum >> 24)) & 0xff);
2005         crcSum = ((crcSum << 8) ^ CrcT32[tmp]);
2006 }
2007 /* funzioni per l'inversione dei byte e del crc32 */
2008
2009 char reflectByte(char inbyte)
2010 {
2011   // reflect one byte
2012
2013   unsigned char outbyte=0;
2014   unsigned char i=0x01;
2015   unsigned char j;
2016
2017   for (j=0x080; j; j>>=1) 
2018   {
2019     if (inbyte & i) outbyte|=j;
2020     i<<=1;
2021   }
2022   
2023   return outbyte;
2024 }
2025
2026
2027 void reflectCRC32()
2028 {
2029  
2030
2031   unsigned long outcrc=0;
2032   unsigned long i=0x00000001;
2033   unsigned long j;
2034
2035   for (j=0x80000000; j; j>>=1) 
2036   {
2037     if (crcSum & i) 
2038                 outcrc|=j;
2039     i=i<<1;
2040   }
2041   crcSum = outcrc;
2042 }
2043
2044 /*
2045 int crc_ccitt(char *buffer, int len){
2046         char c;
2047         int i;
2048         ResetCRC();
2049         for (i=0; i<len; i++) {
2050                 c= *buffer;
2051                 UpdateCRC(c);
2052                 buffer++;
2053         }
2054         return crcSum;
2055 }
2056
2057 */
2058
2059
2060 //funzioni di conversione allo pseudo floating point format 
2061 short int d2pfp(double in){
2062         long *punt, data;
2063         short int mant, ex, out;
2064         punt = &in;
2065         punt++;
2066         data = *punt;
2067         mant = (data>>9) & 0x07FF;
2068         ex = (data>>20) & 0x07FF;
2069         out = ex+15;
2070         out = out << 11;
2071         out &= 0x0000F800;
2072         out |= mant;
2073         return out;
2074 }
2075
2076
2077 double pfp2d(short int in){
2078         double out;
2079         short int ex, mant;
2080         mant = in & 0x07FF;
2081         ex = (in >> 11) & 0x001F;
2082         out = pow(2,ex-15)*(1+(mant/pow(2,11)));
2083         return out;
2084 }