2 * The copyright in this software is being made available under the 2-clauses
3 * BSD License, included below. This software may be subject to other third
4 * party and contributor rights, including patent rights, and no such rights
5 * are granted under this license.
7 * Copyright (c) 2001-2003, David Janssens
8 * Copyright (c) 2002-2003, Yannick Verschueren
9 * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
10 * Copyright (c) 2005, Herve Drolon, FreeImage Team
11 * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
12 * Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
37 #include "opj_includes.h"
41 /** @defgroup JPWL JPWL - JPEG-2000 Part11 (JPWL) codestream manager */
44 /** @name Local static variables */
47 /** number of JPWL prepared markers */
48 static int jwmarker_num;
49 /** properties of JPWL markers to insert */
50 static jpwl_marker_t jwmarker[JPWL_MAX_NO_MARKERS];
56 /** @name Local static functions */
59 /** create an EPC marker segment
60 @param j2k J2K compressor handle
61 @param esd_on true if ESD is activated
62 @param red_on true if RED is activated
63 @param epb_on true if EPB is activated
64 @param info_on true if informative techniques are activated
65 @return returns the freshly created EPC
67 jpwl_epc_ms_t *jpwl_epc_create(opj_j2k_t *j2k, opj_bool esd_on, opj_bool red_on, opj_bool epb_on, opj_bool info_on);
71 /** create an EPC marker segment
72 @param j2k J2K compressor handle
73 @param comps considered component (-1=average, 0/1/2/...=component no.)
74 @param addrm addressing mode (0=packet, 1=byte range, 2=packet range, 3=reserved)
75 @param ad_size size of addresses (2/4 bytes)
76 @param senst sensitivity type
77 @param se_size sensitivity values size (1/2 bytes)
78 @param tileno tile where this ESD lies (-1 means MH)
79 @param svalnum number of sensitivity values (if 0, they will be automatically filled)
80 @param sensval pointer to an array of sensitivity values (if NULL, they will be automatically filled)
81 @return returns the freshly created ESD
83 jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comps,
84 unsigned char addrm, unsigned char ad_size,
85 unsigned char senst, int se_size, int tileno,
86 unsigned long int svalnum, void *sensval);
88 /** this function is used to compare two JPWL markers based on
89 their relevant wishlist position
90 @param arg1 pointer to first marker
91 @param arg2 pointer to second marker
92 @return 1 if arg1>arg2, 0 if arg1=arg2, -1 if arg1<arg2
94 int jpwl_markcomp(const void *arg1, const void *arg2);
96 /** write an EPB MS to a buffer
97 @param j2k J2K compressor handle
98 @param epbmark pointer to the EPB MS
99 @param buf pointer to the memory buffer
101 void jpwl_epb_write(opj_j2k_t *j2k, jpwl_epb_ms_t *epbmark, unsigned char *buf);
103 /** write an EPC MS to a buffer
104 @param j2k J2K compressor handle
105 @param epcmark pointer to the EPC MS
106 @param buf pointer to the memory buffer
108 void jpwl_epc_write(opj_j2k_t *j2k, jpwl_epc_ms_t *epcmark, unsigned char *buf);
111 * write an ESD MS to a buffer
112 @param j2k J2K compressor handle
113 @param esd pointer to the ESD MS
114 @param buf pointer to the memory buffer
116 void jpwl_esd_write(opj_j2k_t *j2k, jpwl_esd_ms_t *esdmark, unsigned char *buf);
118 /*-----------------------------------------------------------------*/
120 void jpwl_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
124 /* let's reset some settings */
126 /* clear the existing markers */
127 for (mm = 0; mm < jwmarker_num; mm++) {
129 switch (jwmarker[mm].id) {
132 opj_free(jwmarker[mm].m.epbmark);
136 opj_free(jwmarker[mm].m.epcmark);
140 opj_free(jwmarker[mm].m.esdmark);
144 opj_free(jwmarker[mm].m.redmark);
152 /* clear the marker structure array */
153 memset(jwmarker, 0, sizeof(jpwl_marker_t) * JPWL_MAX_NO_MARKERS);
155 /* no more markers in the list */
158 /* let's begin creating a marker list, according to user wishes */
159 jpwl_prepare_marks(j2k, cio, image);
161 /* now we dump the JPWL markers on the codestream */
162 jpwl_dump_marks(j2k, cio, image);
164 /* do not know exactly what is this for,
165 but it gets called during index creation */
166 j2k->pos_correction = 0;
170 opj_bool j2k_add_marker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
175 /* expand the list? */
176 if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) {
177 opj_marker_info_t* new_marker;
178 cstr_info->maxmarknum += 100;
179 new_marker = (opj_marker_info_t*)opj_realloc(cstr_info->marker, cstr_info->maxmarknum * sizeof(opj_marker_info_t));
182 opj_free(cstr_info->marker);
183 cstr_info->marker = 0;
184 cstr_info->marknum = 0;
185 cstr_info->maxmarknum = 0;
186 /* opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to add a marker\n"); */
187 /* TODO_test_add_marker_result;*/
190 cstr_info->marker = new_marker;
194 cstr_info->marker[cstr_info->marknum].type = type;
195 cstr_info->marker[cstr_info->marknum].pos = pos;
196 cstr_info->marker[cstr_info->marknum].len = len;
197 cstr_info->marknum++;
202 void jpwl_prepare_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
204 unsigned short int socsiz_len = 0;
205 int ciopos = cio_tell(cio), soc_pos = j2k->cstr_info->main_head_start;
206 unsigned char *socp = NULL;
208 int tileno, acc_tpno, tpno, tilespec, hprot, sens, pprot, packspec, lastileno, packno;
210 jpwl_epb_ms_t *epb_mark;
211 jpwl_epc_ms_t *epc_mark;
212 jpwl_esd_ms_t *esd_mark;
215 /* find (SOC + SIZ) length */
216 /* I assume SIZ is always the first marker after SOC */
217 cio_seek(cio, soc_pos + 4);
218 socsiz_len = (unsigned short int) cio_read(cio, 2) + 4; /* add the 2 marks length itself */
219 cio_seek(cio, soc_pos + 0);
220 socp = cio_getbp(cio); /* pointer to SOC */
223 EPC MS for Main Header: if we are here it's required
226 if ((epc_mark = jpwl_epc_create(
228 j2k->cp->esd_on, /* is ESD present? */
229 j2k->cp->red_on, /* is RED present? */
230 j2k->cp->epb_on, /* is EPB present? */
231 OPJ_FALSE /* are informative techniques present? */
234 /* Add this marker to the 'insertanda' list */
236 jwmarker[jwmarker_num].id = J2K_MS_EPC; /* its type */
237 jwmarker[jwmarker_num].m.epcmark = epc_mark; /* the EPC */
238 jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* after SIZ */
239 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.1; /* not so first */
240 jwmarker[jwmarker_num].len = epc_mark->Lepc; /* its length */
241 jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready */
242 jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */
243 jwmarker[jwmarker_num].parms_ready = OPJ_FALSE; /* not ready */
244 jwmarker[jwmarker_num].data_ready = OPJ_TRUE; /* ready */
248 opj_event_msg(j2k->cinfo, EVT_INFO,
249 "MH EPC : setting %s%s%s\n",
250 j2k->cp->esd_on ? "ESD, " : "",
251 j2k->cp->red_on ? "RED, " : "",
252 j2k->cp->epb_on ? "EPB, " : ""
256 /* ooops, problems */
257 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH EPC\n");
261 ESD MS for Main Header
263 /* first of all, must MH have an ESD MS? */
264 if (j2k->cp->esd_on && (j2k->cp->sens_MH >= 0)) {
267 if ((esd_mark = jpwl_esd_create(
268 j2k, /* this encoder handle */
269 -1, /* we are averaging over all components */
270 (unsigned char) j2k->cp->sens_range, /* range method */
271 (unsigned char) j2k->cp->sens_addr, /* sensitivity addressing */
272 (unsigned char) j2k->cp->sens_MH, /* sensitivity method */
273 j2k->cp->sens_size, /* sensitivity size */
274 -1, /* this ESD is in main header */
275 0 /*j2k->cstr_info->num*/, /* number of packets in codestream */
276 NULL /*sensval*/ /* pointer to sensitivity data of packets */
279 /* Add this marker to the 'insertanda' list */
280 if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
281 jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */
282 jwmarker[jwmarker_num].m.esdmark = esd_mark; /* the EPB */
283 jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* we choose to place it after SIZ */
284 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */
285 jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */
286 jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* not ready, yet */
287 jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */
288 jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* not ready */
289 jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* not ready */
293 opj_event_msg(j2k->cinfo, EVT_INFO,
294 "MH ESDs: method %d\n",
299 /* ooops, problems */
300 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH ESD\n");
306 ESD MSs for Tile Part Headers
308 /* cycle through tiles */
309 sens = -1; /* default spec: no ESD */
310 tilespec = 0; /* first tile spec */
312 for (tileno = 0; tileno < j2k->cstr_info->tw * j2k->cstr_info->th; tileno++) {
314 opj_event_msg(j2k->cinfo, EVT_INFO,
315 "Tile %d has %d tile part(s)\n",
316 tileno, j2k->cstr_info->tile[tileno].num_tps
319 /* for every tile part in the tile */
320 for (tpno = 0; tpno < j2k->cstr_info->tile[tileno].num_tps; tpno++, acc_tpno++) {
322 int sot_len, Psot, Psotp, mm;
323 unsigned long sot_pos, post_sod_pos;
325 unsigned long int left_THmarks_len;
327 /******* sot_pos = j2k->cstr_info->tile[tileno].start_pos; */
328 sot_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos;
329 cio_seek(cio, sot_pos + 2);
330 sot_len = cio_read(cio, 2); /* SOT Len */
332 Psotp = cio_tell(cio);
333 Psot = cio_read(cio, 4); /* tile length */
335 /******* post_sod_pos = j2k->cstr_info->tile[tileno].end_header + 1; */
336 post_sod_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_end_header + 1;
337 left_THmarks_len = post_sod_pos - sot_pos;
339 /* add all the lengths of the markers which are len-ready and stay within SOT and SOD */
340 for (mm = 0; mm < jwmarker_num; mm++) {
341 if ((jwmarker[mm].pos >= sot_pos) && (jwmarker[mm].pos < post_sod_pos)) {
342 if (jwmarker[mm].len_ready)
343 left_THmarks_len += jwmarker[mm].len + 2;
345 opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up TH EPB\n",
346 jwmarker[mm].id, jwmarker[mm].dpos);
352 /******* if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->sens_TPH_tileno[tilespec] == tileno)) */
353 if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->sens_TPH_tileno[tilespec] == acc_tpno))
354 /* we got a specification from this tile onwards */
355 sens = j2k->cp->sens_TPH[tilespec++];
357 /* must this TPH have an ESD MS? */
358 if (j2k->cp->esd_on && (sens >= 0)) {
361 if ((esd_mark = jpwl_esd_create(
362 j2k, /* this encoder handle */
363 -1, /* we are averaging over all components */
364 (unsigned char) j2k->cp->sens_range, /* range method */
365 (unsigned char) j2k->cp->sens_addr, /* sensitivity addressing size */
366 (unsigned char) sens, /* sensitivity method */
367 j2k->cp->sens_size, /* sensitivity value size */
368 tileno, /* this ESD is in a tile */
369 0, /* number of packets in codestream */
370 NULL /* pointer to sensitivity data of packets */
373 /* Add this marker to the 'insertanda' list */
374 if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
375 jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */
376 jwmarker[jwmarker_num].m.esdmark = esd_mark; /* the EPB */
377 /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */
378 jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */
379 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */
380 jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */
381 jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready, yet */
382 jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */
383 jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* not ready */
384 jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* ready */
388 /* update Psot of the tile */
389 cio_seek(cio, Psotp);
390 cio_write(cio, Psot + esd_mark->Lesd + 2, 4);
392 opj_event_msg(j2k->cinfo, EVT_INFO,
393 /******* "TPH ESDs: tile %02d, method %d\n", */
394 "TPH ESDs: tile %02d, part %02d, method %d\n",
401 /* ooops, problems */
402 /***** opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH ESD #%d\n", tileno); */
403 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH ESD #%d,%d\n", tileno, tpno);
413 EPB MS for Main Header
415 /* first of all, must MH have an EPB MS? */
416 if (j2k->cp->epb_on && (j2k->cp->hprot_MH > 0)) {
420 /* position of SOT */
421 unsigned int sot_pos = j2k->cstr_info->main_head_end + 1;
423 /* how much space is there between end of SIZ and beginning of SOT? */
424 int left_MHmarks_len = sot_pos - socsiz_len;
426 /* add all the lengths of the markers which are len-ready and stay within SOC and SOT */
427 for (mm = 0; mm < jwmarker_num; mm++) {
428 if ( jwmarker[mm].pos < sot_pos) { /* jwmarker[mm].pos >=0 since ulong */
429 if (jwmarker[mm].len_ready)
430 left_MHmarks_len += jwmarker[mm].len + 2;
432 opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up MH EPB\n",
433 jwmarker[mm].id, jwmarker[mm].dpos);
440 if ((epb_mark = jpwl_epb_create(
441 j2k, /* this encoder handle */
442 OPJ_TRUE, /* is it the latest? */
443 OPJ_TRUE, /* is it packed? not for now */
444 -1, /* we are in main header */
445 0, /* its index is 0 (first) */
446 j2k->cp->hprot_MH, /* protection type parameters of data */
447 socsiz_len, /* pre-data: only SOC+SIZ */
448 left_MHmarks_len /* post-data: from SOC to SOT, and all JPWL markers within */
451 /* Add this marker to the 'insertanda' list */
452 if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
453 jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */
454 jwmarker[jwmarker_num].m.epbmark = epb_mark; /* the EPB */
455 jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* after SIZ */
456 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */
457 jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */
458 jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready */
459 jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */
460 jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* ready */
461 jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* not ready */
465 opj_event_msg(j2k->cinfo, EVT_INFO,
466 "MH EPB : prot. %d\n",
471 /* ooops, problems */
472 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH EPB\n");
477 EPB MSs for Tile Parts
479 /* cycle through TPHs */
480 hprot = j2k->cp->hprot_MH; /* default spec */
481 tilespec = 0; /* first tile spec */
486 for (tileno = 0; tileno < j2k->cstr_info->tw * j2k->cstr_info->th; tileno++) {
488 opj_event_msg(j2k->cinfo, EVT_INFO,
489 "Tile %d has %d tile part(s)\n",
490 tileno, j2k->cstr_info->tile[tileno].num_tps
493 /* for every tile part in the tile */
494 for (tpno = 0; tpno < j2k->cstr_info->tile[tileno].num_tps; tpno++, acc_tpno++) {
496 int sot_len, Psot, Psotp, mm, epb_index = 0, prot_len = 0;
497 unsigned long sot_pos, post_sod_pos;
498 unsigned long int left_THmarks_len/*, epbs_len = 0*/;
499 int startpack = 0, stoppack = j2k->cstr_info->packno;
500 int first_tp_pack, last_tp_pack;
501 jpwl_epb_ms_t *tph_epb = NULL;
503 /****** sot_pos = j2k->cstr_info->tile[tileno].start_pos; */
504 sot_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos;
505 cio_seek(cio, sot_pos + 2);
506 sot_len = cio_read(cio, 2); /* SOT Len */
508 Psotp = cio_tell(cio);
509 Psot = cio_read(cio, 4); /* tile length */
511 /* a-priori length of the data dwelling between SOT and SOD */
512 /****** post_sod_pos = j2k->cstr_info->tile[tileno].end_header + 1; */
513 post_sod_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_end_header + 1;
514 left_THmarks_len = post_sod_pos - (sot_pos + sot_len + 2);
516 /* add all the lengths of the JPWL markers which are len-ready and stay within SOT and SOD */
517 for (mm = 0; mm < jwmarker_num; mm++) {
518 if ((jwmarker[mm].pos >= sot_pos) && (jwmarker[mm].pos < post_sod_pos)) {
519 if (jwmarker[mm].len_ready)
520 left_THmarks_len += jwmarker[mm].len + 2;
522 opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up TH EPB\n",
523 jwmarker[mm].id, jwmarker[mm].dpos);
529 /****** if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->hprot_TPH_tileno[tilespec] == tileno)) */
530 if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->hprot_TPH_tileno[tilespec] == acc_tpno))
531 /* we got a specification from this tile part onwards */
532 hprot = j2k->cp->hprot_TPH[tilespec++];
534 /* must this TPH have an EPB MS? */
535 if (j2k->cp->epb_on && (hprot > 0)) {
538 if ((epb_mark = jpwl_epb_create(
539 j2k, /* this encoder handle */
540 OPJ_FALSE, /* is it the latest? in TPH, no for now (if huge data size in TPH, we'd need more) */
541 OPJ_TRUE, /* is it packed? yes for now */
542 tileno, /* we are in TPH */
543 epb_index++, /* its index is 0 (first) */
544 hprot, /* protection type parameters of following data */
545 sot_len + 2, /* pre-data length: only SOT */
546 left_THmarks_len /* post-data length: from SOT end to SOD inclusive */
549 /* Add this marker to the 'insertanda' list */
550 if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
551 jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */
552 jwmarker[jwmarker_num].m.epbmark = epb_mark; /* the EPB */
553 /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */
554 jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */
555 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */
556 jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */
557 jwmarker[jwmarker_num].len_ready = OPJ_TRUE; /* ready */
558 jwmarker[jwmarker_num].pos_ready = OPJ_TRUE; /* ready */
559 jwmarker[jwmarker_num].parms_ready = OPJ_TRUE; /* ready */
560 jwmarker[jwmarker_num].data_ready = OPJ_FALSE; /* not ready */
564 /* update Psot of the tile */
565 Psot += epb_mark->Lepb + 2;
567 opj_event_msg(j2k->cinfo, EVT_INFO,
568 /***** "TPH EPB : tile %02d, prot. %d\n", */
569 "TPH EPB : tile %02d, part %02d, prot. %d\n",
575 /* save this TPH EPB address */
579 /* ooops, problems */
580 /****** opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB #%d\n", tileno); */
581 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB in #%d,d\n", tileno, tpno);
587 /* EPB MSs for UEP packet data protection in Tile Parts */
588 /****** for (packno = 0; packno < j2k->cstr_info->num; packno++) { */
589 /*first_tp_pack = (tpno > 0) ? (first_tp_pack + j2k->cstr_info->tile[tileno].tp[tpno - 1].tp_numpacks) : 0;*/
590 first_tp_pack = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pack;
591 last_tp_pack = first_tp_pack + j2k->cstr_info->tile[tileno].tp[tpno].tp_numpacks - 1;
592 for (packno = 0; packno < j2k->cstr_info->tile[tileno].tp[tpno].tp_numpacks; packno++) {
594 /******** if ((packspec < JPWL_MAX_NO_PACKSPECS) &&
595 (j2k->cp->pprot_tileno[packspec] == tileno) && (j2k->cp->pprot_packno[packspec] == packno)) { */
596 if ((packspec < JPWL_MAX_NO_PACKSPECS) &&
597 (j2k->cp->pprot_tileno[packspec] == acc_tpno) && (j2k->cp->pprot_packno[packspec] == packno)) {
599 /* we got a specification from this tile and packet onwards */
600 /* print the previous spec */
602 stoppack = packno - 1;
603 opj_event_msg(j2k->cinfo, EVT_INFO,
604 /***** "UEP EPBs: tile %02d, packs. %02d-%02d (B %d-%d), prot. %d\n", */
605 "UEP EPBs: tile %02d, part %02d, packs. %02d-%02d (B %d-%d), prot. %d\n",
610 /***** j2k->cstr_info->tile[tileno].packet[startpack].start_pos, */
611 j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos,
612 /***** j2k->cstr_info->tile[tileno].packet[stoppack].end_pos, */
613 j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos,
616 /***** prot_len = j2k->cstr_info->tile[tileno].packet[stoppack].end_pos + 1 -
617 j2k->cstr_info->tile[tileno].packet[startpack].start_pos; */
618 prot_len = j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos + 1 -
619 j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos;
622 particular case: if this is the last header and the last packet,
623 then it is better to protect even the EOC marker
625 /****** if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
626 (stoppack == (j2k->cstr_info->num - 1))) */
627 if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
628 (tpno == (j2k->cstr_info->tile[tileno].num_tps - 1)) &&
629 (stoppack == last_tp_pack))
630 /* add the EOC len */
633 /* let's add the EPBs */
634 Psot += jpwl_epbs_add(
635 j2k, /* J2K handle */
636 jwmarker, /* pointer to JPWL markers list */
637 &jwmarker_num, /* pointer to the number of current markers */
638 OPJ_FALSE, /* latest */
639 OPJ_TRUE, /* packed */
640 OPJ_FALSE, /* inside MH */
641 &epb_index, /* pointer to EPB index */
642 pprot, /* protection type */
643 /****** (double) (j2k->cstr_info->tile[tileno].start_pos + sot_len + 2) + 0.0001, */ /* position */
644 (double) (j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2) + 0.0001, /* position */
645 tileno, /* number of tile */
646 0, /* length of pre-data */
647 prot_len /*4000*/ /* length of post-data */
652 pprot = j2k->cp->pprot[packspec++];
655 /*printf("Tile %02d, pack %02d ==> %d\n", tileno, packno, pprot);*/
659 /* we are at the end: print the remaining spec */
660 stoppack = packno - 1;
663 opj_event_msg(j2k->cinfo, EVT_INFO,
664 /**** "UEP EPBs: tile %02d, packs. %02d-%02d (B %d-%d), prot. %d\n", */
665 "UEP EPBs: tile %02d, part %02d, packs. %02d-%02d (B %d-%d), prot. %d\n",
670 /***** j2k->image_info->tile[tileno].packet[startpack].start_pos,
671 j2k->image_info->tile[tileno].packet[stoppack].end_pos, */
672 j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos,
673 j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos,
676 /***** prot_len = j2k->cstr_info->tile[tileno].packet[stoppack].end_pos + 1 -
677 j2k->cstr_info->tile[tileno].packet[startpack].start_pos; */
678 prot_len = j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos + 1 -
679 j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos;
682 particular case: if this is the last header and the last packet,
683 then it is better to protect even the EOC marker
685 /***** if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
686 (stoppack == (j2k->cstr_info->num - 1))) */
687 if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
688 (tpno == (j2k->cstr_info->tile[tileno].num_tps - 1)) &&
689 (stoppack == last_tp_pack))
690 /* add the EOC len */
693 /* let's add the EPBs */
694 Psot += jpwl_epbs_add(
695 j2k, /* J2K handle */
696 jwmarker, /* pointer to JPWL markers list */
697 &jwmarker_num, /* pointer to the number of current markers */
698 OPJ_TRUE, /* latest */
699 OPJ_TRUE, /* packed */
700 OPJ_FALSE, /* inside MH */
701 &epb_index, /* pointer to EPB index */
702 pprot, /* protection type */
703 /***** (double) (j2k->cstr_info->tile[tileno].start_pos + sot_len + 2) + 0.0001,*/ /* position */
704 (double) (j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2) + 0.0001, /* position */
705 tileno, /* number of tile */
706 0, /* length of pre-data */
707 prot_len /*4000*/ /* length of post-data */
711 /* we can now check if the TPH EPB was really the last one */
712 if (tph_epb && (epb_index == 1)) {
713 /* set the TPH EPB to be the last one in current header */
714 tph_epb->Depb |= (unsigned char) ((OPJ_TRUE & 0x0001) << 6);
718 /* write back Psot */
719 cio_seek(cio, Psotp);
720 cio_write(cio, Psot, 4);
726 /* reset the position */
727 cio_seek(cio, ciopos);
731 void jpwl_dump_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
734 unsigned long int old_size = j2k->cstr_info->codestream_size;
735 unsigned long int new_size = old_size;
736 int /*ciopos = cio_tell(cio),*/ soc_pos = j2k->cstr_info->main_head_start;
737 unsigned char *jpwl_buf, *orig_buf;
738 unsigned long int orig_pos;
739 double epbcoding_time = 0.0, esdcoding_time = 0.0;
742 /* Order JPWL markers according to their wishlist position */
743 qsort((void *) jwmarker, (size_t) jwmarker_num, sizeof (jpwl_marker_t), jpwl_markcomp);
745 /* compute markers total size */
746 for (mm = 0; mm < jwmarker_num; mm++) {
747 /*printf("%x, %d, %.10f, %d long\n", jwmarker[mm].id, jwmarker[mm].pos,
748 jwmarker[mm].dpos, jwmarker[mm].len);*/
749 new_size += jwmarker[mm].len + 2;
752 /* allocate a new buffer of proper size */
753 if (!(jpwl_buf = (unsigned char *) opj_malloc((size_t) (new_size + soc_pos) * sizeof(unsigned char)))) {
754 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for JPWL codestream buffer\n");
758 /* copy the jp2 part, if any */
760 memcpy(jpwl_buf, cio->buffer, soc_pos);
763 /* cycle through markers */
764 orig_pos = soc_pos + 0; /* start from the beginning */
765 cio_seek(cio, soc_pos + 0); /* rewind the original */
766 for (mm = 0; mm < jwmarker_num; mm++) {
769 need to copy a piece of the original codestream
772 memcpy(jpwl_buf, cio_getbp(cio), jwmarker[mm].pos - orig_pos);
773 jpwl_buf += jwmarker[mm].pos - orig_pos;
774 orig_pos = jwmarker[mm].pos;
775 cio_seek(cio, orig_pos);
778 then write down the marker
780 switch (jwmarker[mm].id) {
783 jpwl_epb_write(j2k, jwmarker[mm].m.epbmark, jpwl_buf);
787 jpwl_epc_write(j2k, jwmarker[mm].m.epcmark, jpwl_buf);
791 jpwl_esd_write(j2k, jwmarker[mm].m.esdmark, jpwl_buf);
795 memset(jpwl_buf, 0, jwmarker[mm].len + 2); /* placeholder */
802 /* we update the markers struct */
804 j2k->cstr_info->marker[j2k->cstr_info->marknum - 1].pos = (jpwl_buf - orig_buf);
806 /* we set the marker dpos to the new position in the JPWL codestream */
807 jwmarker[mm].dpos = (double) (jpwl_buf - orig_buf);
809 /* advance JPWL buffer position */
810 jpwl_buf += jwmarker[mm].len + 2;
814 /* finish remaining original codestream */
815 memcpy(jpwl_buf, cio_getbp(cio), old_size - (orig_pos - soc_pos));
816 jpwl_buf += old_size - (orig_pos - soc_pos);
817 cio_seek(cio, soc_pos + old_size);
820 update info file based on added markers
822 if (!jpwl_update_info(j2k, jwmarker, jwmarker_num))
823 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not update OPJ cstr_info structure\n");
825 /* now we need to repass some markers and fill their data fields */
827 /* first of all, DL and Pcrc in EPCs */
828 for (mm = 0; mm < jwmarker_num; mm++) {
831 if (jwmarker[mm].id == J2K_MS_EPC) {
833 int epc_pos = (int) jwmarker[mm].dpos, pp;
834 unsigned short int mycrc = 0x0000;
836 /* fix and fill the DL field */
837 jwmarker[mm].m.epcmark->DL = new_size;
838 orig_buf[epc_pos + 6] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 24);
839 orig_buf[epc_pos + 7] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 16);
840 orig_buf[epc_pos + 8] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 8);
841 orig_buf[epc_pos + 9] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 0);
843 /* compute the CRC field (excluding itself) */
844 for (pp = 0; pp < 4; pp++)
845 jpwl_updateCRC16(&mycrc, orig_buf[epc_pos + pp]);
846 for (pp = 6; pp < (jwmarker[mm].len + 2); pp++)
847 jpwl_updateCRC16(&mycrc, orig_buf[epc_pos + pp]);
849 /* fix and fill the CRC */
850 jwmarker[mm].m.epcmark->Pcrc = mycrc;
851 orig_buf[epc_pos + 4] = (unsigned char) (jwmarker[mm].m.epcmark->Pcrc >> 8);
852 orig_buf[epc_pos + 5] = (unsigned char) (jwmarker[mm].m.epcmark->Pcrc >> 0);
857 /* then, sensitivity data in ESDs */
858 esdcoding_time = opj_clock();
859 for (mm = 0; mm < jwmarker_num; mm++) {
862 if (jwmarker[mm].id == J2K_MS_ESD) {
864 /* remember that they are now in a new position (dpos) */
865 int esd_pos = (int) jwmarker[mm].dpos;
867 jpwl_esd_fill(j2k, jwmarker[mm].m.esdmark, &orig_buf[esd_pos]);
872 esdcoding_time = opj_clock() - esdcoding_time;
874 opj_event_msg(j2k->cinfo, EVT_INFO, "ESDs sensitivities computed in %f s\n", esdcoding_time);
876 /* finally, RS or CRC parity in EPBs */
877 epbcoding_time = opj_clock();
878 for (mm = 0; mm < jwmarker_num; mm++) {
881 if (jwmarker[mm].id == J2K_MS_EPB) {
883 /* remember that they are now in a new position (dpos) */
886 /* let's see how many EPBs are following this one, included itself */
887 /* for this to work, we suppose that the markers are correctly ordered */
888 /* and, overall, that they are in packed mode inside headers */
890 for (nn = mm; (nn < jwmarker_num) && (jwmarker[nn].id == J2K_MS_EPB) &&
891 (jwmarker[nn].pos == jwmarker[mm].pos); nn++)
892 accum_len += jwmarker[nn].m.epbmark->Lepb + 2;
894 /* fill the current (first) EPB with post-data starting from the computed position */
895 jpwl_epb_fill(j2k, jwmarker[mm].m.epbmark, &orig_buf[(int) jwmarker[mm].dpos],
896 &orig_buf[(int) jwmarker[mm].dpos + accum_len]);
898 /* fill the remaining EPBs in the header with post-data starting from the last position */
899 for (nn = mm + 1; (nn < jwmarker_num) && (jwmarker[nn].id == J2K_MS_EPB) &&
900 (jwmarker[nn].pos == jwmarker[mm].pos); nn++)
901 jpwl_epb_fill(j2k, jwmarker[nn].m.epbmark, &orig_buf[(int) jwmarker[nn].dpos], NULL);
903 /* skip all the processed EPBs */
908 epbcoding_time = opj_clock() - epbcoding_time;
910 opj_event_msg(j2k->cinfo, EVT_INFO, "EPBs redundancy computed in %f s\n", epbcoding_time);
912 /* free original cio buffer and set it to the JPWL one */
913 opj_free(cio->buffer);
914 cio->cinfo = cio->cinfo; /* no change */
915 cio->openmode = cio->openmode; /* no change */
916 cio->buffer = orig_buf;
917 cio->length = new_size + soc_pos;
918 cio->start = cio->buffer;
919 cio->end = cio->buffer + cio->length;
920 cio->bp = cio->buffer;
921 cio_seek(cio, soc_pos + new_size);
926 void j2k_read_epc(opj_j2k_t *j2k) {
927 unsigned long int DL, Lepcp, Pcrcp, l;
928 unsigned short int Lepc, Pcrc = 0x0000;
930 opj_cio_t *cio = j2k->cio;
933 /* Simply read the EPC parameters */
934 Lepcp = cio_tell(cio);
935 Lepc = cio_read(cio, 2);
936 Pcrcp = cio_tell(cio);
937 cio_skip(cio, 2); /* Pcrc */
938 DL = cio_read(cio, 4);
939 Pepc = cio_read(cio, 1);
942 cio_seek(cio, Lepcp - 2);
945 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
946 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
949 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
950 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
955 /* read all remaining */
956 for (l = 4; l < Lepc; l++)
957 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
959 /* check Pcrc with the result */
960 cio_seek(cio, Pcrcp);
961 ans1 = (Pcrc == (unsigned short int) cio_read(cio, 2)) ? "crc-ok" : "crc-ko";
963 /* now we write them to screen */
964 opj_event_msg(j2k->cinfo, EVT_INFO,
965 "EPC(%u,%d): %s, DL=%d%s %s %s\n",
969 DL, /* data length this EPC is referring to */
970 (Pepc & 0x10) ? ", esd" : "", /* ESD is present */
971 (Pepc & 0x20) ? ", red" : "", /* RED is present */
972 (Pepc & 0x40) ? ", epb" : ""); /* EPB is present */
974 cio_seek(cio, Lepcp + Lepc);
978 void j2k_write_epc(opj_j2k_t *j2k) {
980 unsigned long int DL, Lepcp, Pcrcp, l;
981 unsigned short int Lepc, Pcrc;
984 opj_cio_t *cio = j2k->cio;
986 cio_write(cio, J2K_MS_EPC, 2); /* EPC */
987 Lepcp = cio_tell(cio);
990 /* CRC-16 word of the EPC */
991 Pcrc = 0x0000; /* initialize */
992 Pcrcp = cio_tell(cio);
993 cio_write(cio, Pcrc, 2); /* Pcrc placeholder*/
995 /* data length of the EPC protection domain */
996 DL = 0x00000000; /* we leave this set to 0, as if the information is not available */
997 cio_write(cio, DL, 4); /* DL */
999 /* jpwl capabilities */
1001 cio_write(cio, Pepc, 1); /* Pepc */
1004 /* no ID's, as of now */
1006 Lepc = (unsigned short) (cio_tell(cio) - Lepcp);
1007 cio_seek(cio, Lepcp);
1008 cio_write(cio, Lepc, 2); /* Lepc */
1011 cio_seek(cio, Lepcp - 2);
1014 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
1015 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
1018 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
1019 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
1024 /* read all remaining */
1025 for (l = 4; l < Lepc; l++)
1026 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
1028 /* fill Pcrc with the result */
1029 cio_seek(cio, Pcrcp);
1030 cio_write(cio, Pcrc, 2);
1032 cio_seek(cio, Lepcp + Lepc);
1034 /* marker struct update */
1035 j2k_add_marker(j2k->cstr_info, J2K_MS_EPC, Lepcp - 2, Lepc + 2);
1040 void j2k_read_epb(opj_j2k_t *j2k) {
1041 unsigned long int LDPepb, Pepb;
1042 unsigned short int Lepb;
1046 static opj_bool first_in_tph = OPJ_TRUE;
1047 int type, pre_len, post_len;
1048 static unsigned char *redund = NULL;
1050 opj_cio_t *cio = j2k->cio;
1052 /* B/W = 45, RGB = 51 */
1053 /* SIZ SIZ_FIELDS SIZ_COMPS FOLLOWING_MARKER */
1054 int skipnum = 2 + 38 + 3 * j2k->cp->exp_comps + 2;
1056 if (j2k->cp->correct) {
1058 /* go back to EPB marker value */
1059 cio_seek(cio, cio_tell(cio) - 2);
1061 /* we need to understand where we are */
1062 if (j2k->state == J2K_STATE_MH) {
1065 pre_len = skipnum; /* SOC+SIZ */
1066 post_len = -1; /* auto */
1068 } else if ((j2k->state == J2K_STATE_TPH) && first_in_tph) {
1071 pre_len = 12; /* SOC+SIZ */
1072 first_in_tph = OPJ_FALSE;
1073 post_len = -1; /* auto */
1076 /* we are elsewhere */
1077 type = 2; /* other */
1078 pre_len = 0; /* nada */
1079 post_len = -1; /* auto */
1083 /* call EPB corrector */
1084 /*printf("before %x, ", redund);*/
1085 status = jpwl_epb_correct(j2k, /* J2K decompressor handle */
1086 cio->bp, /* pointer to EPB in codestream buffer */
1087 type, /* EPB type: MH */
1088 pre_len, /* length of pre-data */
1089 post_len, /* length of post-data: -1 means auto */
1090 NULL, /* do everything auto */
1093 /*printf("after %x\n", redund);*/
1095 /* Read the (possibly corrected) EPB parameters */
1097 Lepb = cio_read(cio, 2);
1098 Depb = cio_read(cio, 1);
1099 LDPepb = cio_read(cio, 4);
1100 Pepb = cio_read(cio, 4);
1104 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL correction could not be performed\n");
1106 /* advance to EPB endpoint */
1107 cio_skip(cio, Lepb + 2);
1112 /* last in current header? */
1114 redund = NULL; /* reset the pointer to L4 buffer */
1115 first_in_tph = OPJ_TRUE;
1118 /* advance to EPB endpoint */
1119 cio_skip(cio, Lepb - 11);
1123 /* Simply read the EPB parameters */
1124 Lepb = cio_read(cio, 2);
1125 Depb = cio_read(cio, 1);
1126 LDPepb = cio_read(cio, 4);
1127 Pepb = cio_read(cio, 4);
1129 /* What does Pepb tells us about the protection method? */
1130 if (((Pepb & 0xF0000000) >> 28) == 0)
1131 sprintf(str1, "pred"); /* predefined */
1132 else if (((Pepb & 0xF0000000) >> 28) == 1)
1133 sprintf(str1, "crc-%lu", 16 * ((Pepb & 0x00000001) + 1)); /* CRC mode */
1134 else if (((Pepb & 0xF0000000) >> 28) == 2)
1135 sprintf(str1, "rs(%lu,32)", (Pepb & 0x0000FF00) >> 8); /* RS mode */
1136 else if (Pepb == 0xFFFFFFFF)
1137 sprintf(str1, "nometh"); /* RS mode */
1139 sprintf(str1, "unknown"); /* unknown */
1141 /* Now we write them to screen */
1142 opj_event_msg(j2k->cinfo, EVT_INFO,
1143 "EPB(%d): (%sl, %sp, %u), %lu, %s\n",
1145 (Depb & 0x40) ? "" : "n", /* latest EPB or not? */
1146 (Depb & 0x80) ? "" : "n", /* packed or unpacked EPB? */
1147 (Depb & 0x3F), /* EPB index value */
1148 LDPepb, /*length of the data protected by the EPB */
1149 str1); /* protection method */
1151 cio_skip(cio, Lepb - 11);
1155 void j2k_write_epb(opj_j2k_t *j2k) {
1156 unsigned long int LDPepb, Pepb, Lepbp;
1157 unsigned short int Lepb;
1160 opj_cio_t *cio = j2k->cio;
1162 cio_write(cio, J2K_MS_EPB, 2); /* EPB */
1163 Lepbp = cio_tell(cio);
1167 Depb = 0x00; /* test */
1168 cio_write(cio, Depb, 1); /* Depb */
1170 /* length of the data to be protected by this EPB */
1171 LDPepb = 0x00000000; /* test */
1172 cio_write(cio, LDPepb, 4); /* LDPepb */
1174 /* next error correction tool */
1175 Pepb = 0x00000000; /* test */
1176 cio_write(cio, Pepb, 4); /* Pepb */
1179 /* no data, as of now */
1181 Lepb = (unsigned short) (cio_tell(cio) - Lepbp);
1182 cio_seek(cio, Lepbp);
1183 cio_write(cio, Lepb, 2); /* Lepb */
1185 cio_seek(cio, Lepbp + Lepb);
1187 /* marker struct update */
1188 j2k_add_marker(j2k->cstr_info, J2K_MS_EPB, Lepbp - 2, Lepb + 2);
1191 void j2k_read_esd(opj_j2k_t *j2k) {
1192 unsigned short int Lesd, Cesd;
1195 int cesdsize = (j2k->image->numcomps >= 257) ? 2 : 1;
1197 char str1[4][4] = {"p", "br", "pr", "res"};
1198 char str2[8][8] = {"res", "mse", "mse-r", "psnr", "psnr-i", "maxerr", "tse", "res"};
1200 opj_cio_t *cio = j2k->cio;
1202 /* Simply read the ESD parameters */
1203 Lesd = cio_read(cio, 2);
1204 Cesd = cio_read(cio, cesdsize);
1205 Pesd = cio_read(cio, 1);
1207 /* Now we write them to screen */
1208 opj_event_msg(j2k->cinfo, EVT_INFO,
1209 "ESD(%d): c%d, %s, %s, %s, %s, %s\n",
1210 cio_tell(cio) - (5 + cesdsize),
1211 Cesd, /* component number for this ESD */
1212 str1[(Pesd & (unsigned char) 0xC0) >> 6], /* addressing mode */
1213 str2[(Pesd & (unsigned char) 0x38) >> 3], /* sensitivity type */
1214 ((Pesd & (unsigned char) 0x04) >> 2) ? "2Bs" : "1Bs",
1215 ((Pesd & (unsigned char) 0x02) >> 1) ? "4Ba" : "2Ba",
1216 (Pesd & (unsigned char) 0x01) ? "avgc" : "");
1218 cio_skip(cio, Lesd - (3 + cesdsize));
1221 void j2k_read_red(opj_j2k_t *j2k) {
1222 unsigned short int Lred;
1224 char str1[4][4] = {"p", "br", "pr", "res"};
1226 opj_cio_t *cio = j2k->cio;
1228 /* Simply read the RED parameters */
1229 Lred = cio_read(cio, 2);
1230 Pred = cio_read(cio, 1);
1232 /* Now we write them to screen */
1233 opj_event_msg(j2k->cinfo, EVT_INFO,
1234 "RED(%d): %s, %dc, %s, %s\n",
1236 str1[(Pred & (unsigned char) 0xC0) >> 6], /* addressing mode */
1237 (Pred & (unsigned char) 0x38) >> 3, /* corruption level */
1238 ((Pred & (unsigned char) 0x02) >> 1) ? "4Ba" : "2Ba", /* address range */
1239 (Pred & (unsigned char) 0x01) ? "errs" : "free"); /* error free? */
1241 cio_skip(cio, Lred - 3);
1244 opj_bool jpwl_check_tile(opj_j2k_t *j2k, opj_tcd_t *tcd, int tileno) {
1246 #ifdef oerhgierhgvhreit4u
1248 we navigate through the tile and find possible invalid parameters:
1249 this saves a lot of crashes!!!!!
1251 int compno, resno, precno, /*layno,*/ bandno, blockno;
1252 int numprecincts, numblocks;
1254 /* this is the selected tile */
1255 opj_tcd_tile_t *tile = &(tcd->tcd_image->tiles[tileno]);
1257 /* will keep the component */
1258 opj_tcd_tilecomp_t *comp = NULL;
1260 /* will keep the resolution */
1261 opj_tcd_resolution_t *res;
1263 /* will keep the subband */
1264 opj_tcd_band_t *band;
1266 /* will keep the precinct */
1267 opj_tcd_precinct_t *prec;
1269 /* will keep the codeblock */
1270 opj_tcd_cblk_t *block;
1272 /* check all tile components */
1273 for (compno = 0; compno < tile->numcomps; compno++) {
1274 comp = &(tile->comps[compno]);
1276 /* check all component resolutions */
1277 for (resno = 0; resno < comp->numresolutions; resno++) {
1278 res = &(comp->resolutions[resno]);
1279 numprecincts = res->pw * res->ph;
1281 /* check all the subbands */
1282 for (bandno = 0; bandno < res->numbands; bandno++) {
1283 band = &(res->bands[bandno]);
1285 /* check all the precincts */
1286 for (precno = 0; precno < numprecincts; precno++) {
1287 prec = &(band->precincts[precno]);
1288 numblocks = prec->ch * prec->cw;
1290 /* check all the codeblocks */
1291 for (blockno = 0; blockno < numblocks; blockno++) {
1292 block = &(prec->cblks[blockno]);
1294 /* x-origin is invalid */
1295 if ((block->x0 < prec->x0) || (block->x0 > prec->x1)) {
1296 opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
1297 "JPWL: wrong x-cord of block origin %d => x-prec is (%d, %d)\n",
1298 block->x0, prec->x0, prec->x1);
1299 if (!JPWL_ASSUME || JPWL_ASSUME)
1319 #endif /* USE_JPWL */
1324 /** @defgroup JPSEC JPSEC - JPEG-2000 Part 8 (JPSEC) codestream manager */
1328 /** @name Local static functions */
1331 void j2k_read_sec(opj_j2k_t *j2k) {
1332 unsigned short int Lsec;
1334 opj_cio_t *cio = j2k->cio;
1336 /* Simply read the SEC length */
1337 Lsec = cio_read(cio, 2);
1339 /* Now we write them to screen */
1340 opj_event_msg(j2k->cinfo, EVT_INFO,
1345 cio_skip(cio, Lsec - 2);
1348 void j2k_write_sec(opj_j2k_t *j2k) {
1349 unsigned short int Lsec = 24;
1352 opj_cio_t *cio = j2k->cio;
1354 cio_write(cio, J2K_MS_SEC, 2); /* SEC */
1355 cio_write(cio, Lsec, 2);
1357 /* write dummy data */
1358 for (i = 0; i < Lsec - 2; i++)
1359 cio_write(cio, 0, 1);
1362 void j2k_read_insec(opj_j2k_t *j2k) {
1363 unsigned short int Linsec;
1365 opj_cio_t *cio = j2k->cio;
1367 /* Simply read the INSEC length */
1368 Linsec = cio_read(cio, 2);
1370 /* Now we write them to screen */
1371 opj_event_msg(j2k->cinfo, EVT_INFO,
1376 cio_skip(cio, Linsec - 2);
1384 #endif /* USE_JPSEC */