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