One more field in the codestream_info struct for recording the number of packets...
[openjpeg.git] / jpwl / jpwl_lib.c
1 /*
2  * Copyright (c) 2001-2003, David Janssens
3  * Copyright (c) 2002-2003, Yannick Verschueren
4  * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
5  * Copyright (c) 2005, Herv� Drolon, FreeImage Team
6  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
7  * Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #ifdef USE_JPWL
33
34 #include "../libopenjpeg/opj_includes.h"
35
36 /** Minimum and maximum values for the double->pfp conversion */
37 #define MIN_V1 0.0
38 #define MAX_V1 17293822569102704640.0
39 #define MIN_V2 0.000030517578125
40 #define MAX_V2 131040.0
41
42 /** conversion between a double precision floating point
43 number and the corresponding pseudo-floating point used 
44 to represent sensitivity values
45 @param V the double precision value
46 @param bytes the number of bytes of the representation
47 @return the pseudo-floating point value (cast accordingly)
48 */
49 unsigned short int jpwl_double_to_pfp(double V, int bytes);
50
51 /** conversion between a pseudo-floating point used 
52 to represent sensitivity values and the corresponding
53 double precision floating point number  
54 @param em the pseudo-floating point value (cast accordingly)
55 @param bytes the number of bytes of the representation
56 @return the double precision value
57 */
58 double jpwl_pfp_to_double(unsigned short int em, int bytes);
59
60         /*-------------------------------------------------------------*/
61
62 int jpwl_markcomp(const void *arg1, const void *arg2)
63 {
64    /* Compare the two markers' positions */
65    double diff = (((jpwl_marker_t *) arg1)->dpos - ((jpwl_marker_t *) arg2)->dpos);
66
67    if (diff == 0.0)
68            return (0);
69    else if (diff < 0)
70            return (-1);
71    else
72            return (+1);
73 }
74
75 int jpwl_epbs_add(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int *jwmarker_num,
76                                   bool latest, bool packed, bool insideMH, int *idx, int hprot,
77                                   double place_pos, int tileno,
78                                   unsigned long int pre_len, unsigned long int post_len) {
79
80         jpwl_epb_ms_t *epb_mark = NULL;
81
82         int k_pre, k_post, n_pre, n_post;
83         
84         unsigned long int L1, L2, dL4, max_postlen, epbs_len = 0;
85
86         /* We find RS(n,k) for EPB parms and pre-data, if any */
87         if (insideMH && (*idx == 0)) {
88                 /* First EPB in MH */ 
89                 k_pre = 64;
90                 n_pre = 160;
91         } else if (!insideMH && (*idx == 0)) {
92                 /* First EPB in TH */
93                 k_pre = 25;
94                 n_pre = 80;
95         } else {
96                 /* Following EPBs in MH or TH */
97                 k_pre = 13;
98                 n_pre = 40;
99         };
100
101         /* Find lengths, Figs. B3 and B4 */
102         /* size of pre data: pre_buf(pre_len) + EPB(2) + Lepb(2) + Depb(1) + LDPepb(4) + Pepb(4) */
103         L1 = pre_len + 13;
104
105         /* size of pre-data redundancy */
106         /*   (redundancy per codeword)       *     (number of codewords, rounded up)   */
107         L2 = (n_pre - k_pre) * (unsigned long int) ceil((double) L1 / (double) k_pre);
108
109         /* Find protection type for post data and its associated redundancy field length*/
110         if ((hprot == 16) || (hprot == 32)) {
111                 /* there is a CRC for post-data */
112                 k_post = post_len;
113                 n_post = post_len + (hprot >> 3);
114                 /*L3 = hprot >> 3;*/ /* 2 (CRC-16) or 4 (CRC-32) bytes */
115
116         } else if ((hprot >= 37) && (hprot <= 128)) {
117                 /* there is a RS for post-data */
118                 k_post = 32;
119                 n_post = hprot;
120
121         } else {
122                 /* Use predefined codes */
123                 n_post = n_pre;
124                 k_post = k_pre;
125         };
126
127         /* Create the EPB(s) */
128         while (post_len > 0) {
129
130                 /* maximum postlen in order to respect EPB size
131                 (we use JPWL_MAXIMUM_EPB_ROOM instead of 65535 for keeping room for EPB parms)*/
132                 /*      (message word size)    *            (number of containable parity words)  */
133                 max_postlen = k_post * (unsigned long int) floor((double) JPWL_MAXIMUM_EPB_ROOM / (double) (n_post - k_post));
134
135                 /* maximum postlen in order to respect EPB size */
136                 if (*idx == 0)
137                         /* (we use (JPWL_MAXIMUM_EPB_ROOM - L2) instead of 65535 for keeping room for EPB parms + pre-data) */
138                         /*      (message word size)    *                   (number of containable parity words)  */
139                         max_postlen = k_post * (unsigned long int) floor((double) (JPWL_MAXIMUM_EPB_ROOM - L2) / (double) (n_post - k_post));
140
141                 else
142                         /* (we use JPWL_MAXIMUM_EPB_ROOM instead of 65535 for keeping room for EPB parms) */
143                         /*      (message word size)    *            (number of containable parity words)  */
144                         max_postlen = k_post * (unsigned long int) floor((double) JPWL_MAXIMUM_EPB_ROOM / (double) (n_post - k_post));
145
146                 /* length to use */
147                 dL4 = min(max_postlen, post_len);
148
149                 if (epb_mark = jpwl_epb_create(
150                         j2k, /* this encoder handle */
151                         latest ? (dL4 < max_postlen) : false, /* is it the latest? */
152                         packed, /* is it packed? */
153                         tileno, /* we are in TPH */
154                         *idx, /* its index */
155                         hprot, /* protection type parameters of following data */
156                         0, /* pre-data: nothing for now */
157                         dL4 /* post-data: the stub computed previously */
158                         )) {
159                         
160                         /* Add this marker to the 'insertanda' list */
161                         if (*jwmarker_num < JPWL_MAX_NO_MARKERS) {
162                                 jwmarker[*jwmarker_num].id = J2K_MS_EPB; /* its type */
163                                 jwmarker[*jwmarker_num].epbmark = epb_mark; /* the EPB */
164                                 jwmarker[*jwmarker_num].pos = (int) place_pos; /* after SOT */
165                                 jwmarker[*jwmarker_num].dpos = place_pos + 0.0000001 * (double)(*idx); /* not very first! */
166                                 jwmarker[*jwmarker_num].len = epb_mark->Lepb; /* its length */
167                                 jwmarker[*jwmarker_num].len_ready = true; /* ready */
168                                 jwmarker[*jwmarker_num].pos_ready = true; /* ready */
169                                 jwmarker[*jwmarker_num].parms_ready = true; /* ready */
170                                 jwmarker[*jwmarker_num].data_ready = false; /* not ready */
171                                 (*jwmarker_num)++;
172                         }
173
174                         /* increment epb index */
175                         (*idx)++;
176
177                         /* decrease postlen */
178                         post_len -= dL4;
179
180                         /* increase the total length of EPBs */
181                         epbs_len += epb_mark->Lepb + 2;
182
183                 } else {
184                         /* ooops, problems */
185                         opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB for UEP in tile %d\n", tileno);                          
186                 };
187         }
188
189         return epbs_len;
190 }
191
192
193 jpwl_epb_ms_t *jpwl_epb_create(opj_j2k_t *j2k, bool latest, bool packed, int tileno, int idx, int hprot,
194                                                   unsigned long int pre_len, unsigned long int post_len) {
195
196         jpwl_epb_ms_t *epb = NULL;
197         unsigned short int data_len = 0;
198         unsigned short int L2, L3;
199         unsigned long int L1, L4;
200         unsigned char *predata_in = NULL;
201
202         bool insideMH = (tileno == -1);
203
204         /* Alloc space */
205         if (!(epb = (jpwl_epb_ms_t *) opj_malloc((size_t) 1 * sizeof (jpwl_epb_ms_t)))) {
206                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for one EPB MS\n");
207                 return NULL;
208         };
209
210         /* We set RS(n,k) for EPB parms and pre-data, if any */
211         if (insideMH && (idx == 0)) {
212                 /* First EPB in MH */ 
213                 epb->k_pre = 64;
214                 epb->n_pre = 160;
215         } else if (!insideMH && (idx == 0)) {
216                 /* First EPB in TH */
217                 epb->k_pre = 25;
218                 epb->n_pre = 80;
219         } else {
220                 /* Following EPBs in MH or TH */
221                 epb->k_pre = 13;
222                 epb->n_pre = 40;
223         };
224
225         /* Find lengths, Figs. B3 and B4 */
226         /* size of pre data: pre_buf(pre_len) + EPB(2) + Lepb(2) + Depb(1) + LDPepb(4) + Pepb(4) */
227         L1 = pre_len + 13;
228         epb->pre_len = pre_len;
229
230         /* size of pre-data redundancy */
231         /*   (redundancy per codeword)       *               (number of codewords, rounded up)   */
232         L2 = (epb->n_pre - epb->k_pre) * (unsigned short int) ceil((double) L1 / (double) epb->k_pre);
233
234         /* length of post-data */
235         L4 = post_len;
236         epb->post_len = post_len;
237
238         /* Find protection type for post data and its associated redundancy field length*/
239         if ((hprot == 16) || (hprot == 32)) {
240                 /* there is a CRC for post-data */
241                 epb->Pepb = 0x10000000 | ((unsigned long int) hprot >> 5); /* 0=CRC-16, 1=CRC-32 */
242                 epb->k_post = post_len;
243                 epb->n_post = post_len + (hprot >> 3);
244                 /*L3 = hprot >> 3;*/ /* 2 (CRC-16) or 4 (CRC-32) bytes */
245
246         } else if ((hprot >= 37) && (hprot <= 128)) {
247                 /* there is a RS for post-data */
248                 epb->Pepb = 0x20000020 | (((unsigned long int) hprot & 0x000000FF) << 8);
249                 epb->k_post = 32;
250                 epb->n_post = hprot;
251
252         } else if (hprot == 1) {
253                 /* Use predefined codes */
254                 epb->Pepb = (unsigned long int) 0x00000000;
255                 epb->n_post = epb->n_pre;
256                 epb->k_post = epb->k_pre;
257         
258         } else if (hprot == 0) {
259                 /* Placeholder EPB: only protects its parameters, no protection method */
260                 epb->Pepb = (unsigned long int) 0xFFFFFFFF;
261                 epb->n_post = 1;
262                 epb->k_post = 1;
263         
264         } else {
265                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Invalid protection value for EPB h = %d\n", hprot);                               
266                 return NULL;
267         }
268
269         epb->hprot = hprot;
270
271         /*   (redundancy per codeword)          *                (number of codewords, rounded up) */
272         L3 = (epb->n_post - epb->k_post) * (unsigned short int) ceil((double) L4 / (double) epb->k_post);
273
274         /* private fields */
275         epb->tileno = tileno;
276
277         /* Fill some fields of the EPB */
278
279         /* total length of the EPB MS (less the EPB marker itself): */
280         /* Lepb(2) + Depb(1) + LDPepb(4) + Pepb(4) + pre_redundancy + post-redundancy */
281         epb->Lepb = 11 + L2 + L3;
282
283         /* EPB style */
284         epb->Depb = ((packed & 0x0001) << 7) | ((latest & 0x0001) << 6) | (idx & 0x003F);
285
286         /* length of data protected by EPB: */
287         epb->LDPepb = L1 + L4;
288
289         return epb;
290 }
291
292 void jpwl_epb_write(jpwl_epb_ms_t *epb, unsigned char *buf) {
293
294         /* Marker */
295         *(buf++) = (unsigned char) (J2K_MS_EPB >> 8); 
296         *(buf++) = (unsigned char) (J2K_MS_EPB >> 0); 
297
298         /* Lepb */
299         *(buf++) = (unsigned char) (epb->Lepb >> 8); 
300         *(buf++) = (unsigned char) (epb->Lepb >> 0); 
301
302         /* Depb */
303         *(buf++) = (unsigned char) (epb->Depb >> 0); 
304
305         /* LDPepb */
306         *(buf++) = (unsigned char) (epb->LDPepb >> 24); 
307         *(buf++) = (unsigned char) (epb->LDPepb >> 16); 
308         *(buf++) = (unsigned char) (epb->LDPepb >> 8); 
309         *(buf++) = (unsigned char) (epb->LDPepb >> 0); 
310
311         /* Pepb */
312         *(buf++) = (unsigned char) (epb->Pepb >> 24); 
313         *(buf++) = (unsigned char) (epb->Pepb >> 16); 
314         *(buf++) = (unsigned char) (epb->Pepb >> 8); 
315         *(buf++) = (unsigned char) (epb->Pepb >> 0); 
316
317         /* Data */
318         /*memcpy(buf, epb->data, (size_t) epb->Lepb - 11);*/
319         memset(buf, 0, (size_t) epb->Lepb - 11);
320 };
321
322
323 jpwl_epc_ms_t *jpwl_epc_create(opj_j2k_t *j2k, bool esd_on, bool red_on, bool epb_on, bool info_on) {
324
325         jpwl_epc_ms_t *epc = NULL;
326
327         /* Alloc space */
328         if (!(epc = (jpwl_epc_ms_t *) malloc((size_t) 1 * sizeof (jpwl_epc_ms_t)))) {
329                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for EPC MS\n");
330                 return NULL;
331         };
332
333         /* Set the EPC parameters */
334         epc->esd_on = esd_on;
335         epc->epb_on = epb_on;
336         epc->red_on = red_on;
337         epc->info_on = info_on;
338
339         /* Fill the EPC fields with default values */
340         epc->Lepc = 9;
341         epc->Pcrc = 0x0000;
342         epc->DL = 0x00000000;
343         epc->Pepc = ((j2k->cp->esd_on & 0x0001) << 4) | ((j2k->cp->red_on & 0x0001) << 5) |
344                 ((j2k->cp->epb_on & 0x0001) << 6) | ((j2k->cp->info_on & 0x0001) << 7);
345
346         return (epc);
347 }
348
349 bool jpwl_epb_fill(opj_j2k_t *j2k, jpwl_epb_ms_t *epb, unsigned char *buf, unsigned char *post_buf) {
350
351         unsigned long int L1, L2, L3, L4;
352         int remaining;
353         unsigned long int P, NN_P;
354
355         /* Operating buffer */
356         static unsigned char codeword[NN], *parityword;
357
358         unsigned char *L1_buf, *L2_buf;
359         /* these ones are static, since we need to keep memory of
360          the exact place from one call to the other */
361         static unsigned char *L3_buf, *L4_buf;
362
363         /* some consistency check */
364         if (!buf) {
365                 opj_event_msg(j2k->cinfo, EVT_ERROR, "There is no operating buffer for EPBs\n");
366                 return false;
367         }
368
369         if (!post_buf && !L4_buf) {
370                 opj_event_msg(j2k->cinfo, EVT_ERROR, "There is no operating buffer for EPBs data\n");
371                 return false;
372         }
373
374         /*
375          * Compute parity bytes on pre-data, ALWAYS present (at least only for EPB parms)
376          */
377
378         /* Initialize RS structures */
379         P = epb->n_pre - epb->k_pre;
380         NN_P = NN - P;
381         memset(codeword, 0, NN);
382         parityword = codeword + NN_P;
383         init_rs(NN_P);
384
385         /* pre-data begins pre_len bytes before of EPB buf */
386         L1_buf = buf - epb->pre_len;
387         L1 = epb->pre_len + 13;
388
389         /* redundancy for pre-data begins immediately after EPB parms */
390         L2_buf = buf + 13;
391         L2 = (epb->n_pre - epb->k_pre) * (unsigned short int) ceil((double) L1 / (double) epb->k_pre);
392
393         /* post-data
394            the position of L4 buffer can be:
395              1) passed as a parameter: in that case use it
396              2) null: in that case use the previous (static) one
397         */
398         if (post_buf)
399                 L4_buf = post_buf;
400         L4 = epb->post_len;
401
402         /* post-data redundancy begins immediately after pre-data redundancy */
403         L3_buf = L2_buf + L2;
404         L3 = (epb->n_post - epb->k_post) * (unsigned short int) ceil((double) L4 / (double) epb->k_post);
405
406         /* let's check whether EPB length is sufficient to contain all these data */
407         if (epb->Lepb < (11 + L2 + L3))
408                 opj_event_msg(j2k->cinfo, EVT_ERROR, "There is no room in EPB data field for writing redundancy data\n");
409         /*printf("Env. %d, nec. %d (%d + %d)\n", epb->Lepb - 11, L2 + L3, L2, L3);*/
410
411         /* Compute redundancy of pre-data message words */
412         remaining = L1;
413         while (remaining) {
414
415                 /* copy message data into codeword buffer */
416                 if (remaining < epb->k_pre) {
417                         /* the last message word is zero-padded */
418                         memset(codeword, 0, NN);
419                         memcpy(codeword, L1_buf, remaining);
420                         L1_buf += remaining;
421                         remaining = 0;
422
423                 } else {
424                         memcpy(codeword, L1_buf, epb->k_pre);
425                         L1_buf += epb->k_pre;
426                         remaining -= epb->k_pre;
427
428                 }
429
430                 /* Encode the buffer and obtain parity bytes */
431                 if (encode_rs(codeword, parityword))
432                         opj_event_msg(j2k->cinfo, EVT_WARNING,
433                                 "Possible encoding error in codeword @ position #%d\n", (L1_buf - buf) / epb->k_pre);
434
435                 /* copy parity bytes only in redundancy buffer */
436                 memcpy(L2_buf, parityword, P); 
437
438                 /* advance parity buffer */
439                 L2_buf += P;
440         }
441
442         /*
443          * Compute parity bytes on post-data, may be absent if there are no data
444          */
445         /*printf("Hprot is %d (tileno=%d, k_pre=%d, n_pre=%d, k_post=%d, n_post=%d, pre_len=%d, post_len=%d)\n",
446                 epb->hprot, epb->tileno, epb->k_pre, epb->n_pre, epb->k_post, epb->n_post, epb->pre_len,
447                 epb->post_len);*/
448         if (epb->hprot < 0) {
449
450                 /* there should be no EPB */
451                 
452         } else if (epb->hprot == 0) {
453
454                 /* no protection for the data */
455                 /* advance anyway */
456                 L4_buf += epb->post_len;
457
458         } else if (epb->hprot == 16) {
459
460                 /* CRC-16 */
461                 unsigned short int mycrc = 0x0000;
462
463                 /* compute the CRC field (excluding itself) */
464                 remaining = L4;
465                 while (remaining--)
466                         jpwl_updateCRC16(&mycrc, *(L4_buf++));
467
468                 /* write the CRC field */
469                 *(L3_buf++) = (unsigned char) (mycrc >> 8);
470                 *(L3_buf++) = (unsigned char) (mycrc >> 0);
471
472         } else if (epb->hprot == 32) {
473
474                 /* CRC-32 */
475                 unsigned long int mycrc = 0x00000000;
476
477                 /* compute the CRC field (excluding itself) */
478                 remaining = L4;
479                 while (remaining--)
480                         jpwl_updateCRC32(&mycrc, *(L4_buf++));
481
482                 /* write the CRC field */
483                 *(L3_buf++) = (unsigned char) (mycrc >> 24);
484                 *(L3_buf++) = (unsigned char) (mycrc >> 16);
485                 *(L3_buf++) = (unsigned char) (mycrc >> 8);
486                 *(L3_buf++) = (unsigned char) (mycrc >> 0);
487
488         } else {
489
490                 /* RS */
491
492                 /* Initialize RS structures */
493                 P = epb->n_post - epb->k_post;
494                 NN_P = NN - P;
495                 memset(codeword, 0, NN);
496                 parityword = codeword + NN_P;
497                 init_rs(NN_P);
498
499                 /* Compute redundancy of post-data message words */
500                 remaining = L4;
501                 while (remaining) {
502
503                         /* copy message data into codeword buffer */
504                         if (remaining < epb->k_post) {
505                                 /* the last message word is zero-padded */
506                                 memset(codeword, 0, NN);
507                                 memcpy(codeword, L4_buf, remaining);
508                                 L4_buf += remaining;
509                                 remaining = 0;
510
511                         } else {
512                                 memcpy(codeword, L4_buf, epb->k_post);
513                                 L4_buf += epb->k_post;
514                                 remaining -= epb->k_post;
515
516                         }
517
518                         /* Encode the buffer and obtain parity bytes */
519                         if (encode_rs(codeword, parityword))
520                                 opj_event_msg(j2k->cinfo, EVT_WARNING,
521                                         "Possible encoding error in codeword @ position #%d\n", (L4_buf - buf) / epb->k_post);
522
523                         /* copy parity bytes only in redundancy buffer */
524                         memcpy(L3_buf, parityword, P); 
525
526                         /* advance parity buffer */
527                         L3_buf += P;
528                 }
529
530         }
531
532         return true;
533 }
534
535
536 bool jpwl_correct(opj_j2k_t *j2k) {
537
538         opj_cio_t *cio = j2k->cio;
539         bool status;
540         static bool mh_done = false;
541         int mark_pos, id, len, skips, sot_pos;
542         unsigned long int Psot = 0;
543
544         /* go back to marker position */
545         mark_pos = cio_tell(cio) - 2;
546         cio_seek(cio, mark_pos);
547
548         if ((j2k->state == J2K_STATE_MHSOC) && !mh_done) {
549
550                 int mark_val = 0, skipnum = 0;
551
552                 /*
553                   COLOR IMAGE
554                   first thing to do, if we are here, is to look whether
555                   51 (skipnum) positions ahead there is an EPB, in case of MH
556                 */
557                 /*
558                   B/W IMAGE
559                   first thing to do, if we are here, is to look whether
560                   45 (skipnum) positions ahead there is an EPB, in case of MH
561                 */
562                 /*       SIZ   SIZ_FIELDS     SIZ_COMPS               FOLLOWING_MARKER */
563                 skipnum = 2  +     38     + 3 * j2k->cp->exp_comps  +         2;
564                 if ((cio->bp + skipnum) < cio->end) {
565
566                         cio_skip(cio, skipnum);
567
568                         /* check that you are not going beyond the end of codestream */
569
570                         /* call EPB corrector */
571                         status = jpwl_epb_correct(j2k,     /* J2K decompressor handle */
572                                                                           cio->bp, /* pointer to EPB in codestream buffer */
573                                                                           0,       /* EPB type: MH */
574                                                                           skipnum,      /* length of pre-data */
575                                                                           -1,      /* length of post-data: -1 means auto */
576                                                                           NULL,
577                                                                           NULL
578                                                                          );
579
580                         /* read the marker value */
581                         mark_val = (*(cio->bp) << 8) | *(cio->bp + 1);
582
583                         if (status && (mark_val == J2K_MS_EPB)) {
584                                 /* we found it! */
585                                 mh_done = true;
586                                 return true;
587                         }
588
589                 }
590
591         }
592
593         if (true /*(j2k->state == J2K_STATE_TPHSOT) || (j2k->state == J2K_STATE_TPH)*/) {
594                 /* else, look if 12 positions ahead there is an EPB, in case of TPH */
595                 cio_seek(cio, mark_pos);
596                 if ((cio->bp + 12) < cio->end) {
597
598                         cio_skip(cio, 12);
599
600                         /* call EPB corrector */
601                         status = jpwl_epb_correct(j2k,     /* J2K decompressor handle */
602                                                                           cio->bp, /* pointer to EPB in codestream buffer */
603                                                                           1,       /* EPB type: TPH */
604                                                                           12,      /* length of pre-data */
605                                                                           -1,      /* length of post-data: -1 means auto */
606                                                                           NULL,
607                                                                           NULL
608                                                                          );
609                         if (status)
610                                 /* we found it! */
611                                 return true;
612                 }
613         }
614
615         return false;
616
617         /* for now, don't use this code */
618
619         /* else, look if here is an EPB, in case of other */
620         if (mark_pos > 64) {
621                 /* it cannot stay before the first MH EPB */
622                 cio_seek(cio, mark_pos);
623                 cio_skip(cio, 0);
624
625                 /* call EPB corrector */
626                 status = jpwl_epb_correct(j2k,     /* J2K decompressor handle */
627                                                                   cio->bp, /* pointer to EPB in codestream buffer */
628                                                                   2,       /* EPB type: TPH */
629                                                                   0,       /* length of pre-data */
630                                                                   -1,      /* length of post-data: -1 means auto */
631                                                                   NULL,
632                                                                   NULL
633                                                                  );
634                 if (status)
635                         /* we found it! */
636                         return true;
637         }
638
639         /* nope, no EPBs probably, or they are so damaged that we can give up */
640         return false;
641         
642         return true;
643
644         /* AN ATTEMPT OF PARSER */
645         /* NOT USED ACTUALLY    */
646
647         /* go to the beginning of the file */
648         cio_seek(cio, 0);
649
650         /* let's begin */
651         j2k->state = J2K_STATE_MHSOC;
652
653         /* cycle all over the markers */
654         while (cio_tell(cio) < cio->length) {
655
656                 /* read the marker */
657                 mark_pos = cio_tell(cio);
658                 id = cio_read(cio, 2);
659
660                 /* details */
661                 printf("Marker@%d: %X\n", cio_tell(cio) - 2, id);
662
663                 /* do an action in response to the read marker */
664                 switch (id) {
665
666                 /* short markers */
667
668                         /* SOC */
669                 case J2K_MS_SOC:
670                         j2k->state = J2K_STATE_MHSIZ;
671                         len = 0;
672                         skips = 0;
673                         break;
674
675                         /* EOC */
676                 case J2K_MS_EOC:
677                         j2k->state = J2K_STATE_MT;
678                         len = 0;
679                         skips = 0;
680                         break;
681
682                         /* particular case of SOD */
683                 case J2K_MS_SOD:
684                         len = Psot - (mark_pos - sot_pos) - 2;
685                         skips = len;
686                         break;
687
688                 /* long markers */
689
690                         /* SOT */
691                 case J2K_MS_SOT:
692                         j2k->state = J2K_STATE_TPH;
693                         sot_pos = mark_pos; /* position of SOT */
694                         len = cio_read(cio, 2); /* read the length field */
695                         cio_skip(cio, 2); /* this field is unnecessary */
696                         Psot = cio_read(cio, 4); /* tile length */
697                         skips = len - 8;
698                         break;
699
700                         /* remaining */
701                 case J2K_MS_SIZ:
702                         j2k->state = J2K_STATE_MH;
703                         /* read the length field */
704                         len = cio_read(cio, 2);
705                         skips = len - 2;
706                         break;
707
708                         /* remaining */
709                 default:
710                         /* read the length field */
711                         len = cio_read(cio, 2);
712                         skips = len - 2;
713                         break;
714
715                 }
716
717                 /* skip to marker's end */
718                 cio_skip(cio, skips);   
719
720         }
721
722
723 }
724
725 bool jpwl_epb_correct(opj_j2k_t *j2k, unsigned char *buffer, int type, int pre_len, int post_len, int *conn,
726                                           unsigned char **L4_bufp) {
727
728         /* Operating buffer */
729         unsigned char codeword[NN], *parityword;
730
731         unsigned long int P, NN_P;
732         unsigned long int L1, L4;
733         int remaining, n_pre, k_pre, n_post, k_post;
734
735         int status, tt;
736
737         int orig_pos = cio_tell(j2k->cio);
738
739         unsigned char *L1_buf, *L2_buf;
740         unsigned char *L3_buf, *L4_buf;
741
742         unsigned long int LDPepb, Pepb;
743         unsigned short int Lepb;
744         unsigned char Depb;
745         char str1[25] = "";
746         int myconn, errnum = 0;
747         bool errflag = false;
748         
749         opj_cio_t *cio = j2k->cio;
750
751         /* check for common errors */
752         if (!buffer) {
753                 opj_event_msg(j2k->cinfo, EVT_ERROR, "The EPB pointer is a NULL buffer\n");
754                 return false;
755         }
756         
757         /* set bignesses */
758         L1 = pre_len + 13;
759
760         /* pre-data correction */
761         switch (type) {
762
763         case 0:
764                 /* MH EPB */
765                 k_pre = 64;
766                 n_pre = 160;
767                 break;
768
769         case 1:
770                 /* TPH EPB */
771                 k_pre = 25;
772                 n_pre = 80;
773                 break;
774
775         case 2:
776                 /* other EPBs */
777                 k_pre = 13;
778                 n_pre = 40;
779                 break;
780
781         case 3:
782                 /* automatic setup */
783                 break;
784
785         default:
786                 /* unknown type */
787                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Unknown expected EPB type\n");
788                 return false;
789                 break;
790
791         }
792
793         /* Initialize RS structures */
794         P = n_pre - k_pre;
795         NN_P = NN - P;
796         tt = (int) floor((float) P / 2.0F); /* correction capability of the code */
797         memset(codeword, 0, NN);
798         parityword = codeword + NN_P;
799         init_rs(NN_P);
800
801         /* Correct pre-data message words */
802         L1_buf = buffer - pre_len;
803         L2_buf = buffer + 13;
804         remaining = L1;
805         while (remaining) {
806  
807                 /* always zero-pad codewords */
808                 /* (this is required, since after decoding the zeros in the long codeword
809                     could change, and keep unchanged in subsequent calls) */
810                 memset(codeword, 0, NN);
811
812                 /* copy codeword buffer into message bytes */
813                 if (remaining < k_pre)
814                         memcpy(codeword, L1_buf, remaining);
815                 else
816                         memcpy(codeword, L1_buf, k_pre);
817
818                 /* copy redundancy buffer in parity bytes */
819                 memcpy(parityword, L2_buf, P); 
820
821                 /* Decode the buffer and possibly obtain corrected bytes */
822                 status = eras_dec_rs(codeword, NULL, 0);
823                 if (status == -1) {
824                         /*if (conn == NULL)
825                                 opj_event_msg(j2k->cinfo, EVT_WARNING,
826                                         "Possible decoding error in codeword @ position #%d\n", (L1_buf - buffer) / k_pre);*/
827                         errflag = true;
828                         /* we can try to safely get out from the function:
829                           if we are here, either this is not an EPB or the first codeword
830                           is too damaged to be helpful */
831                         /*return false;*/
832
833                 } else if (status == 0) {
834                         /*if (conn == NULL)
835                                 opj_event_msg(j2k->cinfo, EVT_INFO, "codeword is correctly decoded\n");*/
836
837                 } else if (status <= tt) {
838                         /* it has corrected 0 <= errs <= tt */
839                         /*if (conn == NULL)
840                                 opj_event_msg(j2k->cinfo, EVT_WARNING, "%d errors corrected in codeword\n", status);*/
841                         errnum += status;
842
843                 } else {
844                         /*if (conn == NULL)
845                                 opj_event_msg(j2k->cinfo, EVT_WARNING, "EPB correction capability exceeded\n");
846                         return false;*/
847                         errflag = true;
848                 }
849
850
851                 /* advance parity buffer */
852                 if ((status >= 0) && (status <= tt))
853                         /* copy back corrected parity only if all is OK */
854                         memcpy(L2_buf, parityword, P);
855                 L2_buf += P;
856
857                 /* advance message buffer */
858                 if (remaining < k_pre) {
859                         if ((status >= 0) && (status <= tt))
860                                 /* copy back corrected data only if all is OK */
861                                 memcpy(L1_buf, codeword, remaining);
862                         L1_buf += remaining;
863                         remaining = 0;
864
865                 } else {
866                         if ((status >= 0) && (status <= tt))
867                                 /* copy back corrected data only if all is OK */
868                                 memcpy(L1_buf, codeword, k_pre);
869                         L1_buf += k_pre;
870                         remaining -= k_pre;
871
872                 }
873         }
874
875         /* print summary */
876         if (!conn) {
877
878                 /*if (errnum)
879                         opj_event_msg(j2k->cinfo, EVT_INFO, "+ %d symbol errors corrected (Ps=%.1e)\n", errnum,
880                                 (float) errnum / ((float) n_pre * (float) L1 / (float) k_pre));*/
881                 if (errflag) {
882                         /*opj_event_msg(j2k->cinfo, EVT_INFO, "+ there were unrecoverable errors\n");*/
883                         return false;
884                 }
885
886         }
887
888         /* presumably, now, EPB parameters are correct */
889         /* let's get them */
890
891         /* Simply read the EPB parameters */
892         if (conn)
893                 cio->bp = buffer;
894         cio_skip(cio, 2); /* the marker */
895         Lepb = cio_read(cio, 2);
896         Depb = cio_read(cio, 1);
897         LDPepb = cio_read(cio, 4);
898         Pepb = cio_read(cio, 4);
899
900         /* What does Pepb tells us about the protection method? */
901         if (((Pepb & 0xF0000000) >> 28) == 0)
902                 sprintf(str1, "pred"); /* predefined */
903         else if (((Pepb & 0xF0000000) >> 28) == 1)
904                 sprintf(str1, "crc-%d", 16 * ((Pepb & 0x00000001) + 1)); /* CRC mode */
905         else if (((Pepb & 0xF0000000) >> 28) == 2)
906                 sprintf(str1, "rs(%d,32)", (Pepb & 0x0000FF00) >> 8); /* RS mode */
907         else if (Pepb == 0xFFFFFFFF)
908                 sprintf(str1, "nometh"); /* RS mode */
909         else
910                 sprintf(str1, "unknown"); /* unknown */
911
912         /* Now we write them to screen */
913         if (!conn && post_len)
914                 opj_event_msg(j2k->cinfo, EVT_INFO,
915                         "EPB(%d): (%sl, %sp, %u), %lu, %s\n",
916                         cio_tell(cio) - 13,
917                         (Depb & 0x40) ? "" : "n", /* latest EPB or not? */
918                         (Depb & 0x80) ? "" : "n", /* packed or unpacked EPB? */
919                         (Depb & 0x3F), /* EPB index value */
920                         LDPepb, /*length of the data protected by the EPB */
921                         str1); /* protection method */
922
923
924         /* well, we need to investigate how long is the connected length of packed EPBs */
925         myconn = Lepb + 2;
926         if ((Depb & 0x40) == 0) /* not latest in header */
927                 jpwl_epb_correct(j2k,      /* J2K decompressor handle */
928                                              buffer + Lepb + 2,   /* pointer to next EPB in codestream buffer */
929                                              2,     /* EPB type: should be of other type */
930                                              0,  /* only EPB fields */
931                                              0, /* do not look after */
932                                                  &myconn,
933                                                  NULL
934                                              );
935         if (conn)
936                 *conn += myconn;
937
938         /*if (!conn)
939                 printf("connected = %d\n", myconn);*/
940
941         /*cio_seek(j2k->cio, orig_pos);
942         return true;*/
943
944         /* post-data
945            the position of L4 buffer is at the end of currently connected EPBs
946         */
947         if (!(L4_bufp))
948                 L4_buf = buffer + myconn;
949         else if (!(*L4_bufp))
950                 L4_buf = buffer + myconn;
951         else
952                 L4_buf = *L4_bufp;
953         if (post_len == -1) 
954                 L4 = LDPepb - pre_len - 13;
955         else if (post_len == 0)
956                 L4 = 0;
957         else
958                 L4 = post_len;
959
960         L3_buf = L2_buf;
961
962         /* Do a further check here on the read parameters */
963         if (L4 > (unsigned long) cio_numbytesleft(j2k->cio))
964                 /* overflow */
965                 return false;
966
967         /* we are ready for decoding the remaining data */
968         if (((Pepb & 0xF0000000) >> 28) == 1) {
969                 /* CRC here */
970                 if ((16 * ((Pepb & 0x00000001) + 1)) == 16) {
971
972                         /* CRC-16 */
973                         unsigned short int mycrc = 0x0000, filecrc = 0x0000;
974
975                         /* compute the CRC field */
976                         remaining = L4;
977                         while (remaining--)
978                                 jpwl_updateCRC16(&mycrc, *(L4_buf++));
979
980                         /* read the CRC field */
981                         filecrc = *(L3_buf++) << 8;
982                         filecrc |= *(L3_buf++);
983
984                         /* check the CRC field */
985                         if (mycrc == filecrc) {
986                                 if (conn == NULL)
987                                         opj_event_msg(j2k->cinfo, EVT_INFO, "- CRC is OK\n");
988                         } else {
989                                 if (conn == NULL)
990                                         opj_event_msg(j2k->cinfo, EVT_WARNING, "- CRC is KO (r=%d, c=%d)\n", filecrc, mycrc);
991                                 errflag = true;
992                         }       
993                 }
994
995                 if ((16 * ((Pepb & 0x00000001) + 1)) == 32) {
996
997                         /* CRC-32 */
998                         unsigned long int mycrc = 0x00000000, filecrc = 0x00000000;
999
1000                         /* compute the CRC field */
1001                         remaining = L4;
1002                         while (remaining--)
1003                                 jpwl_updateCRC32(&mycrc, *(L4_buf++));
1004
1005                         /* read the CRC field */
1006                         filecrc = *(L3_buf++) << 24;
1007                         filecrc |= *(L3_buf++) << 16;
1008                         filecrc |= *(L3_buf++) << 8;
1009                         filecrc |= *(L3_buf++);
1010
1011                         /* check the CRC field */
1012                         if (mycrc == filecrc) {
1013                                 if (conn == NULL)
1014                                         opj_event_msg(j2k->cinfo, EVT_INFO, "- CRC is OK\n");
1015                         } else {
1016                                 if (conn == NULL)
1017                                         opj_event_msg(j2k->cinfo, EVT_WARNING, "- CRC is KO (r=%d, c=%d)\n", filecrc, mycrc);
1018                                 errflag = true;
1019                         }
1020                 }
1021
1022         } else if (Pepb == 0xFFFFFFFF) {
1023                 /* no method */
1024
1025                 /* advance without doing anything */
1026                 remaining = L4;
1027                 while (remaining--)
1028                         L4_buf++;
1029
1030         } else if ((((Pepb & 0xF0000000) >> 28) == 2) || (((Pepb & 0xF0000000) >> 28) == 0)) {
1031                 /* RS coding here */
1032
1033                 if (((Pepb & 0xF0000000) >> 28) == 0) {
1034
1035                         k_post = k_pre;
1036                         n_post = n_pre;
1037
1038                 } else {
1039
1040                         k_post = 32;
1041                         n_post = (Pepb & 0x0000FF00) >> 8;
1042                 }
1043
1044                 /* Initialize RS structures */
1045                 P = n_post - k_post;
1046                 NN_P = NN - P;
1047                 tt = (int) floor((float) P / 2.0F); /* again, correction capability */
1048                 memset(codeword, 0, NN);
1049                 parityword = codeword + NN_P;
1050                 init_rs(NN_P);
1051
1052                 /* Correct post-data message words */
1053                 /*L4_buf = buffer + Lepb + 2;*/
1054                 L3_buf = L2_buf;
1055                 remaining = L4;
1056                 while (remaining) {
1057  
1058                         /* always zero-pad codewords */
1059                         /* (this is required, since after decoding the zeros in the long codeword
1060                                 could change, and keep unchanged in subsequent calls) */
1061                         memset(codeword, 0, NN);
1062
1063                         /* copy codeword buffer into message bytes */
1064                         if (remaining < k_post)
1065                                 memcpy(codeword, L4_buf, remaining);
1066                         else
1067                                 memcpy(codeword, L4_buf, k_post);
1068
1069                         /* copy redundancy buffer in parity bytes */
1070                         memcpy(parityword, L3_buf, P); 
1071
1072                         /* Decode the buffer and possibly obtain corrected bytes */
1073                         status = eras_dec_rs(codeword, NULL, 0);
1074                         if (status == -1) {
1075                                 /*if (conn == NULL)
1076                                         opj_event_msg(j2k->cinfo, EVT_WARNING,
1077                                                 "Possible decoding error in codeword @ position #%d\n", (L4_buf - (buffer + Lepb + 2)) / k_post);*/
1078                                 errflag = true;
1079
1080                         } else if (status == 0) {
1081                                 /*if (conn == NULL)
1082                                         opj_event_msg(j2k->cinfo, EVT_INFO, "codeword is correctly decoded\n");*/
1083
1084                         } else if (status <= tt) {
1085                                 /*if (conn == NULL)
1086                                         opj_event_msg(j2k->cinfo, EVT_WARNING, "%d errors corrected in codeword\n", status);*/
1087                                 errnum += status;
1088
1089                         } else {
1090                                 /*if (conn == NULL)
1091                                         opj_event_msg(j2k->cinfo, EVT_WARNING, "EPB correction capability exceeded\n");
1092                                 return false;*/
1093                                 errflag = true;
1094                         }
1095
1096
1097                         /* advance parity buffer */
1098                         if ((status >= 0) && (status <= tt))
1099                                 /* copy back corrected data only if all is OK */
1100                                 memcpy(L3_buf, parityword, P);
1101                         L3_buf += P;
1102
1103                         /* advance message buffer */
1104                         if (remaining < k_post) {
1105                                 if ((status >= 0) && (status <= tt))
1106                                         /* copy back corrected data only if all is OK */
1107                                         memcpy(L4_buf, codeword, remaining);
1108                                 L4_buf += remaining;
1109                                 remaining = 0;
1110
1111                         } else {
1112                                 if ((status >= 0) && (status <= tt))
1113                                         /* copy back corrected data only if all is OK */
1114                                         memcpy(L4_buf, codeword, k_post);
1115                                 L4_buf += k_post;
1116                                 remaining -= k_post;
1117
1118                         }
1119                 }
1120         }
1121
1122         /* give back the L4_buf address */
1123         if (L4_bufp)
1124                 *L4_bufp = L4_buf;
1125
1126         /* print summary */
1127         if (!conn) {
1128
1129                 if (errnum)
1130                         opj_event_msg(j2k->cinfo, EVT_INFO, "- %d symbol errors corrected (Ps=%.1e)\n", errnum,
1131                                 (float) errnum / (float) LDPepb);
1132                 if (errflag)
1133                         opj_event_msg(j2k->cinfo, EVT_INFO, "- there were unrecoverable errors\n");
1134
1135         }
1136
1137         cio_seek(j2k->cio, orig_pos);
1138
1139         return true;
1140 }
1141
1142 void jpwl_epc_write(jpwl_epc_ms_t *epc, unsigned char *buf) {
1143
1144         /* Marker */
1145         *(buf++) = (unsigned char) (J2K_MS_EPC >> 8); 
1146         *(buf++) = (unsigned char) (J2K_MS_EPC >> 0); 
1147
1148         /* Lepc */
1149         *(buf++) = (unsigned char) (epc->Lepc >> 8); 
1150         *(buf++) = (unsigned char) (epc->Lepc >> 0); 
1151
1152         /* Pcrc */
1153         *(buf++) = (unsigned char) (epc->Pcrc >> 8); 
1154         *(buf++) = (unsigned char) (epc->Pcrc >> 0);
1155
1156         /* DL */
1157         *(buf++) = (unsigned char) (epc->DL >> 24); 
1158         *(buf++) = (unsigned char) (epc->DL >> 16); 
1159         *(buf++) = (unsigned char) (epc->DL >> 8); 
1160         *(buf++) = (unsigned char) (epc->DL >> 0); 
1161
1162         /* Pepc */
1163         *(buf++) = (unsigned char) (epc->Pepc >> 0); 
1164
1165         /* Data */
1166         /*memcpy(buf, epc->data, (size_t) epc->Lepc - 9);*/
1167         memset(buf, 0, (size_t) epc->Lepc - 9);
1168 };
1169
1170 int jpwl_esds_add(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int *jwmarker_num,
1171                                   int comps, unsigned char addrm, unsigned char ad_size,
1172                                   unsigned char senst, unsigned char se_size,
1173                                   double place_pos, int tileno) {
1174
1175         return 0;
1176 }
1177
1178 jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comp, unsigned char addrm, unsigned char ad_size,
1179                                                                 unsigned char senst, unsigned char se_size, int tileno,
1180                                                                 unsigned long int svalnum, void *sensval) {
1181
1182         jpwl_esd_ms_t *esd = NULL;
1183
1184         /* Alloc space */
1185         if (!(esd = (jpwl_esd_ms_t *) malloc((size_t) 1 * sizeof (jpwl_esd_ms_t)))) {
1186                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for ESD MS\n");
1187                 return NULL;
1188         };
1189
1190         /* if relative sensitivity, activate byte range mode */
1191         if (senst == 0)
1192                 addrm = 1;
1193
1194         /* size of sensval's ... */
1195         if ((ad_size != 0) && (ad_size != 2) && (ad_size != 4)) {
1196                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Address size %d for ESD MS is forbidden\n", ad_size);
1197                 return NULL;
1198         }
1199         if ((se_size != 1) && (se_size != 2)) {
1200                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Sensitivity size %d for ESD MS is forbidden\n", se_size);
1201                 return NULL;
1202         }
1203         
1204         /* ... depends on the addressing mode */
1205         switch (addrm) {
1206
1207         /* packet mode */
1208         case (0):
1209                 ad_size = 0; /* as per the standard */
1210                 esd->sensval_size = se_size; 
1211                 break;
1212
1213         /* byte range */
1214         case (1):
1215                 /* auto sense address size */
1216                 if (ad_size == 0)
1217                         /* if there are more than 66% of (2^16 - 1) bytes, switch to 4 bytes
1218                          (we keep space for possible EPBs being inserted) */
1219                         ad_size = (j2k->cstr_info->codestream_size > (1 * 65535 / 3)) ? 4 : 2;
1220                 esd->sensval_size = ad_size + ad_size + se_size; 
1221                 break;
1222
1223         /* packet range */
1224         case (2):
1225                 /* auto sense address size */
1226                 if (ad_size == 0)
1227                         /* if there are more than 2^16 - 1 packets, switch to 4 bytes */
1228                         ad_size = (j2k->cstr_info->num > 65535) ? 4 : 2;
1229                 esd->sensval_size = ad_size + ad_size + se_size; 
1230                 break;
1231
1232         case (3):
1233                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Address mode %d for ESD MS is unimplemented\n", addrm);
1234                 return NULL;
1235
1236         default:
1237                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Address mode %d for ESD MS is forbidden\n", addrm);
1238                 return NULL;
1239         }
1240
1241         /* set or unset sensitivity values */
1242         if (svalnum <= 0) {
1243
1244                 switch (senst) {
1245
1246                 /* just based on the portions of a codestream */
1247                 case (0):
1248                         /* MH + no. of THs + no. of packets */
1249                         svalnum = 1 + (j2k->cstr_info->tw * j2k->cstr_info->th) * (1 + j2k->cstr_info->num);
1250                         break;
1251
1252                 /* all the ones that are based on the packets */
1253                 default:
1254                         if (tileno < 0)
1255                                 /* MH: all the packets and all the tiles info is written */
1256                                 svalnum = j2k->cstr_info->tw * j2k->cstr_info->th * j2k->cstr_info->num;
1257                         else
1258                                 /* TPH: only that tile info is written */
1259                                 svalnum = j2k->cstr_info->num;
1260                         break;
1261
1262                 }
1263         }               
1264
1265         /* fill private fields */
1266         esd->senst = senst;
1267         esd->ad_size = ad_size;
1268         esd->se_size = se_size;
1269         esd->addrm = addrm;
1270         esd->svalnum = svalnum;
1271         esd->numcomps = j2k->image->numcomps;
1272         esd->tileno = tileno;
1273         
1274         /* Set the ESD parameters */
1275         /* length, excluding data field */
1276         if (esd->numcomps < 257)
1277                 esd->Lesd = 4 + (unsigned short int) (esd->svalnum * esd->sensval_size);
1278         else
1279                 esd->Lesd = 5 + (unsigned short int) (esd->svalnum * esd->sensval_size);
1280
1281         /* component data field */
1282         if (comp >= 0)
1283                 esd->Cesd = comp;
1284         else
1285                 /* we are averaging */
1286                 esd->Cesd = 0;
1287
1288         /* Pesd field */
1289         esd->Pesd = 0x00;
1290         esd->Pesd |= (esd->addrm & 0x03) << 6; /* addressing mode */
1291         esd->Pesd |= (esd->senst & 0x07) << 3; /* sensitivity type */
1292         esd->Pesd |= ((esd->se_size >> 1) & 0x01) << 2; /* sensitivity size */
1293         esd->Pesd |= ((esd->ad_size >> 2) & 0x01) << 1; /* addressing size */
1294         esd->Pesd |= (comp < 0) ? 0x01 : 0x00; /* averaging components */
1295
1296         /* if pointer to sensval is NULL, we can fill data field by ourselves */
1297         if (!sensval) {
1298
1299                 /* old code moved to jpwl_esd_fill() */
1300                 esd->data = NULL;
1301
1302         } else {
1303                         /* we set the data field as the sensitivity values poinnter passed to the function */
1304                         esd->data = (unsigned char *) sensval;
1305         }
1306
1307         return (esd);
1308 }
1309
1310 bool jpwl_esd_fill(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) {
1311
1312         int i;
1313         unsigned long int vv;
1314         unsigned long int addr1, addr2;
1315         double dvalue, Omax2, tmp, TSE, MSE, oldMSE, PSNR, oldPSNR;
1316         unsigned short int pfpvalue;
1317         unsigned long int addrmask = 0x00000000;
1318         bool doneMH = false, doneTPH = false;
1319
1320         /* sensitivity values in image info are as follows:
1321                 - for each tile, distotile is the starting distortion for that tile, sum of all components
1322                 - for each packet in a tile, disto is the distortion reduction caused by that packet to that tile
1323                 - the TSE for a single tile should be given by   distotile - sum(disto)  , for all components
1324                 - the MSE for a single tile is given by     TSE / nbpix    , for all components
1325                 - the PSNR for a single tile is given by   10*log10( Omax^2 / MSE)    , for all components
1326                   (Omax is given by    2^bpp - 1    for unsigned images and by    2^(bpp - 1) - 1    for signed images
1327         */
1328
1329         /* browse all components and find Omax */
1330         Omax2 = 0.0;
1331         for (i = 0; i < j2k->image->numcomps; i++) {
1332                 tmp = pow(2.0, (double) (j2k->image->comps[i].sgnd ?
1333                         (j2k->image->comps[i].bpp - 1) : (j2k->image->comps[i].bpp))) - 1;
1334                 if (tmp > Omax2)
1335                         Omax2 = tmp;
1336         }
1337         Omax2 = Omax2 * Omax2;
1338
1339         /* if pointer of esd->data is not null, simply write down all the values byte by byte */
1340         if (esd->data) {
1341                 for (i = 0; i < (int) esd->svalnum; i++)
1342                         *(buf++) = esd->data[i]; 
1343                 return true;
1344         }
1345
1346         /* addressing mask */
1347         if (esd->ad_size == 2)
1348                 addrmask = 0x0000FFFF; /* two bytes */
1349         else
1350                 addrmask = 0xFFFFFFFF; /* four bytes */
1351
1352         /* set on precise point where sensitivity starts */
1353         if (esd->numcomps < 257)
1354                 buf += 6;
1355         else
1356                 buf += 7;
1357
1358         /* let's fill the data fields */
1359         for (vv = (esd->tileno < 0) ? 0 : (j2k->cstr_info->num * esd->tileno); vv < esd->svalnum; vv++) {
1360
1361                 int thistile = vv / j2k->cstr_info->num, thispacket = vv % j2k->cstr_info->num;
1362
1363                 /* skip for the hack some lines below */
1364                 if (thistile == j2k->cstr_info->tw * j2k->cstr_info->th)
1365                         break;
1366
1367                 /* starting tile distortion */
1368                 if (thispacket == 0) {
1369                         TSE = j2k->cstr_info->tile[thistile].distotile;
1370                         oldMSE = TSE / j2k->cstr_info->tile[thistile].nbpix;
1371                         oldPSNR = 10.0 * log10(Omax2 / oldMSE);
1372                 }
1373
1374                 /* TSE */
1375                 TSE -= j2k->cstr_info->tile[thistile].packet[thispacket].disto;
1376
1377                 /* MSE */
1378                 MSE = TSE / j2k->cstr_info->tile[thistile].nbpix;
1379
1380                 /* PSNR */
1381                 PSNR = 10.0 * log10(Omax2 / MSE);
1382
1383                 /* fill the address range */
1384                 switch (esd->addrm) {
1385
1386                 /* packet mode */
1387                 case (0):
1388                         /* nothing, there is none */
1389                         break;
1390
1391                 /* byte range */
1392                 case (1):
1393                         /* start address of packet */
1394                         addr1 = (j2k->cstr_info->tile[thistile].packet[thispacket].start_pos) & addrmask;
1395                         /* end address of packet */
1396                         addr2 = (j2k->cstr_info->tile[thistile].packet[thispacket].end_pos) & addrmask;
1397                         break;
1398
1399                 /* packet range */
1400                 case (2):
1401                         /* not implemented here */
1402                         opj_event_msg(j2k->cinfo, EVT_WARNING, "Addressing mode packet_range is not implemented\n");
1403                         break;
1404
1405                 /* unknown addressing method */
1406                 default:
1407                         /* not implemented here */
1408                         opj_event_msg(j2k->cinfo, EVT_WARNING, "Unknown addressing mode\n");
1409                         break;
1410
1411                 }
1412
1413                 /* hack for writing relative sensitivity of MH and TPHs */
1414                 if ((esd->senst == 0) && (thispacket == 0)) {
1415
1416                         /* possible MH */
1417                         if ((thistile == 0) && !doneMH) {
1418                                 /* we have to manage MH addresses */
1419                                 addr1 = 0; /* start of MH */
1420                                 addr2 = j2k->cstr_info->main_head_end; /* end of MH */
1421                                 /* set special dvalue for this MH */
1422                                 dvalue = -10.0;
1423                                 doneMH = true; /* don't come here anymore */
1424                                 vv--; /* wrap back loop counter */
1425
1426                         } else if (!doneTPH) {
1427                                 /* we have to manage TPH addresses */
1428                                 addr1 = j2k->cstr_info->tile[thistile].start_pos;
1429                                 addr2 = j2k->cstr_info->tile[thistile].end_header;
1430                                 /* set special dvalue for this TPH */
1431                                 dvalue = -1.0;
1432                                 doneTPH = true; /* don't come here till the next tile */
1433                                 vv--; /* wrap back loop counter */
1434                         }
1435
1436                 } else
1437                         doneTPH = false; /* reset TPH counter */
1438
1439                 /* write the addresses to the buffer */
1440                 switch (esd->ad_size) {
1441
1442                 case (0):
1443                         /* do nothing */
1444                         break;
1445
1446                 case (2):
1447                         /* two bytes */
1448                         *(buf++) = (unsigned char) (addr1 >> 8); 
1449                         *(buf++) = (unsigned char) (addr1 >> 0); 
1450                         *(buf++) = (unsigned char) (addr2 >> 8); 
1451                         *(buf++) = (unsigned char) (addr2 >> 0); 
1452                         break;
1453
1454                 case (4):
1455                         /* four bytes */
1456                         *(buf++) = (unsigned char) (addr1 >> 24); 
1457                         *(buf++) = (unsigned char) (addr1 >> 16); 
1458                         *(buf++) = (unsigned char) (addr1 >> 8); 
1459                         *(buf++) = (unsigned char) (addr1 >> 0); 
1460                         *(buf++) = (unsigned char) (addr2 >> 24); 
1461                         *(buf++) = (unsigned char) (addr2 >> 16); 
1462                         *(buf++) = (unsigned char) (addr2 >> 8); 
1463                         *(buf++) = (unsigned char) (addr2 >> 0); 
1464                         break;
1465
1466                 default:
1467                         /* do nothing */
1468                         break;
1469                 }
1470
1471
1472                 /* let's fill the value field */
1473                 switch (esd->senst) {
1474
1475                 /* relative sensitivity */
1476                 case (0):
1477                         /* we just write down the packet ordering */
1478                         if (dvalue == -10)
1479                                 /* MH */
1480                                 dvalue = MAX_V1 + 1000.0; /* this will cause pfpvalue set to 0xFFFF */
1481                         else if (dvalue == -1)
1482                                 /* TPH */
1483                                 dvalue = MAX_V1 + 1000.0; /* this will cause pfpvalue set to 0xFFFF */
1484                         else
1485                                 /* packet: first is most important, and then in decreasing order
1486                                 down to the last, which counts for 1 */
1487                                 dvalue = jpwl_pfp_to_double((unsigned short) (j2k->cstr_info->num - thispacket), esd->se_size);
1488                         break;
1489
1490                 /* MSE */
1491                 case (1):
1492                         /* !!! WRONG: let's put here disto field of packets !!! */
1493                         dvalue = MSE;
1494                         break;
1495
1496                 /* MSE reduction */
1497                 case (2):
1498                         dvalue = oldMSE - MSE;
1499                         oldMSE = MSE;
1500                         break;
1501
1502                 /* PSNR */
1503                 case (3):
1504                         dvalue = PSNR;
1505                         break;
1506
1507                 /* PSNR increase */
1508                 case (4):
1509                         dvalue = PSNR - oldPSNR;
1510                         oldPSNR = PSNR;
1511                         break;
1512
1513                 /* MAXERR */
1514                 case (5):
1515                         dvalue = 0.0;
1516                         opj_event_msg(j2k->cinfo, EVT_WARNING, "MAXERR sensitivity mode is not implemented\n");
1517                         break;
1518
1519                 /* TSE */
1520                 case (6):
1521                         dvalue = TSE;
1522                         break;
1523
1524                 /* reserved */
1525                 case (7):
1526                         dvalue = 0.0;
1527                         opj_event_msg(j2k->cinfo, EVT_WARNING, "Reserved sensitivity mode is not implemented\n");
1528                         break;
1529
1530                 default:
1531                         dvalue = 0.0;
1532                         break;
1533                 }
1534
1535                 /* compute the pseudo-floating point value */
1536                 pfpvalue = jpwl_double_to_pfp(dvalue, esd->se_size);
1537
1538                 /* write the pfp value to the buffer */
1539                 switch (esd->se_size) {
1540
1541                 case (1):
1542                         /* one byte */
1543                         *(buf++) = (unsigned char) (pfpvalue >> 0); 
1544                         break;
1545
1546                 case (2):
1547                         /* two bytes */
1548                         *(buf++) = (unsigned char) (pfpvalue >> 8); 
1549                         *(buf++) = (unsigned char) (pfpvalue >> 0); 
1550                         break;
1551                 }
1552
1553         }
1554
1555         return true;
1556 }
1557
1558 void jpwl_esd_write(jpwl_esd_ms_t *esd, unsigned char *buf) {
1559
1560         /* Marker */
1561         *(buf++) = (unsigned char) (J2K_MS_ESD >> 8); 
1562         *(buf++) = (unsigned char) (J2K_MS_ESD >> 0); 
1563
1564         /* Lesd */
1565         *(buf++) = (unsigned char) (esd->Lesd >> 8); 
1566         *(buf++) = (unsigned char) (esd->Lesd >> 0); 
1567
1568         /* Cesd */
1569         if (esd->numcomps >= 257)
1570                 *(buf++) = (unsigned char) (esd->Cesd >> 8); 
1571         *(buf++) = (unsigned char) (esd->Cesd >> 0); 
1572
1573         /* Pesd */
1574         *(buf++) = (unsigned char) (esd->Pesd >> 0); 
1575
1576         /* Data */
1577         if (esd->numcomps < 257)
1578                 memset(buf, 0xAA, (size_t) esd->Lesd - 4);
1579                 /*memcpy(buf, esd->data, (size_t) esd->Lesd - 4);*/
1580         else
1581                 memset(buf, 0xAA, (size_t) esd->Lesd - 5);
1582                 /*memcpy(buf, esd->data, (size_t) esd->Lesd - 5);*/
1583 }
1584
1585 unsigned short int jpwl_double_to_pfp(double V, int bytes) {
1586
1587         unsigned short int em, e, m;
1588
1589         switch (bytes) {
1590
1591         case (1):
1592
1593                 if (V < MIN_V1) {
1594                         e = 0x0000;
1595                         m = 0x0000;
1596                 } else if (V > MAX_V1) {
1597                         e = 0x000F;
1598                         m = 0x000F;
1599                 } else {
1600                         e = (unsigned short int) (floor(log(V) * 1.44269504088896) / 4.0);
1601                         m = (unsigned short int) (0.5 + (V / (pow(2.0, (double) (4 * e)))));
1602                 }
1603                 em = ((e & 0x000F) << 4) + (m & 0x000F);                
1604                 break;
1605
1606         case (2):
1607
1608                 if (V < MIN_V2) {
1609                         e = 0x0000;
1610                         m = 0x0000;
1611                 } else if (V > MAX_V2) {
1612                         e = 0x001F;
1613                         m = 0x07FF;
1614                 } else {
1615                         e = (unsigned short int) floor(log(V) * 1.44269504088896) + 15;
1616                         m = (unsigned short int) (0.5 + 2048.0 * ((V / (pow(2.0, (double) e - 15.0))) - 1.0));
1617                 }
1618                 em = ((e & 0x001F) << 11) + (m & 0x07FF);
1619                 break;
1620
1621         default:
1622
1623                 em = 0x0000;
1624                 break;
1625         };
1626
1627         return em;
1628 }
1629
1630 double jpwl_pfp_to_double(unsigned short int em, int bytes) {
1631
1632         double V;
1633
1634         switch (bytes) {
1635
1636         case 1:
1637                 V = (double) (em & 0x0F) * pow(2.0, (double) (em & 0xF0));
1638                 break;
1639
1640         case 2:
1641
1642                 V = pow(2.0, (double) ((em & 0xF800) >> 11) - 15.0) * (1.0 + (double) (em & 0x07FF) / 2048.0);
1643                 break;
1644
1645         default:
1646                 V = 0.0;
1647                 break;
1648
1649         }
1650
1651         return V;
1652
1653 }
1654
1655 bool jpwl_update_info(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int jwmarker_num) {
1656
1657         int mm;
1658         unsigned long int addlen;
1659
1660         opj_codestream_info_t *info = j2k->cstr_info;
1661         int tileno, tpno, packno, numtiles = info->th * info->tw, numpacks = info->num;
1662
1663         if (!j2k || !jwmarker ) {
1664                 opj_event_msg(j2k->cinfo, EVT_ERROR, "J2K handle or JPWL markers list badly allocated\n");
1665                 return false;
1666         }
1667
1668         /* main_head_end: how many markers are there before? */
1669         addlen = 0;
1670         for (mm = 0; mm < jwmarker_num; mm++)
1671                 if (jwmarker[mm].pos < (unsigned long int) info->main_head_end)
1672                         addlen += jwmarker[mm].len + 2;
1673         info->main_head_end += addlen;
1674
1675         /* codestream_size: always increment with all markers */
1676         addlen = 0;
1677         for (mm = 0; mm < jwmarker_num; mm++)
1678                 addlen += jwmarker[mm].len + 2;
1679         info->codestream_size += addlen;
1680
1681         /* navigate through all the tiles */
1682         for (tileno = 0; tileno < numtiles; tileno++) {
1683
1684                 /* start_pos: increment with markers before SOT */
1685                 addlen = 0;
1686                 for (mm = 0; mm < jwmarker_num; mm++)
1687                         if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].start_pos)
1688                                 addlen += jwmarker[mm].len + 2;
1689                 info->tile[tileno].start_pos += addlen;
1690
1691                 /* end_header: increment with markers before of it */
1692                 addlen = 0;
1693                 for (mm = 0; mm < jwmarker_num; mm++)
1694                         if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].end_header)
1695                                 addlen += jwmarker[mm].len + 2;
1696                 info->tile[tileno].end_header += addlen;
1697
1698                 /* end_pos: increment with markers before the end of this tile */
1699                 /* code is disabled, since according to JPWL no markers can be beyond TPH */
1700                 /*addlen = 0;
1701                 for (mm = 0; mm < jwmarker_num; mm++)
1702                         if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].end_pos)
1703                                 addlen += jwmarker[mm].len + 2;*/
1704                 info->tile[tileno].end_pos += addlen;
1705
1706                 /* navigate through all the tile parts */
1707                 for (tpno = 0; tpno < info->tile[tileno].num_tps; tpno++) {
1708
1709                         /* start_pos: increment with markers before SOT */
1710                         addlen = 0;
1711                         for (mm = 0; mm < jwmarker_num; mm++)
1712                                 if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp_start_pos[tpno])
1713                                         addlen += jwmarker[mm].len + 2;
1714                         info->tile[tileno].tp_start_pos[tpno] += addlen;
1715
1716                         /* end_header: increment with markers before of it */
1717                         addlen = 0;
1718                         for (mm = 0; mm < jwmarker_num; mm++)
1719                                 if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp_end_header[tpno])
1720                                         addlen += jwmarker[mm].len + 2;
1721                         info->tile[tileno].tp_end_header[tpno] += addlen;
1722
1723                         /* end_pos: increment with markers before the end of this tile part */
1724                         addlen = 0;
1725                         for (mm = 0; mm < jwmarker_num; mm++)
1726                                 if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp_end_pos[tpno])
1727                                         addlen += jwmarker[mm].len + 2;
1728                         info->tile[tileno].tp_end_pos[tpno] += addlen;
1729
1730                 }
1731
1732                 /* navigate through all the packets in this tile */
1733                 for (packno = 0; packno < numpacks; packno++) {
1734                         
1735                         /* start_pos: increment with markers before the packet */
1736                         /* disabled for the same reason as before */
1737                         /*addlen = 0;
1738                         for (mm = 0; mm < jwmarker_num; mm++)
1739                                 if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].packet[packno].start_pos)
1740                                         addlen += jwmarker[mm].len + 2;*/
1741                         info->tile[tileno].packet[packno].start_pos += addlen;
1742
1743                         /* end_pos: increment if marker is before the end of packet */
1744                         /* disabled for the same reason as before */
1745                         /*addlen = 0;
1746                         for (mm = 0; mm < jwmarker_num; mm++)
1747                                 if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].packet[packno].end_pos)
1748                                         addlen += jwmarker[mm].len + 2;*/
1749                         info->tile[tileno].packet[packno].end_pos += addlen;
1750
1751                 }
1752         }
1753
1754         return true;
1755 }
1756
1757 #endif /* USE_JPWL */