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