2 * Copyright 2004-2005 Andrea Betti and Michele Massarelli
3 * Copyright 2004-2005 DIEI, University of Perugia
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
29 /* questa � un' estensione della libreria dell'openjpeg in grado di implementare
30 * la parte 11 dello standard JPEG2000 ossia il JPWL
45 #define JPWL_MS_EPC 0xff68
46 #define JPWL_MS_EPB 0xff66
47 #define JPWL_MS_ESD 0xff67
48 #define JPWL_MS_RED 0xff69
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
62 //carica la struttura relativa ai parametri JPWL
63 extern JPWL_cp_t jpwl_cp;
65 extern j2k_cp_t *j2k_cp;
66 extern info_image info_IM;
69 static long pepbs[1000];
70 static int cont_epb=0;
71 static int scavalcato=0;
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};
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};
173 /* inizializza i parametri relativi al JPWL *
174 * disabilitando le funzionalit� */
176 void jpwl_cp_init(JPWL_cp_t *jpwl_cp){
177 jpwl_cp->JPWL_on = 0;
181 jpwl_cp->info_tech_on = 0;
184 /****************************************************************************************
188 ****************************************************************************************/
190 /* Scrive il marker segment EPC
191 version 0.1: in questa prima fase questo andr� subito dopo il SIZ */
193 void jpwl_write_EPC(){
196 cio_write(JPWL_MS_EPC, 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)
205 // P_EPC indica se nella codestream saranno usati gli altri
206 // marker segment oppure tecniche informative aggiuntive
213 if (jpwl_cp.info_tech_on)
219 JPWL_write_Pepbs(NULL,0);
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
236 len = cio_tell() - lenp;
247 for (i=6; i<(len + 2); i++){
252 cio_write(crcSum, 2);
253 cio_seek(lenp + len);
258 void jpwl_write_EPC_fin(unsigned long CL, long *pepbs, int num_epb){
260 unsigned long len_codestr;
262 cio_write(JPWL_MS_EPC, 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)
271 // P_EPC indica se nella codestream saranno usati gli altri
272 // marker segment oppure tecniche informative aggiuntive
279 if (jpwl_cp.info_tech_on)
285 JPWL_write_Pepbs(pepbs, num_epb);
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
302 len = cio_tell() - lenp;
305 //scrivo la lunghezza della codestream
307 len_codestr = CL + len + 2;
308 cio_write(len_codestr, 4);
317 for (i=6; i<(len + 2); i++){
322 cio_write(crcSum, 2);
323 cio_seek(lenp + len);
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;
332 unsigned int len = 11, lenp, scrivi_pb, cont, leggi, tenta=0;
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
341 cio_write(JPWL_MS_EPB, 2);
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
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
356 } else { // altro epb
363 if (!Pepb) { // per codificare i dati seguenti uso lo stesso codice di prima
367 len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
370 if (Pepb == 0xffffffff)
372 else {if ((Pepb >> 28)== 1){
373 if ((Pepb & 0x00000001)){
380 } else {if ((Pepb >> 28)== 2){
381 n2 = ((Pepb & 0x0000ff00)>> 8);
382 k2 = (Pepb & 0x000000ff);
384 len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
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);
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 ");
402 if(!(index_of=(int *) calloc(256,sizeof(int))))
403 printf("Non pu� essere allocata memoria per eseguire il programma2\n ");
405 if(!(gg=(int *) calloc((n1 - k1 +1),sizeof(int))))
406 printf("Non pu� essere allocata memoria per eseguire il programma3\n ");
410 if(!(data_=(int *) calloc(k, sizeof(int))))
411 printf("Non pu� essere allocata memoria per eseguire il programma4\n ");
413 if(!(bb=(int *) calloc((n1 - k1),sizeof(int))))
414 printf("Non pu� essere allocata memoria per eseguire il programma5\n ");
416 generate_gf(alpha_to, index_of);
418 gen_poly(k, alpha_to, index_of, gg);
420 scrivi_pb = cio_tell();
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
432 for (j=k1; j<k; j++) data_[j] = 0; // padding per la gestione di codici "accorciati"
435 encode_rs(k,alpha_to, index_of, gg, bb, data_);
438 for (j=0; j<(n1-k1); j++)
440 scrivi_pb = cio_tell();
451 /* protezione dei dati seguenti */
455 if (CRC == 1){ //crc ccitt 16 bit questo � l'algo
457 for (i=0; i < LDPepb; i++){
460 cio_write(crcSum & 0xffff, 2);
463 /*per fare il crc32 occorre invertire i byte in ingresso, invertire il crc calcolato
464 e farne il complemento a 1*/
466 for (i=0; i < LDPepb; i++){
467 UpdateCRC32(reflectByte(buf[i]));
470 crcSum ^= 0xffffffff;
471 cio_write((crcSum & 0xffff0000) >> 16, 2);
472 cio_write((crcSum & 0x0000ffff), 2);
475 //printf("n2, k2: %d %d\n", n2, k2);
478 if(!(alpha_to=(int *) malloc(256*sizeof(int))))
479 printf("Non pu� essere allocata memoria per eseguire il programma1\n ");
481 if(!(index_of=(int *) malloc(256*sizeof(int))))
482 printf("Non pu� essere allocata memoria per eseguire il programma2\n ");
484 if(!(gg=(int *) malloc((n2 - k2 +1)*sizeof(int))))
485 printf("Non pu� essere allocata memoria per eseguire il programma3\n ");
487 if(!(data_=(int *) malloc(k*sizeof(int))))
488 printf("Non pu� essere allocata memoria per eseguire il programma4\n ");
490 if(!(bb=(int *) malloc((n2 - k2)*sizeof(int))))
491 printf("Non pu� essere allocata memoria per eseguire il programma5\n ");
493 generate_gf(alpha_to, index_of);
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);
499 for (cont = 0; cont < (unsigned int)ceil((double)LDPepb/k2); cont++) {
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
507 for (j=k2; j<k; j++) data_[j] = 0; // padding per la gestione di codici "accorciati"
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);
515 encode_rs(k, alpha_to, index_of, gg, bb, data_);
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);
523 for (j=0; j<(n2-k2); j++){
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;
548 cio_write(JPWL_MS_ESD,2);
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);
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);
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));
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--;
579 // calcolo di dPSNR, dMSE e PSNR
580 // nuova routine pi� snella!!
581 for (i = notil; i < ult; i++){
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;
595 PSNR[i][npack] = PSNR[i][npack-1];
600 //ora scrivo i valori di sensibilit� in base alla metrica scelta
603 //relative error sensitivity: i lvelli di sensibilit� coincidono con i layer (livello 0 = header)
604 //uso sette livelli di sensibilit� relativa
609 for (i = notil; i < ult; i++){
610 for (npack=0; npack < (info_IM.num); npack++){
611 if (dPSNR[i][npack]>10)
613 else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8))
615 else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6))
617 else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5))
619 else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3))
621 else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7))
624 //(dPSNR[i][npack]<=1.7)
633 for (i = notil; i < ult; i++){
638 for (npack=0; npack < (info_IM.num); npack++){
640 //determinazione dei livelli
641 if (dPSNR[i][npack]>10)
643 else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8))
645 else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6))
647 else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5))
649 else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3))
651 else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7))
654 //(dPSNR[i][npack]<=1.7)
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);
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);
675 for (i = notil; i < ult; i++){
680 for (npack=0; npack < (info_IM.num); npack++){
682 //determinazione dei livelli (catena di if-else-if)
683 if (dPSNR[i][npack]>10)
685 else if ((dPSNR[i][npack]<=10)&&(dPSNR[i][npack]>8))
687 else if ((dPSNR[i][npack]<=8)&&(dPSNR[i][npack]>6))
689 else if ((dPSNR[i][npack]<=6)&&(dPSNR[i][npack]> 4.5))
691 else if ((dPSNR[i][npack]<=4.5)&&(dPSNR[i][npack]>3))
693 else if ((dPSNR[i][npack]<=3)&&(dPSNR[i][npack]>1.7))
696 //(dPSNR[i][npack]<=1.7)
702 cio_write(start, nb_pos);
703 cio_write(end-1, nb_pos);
704 cio_write(lev, nb_sv);
709 cio_write(start, nb_pos);
710 cio_write(end - 1, nb_pos);
711 cio_write(lev, nb_sv);
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);
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;
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);
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);
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;
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);
779 cio_write(start, nb_pos);
780 cio_write(end-1, nb_pos);
781 cio_write(d2pfp(val), nb_sv);
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);
802 //scrivo la mse reduction media relativa ad un blocco di dieci pacchetti
803 for (i = notil; i < ult; i++){
807 for (npack=0; npack < (info_IM.num); npack++){
808 val += dMSE[i][npack];
809 if (((npack+1) % 10)==0){
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);
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);
829 //scrivo la mse reduction media relativa ad un blocco di dieci pacchetti
830 for (i = notil; i < ult; i++){
834 for (npack=0; npack < (info_IM.num); npack++){
835 val += dMSE[i][npack];
836 if (((npack+1) % 10)==0){
838 cio_write(start, nb_pos);
839 cio_write(end, nb_pos);
840 cio_write(d2pfp(val), nb_sv);
848 cio_write(start, nb_pos);
849 cio_write(end-1, nb_pos);
850 cio_write(d2pfp(val), nb_sv);
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);
871 //divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano
872 for (i = notil; i < ult; i++){
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);
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);
897 //divido in blocchi da 10 pacchetti (l'ultimo blocco dipende da quanti pacchetti restano
898 for (i = notil; i < ult; i++){
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);
911 cio_write(start, nb_pos);
912 cio_write(end-1, nb_pos);
913 cio_write(d2pfp(PSNR[i][end-1]), nb_sv);
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);
935 //scrivo il psnr increase medio relativo ad un blocco di dieci pacchetti
936 for (i = notil; i < ult; i++){
940 for (npack=0; npack < (info_IM.num); npack++){
941 val += dPSNR[i][npack];
942 if (((npack+1) % 10)==0){
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);
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);
962 //scrivo il psnr increase medio relativo ad un blocco di dieci pacchetti
963 for (i = notil; i < ult; i++){
967 for (npack=0; npack < (info_IM.num); npack++){
968 val += dPSNR[i][npack];
969 if (((npack+1) % 10)==0){
971 cio_write(start, nb_pos);
972 cio_write(end, nb_pos);
973 cio_write(d2pfp(val), nb_sv);
981 cio_write(start, nb_pos);
982 cio_write(end-1, nb_pos);
983 cio_write(d2pfp(val), nb_sv);
994 printf("Opzione MAXERR non supportata\n");
997 printf("opzione riservata per uso futuro\n");
999 for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
1002 for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
1005 for (i=0; i<j2k_cp->th * j2k_cp->tw; i++)
1009 len = cio_tell() - set;
1016 int JPWL_len_EPB(unsigned int LDPepb, unsigned int Pepb, unsigned char Depb){
1017 unsigned int len = 11, n1, n2, k1, k2, lenp;
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
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
1032 } else { // altro epb
1038 if (!Pepb) { // per codificare i dati seguenti uso lo stesso codice di prima
1041 len +=(unsigned int) ceil((double)LDPepb/k2)*(n2 - k2);
1044 if (Pepb == 0xffffffff)
1047 else {if ((Pepb >> 28)== 1){
1048 if ((Pepb & 0x00000001)){
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);
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)
1072 cio_write(jpwl_cp.pred,1);
1079 void JPWL_write_Pepbs(long *pepbs, int num_epb){
1082 cio_write(0,2); // id relativo all'uso degli epb
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
1092 for (i=0; i<num_epb; i++)
1093 cio_write(pepbs[i],4);
1097 cio_write(pos-lenp,2);
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;
1106 //mi metto all'inizio dei dati dell'esd
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) {
1119 start = cio_read(nb_pos);
1120 //printf("start: %d\n", start);
1121 end = cio_read(nb_pos);
1122 //printf("end: %d\n", end);
1124 cio_write(start + offset, nb_pos);
1125 cio_write(end + offset, nb_pos);
1127 //printf("pos: %d\n", cio_tell());
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
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);
1144 len_max = 0xFF80 * k2 / (n2 - k2);
1145 *num_epb = (int) ceil((double) LDPepb / len_max);
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;
1162 PSNR = (double *) malloc(info_IM.num*sizeof(double));
1165 //mi piazzo alla fine di SOT
1168 //determino il psnr che si raggiunge con ogni pacchetto
1170 //printf("M: %f\n",M);
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);
1180 PSNR[npack] = (10 * log10(M/(maxMSE - val)));
1183 PSNR[npack] = PSNR[npack-1];
1185 printf("psnr %d: %f\n ", npack, PSNR[npack] );
1188 //a questo punto determino le fasce
1191 //inizializzo le posizioni
1197 while (npack<info_IM.num){
1198 //printf("conta: %d\n", npack);
1199 if (PSNR[npack]<20){
1202 else if ((PSNR[npack]>=20)&&(PSNR[npack]<23)){
1212 else if ((PSNR[npack]>=23)&&(PSNR[npack]<26)){
1222 else if ((PSNR[npack]>=26)&&(PSNR[npack]<35)){
1232 else if ((PSNR[npack]>=35)&&(PSNR[npack]<37)){
1243 end[fa]=info_IM.num-1;
1250 // devo mettere la fine all'ultima fascia abilitata
1253 if(start[fa] == info_IM.num){
1254 //disattivo l'ultima fascia se non correttamente abilitata
1259 end[fa]=info_IM.num-1;
1261 printf("livello start end\n");
1263 printf("%d\t%d\t%d\n", i, start[i], end[i]);
1266 printf("pepb[%d]: %x\n", i, jpwl_cp.pepb[i]);
1268 //determino anticipatamente le lunghezze degli epb
1270 Psot_cor += JPWL_len_EPB((len_header), jpwl_cp.pepb[0], 0) + 2;
1272 //devo calcolare le lunghezze degli epb necessari per ogni fascia
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]); */
1279 //poich� non viene considerato il marker SOD
1281 lmax[i] = pianifica_epb(len[i], jpwl_cp.pepb[i+1], &no_epb[i]);
1282 /*printf("lmax[%d]: %d\n", i, lmax[i]);*/
1284 /*printf("num epb[%d]: %d\n",i, no_epb[i]);*/
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);
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);
1292 if ((!(len_header))&&(i==1))
1293 Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x0);
1295 Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x41);
1298 Psot_cor += 2*(no_epb[i]);
1304 /*printf("fa: %d\n", fa);
1305 printf("psot_cor: %d\n", Psot_cor);
1306 printf("tot_epb: %d\n", tot_epb);*/
1311 /*printf("lendata: %d\n", len[5]);*/
1313 len_til=cio_read(4);
1315 cio_write(Psot_cor + len_til,4);
1319 if (info_IM.index_on){
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);
1327 //scrivo gli EPB e riporto i buffer
1329 JPWL_write_EPB(header, len_header, jpwl_cp.pepb[0], 0);
1331 pepbs[cont_epb++]=jpwl_cp.pepb[0];
1333 for (i = 0; i < len_header; i++)
1334 cio_write(header[i],1);
1336 mask = (tot_epb == 1) ? 0x40 : 0x80;
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++){
1342 depb = mask | ((l+h)&0x3F);
1344 while (((cont + k*lmax[i])< len[i])&&(cont < lmax[i])){
1345 data[cont] = bs[cont + k*lmax[i] + lung];
1348 if ((cont < lmax[i])&&(i==fa))
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];
1362 /*printf("lung: %d\n", lung );*/
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;
1373 int *lmax, *no_epb, *len;
1375 //determino il numero dei layer
1376 n_lay = info_IM.Layer;
1378 //determino il numero di pacchetti per layer
1379 npack = info_IM.num / n_lay;
1381 //preparo i vettori necessari
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 ");
1390 //mi piazzo alla fine di SOT
1394 //determino anticipatamente le lunghezze degli epb
1396 Psot_cor += JPWL_len_EPB((len_header), jpwl_cp.pepb[0], 0) + 2;
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]); */
1404 //poich� non viene considerato il marker SOD
1406 lmax[i] = pianifica_epb(len[i], jpwl_cp.pepb[i+1], &no_epb[i]);
1407 /*printf("lmax[%d]: %d\n", i, lmax[i]);*/
1409 /*printf("num epb[%d]: %d\n",i, no_epb[i]);*/
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);
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);
1417 if ((!(len_header))&&(i==1))
1418 Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x0);
1420 Psot_cor += JPWL_len_EPB((len[i]), jpwl_cp.pepb[i+1], 0x41);
1423 Psot_cor += 2*(no_epb[i]);
1426 //correzione di psot
1428 len_til=cio_read(4);
1430 cio_write(Psot_cor + len_til,4);
1434 if (info_IM.index_on){
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);
1443 //scrivo gli EPB e riporto i buffer
1445 JPWL_write_EPB(header, len_header, jpwl_cp.pepb[0], 0);
1447 pepbs[cont_epb++]=jpwl_cp.pepb[0];
1449 for (i = 0; i < len_header; i++)
1450 cio_write(header[i],1);
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++){
1460 depb = mask | ((l+h)&0x3F);
1462 while (((cont + k*lmax[i])< len[i])&&(cont < lmax[i])){
1463 data[cont] = bs[cont + k*lmax[i] + lung];
1466 if ((cont < lmax[i]) && (i == (n_lay-1)))
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];
1482 /*printf("lung: %d\n", lung );*/
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;
1494 // controllo se devo usare gli epb
1495 if (jpwl_cp.EPB_on){
1497 //parser, serve a determinare le lunghezze degli epb e scrivere quelli nei tile part
1498 cio_init(input, CL*4);
1501 len_mar = cio_read(2);
1502 cio_skip(len_mar-2);
1504 j2k_state = J2K_STATE_MH;
1506 //printf("mark: %x\n",mark);
1507 while (mark!=0xff90){
1508 len_mar = cio_read(2);
1509 cio_skip(len_mar-2);
1511 //printf("mark: %x\n",mark);
1513 fine_mh=cio_tell()-2;
1515 pepbs[0]=jpwl_cp.pepb[0];
1517 j2k_state = J2K_STATE_TPH;
1518 for (notil=1; notil <= j2k_cp->tw * j2k_cp->th; notil++){
1520 //trucco per non fare sbagliare nella scrittura di pi� di 64 epb
1523 len_til = cio_read(4);
1527 //printf("mark: %x\n",mark);
1528 while (mark!=0xff93){
1529 len_mar = cio_read(2);
1530 cio_skip(len_mar-2);
1532 //printf("mark: %x\n",mark);
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));
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);
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);
1551 if (jpwl_cp.UEP_on){
1553 Psot_cor=uep_lay(notil,buf2,buf1,len_data1);
1555 len_tot += Psot_cor;
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);
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);
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);
1571 Psot_cor += JPWL_len_EPB((len_data2), jpwl_cp.pepb[1], 0x41);
1573 Psot_cor += JPWL_len_EPB((len_data2), jpwl_cp.pepb[1], 0x0);
1575 Psot_cor += 2*(no_epb);
1576 len_tot += Psot_cor;
1577 //Psot_cor += len_til;
1579 cio_write(Psot_cor + len_til,4);
1583 if (info_IM.index_on){
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);
1591 //scrivo gli EPB e riporto i buffer
1593 JPWL_write_EPB(buf1, len_data1, jpwl_cp.pepb[0], 0);
1595 pepbs[cont_epb++]=jpwl_cp.pepb[0];
1597 for (i = 0; i < len_data1; i++)
1598 cio_write(buf1[i],1);
1600 mask = (no_epb == 1) ? 0x40 : 0x80;
1601 data = (unsigned char *)malloc(lmax*sizeof(unsigned char));
1602 for (i=0; i < no_epb; i++){
1604 depb = mask | ((i+h)&0x3F);
1605 while (((cont + i*lmax)< len_data2)&&(cont < lmax)){
1606 data[cont] = buf2[cont + i*lmax];
1611 JPWL_write_EPB(data, cont, jpwl_cp.pepb[1], depb);
1612 pepbs[cont_epb++]=jpwl_cp.pepb[1];
1618 for (i = 0; i < len_data2; i++)
1619 cio_write(buf2[i],1);
1622 for (i=0; i < len_data3; i++)
1623 cio_write(buf3[i],1);
1630 //ora mi trovo alla fine della codestream
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))){
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);
1640 //printf("%x%x\n", buf1[len_tot - set - 2], buf1[len_tot - set -1]);
1642 jpwl_write_ESD(jpwl_cp.pesd, 0);
1643 len_esd = cio_tell() - end_siz;
1644 //printf("len esd: %d\n",len_esd);
1646 for (i = 0; i < len_data1; i++){
1647 cio_write(buf1[i],1);
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++){
1659 len_SIZ = cio_read(2);
1660 for (i=6; i< 4+len_SIZ; i++){
1663 cio_skip(len_SIZ-2);
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;
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)
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);
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) ){
1696 correggi_esd(corr, len_esd, jpwl_cp.pesd);
1699 len_data1=cur_pos-set;
1700 buf1= (unsigned char *) malloc((len_data1)*sizeof(unsigned char));
1702 for (i=0; i< len_data1; i++){
1703 buf1[i]=cio_read(1);
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);
1710 for (i = fine_mh+len_esd; i < len_tot; i++)
1711 cio_write(input[i],1);
1717 // se devo inserire l'epc da solo lo posiziono subito dopo SIZ
1720 cio_init(output, CL*2);
1721 for (i=0; i< 6; i++){
1725 len_SIZ = cio_read(2);
1726 for (i=6; i< 4+len_SIZ; i++){
1729 cio_skip(len_SIZ-2);
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;
1736 buf1 = (unsigned char *) malloc(len_esd * sizeof(unsigned char));
1737 for (i = 0; i < len_esd; i++){
1738 buf1[i] = cio_read(1);
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;
1757 jpwl_write_EPC_fin(CL + len_esd, NULL, 0);
1758 //controllo se devo inserire la red (solo test)
1762 if (jpwl_cp.ESD_on){
1763 for (i = 0; i < len_esd; i++){
1764 cio_write(buf1[i],1);
1767 if (((jpwl_cp.pesd & 0xC0)>>6)==1) {
1769 correggi_esd(corr, len_esd, jpwl_cp.pesd);
1772 for (i=4+len_SIZ; i < CL; i++){
1773 cio_write(input[i],1);
1782 void get_jpwl_cp(j2k_cp_t *cp){
1783 char risp, scelta,choose;
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");
1794 printf("Do you want to use EPBs (y/n)?: ");
1795 risp = (char) _getche();
1802 printf("UEP or EEP (u,e)?: ");
1803 choose = (char) _getche();
1805 }while(!strchr("ue",choose));
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();
1816 }while(!strchr("12345",scelta));
1818 jpwl_cp.pepb[0]=0x00000000;
1821 printf("Enter the desired n value (k=32 as standard; n between 37 and 128): ");
1824 } while ((n<37)||(n>128));
1825 jpwl_cp.pepb[0] = ( n & 0x000000FF)<<8;
1826 jpwl_cp.pepb[0] |= 0x20000020;
1829 jpwl_cp.pepb[0] = 0x10000000;
1831 jpwl_cp.pepb[0] = 0x10000001;
1833 jpwl_cp.pepb[0] = 0xFFFFFFFF;
1834 printf("pepb1: %x\n", jpwl_cp.pepb[0]);
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();
1844 }while(!strchr("12345",scelta));
1846 jpwl_cp.pepb[1]=0x00000000;
1849 printf("Enter the desired n value (k=32 as standard; n between 37 and 128): ");
1852 } while ((n<37)||(n>128));
1853 jpwl_cp.pepb[1] = ( n & 0x000000FF)<<8;
1854 jpwl_cp.pepb[1] |= 0x20000020;
1857 jpwl_cp.pepb[1] = 0x10000000;
1859 jpwl_cp.pepb[1] = 0x10000001;
1861 jpwl_cp.pepb[1] = 0xFFFFFFFF;
1862 printf("pepb2: %x\n", jpwl_cp.pepb[1]);
1866 printf("N.B.: layer number must be less than or equal to five\n");
1867 param->index_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;
1883 printf("Error in answer.\n");
1884 printf("Do you want to use EPBs (y/n)?: ");
1885 risp = (char) _getche();
1890 printf("Do you want to use ESD (y/n)?: ");
1891 risp = (char) _getche();
1897 param->index_on = 1;
1898 jpwl_cp.pesd = 0x01;
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();
1906 }while(!strchr("123",scelta));
1908 jpwl_cp.pesd |= 0x00;
1910 jpwl_cp.pesd |= 0x42;
1912 jpwl_cp.pesd |= 0x80;
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();
1922 }while(!strchr("12345",scelta));
1924 jpwl_cp.pesd |= 0x00;
1926 jpwl_cp.pesd |= 0x0C;
1928 jpwl_cp.pesd |= 0x14;
1930 jpwl_cp.pesd |= 0x1C;
1932 jpwl_cp.pesd |= 0x24;
1933 printf("pesd: %x\n", jpwl_cp.pesd);
1940 printf("Error entering the answer.\n");
1941 printf("Do you want to use ESD (y/n)?: ");
1942 risp = (char) _getche();
1947 printf("Do you want to use RED (y/n)?: ");
1948 risp = (char) _getche();
1954 //suppongo che la codestream sia corretta => b0=0 e b5b4b3=000
1955 jpwl_cp.pred = 0x00;
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();
1963 }while(!strchr("123",scelta));
1965 jpwl_cp.pred |= 0x00;
1967 jpwl_cp.pred |= 0x42;
1969 jpwl_cp.pred |= 0x80;
1970 printf("pred: %x\n", jpwl_cp.pred);
1977 printf("Error entering the answer.\n");
1978 printf("Do you want to use RED (y/n)?: ");
1979 risp = (char) _getche();
1990 crcSum = 0xffffffff;
1994 void UpdateCRC16(char x)
1997 tmp = ((x ^ (crcSum >> 8)) & 0xff);
1998 crcSum = ((crcSum << 8) ^ CrcT16[tmp]) & 0xffff;
2001 void UpdateCRC32(char x)
2004 tmp = ((x ^ (crcSum >> 24)) & 0xff);
2005 crcSum = ((crcSum << 8) ^ CrcT32[tmp]);
2007 /* funzioni per l'inversione dei byte e del crc32 */
2009 char reflectByte(char inbyte)
2013 unsigned char outbyte=0;
2014 unsigned char i=0x01;
2017 for (j=0x080; j; j>>=1)
2019 if (inbyte & i) outbyte|=j;
2031 unsigned long outcrc=0;
2032 unsigned long i=0x00000001;
2035 for (j=0x80000000; j; j>>=1)
2045 int crc_ccitt(char *buffer, int len){
2049 for (i=0; i<len; i++) {
2060 //funzioni di conversione allo pseudo floating point format
2061 short int d2pfp(double in){
2063 short int mant, ex, out;
2067 mant = (data>>9) & 0x07FF;
2068 ex = (data>>20) & 0x07FF;
2077 double pfp2d(short int in){
2081 ex = (in >> 11) & 0x001F;
2082 out = pow(2,ex-15)*(1+(mant/pow(2,11)));