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
10 * Redistribution and use in source and binary forms, with or without
\r
11 * modification, are permitted provided that the following conditions
\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
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
32 #include "../libopenjpeg/opj_includes.h"
\r
36 /** @defgroup JPWL JPWL - JPEG-2000 Part11 (JPWL) codestream manager */
\r
39 /** @name Local static variables */
\r
42 /** number of JPWL prepared markers */
\r
43 static int jwmarker_num;
\r
44 /** properties of JPWL markers to insert */
\r
45 static jpwl_marker_t jwmarker[JPWL_MAX_NO_MARKERS];
\r
51 /** @name Local static functions */
\r
54 /** create an EPC marker segment
\r
55 @param j2k J2K compressor handle
\r
56 @param esd_on true if ESD is activated
\r
57 @param red_on true if RED is activated
\r
58 @param epb_on true if EPB is activated
\r
59 @param info_on true if informative techniques are activated
\r
60 @return returns the freshly created EPC
\r
62 jpwl_epc_ms_t *jpwl_epc_create(opj_j2k_t *j2k, bool esd_on, bool red_on, bool epb_on, bool info_on);
\r
66 /** create an EPC marker segment
\r
67 @param j2k J2K compressor handle
\r
68 @param comps considered component (-1=average, 0/1/2/...=component no.)
\r
69 @param addrm addressing mode (0=packet, 1=byte range, 2=packet range, 3=reserved)
\r
70 @param ad_size size of addresses (2/4 bytes)
\r
71 @param senst sensitivity type
\r
72 @param se_size sensitivity values size (1/2 bytes)
\r
73 @param tileno tile where this ESD lies (-1 means MH)
\r
74 @param svalnum number of sensitivity values (if 0, they will be automatically filled)
\r
75 @param sensval pointer to an array of sensitivity values (if NULL, they will be automatically filled)
\r
76 @return returns the freshly created ESD
\r
78 jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comps, unsigned char addrm, unsigned char ad_size,
\r
79 unsigned char senst, int se_size, int tileno,
\r
80 unsigned long int svalnum, void *sensval);
\r
82 /** this function is used to compare two JPWL markers based on
\r
83 their relevant wishlist position
\r
84 @param arg1 pointer to first marker
\r
85 @param arg2 pointer to second marker
\r
86 @return 1 if arg1>arg2, 0 if arg1=arg2, -1 if arg1<arg2
\r
88 int jpwl_markcomp(const void *arg1, const void *arg2);
\r
90 /** write an EPB MS to a buffer
\r
91 @param j2k J2K compressor handle
\r
92 @param epbmark pointer to the EPB MS
\r
93 @param buf pointer to the memory buffer
\r
95 void jpwl_epb_write(opj_j2k_t *j2k, jpwl_epb_ms_t *epbmark, unsigned char *buf);
\r
97 /** write an EPC MS to a buffer
\r
98 @param j2k J2K compressor handle
\r
99 @param epcmark pointer to the EPC MS
\r
100 @param buf pointer to the memory buffer
\r
102 void jpwl_epc_write(opj_j2k_t *j2k, jpwl_epc_ms_t *epcmark, unsigned char *buf);
\r
104 /** write an ESD MS to a buffer
\r
105 @param j2k J2K compressor handle
\r
106 @param esdmark pointer to the ESD MS
\r
107 @param buf pointer to the memory buffer
\r
109 void jpwl_esd_write(opj_j2k_t *j2k, jpwl_esd_ms_t *esdmark, unsigned char *buf);
\r
111 /*-----------------------------------------------------------------*/
\r
113 void jpwl_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
\r
117 /* let's reset some settings */
\r
119 /* clear the existing markers */
\r
120 for (mm = 0; mm < jwmarker_num; mm++) {
\r
122 switch (jwmarker[mm].id) {
\r
125 opj_free(jwmarker[mm].m.epbmark);
\r
129 opj_free(jwmarker[mm].m.epcmark);
\r
133 opj_free(jwmarker[mm].m.esdmark);
\r
137 opj_free(jwmarker[mm].m.redmark);
\r
145 /* clear the marker structure array */
\r
146 memset(jwmarker, 0, sizeof(jpwl_marker_t) * JPWL_MAX_NO_MARKERS);
\r
148 /* no more markers in the list */
\r
151 /* let's begin creating a marker list, according to user wishes */
\r
152 jpwl_prepare_marks(j2k, cio, image);
\r
154 /* now we dump the JPWL markers on the codestream */
\r
155 jpwl_dump_marks(j2k, cio, image);
\r
157 /* do not know exactly what is this for,
\r
158 but it gets called during index creation */
\r
159 j2k->pos_correction = 0;
\r
163 void j2k_add_marker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
\r
168 /* expand the list? */
\r
169 if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) {
\r
170 cstr_info->maxmarknum = 100 + (int) ((float) cstr_info->maxmarknum * 1.0F);
\r
171 cstr_info->marker = opj_realloc(cstr_info->marker, cstr_info->maxmarknum);
\r
174 /* add the marker */
\r
175 cstr_info->marker[cstr_info->marknum].type = type;
\r
176 cstr_info->marker[cstr_info->marknum].pos = pos;
\r
177 cstr_info->marker[cstr_info->marknum].len = len;
\r
178 cstr_info->marknum++;
\r
182 void jpwl_prepare_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
\r
184 unsigned short int socsiz_len = 0;
\r
185 int ciopos = cio_tell(cio), soc_pos = j2k->cstr_info->main_head_start;
\r
186 unsigned char *socp = NULL;
\r
188 int tileno, acc_tpno, tpno, tilespec, hprot, sens, pprot, packspec, lastileno, packno;
\r
190 jpwl_epb_ms_t *epb_mark;
\r
191 jpwl_epc_ms_t *epc_mark;
\r
192 jpwl_esd_ms_t *esd_mark;
\r
194 /* find (SOC + SIZ) length */
\r
195 /* I assume SIZ is always the first marker after SOC */
\r
196 cio_seek(cio, soc_pos + 4);
\r
197 socsiz_len = (unsigned short int) cio_read(cio, 2) + 4; /* add the 2 marks length itself */
\r
198 cio_seek(cio, soc_pos + 0);
\r
199 socp = cio_getbp(cio); /* pointer to SOC */
\r
202 EPC MS for Main Header: if we are here it's required
\r
204 /* create the EPC */
\r
205 if ((epc_mark = jpwl_epc_create(
\r
207 j2k->cp->esd_on, /* is ESD present? */
\r
208 j2k->cp->red_on, /* is RED present? */
\r
209 j2k->cp->epb_on, /* is EPB present? */
\r
210 false /* are informative techniques present? */
\r
213 /* Add this marker to the 'insertanda' list */
\r
215 jwmarker[jwmarker_num].id = J2K_MS_EPC; /* its type */
\r
216 jwmarker[jwmarker_num].m.epcmark = epc_mark; /* the EPC */
\r
217 jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* after SIZ */
\r
218 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.1; /* not so first */
\r
219 jwmarker[jwmarker_num].len = epc_mark->Lepc; /* its length */
\r
220 jwmarker[jwmarker_num].len_ready = true; /* ready */
\r
221 jwmarker[jwmarker_num].pos_ready = true; /* ready */
\r
222 jwmarker[jwmarker_num].parms_ready = false; /* not ready */
\r
223 jwmarker[jwmarker_num].data_ready = true; /* ready */
\r
227 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
228 "MH EPC : setting %s%s%s\n",
\r
229 j2k->cp->esd_on ? "ESD, " : "",
\r
230 j2k->cp->red_on ? "RED, " : "",
\r
231 j2k->cp->epb_on ? "EPB, " : ""
\r
235 /* ooops, problems */
\r
236 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH EPC\n");
\r
240 ESD MS for Main Header
\r
242 /* first of all, must MH have an ESD MS? */
\r
243 if (j2k->cp->esd_on && (j2k->cp->sens_MH >= 0)) {
\r
245 /* Create the ESD */
\r
246 if ((esd_mark = jpwl_esd_create(
\r
247 j2k, /* this encoder handle */
\r
248 -1, /* we are averaging over all components */
\r
249 (unsigned char) j2k->cp->sens_range, /* range method */
\r
250 (unsigned char) j2k->cp->sens_addr, /* sensitivity addressing */
\r
251 (unsigned char) j2k->cp->sens_MH, /* sensitivity method */
\r
252 j2k->cp->sens_size, /* sensitivity size */
\r
253 -1, /* this ESD is in main header */
\r
254 0 /*j2k->cstr_info->num*/, /* number of packets in codestream */
\r
255 NULL /*sensval*/ /* pointer to sensitivity data of packets */
\r
258 /* Add this marker to the 'insertanda' list */
\r
259 if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
\r
260 jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */
\r
261 jwmarker[jwmarker_num].m.esdmark = esd_mark; /* the EPB */
\r
262 jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* we choose to place it after SIZ */
\r
263 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */
\r
264 jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */
\r
265 jwmarker[jwmarker_num].len_ready = true; /* not ready, yet */
\r
266 jwmarker[jwmarker_num].pos_ready = true; /* ready */
\r
267 jwmarker[jwmarker_num].parms_ready = true; /* not ready */
\r
268 jwmarker[jwmarker_num].data_ready = false; /* not ready */
\r
272 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
273 "MH ESDs: method %d\n",
\r
278 /* ooops, problems */
\r
279 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH ESD\n");
\r
285 ESD MSs for Tile Part Headers
\r
287 /* cycle through tiles */
\r
288 sens = -1; /* default spec: no ESD */
\r
289 tilespec = 0; /* first tile spec */
\r
291 for (tileno = 0; tileno < j2k->cstr_info->tw * j2k->cstr_info->th; tileno++) {
\r
293 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
294 "Tile %d has %d tile part(s)\n",
\r
295 tileno, j2k->cstr_info->tile[tileno].num_tps
\r
298 /* for every tile part in the tile */
\r
299 for (tpno = 0; tpno < j2k->cstr_info->tile[tileno].num_tps; tpno++, acc_tpno++) {
\r
301 int sot_len, Psot, Psotp, mm;
\r
302 unsigned long sot_pos, post_sod_pos;
\r
304 unsigned long int left_THmarks_len;
\r
306 /******* sot_pos = j2k->cstr_info->tile[tileno].start_pos; */
\r
307 sot_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos;
\r
308 cio_seek(cio, sot_pos + 2);
\r
309 sot_len = cio_read(cio, 2); /* SOT Len */
\r
311 Psotp = cio_tell(cio);
\r
312 Psot = cio_read(cio, 4); /* tile length */
\r
314 /******* post_sod_pos = j2k->cstr_info->tile[tileno].end_header + 1; */
\r
315 post_sod_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_end_header + 1;
\r
316 left_THmarks_len = post_sod_pos - sot_pos;
\r
318 /* add all the lengths of the markers which are len-ready and stay within SOT and SOD */
\r
319 for (mm = 0; mm < jwmarker_num; mm++) {
\r
320 if ((jwmarker[mm].pos >= sot_pos) && (jwmarker[mm].pos < post_sod_pos)) {
\r
321 if (jwmarker[mm].len_ready)
\r
322 left_THmarks_len += jwmarker[mm].len + 2;
\r
324 opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up TH EPB\n",
\r
325 jwmarker[mm].id, jwmarker[mm].dpos);
\r
331 /******* if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->sens_TPH_tileno[tilespec] == tileno)) */
\r
332 if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->sens_TPH_tileno[tilespec] == acc_tpno))
\r
333 /* we got a specification from this tile onwards */
\r
334 sens = j2k->cp->sens_TPH[tilespec++];
\r
336 /* must this TPH have an ESD MS? */
\r
337 if (j2k->cp->esd_on && (sens >= 0)) {
\r
339 /* Create the ESD */
\r
340 if ((esd_mark = jpwl_esd_create(
\r
341 j2k, /* this encoder handle */
\r
342 -1, /* we are averaging over all components */
\r
343 (unsigned char) j2k->cp->sens_range, /* range method */
\r
344 (unsigned char) j2k->cp->sens_addr, /* sensitivity addressing size */
\r
345 (unsigned char) sens, /* sensitivity method */
\r
346 j2k->cp->sens_size, /* sensitivity value size */
\r
347 tileno, /* this ESD is in a tile */
\r
348 0, /* number of packets in codestream */
\r
349 NULL /* pointer to sensitivity data of packets */
\r
352 /* Add this marker to the 'insertanda' list */
\r
353 if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
\r
354 jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */
\r
355 jwmarker[jwmarker_num].m.esdmark = esd_mark; /* the EPB */
\r
356 /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */
\r
357 jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */
\r
358 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */
\r
359 jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */
\r
360 jwmarker[jwmarker_num].len_ready = true; /* ready, yet */
\r
361 jwmarker[jwmarker_num].pos_ready = true; /* ready */
\r
362 jwmarker[jwmarker_num].parms_ready = true; /* not ready */
\r
363 jwmarker[jwmarker_num].data_ready = false; /* ready */
\r
367 /* update Psot of the tile */
\r
368 cio_seek(cio, Psotp);
\r
369 cio_write(cio, Psot + esd_mark->Lesd + 2, 4);
\r
371 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
372 /******* "TPH ESDs: tile %02d, method %d\n", */
\r
373 "TPH ESDs: tile %02d, part %02d, method %d\n",
\r
374 /******* tileno, */
\r
380 /* ooops, problems */
\r
381 /***** opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH ESD #%d\n", tileno); */
\r
382 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH ESD #%d,%d\n", tileno, tpno);
\r
392 EPB MS for Main Header
\r
394 /* first of all, must MH have an EPB MS? */
\r
395 if (j2k->cp->epb_on && (j2k->cp->hprot_MH > 0)) {
\r
399 /* position of SOT */
\r
400 unsigned int sot_pos = j2k->cstr_info->main_head_end + 1;
\r
402 /* how much space is there between end of SIZ and beginning of SOT? */
\r
403 int left_MHmarks_len = sot_pos - socsiz_len;
\r
405 /* add all the lengths of the markers which are len-ready and stay within SOC and SOT */
\r
406 for (mm = 0; mm < jwmarker_num; mm++) {
\r
407 if ((jwmarker[mm].pos >=0) && (jwmarker[mm].pos < sot_pos)) {
\r
408 if (jwmarker[mm].len_ready)
\r
409 left_MHmarks_len += jwmarker[mm].len + 2;
\r
411 opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up MH EPB\n",
\r
412 jwmarker[mm].id, jwmarker[mm].dpos);
\r
418 /* Create the EPB */
\r
419 if ((epb_mark = jpwl_epb_create(
\r
420 j2k, /* this encoder handle */
\r
421 true, /* is it the latest? */
\r
422 true, /* is it packed? not for now */
\r
423 -1, /* we are in main header */
\r
424 0, /* its index is 0 (first) */
\r
425 j2k->cp->hprot_MH, /* protection type parameters of data */
\r
426 socsiz_len, /* pre-data: only SOC+SIZ */
\r
427 left_MHmarks_len /* post-data: from SOC to SOT, and all JPWL markers within */
\r
430 /* Add this marker to the 'insertanda' list */
\r
431 if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
\r
432 jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */
\r
433 jwmarker[jwmarker_num].m.epbmark = epb_mark; /* the EPB */
\r
434 jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* after SIZ */
\r
435 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */
\r
436 jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */
\r
437 jwmarker[jwmarker_num].len_ready = true; /* ready */
\r
438 jwmarker[jwmarker_num].pos_ready = true; /* ready */
\r
439 jwmarker[jwmarker_num].parms_ready = true; /* ready */
\r
440 jwmarker[jwmarker_num].data_ready = false; /* not ready */
\r
444 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
445 "MH EPB : prot. %d\n",
\r
450 /* ooops, problems */
\r
451 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH EPB\n");
\r
456 EPB MSs for Tile Parts
\r
458 /* cycle through TPHs */
\r
459 hprot = j2k->cp->hprot_MH; /* default spec */
\r
460 tilespec = 0; /* first tile spec */
\r
465 for (tileno = 0; tileno < j2k->cstr_info->tw * j2k->cstr_info->th; tileno++) {
\r
467 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
468 "Tile %d has %d tile part(s)\n",
\r
469 tileno, j2k->cstr_info->tile[tileno].num_tps
\r
472 /* for every tile part in the tile */
\r
473 for (tpno = 0; tpno < j2k->cstr_info->tile[tileno].num_tps; tpno++, acc_tpno++) {
\r
475 int sot_len, Psot, Psotp, mm, epb_index = 0, prot_len = 0;
\r
476 unsigned long sot_pos, post_sod_pos;
\r
477 unsigned long int left_THmarks_len/*, epbs_len = 0*/;
\r
478 int startpack = 0, stoppack = j2k->cstr_info->packno;
\r
479 int first_tp_pack, last_tp_pack;
\r
480 jpwl_epb_ms_t *tph_epb = NULL;
\r
482 /****** sot_pos = j2k->cstr_info->tile[tileno].start_pos; */
\r
483 sot_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos;
\r
484 cio_seek(cio, sot_pos + 2);
\r
485 sot_len = cio_read(cio, 2); /* SOT Len */
\r
487 Psotp = cio_tell(cio);
\r
488 Psot = cio_read(cio, 4); /* tile length */
\r
490 /* a-priori length of the data dwelling between SOT and SOD */
\r
491 /****** post_sod_pos = j2k->cstr_info->tile[tileno].end_header + 1; */
\r
492 post_sod_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_end_header + 1;
\r
493 left_THmarks_len = post_sod_pos - (sot_pos + sot_len + 2);
\r
495 /* add all the lengths of the JPWL markers which are len-ready and stay within SOT and SOD */
\r
496 for (mm = 0; mm < jwmarker_num; mm++) {
\r
497 if ((jwmarker[mm].pos >= sot_pos) && (jwmarker[mm].pos < post_sod_pos)) {
\r
498 if (jwmarker[mm].len_ready)
\r
499 left_THmarks_len += jwmarker[mm].len + 2;
\r
501 opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up TH EPB\n",
\r
502 jwmarker[mm].id, jwmarker[mm].dpos);
\r
508 /****** if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->hprot_TPH_tileno[tilespec] == tileno)) */
\r
509 if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->hprot_TPH_tileno[tilespec] == acc_tpno))
\r
510 /* we got a specification from this tile part onwards */
\r
511 hprot = j2k->cp->hprot_TPH[tilespec++];
\r
513 /* must this TPH have an EPB MS? */
\r
514 if (j2k->cp->epb_on && (hprot > 0)) {
\r
516 /* Create the EPB */
\r
517 if ((epb_mark = jpwl_epb_create(
\r
518 j2k, /* this encoder handle */
\r
519 false, /* is it the latest? in TPH, no for now (if huge data size in TPH, we'd need more) */
\r
520 true, /* is it packed? yes for now */
\r
521 tileno, /* we are in TPH */
\r
522 epb_index++, /* its index is 0 (first) */
\r
523 hprot, /* protection type parameters of following data */
\r
524 sot_len + 2, /* pre-data length: only SOT */
\r
525 left_THmarks_len /* post-data length: from SOT end to SOD inclusive */
\r
528 /* Add this marker to the 'insertanda' list */
\r
529 if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
\r
530 jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */
\r
531 jwmarker[jwmarker_num].m.epbmark = epb_mark; /* the EPB */
\r
532 /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */
\r
533 jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */
\r
534 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */
\r
535 jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */
\r
536 jwmarker[jwmarker_num].len_ready = true; /* ready */
\r
537 jwmarker[jwmarker_num].pos_ready = true; /* ready */
\r
538 jwmarker[jwmarker_num].parms_ready = true; /* ready */
\r
539 jwmarker[jwmarker_num].data_ready = false; /* not ready */
\r
543 /* update Psot of the tile */
\r
544 Psot += epb_mark->Lepb + 2;
\r
546 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
547 /***** "TPH EPB : tile %02d, prot. %d\n", */
\r
548 "TPH EPB : tile %02d, part %02d, prot. %d\n",
\r
554 /* save this TPH EPB address */
\r
555 tph_epb = epb_mark;
\r
558 /* ooops, problems */
\r
559 /****** opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB #%d\n", tileno); */
\r
560 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB in #%d,d\n", tileno, tpno);
\r
566 /* EPB MSs for UEP packet data protection in Tile Parts */
\r
567 /****** for (packno = 0; packno < j2k->cstr_info->num; packno++) { */
\r
568 /*first_tp_pack = (tpno > 0) ? (first_tp_pack + j2k->cstr_info->tile[tileno].tp[tpno - 1].tp_numpacks) : 0;*/
\r
569 first_tp_pack = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pack;
\r
570 last_tp_pack = first_tp_pack + j2k->cstr_info->tile[tileno].tp[tpno].tp_numpacks - 1;
\r
571 for (packno = 0; packno < j2k->cstr_info->tile[tileno].tp[tpno].tp_numpacks; packno++) {
\r
573 /******** if ((packspec < JPWL_MAX_NO_PACKSPECS) &&
\r
574 (j2k->cp->pprot_tileno[packspec] == tileno) && (j2k->cp->pprot_packno[packspec] == packno)) { */
\r
575 if ((packspec < JPWL_MAX_NO_PACKSPECS) &&
\r
576 (j2k->cp->pprot_tileno[packspec] == acc_tpno) && (j2k->cp->pprot_packno[packspec] == packno)) {
\r
578 /* we got a specification from this tile and packet onwards */
\r
579 /* print the previous spec */
\r
581 stoppack = packno - 1;
\r
582 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
583 /***** "UEP EPBs: tile %02d, packs. %02d-%02d (B %d-%d), prot. %d\n", */
\r
584 "UEP EPBs: tile %02d, part %02d, packs. %02d-%02d (B %d-%d), prot. %d\n",
\r
589 /***** j2k->cstr_info->tile[tileno].packet[startpack].start_pos, */
\r
590 j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos,
\r
591 /***** j2k->cstr_info->tile[tileno].packet[stoppack].end_pos, */
\r
592 j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos,
\r
595 /***** prot_len = j2k->cstr_info->tile[tileno].packet[stoppack].end_pos + 1 -
\r
596 j2k->cstr_info->tile[tileno].packet[startpack].start_pos; */
\r
597 prot_len = j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos + 1 -
\r
598 j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos;
\r
601 particular case: if this is the last header and the last packet,
\r
602 then it is better to protect even the EOC marker
\r
604 /****** if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
\r
605 (stoppack == (j2k->cstr_info->num - 1))) */
\r
606 if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
\r
607 (tpno == (j2k->cstr_info->tile[tileno].num_tps - 1)) &&
\r
608 (stoppack == last_tp_pack))
\r
609 /* add the EOC len */
\r
612 /* let's add the EPBs */
\r
613 Psot += jpwl_epbs_add(
\r
614 j2k, /* J2K handle */
\r
615 jwmarker, /* pointer to JPWL markers list */
\r
616 &jwmarker_num, /* pointer to the number of current markers */
\r
617 false, /* latest */
\r
619 false, /* inside MH */
\r
620 &epb_index, /* pointer to EPB index */
\r
621 pprot, /* protection type */
\r
622 /****** (double) (j2k->cstr_info->tile[tileno].start_pos + sot_len + 2) + 0.0001, */ /* position */
\r
623 (double) (j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2) + 0.0001, /* position */
\r
624 tileno, /* number of tile */
\r
625 0, /* length of pre-data */
\r
626 prot_len /*4000*/ /* length of post-data */
\r
630 startpack = packno;
\r
631 pprot = j2k->cp->pprot[packspec++];
\r
634 //printf("Tile %02d, pack %02d ==> %d\n", tileno, packno, pprot);
\r
638 /* we are at the end: print the remaining spec */
\r
639 stoppack = packno - 1;
\r
642 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
643 /**** "UEP EPBs: tile %02d, packs. %02d-%02d (B %d-%d), prot. %d\n", */
\r
644 "UEP EPBs: tile %02d, part %02d, packs. %02d-%02d (B %d-%d), prot. %d\n",
\r
649 /***** j2k->image_info->tile[tileno].packet[startpack].start_pos,
\r
650 j2k->image_info->tile[tileno].packet[stoppack].end_pos, */
\r
651 j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos,
\r
652 j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos,
\r
655 /***** prot_len = j2k->cstr_info->tile[tileno].packet[stoppack].end_pos + 1 -
\r
656 j2k->cstr_info->tile[tileno].packet[startpack].start_pos; */
\r
657 prot_len = j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos + 1 -
\r
658 j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos;
\r
661 particular case: if this is the last header and the last packet,
\r
662 then it is better to protect even the EOC marker
\r
664 /***** if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
\r
665 (stoppack == (j2k->cstr_info->num - 1))) */
\r
666 if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
\r
667 (tpno == (j2k->cstr_info->tile[tileno].num_tps - 1)) &&
\r
668 (stoppack == last_tp_pack))
\r
669 /* add the EOC len */
\r
672 /* let's add the EPBs */
\r
673 Psot += jpwl_epbs_add(
\r
674 j2k, /* J2K handle */
\r
675 jwmarker, /* pointer to JPWL markers list */
\r
676 &jwmarker_num, /* pointer to the number of current markers */
\r
679 false, /* inside MH */
\r
680 &epb_index, /* pointer to EPB index */
\r
681 pprot, /* protection type */
\r
682 /***** (double) (j2k->cstr_info->tile[tileno].start_pos + sot_len + 2) + 0.0001,*/ /* position */
\r
683 (double) (j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2) + 0.0001, /* position */
\r
684 tileno, /* number of tile */
\r
685 0, /* length of pre-data */
\r
686 prot_len /*4000*/ /* length of post-data */
\r
690 /* we can now check if the TPH EPB was really the last one */
\r
691 if (tph_epb && (epb_index == 1)) {
\r
692 /* set the TPH EPB to be the last one in current header */
\r
693 tph_epb->Depb |= (unsigned char) ((true & 0x0001) << 6);
\r
697 /* write back Psot */
\r
698 cio_seek(cio, Psotp);
\r
699 cio_write(cio, Psot, 4);
\r
705 /* reset the position */
\r
706 cio_seek(cio, ciopos);
\r
710 void jpwl_dump_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
\r
713 unsigned long int old_size = j2k->cstr_info->codestream_size;
\r
714 unsigned long int new_size = old_size;
\r
715 int /*ciopos = cio_tell(cio),*/ soc_pos = j2k->cstr_info->main_head_start;
\r
716 unsigned char *jpwl_buf, *orig_buf;
\r
717 unsigned long int orig_pos;
\r
718 double epbcoding_time = 0.0, esdcoding_time = 0.0;
\r
720 /* Order JPWL markers according to their wishlist position */
\r
721 qsort((void *) jwmarker, (size_t) jwmarker_num, sizeof (jpwl_marker_t), jpwl_markcomp);
\r
723 /* compute markers total size */
\r
724 for (mm = 0; mm < jwmarker_num; mm++) {
\r
725 /*printf("%x, %d, %.10f, %d long\n", jwmarker[mm].id, jwmarker[mm].pos,
\r
726 jwmarker[mm].dpos, jwmarker[mm].len);*/
\r
727 new_size += jwmarker[mm].len + 2;
\r
730 /* allocate a new buffer of proper size */
\r
731 if (!(jpwl_buf = (unsigned char *) opj_malloc((size_t) (new_size + soc_pos) * sizeof(unsigned char)))) {
\r
732 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for JPWL codestream buffer\n");
\r
736 /* copy the jp2 part, if any */
\r
737 orig_buf = jpwl_buf;
\r
738 memcpy(jpwl_buf, cio->buffer, soc_pos);
\r
739 jpwl_buf += soc_pos;
\r
741 /* cycle through markers */
\r
742 orig_pos = soc_pos + 0; /* start from the beginning */
\r
743 cio_seek(cio, soc_pos + 0); /* rewind the original */
\r
744 for (mm = 0; mm < jwmarker_num; mm++) {
\r
747 need to copy a piece of the original codestream
\r
750 memcpy(jpwl_buf, cio_getbp(cio), jwmarker[mm].pos - orig_pos);
\r
751 jpwl_buf += jwmarker[mm].pos - orig_pos;
\r
752 orig_pos = jwmarker[mm].pos;
\r
753 cio_seek(cio, orig_pos);
\r
756 then write down the marker
\r
758 switch (jwmarker[mm].id) {
\r
761 jpwl_epb_write(j2k, jwmarker[mm].m.epbmark, jpwl_buf);
\r
765 jpwl_epc_write(j2k, jwmarker[mm].m.epcmark, jpwl_buf);
\r
769 jpwl_esd_write(j2k, jwmarker[mm].m.esdmark, jpwl_buf);
\r
773 memset(jpwl_buf, 0, jwmarker[mm].len + 2); /* placeholder */
\r
780 /* we update the markers struct */
\r
781 if (j2k->cstr_info)
\r
782 j2k->cstr_info->marker[j2k->cstr_info->marknum - 1].pos = (jpwl_buf - orig_buf);
\r
784 /* we set the marker dpos to the new position in the JPWL codestream */
\r
785 jwmarker[mm].dpos = (double) (jpwl_buf - orig_buf);
\r
787 /* advance JPWL buffer position */
\r
788 jpwl_buf += jwmarker[mm].len + 2;
\r
792 /* finish remaining original codestream */
\r
793 memcpy(jpwl_buf, cio_getbp(cio), old_size - (orig_pos - soc_pos));
\r
794 jpwl_buf += old_size - (orig_pos - soc_pos);
\r
795 cio_seek(cio, soc_pos + old_size);
\r
798 update info file based on added markers
\r
800 if (!jpwl_update_info(j2k, jwmarker, jwmarker_num))
\r
801 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not update OPJ cstr_info structure\n");
\r
803 /* now we need to repass some markers and fill their data fields */
\r
805 /* first of all, DL and Pcrc in EPCs */
\r
806 for (mm = 0; mm < jwmarker_num; mm++) {
\r
808 /* find the EPCs */
\r
809 if (jwmarker[mm].id == J2K_MS_EPC) {
\r
811 int epc_pos = (int) jwmarker[mm].dpos, pp;
\r
812 unsigned short int mycrc = 0x0000;
\r
814 /* fix and fill the DL field */
\r
815 jwmarker[mm].m.epcmark->DL = new_size;
\r
816 orig_buf[epc_pos + 6] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 24);
\r
817 orig_buf[epc_pos + 7] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 16);
\r
818 orig_buf[epc_pos + 8] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 8);
\r
819 orig_buf[epc_pos + 9] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 0);
\r
821 /* compute the CRC field (excluding itself) */
\r
822 for (pp = 0; pp < 4; pp++)
\r
823 jpwl_updateCRC16(&mycrc, orig_buf[epc_pos + pp]);
\r
824 for (pp = 6; pp < (jwmarker[mm].len + 2); pp++)
\r
825 jpwl_updateCRC16(&mycrc, orig_buf[epc_pos + pp]);
\r
827 /* fix and fill the CRC */
\r
828 jwmarker[mm].m.epcmark->Pcrc = mycrc;
\r
829 orig_buf[epc_pos + 4] = (unsigned char) (jwmarker[mm].m.epcmark->Pcrc >> 8);
\r
830 orig_buf[epc_pos + 5] = (unsigned char) (jwmarker[mm].m.epcmark->Pcrc >> 0);
\r
835 /* then, sensitivity data in ESDs */
\r
836 esdcoding_time = opj_clock();
\r
837 for (mm = 0; mm < jwmarker_num; mm++) {
\r
839 /* find the ESDs */
\r
840 if (jwmarker[mm].id == J2K_MS_ESD) {
\r
842 /* remember that they are now in a new position (dpos) */
\r
843 int esd_pos = (int) jwmarker[mm].dpos;
\r
845 jpwl_esd_fill(j2k, jwmarker[mm].m.esdmark, &orig_buf[esd_pos]);
\r
850 esdcoding_time = opj_clock() - esdcoding_time;
\r
851 if (j2k->cp->esd_on)
\r
852 opj_event_msg(j2k->cinfo, EVT_INFO, "ESDs sensitivities computed in %f s\n", esdcoding_time);
\r
854 /* finally, RS or CRC parity in EPBs */
\r
855 epbcoding_time = opj_clock();
\r
856 for (mm = 0; mm < jwmarker_num; mm++) {
\r
858 /* find the EPBs */
\r
859 if (jwmarker[mm].id == J2K_MS_EPB) {
\r
861 /* remember that they are now in a new position (dpos) */
\r
864 /* let's see how many EPBs are following this one, included itself */
\r
865 /* for this to work, we suppose that the markers are correctly ordered */
\r
866 /* and, overall, that they are in packed mode inside headers */
\r
868 for (nn = mm; (nn < jwmarker_num) && (jwmarker[nn].id == J2K_MS_EPB) &&
\r
869 (jwmarker[nn].pos == jwmarker[mm].pos); nn++)
\r
870 accum_len += jwmarker[nn].m.epbmark->Lepb + 2;
\r
872 /* fill the current (first) EPB with post-data starting from the computed position */
\r
873 jpwl_epb_fill(j2k, jwmarker[mm].m.epbmark, &orig_buf[(int) jwmarker[mm].dpos],
\r
874 &orig_buf[(int) jwmarker[mm].dpos + accum_len]);
\r
876 /* fill the remaining EPBs in the header with post-data starting from the last position */
\r
877 for (nn = mm + 1; (nn < jwmarker_num) && (jwmarker[nn].id == J2K_MS_EPB) &&
\r
878 (jwmarker[nn].pos == jwmarker[mm].pos); nn++)
\r
879 jpwl_epb_fill(j2k, jwmarker[nn].m.epbmark, &orig_buf[(int) jwmarker[nn].dpos], NULL);
\r
881 /* skip all the processed EPBs */
\r
886 epbcoding_time = opj_clock() - epbcoding_time;
\r
887 if (j2k->cp->epb_on)
\r
888 opj_event_msg(j2k->cinfo, EVT_INFO, "EPBs redundancy computed in %f s\n", epbcoding_time);
\r
890 /* free original cio buffer and set it to the JPWL one */
\r
891 opj_free(cio->buffer);
\r
892 cio->cinfo = cio->cinfo; /* no change */
\r
893 cio->openmode = cio->openmode; /* no change */
\r
894 cio->buffer = orig_buf;
\r
895 cio->length = new_size + soc_pos;
\r
896 cio->start = cio->buffer;
\r
897 cio->end = cio->buffer + cio->length;
\r
898 cio->bp = cio->buffer;
\r
899 cio_seek(cio, soc_pos + new_size);
\r
904 void j2k_read_epc(opj_j2k_t *j2k) {
\r
905 unsigned long int DL, Lepcp, Pcrcp, l;
\r
906 unsigned short int Lepc, Pcrc = 0x0000;
\r
907 unsigned char Pepc;
\r
908 opj_cio_t *cio = j2k->cio;
\r
911 /* Simply read the EPC parameters */
\r
912 Lepcp = cio_tell(cio);
\r
913 Lepc = cio_read(cio, 2);
\r
914 Pcrcp = cio_tell(cio);
\r
915 cio_skip(cio, 2); /* Pcrc */
\r
916 DL = cio_read(cio, 4);
\r
917 Pepc = cio_read(cio, 1);
\r
920 cio_seek(cio, Lepcp - 2);
\r
923 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
\r
924 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
\r
927 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
\r
928 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
\r
933 /* read all remaining */
\r
934 for (l = 4; l < Lepc; l++)
\r
935 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
\r
937 /* check Pcrc with the result */
\r
938 cio_seek(cio, Pcrcp);
\r
939 ans1 = (Pcrc == (unsigned short int) cio_read(cio, 2)) ? "crc-ok" : "crc-ko";
\r
941 /* now we write them to screen */
\r
942 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
943 "EPC(%u,%d): %s, DL=%d%s %s %s\n",
\r
947 DL, /* data length this EPC is referring to */
\r
948 (Pepc & 0x10) ? ", esd" : "", /* ESD is present */
\r
949 (Pepc & 0x20) ? ", red" : "", /* RED is present */
\r
950 (Pepc & 0x40) ? ", epb" : ""); /* EPB is present */
\r
952 cio_seek(cio, Lepcp + Lepc);
\r
955 void j2k_write_epc(opj_j2k_t *j2k) {
\r
957 unsigned long int DL, Lepcp, Pcrcp, l;
\r
958 unsigned short int Lepc, Pcrc;
\r
959 unsigned char Pepc;
\r
961 opj_cio_t *cio = j2k->cio;
\r
963 cio_write(cio, J2K_MS_EPC, 2); /* EPC */
\r
964 Lepcp = cio_tell(cio);
\r
967 /* CRC-16 word of the EPC */
\r
968 Pcrc = 0x0000; /* initialize */
\r
969 Pcrcp = cio_tell(cio);
\r
970 cio_write(cio, Pcrc, 2); /* Pcrc placeholder*/
\r
972 /* data length of the EPC protection domain */
\r
973 DL = 0x00000000; /* we leave this set to 0, as if the information is not available */
\r
974 cio_write(cio, DL, 4); /* DL */
\r
976 /* jpwl capabilities */
\r
978 cio_write(cio, Pepc, 1); /* Pepc */
\r
981 /* no ID's, as of now */
\r
983 Lepc = (unsigned short) (cio_tell(cio) - Lepcp);
\r
984 cio_seek(cio, Lepcp);
\r
985 cio_write(cio, Lepc, 2); /* Lepc */
\r
988 cio_seek(cio, Lepcp - 2);
\r
991 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
\r
992 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
\r
995 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
\r
996 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
\r
1001 /* read all remaining */
\r
1002 for (l = 4; l < Lepc; l++)
\r
1003 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
\r
1005 /* fill Pcrc with the result */
\r
1006 cio_seek(cio, Pcrcp);
\r
1007 cio_write(cio, Pcrc, 2);
\r
1009 cio_seek(cio, Lepcp + Lepc);
\r
1011 /* marker struct update */
\r
1012 j2k_add_marker(j2k->cstr_info, J2K_MS_EPC, Lepcp - 2, Lepc + 2);
\r
1016 void j2k_read_epb(opj_j2k_t *j2k) {
\r
1017 unsigned long int LDPepb, Pepb;
\r
1018 unsigned short int Lepb;
\r
1019 unsigned char Depb;
\r
1020 char str1[25] = "";
\r
1022 static bool first_in_tph = true;
\r
1023 int type, pre_len, post_len;
\r
1024 static unsigned char *redund = NULL;
\r
1026 opj_cio_t *cio = j2k->cio;
\r
1028 /* B/W = 45, RGB = 51 */
\r
1029 /* SIZ SIZ_FIELDS SIZ_COMPS FOLLOWING_MARKER */
\r
1030 int skipnum = 2 + 38 + 3 * j2k->cp->exp_comps + 2;
\r
1032 if (j2k->cp->correct) {
\r
1034 /* go back to EPB marker value */
\r
1035 cio_seek(cio, cio_tell(cio) - 2);
\r
1037 /* we need to understand where we are */
\r
1038 if (j2k->state == J2K_STATE_MH) {
\r
1039 /* we are in MH */
\r
1040 type = 0; /* MH */
\r
1041 pre_len = skipnum; /* SOC+SIZ */
\r
1042 post_len = -1; /* auto */
\r
1044 } else if ((j2k->state == J2K_STATE_TPH) && first_in_tph) {
\r
1045 /* we are in TPH */
\r
1046 type = 1; /* TPH */
\r
1047 pre_len = 12; /* SOC+SIZ */
\r
1048 first_in_tph = false;
\r
1049 post_len = -1; /* auto */
\r
1052 /* we are elsewhere */
\r
1053 type = 2; /* other */
\r
1054 pre_len = 0; /* nada */
\r
1055 post_len = -1; /* auto */
\r
1059 /* call EPB corrector */
\r
1060 /*printf("before %x, ", redund);*/
\r
1061 status = jpwl_epb_correct(j2k, /* J2K decompressor handle */
\r
1062 cio->bp, /* pointer to EPB in codestream buffer */
\r
1063 type, /* EPB type: MH */
\r
1064 pre_len, /* length of pre-data */
\r
1065 post_len, /* length of post-data: -1 means auto */
\r
1066 NULL, /* do everything auto */
\r
1069 /*printf("after %x\n", redund);*/
\r
1071 /* Read the (possibly corrected) EPB parameters */
\r
1073 Lepb = cio_read(cio, 2);
\r
1074 Depb = cio_read(cio, 1);
\r
1075 LDPepb = cio_read(cio, 4);
\r
1076 Pepb = cio_read(cio, 4);
\r
1080 opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL correction could not be performed\n");
\r
1082 /* advance to EPB endpoint */
\r
1083 cio_skip(cio, Lepb + 2);
\r
1088 /* last in current header? */
\r
1089 if (Depb & 0x40) {
\r
1090 redund = NULL; /* reset the pointer to L4 buffer */
\r
1091 first_in_tph = true;
\r
1094 /* advance to EPB endpoint */
\r
1095 cio_skip(cio, Lepb - 11);
\r
1099 /* Simply read the EPB parameters */
\r
1100 Lepb = cio_read(cio, 2);
\r
1101 Depb = cio_read(cio, 1);
\r
1102 LDPepb = cio_read(cio, 4);
\r
1103 Pepb = cio_read(cio, 4);
\r
1105 /* What does Pepb tells us about the protection method? */
\r
1106 if (((Pepb & 0xF0000000) >> 28) == 0)
\r
1107 sprintf(str1, "pred"); /* predefined */
\r
1108 else if (((Pepb & 0xF0000000) >> 28) == 1)
\r
1109 sprintf(str1, "crc-%lu", 16 * ((Pepb & 0x00000001) + 1)); /* CRC mode */
\r
1110 else if (((Pepb & 0xF0000000) >> 28) == 2)
\r
1111 sprintf(str1, "rs(%lu,32)", (Pepb & 0x0000FF00) >> 8); /* RS mode */
\r
1112 else if (Pepb == 0xFFFFFFFF)
\r
1113 sprintf(str1, "nometh"); /* RS mode */
\r
1115 sprintf(str1, "unknown"); /* unknown */
\r
1117 /* Now we write them to screen */
\r
1118 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
1119 "EPB(%d): (%sl, %sp, %u), %lu, %s\n",
\r
1120 cio_tell(cio) - 13,
\r
1121 (Depb & 0x40) ? "" : "n", /* latest EPB or not? */
\r
1122 (Depb & 0x80) ? "" : "n", /* packed or unpacked EPB? */
\r
1123 (Depb & 0x3F), /* EPB index value */
\r
1124 LDPepb, /*length of the data protected by the EPB */
\r
1125 str1); /* protection method */
\r
1127 cio_skip(cio, Lepb - 11);
\r
1131 void j2k_write_epb(opj_j2k_t *j2k) {
\r
1132 unsigned long int LDPepb, Pepb, Lepbp;
\r
1133 unsigned short int Lepb;
\r
1134 unsigned char Depb;
\r
1136 opj_cio_t *cio = j2k->cio;
\r
1138 cio_write(cio, J2K_MS_EPB, 2); /* EPB */
\r
1139 Lepbp = cio_tell(cio);
\r
1143 Depb = 0x00; /* test */
\r
1144 cio_write(cio, Depb, 1); /* Depb */
\r
1146 /* length of the data to be protected by this EPB */
\r
1147 LDPepb = 0x00000000; /* test */
\r
1148 cio_write(cio, LDPepb, 4); /* LDPepb */
\r
1150 /* next error correction tool */
\r
1151 Pepb = 0x00000000; /* test */
\r
1152 cio_write(cio, Pepb, 4); /* Pepb */
\r
1155 /* no data, as of now */
\r
1157 Lepb = (unsigned short) (cio_tell(cio) - Lepbp);
\r
1158 cio_seek(cio, Lepbp);
\r
1159 cio_write(cio, Lepb, 2); /* Lepb */
\r
1161 cio_seek(cio, Lepbp + Lepb);
\r
1163 /* marker struct update */
\r
1164 j2k_add_marker(j2k->cstr_info, J2K_MS_EPB, Lepbp - 2, Lepb + 2);
\r
1167 void j2k_read_esd(opj_j2k_t *j2k) {
\r
1168 unsigned short int Lesd, Cesd;
\r
1169 unsigned char Pesd;
\r
1171 int cesdsize = (j2k->image->numcomps >= 257) ? 2 : 1;
\r
1173 char str1[4][4] = {"p", "br", "pr", "res"};
\r
1174 char str2[8][8] = {"res", "mse", "mse-r", "psnr", "psnr-i", "maxerr", "tse", "res"};
\r
1176 opj_cio_t *cio = j2k->cio;
\r
1178 /* Simply read the ESD parameters */
\r
1179 Lesd = cio_read(cio, 2);
\r
1180 Cesd = cio_read(cio, cesdsize);
\r
1181 Pesd = cio_read(cio, 1);
\r
1183 /* Now we write them to screen */
\r
1184 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
1185 "ESD(%d): c%d, %s, %s, %s, %s, %s\n",
\r
1186 cio_tell(cio) - (5 + cesdsize),
\r
1187 Cesd, /* component number for this ESD */
\r
1188 str1[(Pesd & (unsigned char) 0xC0) >> 6], /* addressing mode */
\r
1189 str2[(Pesd & (unsigned char) 0x38) >> 3], /* sensitivity type */
\r
1190 ((Pesd & (unsigned char) 0x04) >> 2) ? "2Bs" : "1Bs",
\r
1191 ((Pesd & (unsigned char) 0x02) >> 1) ? "4Ba" : "2Ba",
\r
1192 (Pesd & (unsigned char) 0x01) ? "avgc" : "");
\r
1194 cio_skip(cio, Lesd - (3 + cesdsize));
\r
1197 void j2k_read_red(opj_j2k_t *j2k) {
\r
1198 unsigned short int Lred;
\r
1199 unsigned char Pred;
\r
1200 char str1[4][4] = {"p", "br", "pr", "res"};
\r
1202 opj_cio_t *cio = j2k->cio;
\r
1204 /* Simply read the RED parameters */
\r
1205 Lred = cio_read(cio, 2);
\r
1206 Pred = cio_read(cio, 1);
\r
1208 /* Now we write them to screen */
\r
1209 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
1210 "RED(%d): %s, %dc, %s, %s\n",
\r
1211 cio_tell(cio) - 5,
\r
1212 str1[(Pred & (unsigned char) 0xC0) >> 6], /* addressing mode */
\r
1213 (Pred & (unsigned char) 0x38) >> 3, /* corruption level */
\r
1214 ((Pred & (unsigned char) 0x02) >> 1) ? "4Ba" : "2Ba", /* address range */
\r
1215 (Pred & (unsigned char) 0x01) ? "errs" : "free"); /* error free? */
\r
1217 cio_skip(cio, Lred - 3);
\r
1220 bool jpwl_check_tile(opj_j2k_t *j2k, opj_tcd_t *tcd, int tileno) {
\r
1222 #ifdef oerhgierhgvhreit4u
\r
1224 we navigate through the tile and find possible invalid parameters:
\r
1225 this saves a lot of crashes!!!!!
\r
1227 int compno, resno, precno, /*layno,*/ bandno, blockno;
\r
1228 int numprecincts, numblocks;
\r
1230 /* this is the selected tile */
\r
1231 opj_tcd_tile_t *tile = &(tcd->tcd_image->tiles[tileno]);
\r
1233 /* will keep the component */
\r
1234 opj_tcd_tilecomp_t *comp = NULL;
\r
1236 /* will keep the resolution */
\r
1237 opj_tcd_resolution_t *res;
\r
1239 /* will keep the subband */
\r
1240 opj_tcd_band_t *band;
\r
1242 /* will keep the precinct */
\r
1243 opj_tcd_precinct_t *prec;
\r
1245 /* will keep the codeblock */
\r
1246 opj_tcd_cblk_t *block;
\r
1248 /* check all tile components */
\r
1249 for (compno = 0; compno < tile->numcomps; compno++) {
\r
1250 comp = &(tile->comps[compno]);
\r
1252 /* check all component resolutions */
\r
1253 for (resno = 0; resno < comp->numresolutions; resno++) {
\r
1254 res = &(comp->resolutions[resno]);
\r
1255 numprecincts = res->pw * res->ph;
\r
1257 /* check all the subbands */
\r
1258 for (bandno = 0; bandno < res->numbands; bandno++) {
\r
1259 band = &(res->bands[bandno]);
\r
1261 /* check all the precincts */
\r
1262 for (precno = 0; precno < numprecincts; precno++) {
\r
1263 prec = &(band->precincts[precno]);
\r
1264 numblocks = prec->ch * prec->cw;
\r
1266 /* check all the codeblocks */
\r
1267 for (blockno = 0; blockno < numblocks; blockno++) {
\r
1268 block = &(prec->cblks[blockno]);
\r
1270 /* x-origin is invalid */
\r
1271 if ((block->x0 < prec->x0) || (block->x0 > prec->x1)) {
\r
1272 opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
\r
1273 "JPWL: wrong x-cord of block origin %d => x-prec is (%d, %d)\n",
\r
1274 block->x0, prec->x0, prec->x1);
\r
1275 if (!JPWL_ASSUME || JPWL_ASSUME)
\r
1291 #endif /* USE_JPWL */
\r
1296 /** @defgroup JPSEC JPSEC - JPEG-2000 Part 8 (JPSEC) codestream manager */
\r
1300 /** @name Local static functions */
\r
1303 void j2k_read_sec(opj_j2k_t *j2k) {
\r
1304 unsigned short int Lsec;
\r
1306 opj_cio_t *cio = j2k->cio;
\r
1308 /* Simply read the SEC length */
\r
1309 Lsec = cio_read(cio, 2);
\r
1311 /* Now we write them to screen */
\r
1312 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
1317 cio_skip(cio, Lsec - 2);
\r
1320 void j2k_write_sec(opj_j2k_t *j2k) {
\r
1321 unsigned short int Lsec = 24;
\r
1324 opj_cio_t *cio = j2k->cio;
\r
1326 cio_write(cio, J2K_MS_SEC, 2); /* SEC */
\r
1327 cio_write(cio, Lsec, 2);
\r
1329 /* write dummy data */
\r
1330 for (i = 0; i < Lsec - 2; i++)
\r
1331 cio_write(cio, 0, 1);
\r
1334 void j2k_read_insec(opj_j2k_t *j2k) {
\r
1335 unsigned short int Linsec;
\r
1337 opj_cio_t *cio = j2k->cio;
\r
1339 /* Simply read the INSEC length */
\r
1340 Linsec = cio_read(cio, 2);
\r
1342 /* Now we write them to screen */
\r
1343 opj_event_msg(j2k->cinfo, EVT_INFO,
\r
1348 cio_skip(cio, Linsec - 2);
\r
1356 #endif /* USE_JPSEC */
\r