diff options
Diffstat (limited to 'src/lib/openjpwl/jpwl_lib.c')
| -rw-r--r-- | src/lib/openjpwl/jpwl_lib.c | 3325 |
1 files changed, 1670 insertions, 1655 deletions
diff --git a/src/lib/openjpwl/jpwl_lib.c b/src/lib/openjpwl/jpwl_lib.c index 772c8db3..a6409668 100644 --- a/src/lib/openjpwl/jpwl_lib.c +++ b/src/lib/openjpwl/jpwl_lib.c @@ -1,6 +1,6 @@ /* - * The copyright in this software is being made available under the 2-clauses - * BSD License, included below. This software may be subject to other third + * The copyright in this software is being made available under the 2-clauses + * BSD License, included below. This software may be subject to other third * party and contributor rights, including patent rights, and no such rights * are granted under this license. * @@ -46,7 +46,7 @@ #define MAX_V2 131040.0 /** conversion between a double precision floating point -number and the corresponding pseudo-floating point used +number and the corresponding pseudo-floating point used to represent sensitivity values @param V the double precision value @param bytes the number of bytes of the representation @@ -54,1750 +54,1765 @@ to represent sensitivity values */ unsigned short int jpwl_double_to_pfp(double V, int bytes); -/** conversion between a pseudo-floating point used +/** conversion between a pseudo-floating point used to represent sensitivity values and the corresponding -double precision floating point number +double precision floating point number @param em the pseudo-floating point value (cast accordingly) @param bytes the number of bytes of the representation @return the double precision value */ double jpwl_pfp_to_double(unsigned short int em, int bytes); - /*-------------------------------------------------------------*/ +/*-------------------------------------------------------------*/ int jpwl_markcomp(const void *arg1, const void *arg2) { - /* Compare the two markers' positions */ - double diff = (((jpwl_marker_t *) arg1)->dpos - ((jpwl_marker_t *) arg2)->dpos); - - if (diff == 0.0) - return (0); - else if (diff < 0) - return (-1); - else - return (+1); + /* Compare the two markers' positions */ + double diff = (((jpwl_marker_t *) arg1)->dpos - ((jpwl_marker_t *) arg2)->dpos); + + if (diff == 0.0) + return (0); + else if (diff < 0) + return (-1); + else + return (+1); } int jpwl_epbs_add(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int *jwmarker_num, - opj_bool latest, opj_bool packed, opj_bool insideMH, int *idx, int hprot, - double place_pos, int tileno, - unsigned long int pre_len, unsigned long int post_len) { - - jpwl_epb_ms_t *epb_mark = NULL; - - int k_pre, k_post, n_pre, n_post; - - unsigned long int L1, L2, dL4, max_postlen, epbs_len = 0; - - /* We find RS(n,k) for EPB parms and pre-data, if any */ - if (insideMH && (*idx == 0)) { - /* First EPB in MH */ - k_pre = 64; - n_pre = 160; - } else if (!insideMH && (*idx == 0)) { - /* First EPB in TH */ - k_pre = 25; - n_pre = 80; - } else { - /* Following EPBs in MH or TH */ - k_pre = 13; - n_pre = 40; - }; - - /* Find lengths, Figs. B3 and B4 */ - /* size of pre data: pre_buf(pre_len) + EPB(2) + Lepb(2) + Depb(1) + LDPepb(4) + Pepb(4) */ - L1 = pre_len + 13; - - /* size of pre-data redundancy */ - /* (redundancy per codeword) * (number of codewords, rounded up) */ - L2 = (n_pre - k_pre) * (unsigned long int) ceil((double) L1 / (double) k_pre); - - /* Find protection type for post data and its associated redundancy field length*/ - if ((hprot == 16) || (hprot == 32)) { - /* there is a CRC for post-data */ - k_post = post_len; - n_post = post_len + (hprot >> 3); - /*L3 = hprot >> 3;*/ /* 2 (CRC-16) or 4 (CRC-32) bytes */ - - } else if ((hprot >= 37) && (hprot <= 128)) { - /* there is a RS for post-data */ - k_post = 32; - n_post = hprot; - - } else { - /* Use predefined codes */ - n_post = n_pre; - k_post = k_pre; - }; - - /* Create the EPB(s) */ - while (post_len > 0) { - - /* maximum postlen in order to respect EPB size - (we use JPWL_MAXIMUM_EPB_ROOM instead of 65535 for keeping room for EPB parms)*/ - /* (message word size) * (number of containable parity words) */ - max_postlen = k_post * (unsigned long int) floor((double) JPWL_MAXIMUM_EPB_ROOM / (double) (n_post - k_post)); - - /* maximum postlen in order to respect EPB size */ - if (*idx == 0) - /* (we use (JPWL_MAXIMUM_EPB_ROOM - L2) instead of 65535 for keeping room for EPB parms + pre-data) */ - /* (message word size) * (number of containable parity words) */ - max_postlen = k_post * (unsigned long int) floor((double) (JPWL_MAXIMUM_EPB_ROOM - L2) / (double) (n_post - k_post)); - - else - /* (we use JPWL_MAXIMUM_EPB_ROOM instead of 65535 for keeping room for EPB parms) */ - /* (message word size) * (number of containable parity words) */ - max_postlen = k_post * (unsigned long int) floor((double) JPWL_MAXIMUM_EPB_ROOM / (double) (n_post - k_post)); - - /* null protection case */ - /* the max post length can be as large as the LDPepb field can host */ - if (hprot == 0) - max_postlen = INT_MAX; - - /* length to use */ - dL4 = min(max_postlen, post_len); - - if ((epb_mark = jpwl_epb_create( - j2k, /* this encoder handle */ - latest ? (dL4 < max_postlen) : OPJ_FALSE, /* is it the latest? */ - packed, /* is it packed? */ - tileno, /* we are in TPH */ - *idx, /* its index */ - hprot, /* protection type parameters of following data */ - 0, /* pre-data: nothing for now */ - dL4 /* post-data: the stub computed previously */ - ))) { - - /* Add this marker to the 'insertanda' list */ - if (*jwmarker_num < JPWL_MAX_NO_MARKERS) { - jwmarker[*jwmarker_num].id = J2K_MS_EPB; /* its type */ - jwmarker[*jwmarker_num].m.epbmark = epb_mark; /* the EPB */ - jwmarker[*jwmarker_num].pos = (int) place_pos; /* after SOT */ - jwmarker[*jwmarker_num].dpos = place_pos + 0.0000001 * (double)(*idx); /* not very first! */ - jwmarker[*jwmarker_num].len = epb_mark->Lepb; /* its length */ - jwmarker[*jwmarker_num].len_ready = OPJ_TRUE; /* ready */ - jwmarker[*jwmarker_num].pos_ready = OPJ_TRUE; /* ready */ - jwmarker[*jwmarker_num].parms_ready = OPJ_TRUE; /* ready */ - jwmarker[*jwmarker_num].data_ready = OPJ_FALSE; /* not ready */ - (*jwmarker_num)++; - } - - /* increment epb index */ - (*idx)++; - - /* decrease postlen */ - post_len -= dL4; - - /* increase the total length of EPBs */ - epbs_len += epb_mark->Lepb + 2; - - } else { - /* ooops, problems */ - opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB for UEP in tile %d\n", tileno); - }; - } - - return epbs_len; + opj_bool latest, opj_bool packed, opj_bool insideMH, int *idx, int hprot, + double place_pos, int tileno, + unsigned long int pre_len, unsigned long int post_len) +{ + + jpwl_epb_ms_t *epb_mark = NULL; + + int k_pre, k_post, n_pre, n_post; + + unsigned long int L1, L2, dL4, max_postlen, epbs_len = 0; + + /* We find RS(n,k) for EPB parms and pre-data, if any */ + if (insideMH && (*idx == 0)) { + /* First EPB in MH */ + k_pre = 64; + n_pre = 160; + } else if (!insideMH && (*idx == 0)) { + /* First EPB in TH */ + k_pre = 25; + n_pre = 80; + } else { + /* Following EPBs in MH or TH */ + k_pre = 13; + n_pre = 40; + }; + + /* Find lengths, Figs. B3 and B4 */ + /* size of pre data: pre_buf(pre_len) + EPB(2) + Lepb(2) + Depb(1) + LDPepb(4) + Pepb(4) */ + L1 = pre_len + 13; + + /* size of pre-data redundancy */ + /* (redundancy per codeword) * (number of codewords, rounded up) */ + L2 = (n_pre - k_pre) * (unsigned long int) ceil((double) L1 / (double) k_pre); + + /* Find protection type for post data and its associated redundancy field length*/ + if ((hprot == 16) || (hprot == 32)) { + /* there is a CRC for post-data */ + k_post = post_len; + n_post = post_len + (hprot >> 3); + /*L3 = hprot >> 3;*/ /* 2 (CRC-16) or 4 (CRC-32) bytes */ + + } else if ((hprot >= 37) && (hprot <= 128)) { + /* there is a RS for post-data */ + k_post = 32; + n_post = hprot; + + } else { + /* Use predefined codes */ + n_post = n_pre; + k_post = k_pre; + }; + + /* Create the EPB(s) */ + while (post_len > 0) { + + /* maximum postlen in order to respect EPB size + (we use JPWL_MAXIMUM_EPB_ROOM instead of 65535 for keeping room for EPB parms)*/ + /* (message word size) * (number of containable parity words) */ + max_postlen = k_post * (unsigned long int) floor((double) JPWL_MAXIMUM_EPB_ROOM / (double) (n_post - k_post)); + + /* maximum postlen in order to respect EPB size */ + if (*idx == 0) + /* (we use (JPWL_MAXIMUM_EPB_ROOM - L2) instead of 65535 for keeping room for EPB parms + pre-data) */ + /* (message word size) * (number of containable parity words) */ + max_postlen = k_post * (unsigned long int) floor((double) (JPWL_MAXIMUM_EPB_ROOM - L2) / (double) (n_post - k_post)); + + else + /* (we use JPWL_MAXIMUM_EPB_ROOM instead of 65535 for keeping room for EPB parms) */ + /* (message word size) * (number of containable parity words) */ + max_postlen = k_post * (unsigned long int) floor((double) JPWL_MAXIMUM_EPB_ROOM / (double) (n_post - k_post)); + + /* null protection case */ + /* the max post length can be as large as the LDPepb field can host */ + if (hprot == 0) + max_postlen = INT_MAX; + + /* length to use */ + dL4 = min(max_postlen, post_len); + + if ((epb_mark = jpwl_epb_create( + j2k, /* this encoder handle */ + latest ? (dL4 < max_postlen) : OPJ_FALSE, /* is it the latest? */ + packed, /* is it packed? */ + tileno, /* we are in TPH */ + *idx, /* its index */ + hprot, /* protection type parameters of following data */ + 0, /* pre-data: nothing for now */ + dL4 /* post-data: the stub computed previously */ + ))) { + + /* Add this marker to the 'insertanda' list */ + if (*jwmarker_num < JPWL_MAX_NO_MARKERS) { + jwmarker[*jwmarker_num].id = J2K_MS_EPB; /* its type */ + jwmarker[*jwmarker_num].m.epbmark = epb_mark; /* the EPB */ + jwmarker[*jwmarker_num].pos = (int) place_pos; /* after SOT */ + jwmarker[*jwmarker_num].dpos = place_pos + 0.0000001 * (double)(*idx); /* not very first! */ + jwmarker[*jwmarker_num].len = epb_mark->Lepb; /* its length */ + jwmarker[*jwmarker_num].len_ready = OPJ_TRUE; /* ready */ + jwmarker[*jwmarker_num].pos_ready = OPJ_TRUE; /* ready */ + jwmarker[*jwmarker_num].parms_ready = OPJ_TRUE; /* ready */ + jwmarker[*jwmarker_num].data_ready = OPJ_FALSE; /* not ready */ + (*jwmarker_num)++; + } + + /* increment epb index */ + (*idx)++; + + /* decrease postlen */ + post_len -= dL4; + + /* increase the total length of EPBs */ + epbs_len += epb_mark->Lepb + 2; + + } else { + /* ooops, problems */ + opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB for UEP in tile %d\n", tileno); + }; + } + + return epbs_len; } jpwl_epb_ms_t *jpwl_epb_create(opj_j2k_t *j2k, opj_bool latest, opj_bool packed, int tileno, int idx, int hprot, - unsigned long int pre_len, unsigned long int post_len) { - - jpwl_epb_ms_t *epb = NULL; - /*unsigned short int data_len = 0;*/ - unsigned short int L2, L3; - unsigned long int L1, L4; - /*unsigned char *predata_in = NULL;*/ - - opj_bool insideMH = (tileno == -1); - - /* Alloc space */ - if (!(epb = (jpwl_epb_ms_t *) opj_malloc((size_t) 1 * sizeof (jpwl_epb_ms_t)))) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for one EPB MS\n"); - return NULL; - }; - - /* We set RS(n,k) for EPB parms and pre-data, if any */ - if (insideMH && (idx == 0)) { - /* First EPB in MH */ - epb->k_pre = 64; - epb->n_pre = 160; - } else if (!insideMH && (idx == 0)) { - /* First EPB in TH */ - epb->k_pre = 25; - epb->n_pre = 80; - } else { - /* Following EPBs in MH or TH */ - epb->k_pre = 13; - epb->n_pre = 40; - }; - - /* Find lengths, Figs. B3 and B4 */ - /* size of pre data: pre_buf(pre_len) + EPB(2) + Lepb(2) + Depb(1) + LDPepb(4) + Pepb(4) */ - L1 = pre_len + 13; - epb->pre_len = pre_len; - - /* size of pre-data redundancy */ - /* (redundancy per codeword) * (number of codewords, rounded up) */ - L2 = (epb->n_pre - epb->k_pre) * (unsigned short int) ceil((double) L1 / (double) epb->k_pre); - - /* length of post-data */ - L4 = post_len; - epb->post_len = post_len; - - /* Find protection type for post data and its associated redundancy field length*/ - if ((hprot == 16) || (hprot == 32)) { - /* there is a CRC for post-data */ - epb->Pepb = 0x10000000 | ((unsigned long int) hprot >> 5); /* 0=CRC-16, 1=CRC-32 */ - epb->k_post = post_len; - epb->n_post = post_len + (hprot >> 3); - /*L3 = hprot >> 3;*/ /* 2 (CRC-16) or 4 (CRC-32) bytes */ - - } else if ((hprot >= 37) && (hprot <= 128)) { - /* there is a RS for post-data */ - epb->Pepb = 0x20000020 | (((unsigned long int) hprot & 0x000000FF) << 8); - epb->k_post = 32; - epb->n_post = hprot; - - } else if (hprot == 1) { - /* Use predefined codes */ - epb->Pepb = (unsigned long int) 0x00000000; - epb->n_post = epb->n_pre; - epb->k_post = epb->k_pre; - - } else if (hprot == 0) { - /* Placeholder EPB: only protects its parameters, no protection method */ - epb->Pepb = (unsigned long int) 0xFFFFFFFF; - epb->n_post = 1; - epb->k_post = 1; - - } else { - opj_event_msg(j2k->cinfo, EVT_ERROR, "Invalid protection value for EPB h = %d\n", hprot); - return NULL; - } - - epb->hprot = hprot; - - /* (redundancy per codeword) * (number of codewords, rounded up) */ - L3 = (epb->n_post - epb->k_post) * (unsigned short int) ceil((double) L4 / (double) epb->k_post); - - /* private fields */ - epb->tileno = tileno; - - /* Fill some fields of the EPB */ - - /* total length of the EPB MS (less the EPB marker itself): */ - /* Lepb(2) + Depb(1) + LDPepb(4) + Pepb(4) + pre_redundancy + post-redundancy */ - epb->Lepb = 11 + L2 + L3; - - /* EPB style */ - epb->Depb = ((packed & 0x0001) << 7) | ((latest & 0x0001) << 6) | (idx & 0x003F); - - /* length of data protected by EPB: */ - epb->LDPepb = L1 + L4; - - return epb; + unsigned long int pre_len, unsigned long int post_len) +{ + + jpwl_epb_ms_t *epb = NULL; + /*unsigned short int data_len = 0;*/ + unsigned short int L2, L3; + unsigned long int L1, L4; + /*unsigned char *predata_in = NULL;*/ + + opj_bool insideMH = (tileno == -1); + + /* Alloc space */ + if (!(epb = (jpwl_epb_ms_t *) opj_malloc((size_t) 1 * sizeof (jpwl_epb_ms_t)))) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for one EPB MS\n"); + return NULL; + }; + + /* We set RS(n,k) for EPB parms and pre-data, if any */ + if (insideMH && (idx == 0)) { + /* First EPB in MH */ + epb->k_pre = 64; + epb->n_pre = 160; + } else if (!insideMH && (idx == 0)) { + /* First EPB in TH */ + epb->k_pre = 25; + epb->n_pre = 80; + } else { + /* Following EPBs in MH or TH */ + epb->k_pre = 13; + epb->n_pre = 40; + }; + + /* Find lengths, Figs. B3 and B4 */ + /* size of pre data: pre_buf(pre_len) + EPB(2) + Lepb(2) + Depb(1) + LDPepb(4) + Pepb(4) */ + L1 = pre_len + 13; + epb->pre_len = pre_len; + + /* size of pre-data redundancy */ + /* (redundancy per codeword) * (number of codewords, rounded up) */ + L2 = (epb->n_pre - epb->k_pre) * (unsigned short int) ceil((double) L1 / (double) epb->k_pre); + + /* length of post-data */ + L4 = post_len; + epb->post_len = post_len; + + /* Find protection type for post data and its associated redundancy field length*/ + if ((hprot == 16) || (hprot == 32)) { + /* there is a CRC for post-data */ + epb->Pepb = 0x10000000 | ((unsigned long int) hprot >> 5); /* 0=CRC-16, 1=CRC-32 */ + epb->k_post = post_len; + epb->n_post = post_len + (hprot >> 3); + /*L3 = hprot >> 3;*/ /* 2 (CRC-16) or 4 (CRC-32) bytes */ + + } else if ((hprot >= 37) && (hprot <= 128)) { + /* there is a RS for post-data */ + epb->Pepb = 0x20000020 | (((unsigned long int) hprot & 0x000000FF) << 8); + epb->k_post = 32; + epb->n_post = hprot; + + } else if (hprot == 1) { + /* Use predefined codes */ + epb->Pepb = (unsigned long int) 0x00000000; + epb->n_post = epb->n_pre; + epb->k_post = epb->k_pre; + + } else if (hprot == 0) { + /* Placeholder EPB: only protects its parameters, no protection method */ + epb->Pepb = (unsigned long int) 0xFFFFFFFF; + epb->n_post = 1; + epb->k_post = 1; + + } else { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Invalid protection value for EPB h = %d\n", hprot); + return NULL; + } + + epb->hprot = hprot; + + /* (redundancy per codeword) * (number of codewords, rounded up) */ + L3 = (epb->n_post - epb->k_post) * (unsigned short int) ceil((double) L4 / (double) epb->k_post); + + /* private fields */ + epb->tileno = tileno; + + /* Fill some fields of the EPB */ + + /* total length of the EPB MS (less the EPB marker itself): */ + /* Lepb(2) + Depb(1) + LDPepb(4) + Pepb(4) + pre_redundancy + post-redundancy */ + epb->Lepb = 11 + L2 + L3; + + /* EPB style */ + epb->Depb = ((packed & 0x0001) << 7) | ((latest & 0x0001) << 6) | (idx & 0x003F); + + /* length of data protected by EPB: */ + epb->LDPepb = L1 + L4; + + return epb; } -void jpwl_epb_write(opj_j2k_t *j2k, jpwl_epb_ms_t *epb, unsigned char *buf) { +void jpwl_epb_write(opj_j2k_t *j2k, jpwl_epb_ms_t *epb, unsigned char *buf) +{ - /* Marker */ - *(buf++) = (unsigned char) (J2K_MS_EPB >> 8); - *(buf++) = (unsigned char) (J2K_MS_EPB >> 0); + /* Marker */ + *(buf++) = (unsigned char) (J2K_MS_EPB >> 8); + *(buf++) = (unsigned char) (J2K_MS_EPB >> 0); - /* Lepb */ - *(buf++) = (unsigned char) (epb->Lepb >> 8); - *(buf++) = (unsigned char) (epb->Lepb >> 0); + /* Lepb */ + *(buf++) = (unsigned char) (epb->Lepb >> 8); + *(buf++) = (unsigned char) (epb->Lepb >> 0); - /* Depb */ - *(buf++) = (unsigned char) (epb->Depb >> 0); + /* Depb */ + *(buf++) = (unsigned char) (epb->Depb >> 0); - /* LDPepb */ - *(buf++) = (unsigned char) (epb->LDPepb >> 24); - *(buf++) = (unsigned char) (epb->LDPepb >> 16); - *(buf++) = (unsigned char) (epb->LDPepb >> 8); - *(buf++) = (unsigned char) (epb->LDPepb >> 0); + /* LDPepb */ + *(buf++) = (unsigned char) (epb->LDPepb >> 24); + *(buf++) = (unsigned char) (epb->LDPepb >> 16); + *(buf++) = (unsigned char) (epb->LDPepb >> 8); + *(buf++) = (unsigned char) (epb->LDPepb >> 0); - /* Pepb */ - *(buf++) = (unsigned char) (epb->Pepb >> 24); - *(buf++) = (unsigned char) (epb->Pepb >> 16); - *(buf++) = (unsigned char) (epb->Pepb >> 8); - *(buf++) = (unsigned char) (epb->Pepb >> 0); + /* Pepb */ + *(buf++) = (unsigned char) (epb->Pepb >> 24); + *(buf++) = (unsigned char) (epb->Pepb >> 16); + *(buf++) = (unsigned char) (epb->Pepb >> 8); + *(buf++) = (unsigned char) (epb->Pepb >> 0); - /* Data */ - /*memcpy(buf, epb->data, (size_t) epb->Lepb - 11);*/ - memset(buf, 0, (size_t) epb->Lepb - 11); + /* Data */ + /*memcpy(buf, epb->data, (size_t) epb->Lepb - 11);*/ + memset(buf, 0, (size_t) epb->Lepb - 11); - /* update markers struct */ - j2k_add_marker(j2k->cstr_info, J2K_MS_EPB, -1, epb->Lepb + 2); + /* update markers struct */ + j2k_add_marker(j2k->cstr_info, J2K_MS_EPB, -1, epb->Lepb + 2); } -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) { +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) +{ - jpwl_epc_ms_t *epc = NULL; + jpwl_epc_ms_t *epc = NULL; - /* Alloc space */ - if (!(epc = (jpwl_epc_ms_t *) opj_malloc((size_t) 1 * sizeof (jpwl_epc_ms_t)))) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for EPC MS\n"); - return NULL; - }; + /* Alloc space */ + if (!(epc = (jpwl_epc_ms_t *) opj_malloc((size_t) 1 * sizeof (jpwl_epc_ms_t)))) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for EPC MS\n"); + return NULL; + }; - /* Set the EPC parameters */ - epc->esd_on = esd_on; - epc->epb_on = epb_on; - epc->red_on = red_on; - epc->info_on = info_on; + /* Set the EPC parameters */ + epc->esd_on = esd_on; + epc->epb_on = epb_on; + epc->red_on = red_on; + epc->info_on = info_on; - /* Fill the EPC fields with default values */ - epc->Lepc = 9; - epc->Pcrc = 0x0000; - epc->DL = 0x00000000; - epc->Pepc = ((j2k->cp->esd_on & 0x0001) << 4) | ((j2k->cp->red_on & 0x0001) << 5) | - ((j2k->cp->epb_on & 0x0001) << 6) | ((j2k->cp->info_on & 0x0001) << 7); + /* Fill the EPC fields with default values */ + epc->Lepc = 9; + epc->Pcrc = 0x0000; + epc->DL = 0x00000000; + epc->Pepc = ((j2k->cp->esd_on & 0x0001) << 4) | ((j2k->cp->red_on & 0x0001) << 5) | + ((j2k->cp->epb_on & 0x0001) << 6) | ((j2k->cp->info_on & 0x0001) << 7); - return (epc); + return (epc); } -opj_bool jpwl_epb_fill(opj_j2k_t *j2k, jpwl_epb_ms_t *epb, unsigned char *buf, unsigned char *post_buf) { - - unsigned long int L1, L2, L3, L4; - int remaining; - unsigned long int P, NN_P; - - /* Operating buffer */ - static unsigned char codeword[NN], *parityword; - - unsigned char *L1_buf, *L2_buf; - /* these ones are static, since we need to keep memory of - the exact place from one call to the other */ - static unsigned char *L3_buf, *L4_buf; - - /* some consistency check */ - if (!buf) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "There is no operating buffer for EPBs\n"); - return OPJ_FALSE; - } - - if (!post_buf && !L4_buf) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "There is no operating buffer for EPBs data\n"); - return OPJ_FALSE; - } - - /* - * Compute parity bytes on pre-data, ALWAYS present (at least only for EPB parms) - */ - - /* Initialize RS structures */ - P = epb->n_pre - epb->k_pre; - NN_P = NN - P; - memset(codeword, 0, NN); - parityword = codeword + NN_P; - init_rs(NN_P); - - /* pre-data begins pre_len bytes before of EPB buf */ - L1_buf = buf - epb->pre_len; - L1 = epb->pre_len + 13; - - /* redundancy for pre-data begins immediately after EPB parms */ - L2_buf = buf + 13; - L2 = (epb->n_pre - epb->k_pre) * (unsigned short int) ceil((double) L1 / (double) epb->k_pre); - - /* post-data - the position of L4 buffer can be: - 1) passed as a parameter: in that case use it - 2) null: in that case use the previous (static) one - */ - if (post_buf) - L4_buf = post_buf; - L4 = epb->post_len; - - /* post-data redundancy begins immediately after pre-data redundancy */ - L3_buf = L2_buf + L2; - L3 = (epb->n_post - epb->k_post) * (unsigned short int) ceil((double) L4 / (double) epb->k_post); - - /* let's check whether EPB length is sufficient to contain all these data */ - if (epb->Lepb < (11 + L2 + L3)) - opj_event_msg(j2k->cinfo, EVT_ERROR, "There is no room in EPB data field for writing redundancy data\n"); - /*printf("Env. %d, nec. %d (%d + %d)\n", epb->Lepb - 11, L2 + L3, L2, L3);*/ - - /* Compute redundancy of pre-data message words */ - remaining = L1; - while (remaining) { - - /* copy message data into codeword buffer */ - if (remaining < epb->k_pre) { - /* the last message word is zero-padded */ - memset(codeword, 0, NN); - memcpy(codeword, L1_buf, remaining); - L1_buf += remaining; - remaining = 0; - - } else { - memcpy(codeword, L1_buf, epb->k_pre); - L1_buf += epb->k_pre; - remaining -= epb->k_pre; - - } - - /* Encode the buffer and obtain parity bytes */ - if (encode_rs(codeword, parityword)) - opj_event_msg(j2k->cinfo, EVT_WARNING, - "Possible encoding error in codeword @ position #%d\n", (L1_buf - buf) / epb->k_pre); - - /* copy parity bytes only in redundancy buffer */ - memcpy(L2_buf, parityword, P); - - /* advance parity buffer */ - L2_buf += P; - } - - /* - * Compute parity bytes on post-data, may be absent if there are no data - */ - /*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", - epb->hprot, epb->tileno, epb->k_pre, epb->n_pre, epb->k_post, epb->n_post, epb->pre_len, - epb->post_len);*/ - if (epb->hprot < 0) { - - /* there should be no EPB */ - - } else if (epb->hprot == 0) { - - /* no protection for the data */ - /* advance anyway */ - L4_buf += epb->post_len; - - } else if (epb->hprot == 16) { - - /* CRC-16 */ - unsigned short int mycrc = 0x0000; - - /* compute the CRC field (excluding itself) */ - remaining = L4; - while (remaining--) - jpwl_updateCRC16(&mycrc, *(L4_buf++)); - - /* write the CRC field */ - *(L3_buf++) = (unsigned char) (mycrc >> 8); - *(L3_buf++) = (unsigned char) (mycrc >> 0); - - } else if (epb->hprot == 32) { - - /* CRC-32 */ - unsigned long int mycrc = 0x00000000; - - /* compute the CRC field (excluding itself) */ - remaining = L4; - while (remaining--) - jpwl_updateCRC32(&mycrc, *(L4_buf++)); - - /* write the CRC field */ - *(L3_buf++) = (unsigned char) (mycrc >> 24); - *(L3_buf++) = (unsigned char) (mycrc >> 16); - *(L3_buf++) = (unsigned char) (mycrc >> 8); - *(L3_buf++) = (unsigned char) (mycrc >> 0); - - } else { - - /* RS */ - - /* Initialize RS structures */ - P = epb->n_post - epb->k_post; - NN_P = NN - P; - memset(codeword, 0, NN); - parityword = codeword + NN_P; - init_rs(NN_P); - - /* Compute redundancy of post-data message words */ - remaining = L4; - while (remaining) { - - /* copy message data into codeword buffer */ - if (remaining < epb->k_post) { - /* the last message word is zero-padded */ - memset(codeword, 0, NN); - memcpy(codeword, L4_buf, remaining); - L4_buf += remaining; - remaining = 0; +opj_bool jpwl_epb_fill(opj_j2k_t *j2k, jpwl_epb_ms_t *epb, unsigned char *buf, unsigned char *post_buf) +{ + + unsigned long int L1, L2, L3, L4; + int remaining; + unsigned long int P, NN_P; + + /* Operating buffer */ + static unsigned char codeword[NN], *parityword; + + unsigned char *L1_buf, *L2_buf; + /* these ones are static, since we need to keep memory of + the exact place from one call to the other */ + static unsigned char *L3_buf, *L4_buf; + + /* some consistency check */ + if (!buf) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "There is no operating buffer for EPBs\n"); + return OPJ_FALSE; + } + + if (!post_buf && !L4_buf) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "There is no operating buffer for EPBs data\n"); + return OPJ_FALSE; + } + + /* + * Compute parity bytes on pre-data, ALWAYS present (at least only for EPB parms) + */ + + /* Initialize RS structures */ + P = epb->n_pre - epb->k_pre; + NN_P = NN - P; + memset(codeword, 0, NN); + parityword = codeword + NN_P; + init_rs(NN_P); + + /* pre-data begins pre_len bytes before of EPB buf */ + L1_buf = buf - epb->pre_len; + L1 = epb->pre_len + 13; + + /* redundancy for pre-data begins immediately after EPB parms */ + L2_buf = buf + 13; + L2 = (epb->n_pre - epb->k_pre) * (unsigned short int) ceil((double) L1 / (double) epb->k_pre); + + /* post-data + the position of L4 buffer can be: + 1) passed as a parameter: in that case use it + 2) null: in that case use the previous (static) one + */ + if (post_buf) + L4_buf = post_buf; + L4 = epb->post_len; + + /* post-data redundancy begins immediately after pre-data redundancy */ + L3_buf = L2_buf + L2; + L3 = (epb->n_post - epb->k_post) * (unsigned short int) ceil((double) L4 / (double) epb->k_post); + + /* let's check whether EPB length is sufficient to contain all these data */ + if (epb->Lepb < (11 + L2 + L3)) + opj_event_msg(j2k->cinfo, EVT_ERROR, "There is no room in EPB data field for writing redundancy data\n"); + /*printf("Env. %d, nec. %d (%d + %d)\n", epb->Lepb - 11, L2 + L3, L2, L3);*/ + + /* Compute redundancy of pre-data message words */ + remaining = L1; + while (remaining) { + + /* copy message data into codeword buffer */ + if (remaining < epb->k_pre) { + /* the last message word is zero-padded */ + memset(codeword, 0, NN); + memcpy(codeword, L1_buf, remaining); + L1_buf += remaining; + remaining = 0; + + } else { + memcpy(codeword, L1_buf, epb->k_pre); + L1_buf += epb->k_pre; + remaining -= epb->k_pre; + + } + + /* Encode the buffer and obtain parity bytes */ + if (encode_rs(codeword, parityword)) + opj_event_msg(j2k->cinfo, EVT_WARNING, + "Possible encoding error in codeword @ position #%d\n", (L1_buf - buf) / epb->k_pre); + + /* copy parity bytes only in redundancy buffer */ + memcpy(L2_buf, parityword, P); + + /* advance parity buffer */ + L2_buf += P; + } + + /* + * Compute parity bytes on post-data, may be absent if there are no data + */ + /*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", + epb->hprot, epb->tileno, epb->k_pre, epb->n_pre, epb->k_post, epb->n_post, epb->pre_len, + epb->post_len);*/ + if (epb->hprot < 0) { + + /* there should be no EPB */ + + } else if (epb->hprot == 0) { + + /* no protection for the data */ + /* advance anyway */ + L4_buf += epb->post_len; + + } else if (epb->hprot == 16) { + + /* CRC-16 */ + unsigned short int mycrc = 0x0000; + + /* compute the CRC field (excluding itself) */ + remaining = L4; + while (remaining--) + jpwl_updateCRC16(&mycrc, *(L4_buf++)); + + /* write the CRC field */ + *(L3_buf++) = (unsigned char) (mycrc >> 8); + *(L3_buf++) = (unsigned char) (mycrc >> 0); + + } else if (epb->hprot == 32) { + + /* CRC-32 */ + unsigned long int mycrc = 0x00000000; + + /* compute the CRC field (excluding itself) */ + remaining = L4; + while (remaining--) + jpwl_updateCRC32(&mycrc, *(L4_buf++)); + + /* write the CRC field */ + *(L3_buf++) = (unsigned char) (mycrc >> 24); + *(L3_buf++) = (unsigned char) (mycrc >> 16); + *(L3_buf++) = (unsigned char) (mycrc >> 8); + *(L3_buf++) = (unsigned char) (mycrc >> 0); + + } else { + + /* RS */ + + /* Initialize RS structures */ + P = epb->n_post - epb->k_post; + NN_P = NN - P; + memset(codeword, 0, NN); + parityword = codeword + NN_P; + init_rs(NN_P); + + /* Compute redundancy of post-data message words */ + remaining = L4; + while (remaining) { + + /* copy message data into codeword buffer */ + if (remaining < epb->k_post) { + /* the last message word is zero-padded */ + memset(codeword, 0, NN); + memcpy(codeword, L4_buf, remaining); + L4_buf += remaining; + remaining = 0; + + } else { + memcpy(codeword, L4_buf, epb->k_post); + L4_buf += epb->k_post; + remaining -= epb->k_post; - } else { - memcpy(codeword, L4_buf, epb->k_post); - L4_buf += epb->k_post; - remaining -= epb->k_post; - - } - - /* Encode the buffer and obtain parity bytes */ - if (encode_rs(codeword, parityword)) - opj_event_msg(j2k->cinfo, EVT_WARNING, - "Possible encoding error in codeword @ position #%d\n", (L4_buf - buf) / epb->k_post); + } - /* copy parity bytes only in redundancy buffer */ - memcpy(L3_buf, parityword, P); + /* Encode the buffer and obtain parity bytes */ + if (encode_rs(codeword, parityword)) + opj_event_msg(j2k->cinfo, EVT_WARNING, + "Possible encoding error in codeword @ position #%d\n", (L4_buf - buf) / epb->k_post); - /* advance parity buffer */ - L3_buf += P; - } + /* copy parity bytes only in redundancy buffer */ + memcpy(L3_buf, parityword, P); - } + /* advance parity buffer */ + L3_buf += P; + } - return OPJ_TRUE; + } + + return OPJ_TRUE; } -opj_bool jpwl_correct(opj_j2k_t *j2k) { - - opj_cio_t *cio = j2k->cio; - opj_bool status; - static opj_bool mh_done = OPJ_FALSE; - int mark_pos, id, len, skips, sot_pos; - unsigned long int Psot = 0; - - /* go back to marker position */ - mark_pos = cio_tell(cio) - 2; - cio_seek(cio, mark_pos); - - if ((j2k->state == J2K_STATE_MHSOC) && !mh_done) { - - int mark_val = 0, skipnum = 0; - - /* - COLOR IMAGE - first thing to do, if we are here, is to look whether - 51 (skipnum) positions ahead there is an EPB, in case of MH - */ - /* - B/W IMAGE - first thing to do, if we are here, is to look whether - 45 (skipnum) positions ahead there is an EPB, in case of MH - */ - /* SIZ SIZ_FIELDS SIZ_COMPS FOLLOWING_MARKER */ - skipnum = 2 + 38 + 3 * j2k->cp->exp_comps + 2; - if ((cio->bp + skipnum) < cio->end) { - - cio_skip(cio, skipnum); - - /* check that you are not going beyond the end of codestream */ - - /* call EPB corrector */ - status = jpwl_epb_correct(j2k, /* J2K decompressor handle */ - cio->bp, /* pointer to EPB in codestream buffer */ - 0, /* EPB type: MH */ - skipnum, /* length of pre-data */ - -1, /* length of post-data: -1 means auto */ - NULL, - NULL - ); - - /* read the marker value */ - mark_val = (*(cio->bp) << 8) | *(cio->bp + 1); - - if (status && (mark_val == J2K_MS_EPB)) { - /* we found it! */ - mh_done = OPJ_TRUE; - return OPJ_TRUE; - } - - /* Disable correction in case of missing or bad head EPB */ - /* We can't do better! */ - /* PATCHED: 2008-01-25 */ - /* MOVED UP: 2008-02-01 */ - if (!status) { - j2k->cp->correct = OPJ_FALSE; - opj_event_msg(j2k->cinfo, EVT_WARNING, "Couldn't find the MH EPB: disabling JPWL\n"); - } - - } - - } - - if (OPJ_TRUE /*(j2k->state == J2K_STATE_TPHSOT) || (j2k->state == J2K_STATE_TPH)*/) { - /* else, look if 12 positions ahead there is an EPB, in case of TPH */ - cio_seek(cio, mark_pos); - if ((cio->bp + 12) < cio->end) { - - cio_skip(cio, 12); - - /* call EPB corrector */ - status = jpwl_epb_correct(j2k, /* J2K decompressor handle */ - cio->bp, /* pointer to EPB in codestream buffer */ - 1, /* EPB type: TPH */ - 12, /* length of pre-data */ - -1, /* length of post-data: -1 means auto */ - NULL, - NULL - ); - if (status) - /* we found it! */ - return OPJ_TRUE; - } - } - - return OPJ_FALSE; - - /* for now, don't use this code */ - - /* else, look if here is an EPB, in case of other */ - if (mark_pos > 64) { - /* it cannot stay before the first MH EPB */ - cio_seek(cio, mark_pos); - cio_skip(cio, 0); - - /* call EPB corrector */ - status = jpwl_epb_correct(j2k, /* J2K decompressor handle */ - cio->bp, /* pointer to EPB in codestream buffer */ - 2, /* EPB type: TPH */ - 0, /* length of pre-data */ - -1, /* length of post-data: -1 means auto */ - NULL, - NULL - ); - if (status) - /* we found it! */ - return OPJ_TRUE; - } - - /* nope, no EPBs probably, or they are so damaged that we can give up */ - return OPJ_FALSE; - - return OPJ_TRUE; - - /* AN ATTEMPT OF PARSER */ - /* NOT USED ACTUALLY */ - - /* go to the beginning of the file */ - cio_seek(cio, 0); - - /* let's begin */ - j2k->state = J2K_STATE_MHSOC; - - /* cycle all over the markers */ - while (cio_tell(cio) < cio->length) { - - /* read the marker */ - mark_pos = cio_tell(cio); - id = cio_read(cio, 2); - - /* details */ - printf("Marker@%d: %X\n", cio_tell(cio) - 2, id); - - /* do an action in response to the read marker */ - switch (id) { - - /* short markers */ - - /* SOC */ - case J2K_MS_SOC: - j2k->state = J2K_STATE_MHSIZ; - len = 0; - skips = 0; - break; - - /* EOC */ - case J2K_MS_EOC: - j2k->state = J2K_STATE_MT; - len = 0; - skips = 0; - break; - - /* particular case of SOD */ - case J2K_MS_SOD: - len = Psot - (mark_pos - sot_pos) - 2; - skips = len; - break; - - /* long markers */ - - /* SOT */ - case J2K_MS_SOT: - j2k->state = J2K_STATE_TPH; - sot_pos = mark_pos; /* position of SOT */ - len = cio_read(cio, 2); /* read the length field */ - cio_skip(cio, 2); /* this field is unnecessary */ - Psot = cio_read(cio, 4); /* tile length */ - skips = len - 8; - break; - - /* remaining */ - case J2K_MS_SIZ: - j2k->state = J2K_STATE_MH; - /* read the length field */ - len = cio_read(cio, 2); - skips = len - 2; - break; - - /* remaining */ - default: - /* read the length field */ - len = cio_read(cio, 2); - skips = len - 2; - break; - - } - - /* skip to marker's end */ - cio_skip(cio, skips); - - } +opj_bool jpwl_correct(opj_j2k_t *j2k) +{ + + opj_cio_t *cio = j2k->cio; + opj_bool status; + static opj_bool mh_done = OPJ_FALSE; + int mark_pos, id, len, skips, sot_pos; + unsigned long int Psot = 0; + + /* go back to marker position */ + mark_pos = cio_tell(cio) - 2; + cio_seek(cio, mark_pos); + + if ((j2k->state == J2K_STATE_MHSOC) && !mh_done) { + + int mark_val = 0, skipnum = 0; + + /* + COLOR IMAGE + first thing to do, if we are here, is to look whether + 51 (skipnum) positions ahead there is an EPB, in case of MH + */ + /* + B/W IMAGE + first thing to do, if we are here, is to look whether + 45 (skipnum) positions ahead there is an EPB, in case of MH + */ + /* SIZ SIZ_FIELDS SIZ_COMPS FOLLOWING_MARKER */ + skipnum = 2 + 38 + 3 * j2k->cp->exp_comps + 2; + if ((cio->bp + skipnum) < cio->end) { + + cio_skip(cio, skipnum); + + /* check that you are not going beyond the end of codestream */ + + /* call EPB corrector */ + status = jpwl_epb_correct(j2k, /* J2K decompressor handle */ + cio->bp, /* pointer to EPB in codestream buffer */ + 0, /* EPB type: MH */ + skipnum, /* length of pre-data */ + -1, /* length of post-data: -1 means auto */ + NULL, + NULL + ); + + /* read the marker value */ + mark_val = (*(cio->bp) << 8) | *(cio->bp + 1); + + if (status && (mark_val == J2K_MS_EPB)) { + /* we found it! */ + mh_done = OPJ_TRUE; + return OPJ_TRUE; + } + + /* Disable correction in case of missing or bad head EPB */ + /* We can't do better! */ + /* PATCHED: 2008-01-25 */ + /* MOVED UP: 2008-02-01 */ + if (!status) { + j2k->cp->correct = OPJ_FALSE; + opj_event_msg(j2k->cinfo, EVT_WARNING, "Couldn't find the MH EPB: disabling JPWL\n"); + } + + } + + } + + if (OPJ_TRUE /*(j2k->state == J2K_STATE_TPHSOT) || (j2k->state == J2K_STATE_TPH)*/) { + /* else, look if 12 positions ahead there is an EPB, in case of TPH */ + cio_seek(cio, mark_pos); + if ((cio->bp + 12) < cio->end) { + + cio_skip(cio, 12); + + /* call EPB corrector */ + status = jpwl_epb_correct(j2k, /* J2K decompressor handle */ + cio->bp, /* pointer to EPB in codestream buffer */ + 1, /* EPB type: TPH */ + 12, /* length of pre-data */ + -1, /* length of post-data: -1 means auto */ + NULL, + NULL + ); + if (status) + /* we found it! */ + return OPJ_TRUE; + } + } + + return OPJ_FALSE; + + /* for now, don't use this code */ + + /* else, look if here is an EPB, in case of other */ + if (mark_pos > 64) { + /* it cannot stay before the first MH EPB */ + cio_seek(cio, mark_pos); + cio_skip(cio, 0); + + /* call EPB corrector */ + status = jpwl_epb_correct(j2k, /* J2K decompressor handle */ + cio->bp, /* pointer to EPB in codestream buffer */ + 2, /* EPB type: TPH */ + 0, /* length of pre-data */ + -1, /* length of post-data: -1 means auto */ + NULL, + NULL + ); + if (status) + /* we found it! */ + return OPJ_TRUE; + } + + /* nope, no EPBs probably, or they are so damaged that we can give up */ + return OPJ_FALSE; + + return OPJ_TRUE; + + /* AN ATTEMPT OF PARSER */ + /* NOT USED ACTUALLY */ + + /* go to the beginning of the file */ + cio_seek(cio, 0); + + /* let's begin */ + j2k->state = J2K_STATE_MHSOC; + + /* cycle all over the markers */ + while (cio_tell(cio) < cio->length) { + + /* read the marker */ + mark_pos = cio_tell(cio); + id = cio_read(cio, 2); + + /* details */ + printf("Marker@%d: %X\n", cio_tell(cio) - 2, id); + + /* do an action in response to the read marker */ + switch (id) { + + /* short markers */ + + /* SOC */ + case J2K_MS_SOC: + j2k->state = J2K_STATE_MHSIZ; + len = 0; + skips = 0; + break; + + /* EOC */ + case J2K_MS_EOC: + j2k->state = J2K_STATE_MT; + len = 0; + skips = 0; + break; + + /* particular case of SOD */ + case J2K_MS_SOD: + len = Psot - (mark_pos - sot_pos) - 2; + skips = len; + break; + + /* long markers */ + + /* SOT */ + case J2K_MS_SOT: + j2k->state = J2K_STATE_TPH; + sot_pos = mark_pos; /* position of SOT */ + len = cio_read(cio, 2); /* read the length field */ + cio_skip(cio, 2); /* this field is unnecessary */ + Psot = cio_read(cio, 4); /* tile length */ + skips = len - 8; + break; + + /* remaining */ + case J2K_MS_SIZ: + j2k->state = J2K_STATE_MH; + /* read the length field */ + len = cio_read(cio, 2); + skips = len - 2; + break; + + /* remaining */ + default: + /* read the length field */ + len = cio_read(cio, 2); + skips = len - 2; + break; + + } + + /* skip to marker's end */ + cio_skip(cio, skips); + + } } opj_bool jpwl_epb_correct(opj_j2k_t *j2k, unsigned char *buffer, int type, int pre_len, int post_len, int *conn, - unsigned char **L4_bufp) { - - /* Operating buffer */ - unsigned char codeword[NN], *parityword; - - unsigned long int P, NN_P; - unsigned long int L1, L4; - int remaining, n_pre, k_pre, n_post, k_post; - - int status, tt; - - int orig_pos = cio_tell(j2k->cio); - - unsigned char *L1_buf, *L2_buf; - unsigned char *L3_buf, *L4_buf; - - unsigned long int LDPepb, Pepb; - unsigned short int Lepb; - unsigned char Depb; - char str1[25] = ""; - int myconn, errnum = 0; - opj_bool errflag = OPJ_FALSE; - - opj_cio_t *cio = j2k->cio; - - /* check for common errors */ - if (!buffer) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "The EPB pointer is a NULL buffer\n"); - return OPJ_FALSE; - } - - /* set bignesses */ - L1 = pre_len + 13; - - /* pre-data correction */ - switch (type) { - - case 0: - /* MH EPB */ - k_pre = 64; - n_pre = 160; - break; - - case 1: - /* TPH EPB */ - k_pre = 25; - n_pre = 80; - break; - - case 2: - /* other EPBs */ - k_pre = 13; - n_pre = 40; - break; - - case 3: - /* automatic setup */ - opj_event_msg(j2k->cinfo, EVT_ERROR, "Auto. setup not yet implemented\n"); - return OPJ_FALSE; - break; - - default: - /* unknown type */ - opj_event_msg(j2k->cinfo, EVT_ERROR, "Unknown expected EPB type\n"); - return OPJ_FALSE; - break; - - } - - /* Initialize RS structures */ - P = n_pre - k_pre; - NN_P = NN - P; - tt = (int) floor((float) P / 2.0F); /* correction capability of the code */ - memset(codeword, 0, NN); - parityword = codeword + NN_P; - init_rs(NN_P); - - /* Correct pre-data message words */ - L1_buf = buffer - pre_len; - L2_buf = buffer + 13; - remaining = L1; - while (remaining) { - - /* always zero-pad codewords */ - /* (this is required, since after decoding the zeros in the long codeword - could change, and keep unchanged in subsequent calls) */ - memset(codeword, 0, NN); - - /* copy codeword buffer into message bytes */ - if (remaining < k_pre) - memcpy(codeword, L1_buf, remaining); - else - memcpy(codeword, L1_buf, k_pre); - - /* copy redundancy buffer in parity bytes */ - memcpy(parityword, L2_buf, P); - - /* Decode the buffer and possibly obtain corrected bytes */ - status = eras_dec_rs(codeword, NULL, 0); - if (status == -1) { - /*if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_WARNING, - "Possible decoding error in codeword @ position #%d\n", (L1_buf - buffer) / k_pre);*/ - errflag = OPJ_TRUE; - /* we can try to safely get out from the function: - if we are here, either this is not an EPB or the first codeword - is too damaged to be helpful */ - /*return OPJ_FALSE;*/ - - } else if (status == 0) { - /*if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_INFO, "codeword is correctly decoded\n");*/ - - } else if (status <= tt) { - /* it has corrected 0 <= errs <= tt */ - /*if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_WARNING, "%d errors corrected in codeword\n", status);*/ - errnum += status; - - } else { - /*if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_WARNING, "EPB correction capability exceeded\n"); - return OPJ_FALSE;*/ - errflag = OPJ_TRUE; - } - - - /* advance parity buffer */ - if ((status >= 0) && (status <= tt)) - /* copy back corrected parity only if all is OK */ - memcpy(L2_buf, parityword, P); - L2_buf += P; - - /* advance message buffer */ - if (remaining < k_pre) { - if ((status >= 0) && (status <= tt)) - /* copy back corrected data only if all is OK */ - memcpy(L1_buf, codeword, remaining); - L1_buf += remaining; - remaining = 0; - - } else { - if ((status >= 0) && (status <= tt)) - /* copy back corrected data only if all is OK */ - memcpy(L1_buf, codeword, k_pre); - L1_buf += k_pre; - remaining -= k_pre; - - } - } - - /* print summary */ - if (!conn) { - - /*if (errnum) - opj_event_msg(j2k->cinfo, EVT_INFO, "+ %d symbol errors corrected (Ps=%.1e)\n", errnum, - (float) errnum / ((float) n_pre * (float) L1 / (float) k_pre));*/ - if (errflag) { - /*opj_event_msg(j2k->cinfo, EVT_INFO, "+ there were unrecoverable errors\n");*/ - return OPJ_FALSE; - } - - } - - /* presumably, now, EPB parameters are correct */ - /* let's get them */ - - /* Simply read the EPB parameters */ - if (conn) - cio->bp = buffer; - cio_skip(cio, 2); /* the marker */ - Lepb = cio_read(cio, 2); - Depb = cio_read(cio, 1); - LDPepb = cio_read(cio, 4); - Pepb = cio_read(cio, 4); - - /* What does Pepb tells us about the protection method? */ - if (((Pepb & 0xF0000000) >> 28) == 0) - sprintf(str1, "pred"); /* predefined */ - else if (((Pepb & 0xF0000000) >> 28) == 1) - sprintf(str1, "crc-%lu", 16 * ((Pepb & 0x00000001) + 1)); /* CRC mode */ - else if (((Pepb & 0xF0000000) >> 28) == 2) - sprintf(str1, "rs(%lu,32)", (Pepb & 0x0000FF00) >> 8); /* RS mode */ - else if (Pepb == 0xFFFFFFFF) - sprintf(str1, "nometh"); /* RS mode */ - else - sprintf(str1, "unknown"); /* unknown */ - - /* Now we write them to screen */ - if (!conn && post_len) - opj_event_msg(j2k->cinfo, EVT_INFO, - "EPB(%d): (%sl, %sp, %u), %lu, %s\n", - cio_tell(cio) - 13, - (Depb & 0x40) ? "" : "n", /* latest EPB or not? */ - (Depb & 0x80) ? "" : "n", /* packed or unpacked EPB? */ - (Depb & 0x3F), /* EPB index value */ - LDPepb, /*length of the data protected by the EPB */ - str1); /* protection method */ - - - /* well, we need to investigate how long is the connected length of packed EPBs */ - myconn = Lepb + 2; - if ((Depb & 0x40) == 0) /* not latest in header */ - jpwl_epb_correct(j2k, /* J2K decompressor handle */ - buffer + Lepb + 2, /* pointer to next EPB in codestream buffer */ - 2, /* EPB type: should be of other type */ - 0, /* only EPB fields */ - 0, /* do not look after */ - &myconn, - NULL - ); - if (conn) - *conn += myconn; - - /*if (!conn) - printf("connected = %d\n", myconn);*/ - - /*cio_seek(j2k->cio, orig_pos); - return OPJ_TRUE;*/ - - /* post-data - the position of L4 buffer is at the end of currently connected EPBs - */ - if (!(L4_bufp)) - L4_buf = buffer + myconn; - else if (!(*L4_bufp)) - L4_buf = buffer + myconn; - else - L4_buf = *L4_bufp; - if (post_len == -1) - L4 = LDPepb - pre_len - 13; - else if (post_len == 0) - L4 = 0; - else - L4 = post_len; - - L3_buf = L2_buf; - - /* Do a further check here on the read parameters */ - if (L4 > (unsigned long) cio_numbytesleft(j2k->cio)) - /* overflow */ - return OPJ_FALSE; - - /* we are ready for decoding the remaining data */ - if (((Pepb & 0xF0000000) >> 28) == 1) { - /* CRC here */ - if ((16 * ((Pepb & 0x00000001) + 1)) == 16) { - - /* CRC-16 */ - unsigned short int mycrc = 0x0000, filecrc = 0x0000; - - /* compute the CRC field */ - remaining = L4; - while (remaining--) - jpwl_updateCRC16(&mycrc, *(L4_buf++)); - - /* read the CRC field */ - filecrc = *(L3_buf++) << 8; - filecrc |= *(L3_buf++); - - /* check the CRC field */ - if (mycrc == filecrc) { - if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_INFO, "- CRC is OK\n"); - } else { - if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_WARNING, "- CRC is KO (r=%d, c=%d)\n", filecrc, mycrc); - errflag = OPJ_TRUE; - } - } - - if ((16 * ((Pepb & 0x00000001) + 1)) == 32) { - - /* CRC-32 */ - unsigned long int mycrc = 0x00000000, filecrc = 0x00000000; - - /* compute the CRC field */ - remaining = L4; - while (remaining--) - jpwl_updateCRC32(&mycrc, *(L4_buf++)); - - /* read the CRC field */ - filecrc = *(L3_buf++) << 24; - filecrc |= *(L3_buf++) << 16; - filecrc |= *(L3_buf++) << 8; - filecrc |= *(L3_buf++); - - /* check the CRC field */ - if (mycrc == filecrc) { - if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_INFO, "- CRC is OK\n"); - } else { - if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_WARNING, "- CRC is KO (r=%d, c=%d)\n", filecrc, mycrc); - errflag = OPJ_TRUE; - } - } - - } else if (Pepb == 0xFFFFFFFF) { - /* no method */ - - /* advance without doing anything */ - remaining = L4; - while (remaining--) - L4_buf++; - - } else if ((((Pepb & 0xF0000000) >> 28) == 2) || (((Pepb & 0xF0000000) >> 28) == 0)) { - /* RS coding here */ - - if (((Pepb & 0xF0000000) >> 28) == 0) { - - k_post = k_pre; - n_post = n_pre; - - } else { - - k_post = 32; - n_post = (Pepb & 0x0000FF00) >> 8; - } - - /* Initialize RS structures */ - P = n_post - k_post; - NN_P = NN - P; - tt = (int) floor((float) P / 2.0F); /* again, correction capability */ - memset(codeword, 0, NN); - parityword = codeword + NN_P; - init_rs(NN_P); - - /* Correct post-data message words */ - /*L4_buf = buffer + Lepb + 2;*/ - L3_buf = L2_buf; - remaining = L4; - while (remaining) { - - /* always zero-pad codewords */ - /* (this is required, since after decoding the zeros in the long codeword - could change, and keep unchanged in subsequent calls) */ - memset(codeword, 0, NN); - - /* copy codeword buffer into message bytes */ - if (remaining < k_post) - memcpy(codeword, L4_buf, remaining); - else - memcpy(codeword, L4_buf, k_post); - - /* copy redundancy buffer in parity bytes */ - memcpy(parityword, L3_buf, P); - - /* Decode the buffer and possibly obtain corrected bytes */ - status = eras_dec_rs(codeword, NULL, 0); - if (status == -1) { - /*if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_WARNING, - "Possible decoding error in codeword @ position #%d\n", (L4_buf - (buffer + Lepb + 2)) / k_post);*/ - errflag = OPJ_TRUE; - - } else if (status == 0) { - /*if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_INFO, "codeword is correctly decoded\n");*/ - - } else if (status <= tt) { - /*if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_WARNING, "%d errors corrected in codeword\n", status);*/ - errnum += status; - - } else { - /*if (conn == NULL) - opj_event_msg(j2k->cinfo, EVT_WARNING, "EPB correction capability exceeded\n"); - return OPJ_FALSE;*/ - errflag = OPJ_TRUE; - } - - - /* advance parity buffer */ - if ((status >= 0) && (status <= tt)) - /* copy back corrected data only if all is OK */ - memcpy(L3_buf, parityword, P); - L3_buf += P; - - /* advance message buffer */ - if (remaining < k_post) { - if ((status >= 0) && (status <= tt)) - /* copy back corrected data only if all is OK */ - memcpy(L4_buf, codeword, remaining); - L4_buf += remaining; - remaining = 0; - - } else { - if ((status >= 0) && (status <= tt)) - /* copy back corrected data only if all is OK */ - memcpy(L4_buf, codeword, k_post); - L4_buf += k_post; - remaining -= k_post; - - } - } - } - - /* give back the L4_buf address */ - if (L4_bufp) - *L4_bufp = L4_buf; - - /* print summary */ - if (!conn) { - - if (errnum) - opj_event_msg(j2k->cinfo, EVT_INFO, "- %d symbol errors corrected (Ps=%.1e)\n", errnum, - (float) errnum / (float) LDPepb); - if (errflag) - opj_event_msg(j2k->cinfo, EVT_INFO, "- there were unrecoverable errors\n"); - - } - - cio_seek(j2k->cio, orig_pos); - - return OPJ_TRUE; + unsigned char **L4_bufp) +{ + + /* Operating buffer */ + unsigned char codeword[NN], *parityword; + + unsigned long int P, NN_P; + unsigned long int L1, L4; + int remaining, n_pre, k_pre, n_post, k_post; + + int status, tt; + + int orig_pos = cio_tell(j2k->cio); + + unsigned char *L1_buf, *L2_buf; + unsigned char *L3_buf, *L4_buf; + + unsigned long int LDPepb, Pepb; + unsigned short int Lepb; + unsigned char Depb; + char str1[25] = ""; + int myconn, errnum = 0; + opj_bool errflag = OPJ_FALSE; + + opj_cio_t *cio = j2k->cio; + + /* check for common errors */ + if (!buffer) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "The EPB pointer is a NULL buffer\n"); + return OPJ_FALSE; + } + + /* set bignesses */ + L1 = pre_len + 13; + + /* pre-data correction */ + switch (type) { + + case 0: + /* MH EPB */ + k_pre = 64; + n_pre = 160; + break; + + case 1: + /* TPH EPB */ + k_pre = 25; + n_pre = 80; + break; + + case 2: + /* other EPBs */ + k_pre = 13; + n_pre = 40; + break; + + case 3: + /* automatic setup */ + opj_event_msg(j2k->cinfo, EVT_ERROR, "Auto. setup not yet implemented\n"); + return OPJ_FALSE; + break; + + default: + /* unknown type */ + opj_event_msg(j2k->cinfo, EVT_ERROR, "Unknown expected EPB type\n"); + return OPJ_FALSE; + break; + + } + + /* Initialize RS structures */ + P = n_pre - k_pre; + NN_P = NN - P; + tt = (int) floor((float) P / 2.0F); /* correction capability of the code */ + memset(codeword, 0, NN); + parityword = codeword + NN_P; + init_rs(NN_P); + + /* Correct pre-data message words */ + L1_buf = buffer - pre_len; + L2_buf = buffer + 13; + remaining = L1; + while (remaining) { + + /* always zero-pad codewords */ + /* (this is required, since after decoding the zeros in the long codeword + could change, and keep unchanged in subsequent calls) */ + memset(codeword, 0, NN); + + /* copy codeword buffer into message bytes */ + if (remaining < k_pre) + memcpy(codeword, L1_buf, remaining); + else + memcpy(codeword, L1_buf, k_pre); + + /* copy redundancy buffer in parity bytes */ + memcpy(parityword, L2_buf, P); + + /* Decode the buffer and possibly obtain corrected bytes */ + status = eras_dec_rs(codeword, NULL, 0); + if (status == -1) { + /*if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_WARNING, + "Possible decoding error in codeword @ position #%d\n", (L1_buf - buffer) / k_pre);*/ + errflag = OPJ_TRUE; + /* we can try to safely get out from the function: + if we are here, either this is not an EPB or the first codeword + is too damaged to be helpful */ + /*return OPJ_FALSE;*/ + + } else if (status == 0) { + /*if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_INFO, "codeword is correctly decoded\n");*/ + + } else if (status <= tt) { + /* it has corrected 0 <= errs <= tt */ + /*if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_WARNING, "%d errors corrected in codeword\n", status);*/ + errnum += status; + + } else { + /*if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_WARNING, "EPB correction capability exceeded\n"); + return OPJ_FALSE;*/ + errflag = OPJ_TRUE; + } + + + /* advance parity buffer */ + if ((status >= 0) && (status <= tt)) + /* copy back corrected parity only if all is OK */ + memcpy(L2_buf, parityword, P); + L2_buf += P; + + /* advance message buffer */ + if (remaining < k_pre) { + if ((status >= 0) && (status <= tt)) + /* copy back corrected data only if all is OK */ + memcpy(L1_buf, codeword, remaining); + L1_buf += remaining; + remaining = 0; + + } else { + if ((status >= 0) && (status <= tt)) + /* copy back corrected data only if all is OK */ + memcpy(L1_buf, codeword, k_pre); + L1_buf += k_pre; + remaining -= k_pre; + + } + } + + /* print summary */ + if (!conn) { + + /*if (errnum) + opj_event_msg(j2k->cinfo, EVT_INFO, "+ %d symbol errors corrected (Ps=%.1e)\n", errnum, + (float) errnum / ((float) n_pre * (float) L1 / (float) k_pre));*/ + if (errflag) { + /*opj_event_msg(j2k->cinfo, EVT_INFO, "+ there were unrecoverable errors\n");*/ + return OPJ_FALSE; + } + + } + + /* presumably, now, EPB parameters are correct */ + /* let's get them */ + + /* Simply read the EPB parameters */ + if (conn) + cio->bp = buffer; + cio_skip(cio, 2); /* the marker */ + Lepb = cio_read(cio, 2); + Depb = cio_read(cio, 1); + LDPepb = cio_read(cio, 4); + Pepb = cio_read(cio, 4); + + /* What does Pepb tells us about the protection method? */ + if (((Pepb & 0xF0000000) >> 28) == 0) + sprintf(str1, "pred"); /* predefined */ + else if (((Pepb & 0xF0000000) >> 28) == 1) + sprintf(str1, "crc-%lu", 16 * ((Pepb & 0x00000001) + 1)); /* CRC mode */ + else if (((Pepb & 0xF0000000) >> 28) == 2) + sprintf(str1, "rs(%lu,32)", (Pepb & 0x0000FF00) >> 8); /* RS mode */ + else if (Pepb == 0xFFFFFFFF) + sprintf(str1, "nometh"); /* RS mode */ + else + sprintf(str1, "unknown"); /* unknown */ + + /* Now we write them to screen */ + if (!conn && post_len) + opj_event_msg(j2k->cinfo, EVT_INFO, + "EPB(%d): (%sl, %sp, %u), %lu, %s\n", + cio_tell(cio) - 13, + (Depb & 0x40) ? "" : "n", /* latest EPB or not? */ + (Depb & 0x80) ? "" : "n", /* packed or unpacked EPB? */ + (Depb & 0x3F), /* EPB index value */ + LDPepb, /*length of the data protected by the EPB */ + str1); /* protection method */ + + + /* well, we need to investigate how long is the connected length of packed EPBs */ + myconn = Lepb + 2; + if ((Depb & 0x40) == 0) /* not latest in header */ + jpwl_epb_correct(j2k, /* J2K decompressor handle */ + buffer + Lepb + 2, /* pointer to next EPB in codestream buffer */ + 2, /* EPB type: should be of other type */ + 0, /* only EPB fields */ + 0, /* do not look after */ + &myconn, + NULL + ); + if (conn) + *conn += myconn; + + /*if (!conn) + printf("connected = %d\n", myconn);*/ + + /*cio_seek(j2k->cio, orig_pos); + return OPJ_TRUE;*/ + + /* post-data + the position of L4 buffer is at the end of currently connected EPBs + */ + if (!(L4_bufp)) + L4_buf = buffer + myconn; + else if (!(*L4_bufp)) + L4_buf = buffer + myconn; + else + L4_buf = *L4_bufp; + if (post_len == -1) + L4 = LDPepb - pre_len - 13; + else if (post_len == 0) + L4 = 0; + else + L4 = post_len; + + L3_buf = L2_buf; + + /* Do a further check here on the read parameters */ + if (L4 > (unsigned long) cio_numbytesleft(j2k->cio)) + /* overflow */ + return OPJ_FALSE; + + /* we are ready for decoding the remaining data */ + if (((Pepb & 0xF0000000) >> 28) == 1) { + /* CRC here */ + if ((16 * ((Pepb & 0x00000001) + 1)) == 16) { + + /* CRC-16 */ + unsigned short int mycrc = 0x0000, filecrc = 0x0000; + + /* compute the CRC field */ + remaining = L4; + while (remaining--) + jpwl_updateCRC16(&mycrc, *(L4_buf++)); + + /* read the CRC field */ + filecrc = *(L3_buf++) << 8; + filecrc |= *(L3_buf++); + + /* check the CRC field */ + if (mycrc == filecrc) { + if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_INFO, "- CRC is OK\n"); + } else { + if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_WARNING, "- CRC is KO (r=%d, c=%d)\n", filecrc, mycrc); + errflag = OPJ_TRUE; + } + } + + if ((16 * ((Pepb & 0x00000001) + 1)) == 32) { + + /* CRC-32 */ + unsigned long int mycrc = 0x00000000, filecrc = 0x00000000; + + /* compute the CRC field */ + remaining = L4; + while (remaining--) + jpwl_updateCRC32(&mycrc, *(L4_buf++)); + + /* read the CRC field */ + filecrc = *(L3_buf++) << 24; + filecrc |= *(L3_buf++) << 16; + filecrc |= *(L3_buf++) << 8; + filecrc |= *(L3_buf++); + + /* check the CRC field */ + if (mycrc == filecrc) { + if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_INFO, "- CRC is OK\n"); + } else { + if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_WARNING, "- CRC is KO (r=%d, c=%d)\n", filecrc, mycrc); + errflag = OPJ_TRUE; + } + } + + } else if (Pepb == 0xFFFFFFFF) { + /* no method */ + + /* advance without doing anything */ + remaining = L4; + while (remaining--) + L4_buf++; + + } else if ((((Pepb & 0xF0000000) >> 28) == 2) || (((Pepb & 0xF0000000) >> 28) == 0)) { + /* RS coding here */ + + if (((Pepb & 0xF0000000) >> 28) == 0) { + + k_post = k_pre; + n_post = n_pre; + + } else { + + k_post = 32; + n_post = (Pepb & 0x0000FF00) >> 8; + } + + /* Initialize RS structures */ + P = n_post - k_post; + NN_P = NN - P; + tt = (int) floor((float) P / 2.0F); /* again, correction capability */ + memset(codeword, 0, NN); + parityword = codeword + NN_P; + init_rs(NN_P); + + /* Correct post-data message words */ + /*L4_buf = buffer + Lepb + 2;*/ + L3_buf = L2_buf; + remaining = L4; + while (remaining) { + + /* always zero-pad codewords */ + /* (this is required, since after decoding the zeros in the long codeword + could change, and keep unchanged in subsequent calls) */ + memset(codeword, 0, NN); + + /* copy codeword buffer into message bytes */ + if (remaining < k_post) + memcpy(codeword, L4_buf, remaining); + else + memcpy(codeword, L4_buf, k_post); + + /* copy redundancy buffer in parity bytes */ + memcpy(parityword, L3_buf, P); + + /* Decode the buffer and possibly obtain corrected bytes */ + status = eras_dec_rs(codeword, NULL, 0); + if (status == -1) { + /*if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_WARNING, + "Possible decoding error in codeword @ position #%d\n", (L4_buf - (buffer + Lepb + 2)) / k_post);*/ + errflag = OPJ_TRUE; + + } else if (status == 0) { + /*if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_INFO, "codeword is correctly decoded\n");*/ + + } else if (status <= tt) { + /*if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_WARNING, "%d errors corrected in codeword\n", status);*/ + errnum += status; + + } else { + /*if (conn == NULL) + opj_event_msg(j2k->cinfo, EVT_WARNING, "EPB correction capability exceeded\n"); + return OPJ_FALSE;*/ + errflag = OPJ_TRUE; + } + + + /* advance parity buffer */ + if ((status >= 0) && (status <= tt)) + /* copy back corrected data only if all is OK */ + memcpy(L3_buf, parityword, P); + L3_buf += P; + + /* advance message buffer */ + if (remaining < k_post) { + if ((status >= 0) && (status <= tt)) + /* copy back corrected data only if all is OK */ + memcpy(L4_buf, codeword, remaining); + L4_buf += remaining; + remaining = 0; + + } else { + if ((status >= 0) && (status <= tt)) + /* copy back corrected data only if all is OK */ + memcpy(L4_buf, codeword, k_post); + L4_buf += k_post; + remaining -= k_post; + + } + } + } + + /* give back the L4_buf address */ + if (L4_bufp) + *L4_bufp = L4_buf; + + /* print summary */ + if (!conn) { + + if (errnum) + opj_event_msg(j2k->cinfo, EVT_INFO, "- %d symbol errors corrected (Ps=%.1e)\n", errnum, + (float) errnum / (float) LDPepb); + if (errflag) + opj_event_msg(j2k->cinfo, EVT_INFO, "- there were unrecoverable errors\n"); + + } + + cio_seek(j2k->cio, orig_pos); + + return OPJ_TRUE; } -void jpwl_epc_write(opj_j2k_t *j2k, jpwl_epc_ms_t *epc, unsigned char *buf) { +void jpwl_epc_write(opj_j2k_t *j2k, jpwl_epc_ms_t *epc, unsigned char *buf) +{ - /* Marker */ - *(buf++) = (unsigned char) (J2K_MS_EPC >> 8); - *(buf++) = (unsigned char) (J2K_MS_EPC >> 0); + /* Marker */ + *(buf++) = (unsigned char) (J2K_MS_EPC >> 8); + *(buf++) = (unsigned char) (J2K_MS_EPC >> 0); - /* Lepc */ - *(buf++) = (unsigned char) (epc->Lepc >> 8); - *(buf++) = (unsigned char) (epc->Lepc >> 0); + /* Lepc */ + *(buf++) = (unsigned char) (epc->Lepc >> 8); + *(buf++) = (unsigned char) (epc->Lepc >> 0); - /* Pcrc */ - *(buf++) = (unsigned char) (epc->Pcrc >> 8); - *(buf++) = (unsigned char) (epc->Pcrc >> 0); + /* Pcrc */ + *(buf++) = (unsigned char) (epc->Pcrc >> 8); + *(buf++) = (unsigned char) (epc->Pcrc >> 0); - /* DL */ - *(buf++) = (unsigned char) (epc->DL >> 24); - *(buf++) = (unsigned char) (epc->DL >> 16); - *(buf++) = (unsigned char) (epc->DL >> 8); - *(buf++) = (unsigned char) (epc->DL >> 0); + /* DL */ + *(buf++) = (unsigned char) (epc->DL >> 24); + *(buf++) = (unsigned char) (epc->DL >> 16); + *(buf++) = (unsigned char) (epc->DL >> 8); + *(buf++) = (unsigned char) (epc->DL >> 0); - /* Pepc */ - *(buf++) = (unsigned char) (epc->Pepc >> 0); + /* Pepc */ + *(buf++) = (unsigned char) (epc->Pepc >> 0); - /* Data */ - /*memcpy(buf, epc->data, (size_t) epc->Lepc - 9);*/ - memset(buf, 0, (size_t) epc->Lepc - 9); + /* Data */ + /*memcpy(buf, epc->data, (size_t) epc->Lepc - 9);*/ + memset(buf, 0, (size_t) epc->Lepc - 9); - /* update markers struct */ - j2k_add_marker(j2k->cstr_info, J2K_MS_EPC, -1, epc->Lepc + 2); + /* update markers struct */ + j2k_add_marker(j2k->cstr_info, J2K_MS_EPC, -1, epc->Lepc + 2); } int jpwl_esds_add(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int *jwmarker_num, - int comps, unsigned char addrm, unsigned char ad_size, - unsigned char senst, unsigned char se_size, - double place_pos, int tileno) { + int comps, unsigned char addrm, unsigned char ad_size, + unsigned char senst, unsigned char se_size, + double place_pos, int tileno) +{ - return 0; + return 0; } -jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comp, - unsigned char addrm, unsigned char ad_size, - unsigned char senst, int se_size, int tileno, - unsigned long int svalnum, void *sensval) { - - jpwl_esd_ms_t *esd = NULL; - - /* Alloc space */ - if (!(esd = (jpwl_esd_ms_t *) opj_malloc((size_t) 1 * sizeof (jpwl_esd_ms_t)))) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for ESD MS\n"); - return NULL; - }; - - /* if relative sensitivity, activate byte range mode */ - if (senst == 0) - addrm = 1; - - /* size of sensval's ... */ - if ((ad_size != 0) && (ad_size != 2) && (ad_size != 4)) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "Address size %d for ESD MS is forbidden\n", ad_size); - return NULL; - } - if ((se_size != 1) && (se_size != 2)) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "Sensitivity size %d for ESD MS is forbidden\n", se_size); - return NULL; - } - - /* ... depends on the addressing mode */ - switch (addrm) { - - /* packet mode */ - case (0): - ad_size = 0; /* as per the standard */ - esd->sensval_size = (unsigned int)se_size; - break; - - /* byte range */ - case (1): - /* auto sense address size */ - if (ad_size == 0) - /* if there are more than 66% of (2^16 - 1) bytes, switch to 4 bytes - (we keep space for possible EPBs being inserted) */ - ad_size = (j2k->cstr_info->codestream_size > (1 * 65535 / 3)) ? 4 : 2; - esd->sensval_size = ad_size + ad_size + se_size; - break; - - /* packet range */ - case (2): - /* auto sense address size */ - if (ad_size == 0) - /* if there are more than 2^16 - 1 packets, switch to 4 bytes */ - ad_size = (j2k->cstr_info->packno > 65535) ? 4 : 2; - esd->sensval_size = ad_size + ad_size + se_size; - break; - - case (3): - opj_event_msg(j2k->cinfo, EVT_ERROR, "Address mode %d for ESD MS is unimplemented\n", addrm); - return NULL; - - default: - opj_event_msg(j2k->cinfo, EVT_ERROR, "Address mode %d for ESD MS is forbidden\n", addrm); - return NULL; - } - - /* set or unset sensitivity values */ - if (svalnum <= 0) { - - switch (senst) { - - /* just based on the portions of a codestream */ - case (0): - /* MH + no. of THs + no. of packets */ - svalnum = 1 + (j2k->cstr_info->tw * j2k->cstr_info->th) * (1 + j2k->cstr_info->packno); - break; - - /* all the ones that are based on the packets */ - default: - if (tileno < 0) - /* MH: all the packets and all the tiles info is written */ - svalnum = j2k->cstr_info->tw * j2k->cstr_info->th * j2k->cstr_info->packno; - else - /* TPH: only that tile info is written */ - svalnum = j2k->cstr_info->packno; - break; - - } - } - - /* fill private fields */ - esd->senst = senst; - esd->ad_size = ad_size; - esd->se_size = se_size; - esd->addrm = addrm; - esd->svalnum = svalnum; - esd->numcomps = j2k->image->numcomps; - esd->tileno = tileno; - - /* Set the ESD parameters */ - /* length, excluding data field */ - if (esd->numcomps < 257) - esd->Lesd = 4 + (unsigned short int) (esd->svalnum * esd->sensval_size); - else - esd->Lesd = 5 + (unsigned short int) (esd->svalnum * esd->sensval_size); - - /* component data field */ - if (comp >= 0) - esd->Cesd = comp; - else - /* we are averaging */ - esd->Cesd = 0; - - /* Pesd field */ - esd->Pesd = 0x00; - esd->Pesd |= (esd->addrm & 0x03) << 6; /* addressing mode */ - esd->Pesd |= (esd->senst & 0x07) << 3; /* sensitivity type */ - esd->Pesd |= ((esd->se_size >> 1) & 0x01) << 2; /* sensitivity size */ - esd->Pesd |= ((esd->ad_size >> 2) & 0x01) << 1; /* addressing size */ - esd->Pesd |= (comp < 0) ? 0x01 : 0x00; /* averaging components */ - - /* if pointer to sensval is NULL, we can fill data field by ourselves */ - if (!sensval) { - - /* old code moved to jpwl_esd_fill() */ - esd->data = NULL; - - } else { - /* we set the data field as the sensitivity values poinnter passed to the function */ - esd->data = (unsigned char *) sensval; - } - - return (esd); +jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comp, + unsigned char addrm, unsigned char ad_size, + unsigned char senst, int se_size, int tileno, + unsigned long int svalnum, void *sensval) +{ + + jpwl_esd_ms_t *esd = NULL; + + /* Alloc space */ + if (!(esd = (jpwl_esd_ms_t *) opj_malloc((size_t) 1 * sizeof (jpwl_esd_ms_t)))) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for ESD MS\n"); + return NULL; + }; + + /* if relative sensitivity, activate byte range mode */ + if (senst == 0) + addrm = 1; + + /* size of sensval's ... */ + if ((ad_size != 0) && (ad_size != 2) && (ad_size != 4)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Address size %d for ESD MS is forbidden\n", ad_size); + return NULL; + } + if ((se_size != 1) && (se_size != 2)) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "Sensitivity size %d for ESD MS is forbidden\n", se_size); + return NULL; + } + + /* ... depends on the addressing mode */ + switch (addrm) { + + /* packet mode */ + case (0): + ad_size = 0; /* as per the standard */ + esd->sensval_size = (unsigned int)se_size; + break; + + /* byte range */ + case (1): + /* auto sense address size */ + if (ad_size == 0) + /* if there are more than 66% of (2^16 - 1) bytes, switch to 4 bytes + (we keep space for possible EPBs being inserted) */ + ad_size = (j2k->cstr_info->codestream_size > (1 * 65535 / 3)) ? 4 : 2; + esd->sensval_size = ad_size + ad_size + se_size; + break; + + /* packet range */ + case (2): + /* auto sense address size */ + if (ad_size == 0) + /* if there are more than 2^16 - 1 packets, switch to 4 bytes */ + ad_size = (j2k->cstr_info->packno > 65535) ? 4 : 2; + esd->sensval_size = ad_size + ad_size + se_size; + break; + + case (3): + opj_event_msg(j2k->cinfo, EVT_ERROR, "Address mode %d for ESD MS is unimplemented\n", addrm); + return NULL; + + default: + opj_event_msg(j2k->cinfo, EVT_ERROR, "Address mode %d for ESD MS is forbidden\n", addrm); + return NULL; + } + + /* set or unset sensitivity values */ + if (svalnum <= 0) { + + switch (senst) { + + /* just based on the portions of a codestream */ + case (0): + /* MH + no. of THs + no. of packets */ + svalnum = 1 + (j2k->cstr_info->tw * j2k->cstr_info->th) * (1 + j2k->cstr_info->packno); + break; + + /* all the ones that are based on the packets */ + default: + if (tileno < 0) + /* MH: all the packets and all the tiles info is written */ + svalnum = j2k->cstr_info->tw * j2k->cstr_info->th * j2k->cstr_info->packno; + else + /* TPH: only that tile info is written */ + svalnum = j2k->cstr_info->packno; + break; + + } + } + + /* fill private fields */ + esd->senst = senst; + esd->ad_size = ad_size; + esd->se_size = se_size; + esd->addrm = addrm; + esd->svalnum = svalnum; + esd->numcomps = j2k->image->numcomps; + esd->tileno = tileno; + + /* Set the ESD parameters */ + /* length, excluding data field */ + if (esd->numcomps < 257) + esd->Lesd = 4 + (unsigned short int) (esd->svalnum * esd->sensval_size); + else + esd->Lesd = 5 + (unsigned short int) (esd->svalnum * esd->sensval_size); + + /* component data field */ + if (comp >= 0) + esd->Cesd = comp; + else + /* we are averaging */ + esd->Cesd = 0; + + /* Pesd field */ + esd->Pesd = 0x00; + esd->Pesd |= (esd->addrm & 0x03) << 6; /* addressing mode */ + esd->Pesd |= (esd->senst & 0x07) << 3; /* sensitivity type */ + esd->Pesd |= ((esd->se_size >> 1) & 0x01) << 2; /* sensitivity size */ + esd->Pesd |= ((esd->ad_size >> 2) & 0x01) << 1; /* addressing size */ + esd->Pesd |= (comp < 0) ? 0x01 : 0x00; /* averaging components */ + + /* if pointer to sensval is NULL, we can fill data field by ourselves */ + if (!sensval) { + + /* old code moved to jpwl_esd_fill() */ + esd->data = NULL; + + } else { + /* we set the data field as the sensitivity values poinnter passed to the function */ + esd->data = (unsigned char *) sensval; + } + + return (esd); } -opj_bool jpwl_esd_fill(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) { - - int i; - unsigned long int vv; - unsigned long int addr1 = 0L, addr2 = 0L; - double dvalue = 0.0, Omax2, tmp, TSE = 0.0, MSE, oldMSE = 0.0, PSNR, oldPSNR = 0.0; - unsigned short int pfpvalue; - unsigned long int addrmask = 0x00000000; - opj_bool doneMH = OPJ_FALSE, doneTPH = OPJ_FALSE; - - /* sensitivity values in image info are as follows: - - for each tile, distotile is the starting distortion for that tile, sum of all components - - for each packet in a tile, disto is the distortion reduction caused by that packet to that tile - - the TSE for a single tile should be given by distotile - sum(disto) , for all components - - the MSE for a single tile is given by TSE / nbpix , for all components - - the PSNR for a single tile is given by 10*log10( Omax^2 / MSE) , for all components - (Omax is given by 2^bpp - 1 for unsigned images and by 2^(bpp - 1) - 1 for signed images - */ - - /* browse all components and find Omax */ - Omax2 = 0.0; - for (i = 0; i < j2k->image->numcomps; i++) { - tmp = pow(2.0, (double) (j2k->image->comps[i].sgnd ? - (j2k->image->comps[i].bpp - 1) : (j2k->image->comps[i].bpp))) - 1; - if (tmp > Omax2) - Omax2 = tmp; - } - Omax2 = Omax2 * Omax2; - - /* if pointer of esd->data is not null, simply write down all the values byte by byte */ - if (esd->data) { - for (i = 0; i < (int) esd->svalnum; i++) - *(buf++) = esd->data[i]; - return OPJ_TRUE; - } - - /* addressing mask */ - if (esd->ad_size == 2) - addrmask = 0x0000FFFF; /* two bytes */ - else - addrmask = 0xFFFFFFFF; /* four bytes */ - - /* set on precise point where sensitivity starts */ - if (esd->numcomps < 257) - buf += 6; - else - buf += 7; - - /* let's fill the data fields */ - for (vv = (esd->tileno < 0) ? 0 : (j2k->cstr_info->packno * esd->tileno); vv < esd->svalnum; vv++) { - - int thistile = vv / j2k->cstr_info->packno, thispacket = vv % j2k->cstr_info->packno; - - /* skip for the hack some lines below */ - if (thistile == j2k->cstr_info->tw * j2k->cstr_info->th) - break; - - /* starting tile distortion */ - if (thispacket == 0) { - TSE = j2k->cstr_info->tile[thistile].distotile; - oldMSE = TSE / j2k->cstr_info->tile[thistile].numpix; - oldPSNR = 10.0 * log10(Omax2 / oldMSE); - } - - /* TSE */ - TSE -= j2k->cstr_info->tile[thistile].packet[thispacket].disto; - - /* MSE */ - MSE = TSE / j2k->cstr_info->tile[thistile].numpix; - - /* PSNR */ - PSNR = 10.0 * log10(Omax2 / MSE); - - /* fill the address range */ - switch (esd->addrm) { - - /* packet mode */ - case (0): - /* nothing, there is none */ - break; - - /* byte range */ - case (1): - /* start address of packet */ - addr1 = (j2k->cstr_info->tile[thistile].packet[thispacket].start_pos) & addrmask; - /* end address of packet */ - addr2 = (j2k->cstr_info->tile[thistile].packet[thispacket].end_pos) & addrmask; - break; - - /* packet range */ - case (2): - /* not implemented here */ - opj_event_msg(j2k->cinfo, EVT_WARNING, "Addressing mode packet_range is not implemented\n"); - break; - - /* unknown addressing method */ - default: - /* not implemented here */ - opj_event_msg(j2k->cinfo, EVT_WARNING, "Unknown addressing mode\n"); - break; - - } - - /* hack for writing relative sensitivity of MH and TPHs */ - if ((esd->senst == 0) && (thispacket == 0)) { - - /* possible MH */ - if ((thistile == 0) && !doneMH) { - /* we have to manage MH addresses */ - addr1 = 0; /* start of MH */ - addr2 = j2k->cstr_info->main_head_end; /* end of MH */ - /* set special dvalue for this MH */ - dvalue = -10.0; - doneMH = OPJ_TRUE; /* don't come here anymore */ - vv--; /* wrap back loop counter */ - - } else if (!doneTPH) { - /* we have to manage TPH addresses */ - addr1 = j2k->cstr_info->tile[thistile].start_pos; - addr2 = j2k->cstr_info->tile[thistile].end_header; - /* set special dvalue for this TPH */ - dvalue = -1.0; - doneTPH = OPJ_TRUE; /* don't come here till the next tile */ - vv--; /* wrap back loop counter */ - } - - } else - doneTPH = OPJ_FALSE; /* reset TPH counter */ - - /* write the addresses to the buffer */ - switch (esd->ad_size) { - - case (0): - /* do nothing */ - break; - - case (2): - /* two bytes */ - *(buf++) = (unsigned char) (addr1 >> 8); - *(buf++) = (unsigned char) (addr1 >> 0); - *(buf++) = (unsigned char) (addr2 >> 8); - *(buf++) = (unsigned char) (addr2 >> 0); - break; - - case (4): - /* four bytes */ - *(buf++) = (unsigned char) (addr1 >> 24); - *(buf++) = (unsigned char) (addr1 >> 16); - *(buf++) = (unsigned char) (addr1 >> 8); - *(buf++) = (unsigned char) (addr1 >> 0); - *(buf++) = (unsigned char) (addr2 >> 24); - *(buf++) = (unsigned char) (addr2 >> 16); - *(buf++) = (unsigned char) (addr2 >> 8); - *(buf++) = (unsigned char) (addr2 >> 0); - break; - - default: - /* do nothing */ - break; - } - - - /* let's fill the value field */ - switch (esd->senst) { - - /* relative sensitivity */ - case (0): - /* we just write down the packet ordering */ - if (dvalue == -10) - /* MH */ - dvalue = MAX_V1 + 1000.0; /* this will cause pfpvalue set to 0xFFFF */ - else if (dvalue == -1) - /* TPH */ - dvalue = MAX_V1 + 1000.0; /* this will cause pfpvalue set to 0xFFFF */ - else - /* packet: first is most important, and then in decreasing order - down to the last, which counts for 1 */ - dvalue = jpwl_pfp_to_double((unsigned short) (j2k->cstr_info->packno - thispacket), esd->se_size); - break; - - /* MSE */ - case (1): - /* !!! WRONG: let's put here disto field of packets !!! */ - dvalue = MSE; - break; - - /* MSE reduction */ - case (2): - dvalue = oldMSE - MSE; - oldMSE = MSE; - break; - - /* PSNR */ - case (3): - dvalue = PSNR; - break; - - /* PSNR increase */ - case (4): - dvalue = PSNR - oldPSNR; - oldPSNR = PSNR; - break; - - /* MAXERR */ - case (5): - dvalue = 0.0; - opj_event_msg(j2k->cinfo, EVT_WARNING, "MAXERR sensitivity mode is not implemented\n"); - break; - - /* TSE */ - case (6): - dvalue = TSE; - break; - - /* reserved */ - case (7): - dvalue = 0.0; - opj_event_msg(j2k->cinfo, EVT_WARNING, "Reserved sensitivity mode is not implemented\n"); - break; - - default: - dvalue = 0.0; - break; - } - - /* compute the pseudo-floating point value */ - pfpvalue = jpwl_double_to_pfp(dvalue, esd->se_size); - - /* write the pfp value to the buffer */ - switch (esd->se_size) { - - case (1): - /* one byte */ - *(buf++) = (unsigned char) (pfpvalue >> 0); - break; - - case (2): - /* two bytes */ - *(buf++) = (unsigned char) (pfpvalue >> 8); - *(buf++) = (unsigned char) (pfpvalue >> 0); - break; - } - - } - - return OPJ_TRUE; +opj_bool jpwl_esd_fill(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) +{ + + int i; + unsigned long int vv; + unsigned long int addr1 = 0L, addr2 = 0L; + double dvalue = 0.0, Omax2, tmp, TSE = 0.0, MSE, oldMSE = 0.0, PSNR, oldPSNR = 0.0; + unsigned short int pfpvalue; + unsigned long int addrmask = 0x00000000; + opj_bool doneMH = OPJ_FALSE, doneTPH = OPJ_FALSE; + + /* sensitivity values in image info are as follows: + - for each tile, distotile is the starting distortion for that tile, sum of all components + - for each packet in a tile, disto is the distortion reduction caused by that packet to that tile + - the TSE for a single tile should be given by distotile - sum(disto) , for all components + - the MSE for a single tile is given by TSE / nbpix , for all components + - the PSNR for a single tile is given by 10*log10( Omax^2 / MSE) , for all components + (Omax is given by 2^bpp - 1 for unsigned images and by 2^(bpp - 1) - 1 for signed images + */ + + /* browse all components and find Omax */ + Omax2 = 0.0; + for (i = 0; i < j2k->image->numcomps; i++) { + tmp = pow(2.0, (double) (j2k->image->comps[i].sgnd ? + (j2k->image->comps[i].bpp - 1) : (j2k->image->comps[i].bpp))) - 1; + if (tmp > Omax2) + Omax2 = tmp; + } + Omax2 = Omax2 * Omax2; + + /* if pointer of esd->data is not null, simply write down all the values byte by byte */ + if (esd->data) { + for (i = 0; i < (int) esd->svalnum; i++) + *(buf++) = esd->data[i]; + return OPJ_TRUE; + } + + /* addressing mask */ + if (esd->ad_size == 2) + addrmask = 0x0000FFFF; /* two bytes */ + else + addrmask = 0xFFFFFFFF; /* four bytes */ + + /* set on precise point where sensitivity starts */ + if (esd->numcomps < 257) + buf += 6; + else + buf += 7; + + /* let's fill the data fields */ + for (vv = (esd->tileno < 0) ? 0 : (j2k->cstr_info->packno * esd->tileno); vv < esd->svalnum; vv++) { + + int thistile = vv / j2k->cstr_info->packno, thispacket = vv % j2k->cstr_info->packno; + + /* skip for the hack some lines below */ + if (thistile == j2k->cstr_info->tw * j2k->cstr_info->th) + break; + + /* starting tile distortion */ + if (thispacket == 0) { + TSE = j2k->cstr_info->tile[thistile].distotile; + oldMSE = TSE / j2k->cstr_info->tile[thistile].numpix; + oldPSNR = 10.0 * log10(Omax2 / oldMSE); + } + + /* TSE */ + TSE -= j2k->cstr_info->tile[thistile].packet[thispacket].disto; + + /* MSE */ + MSE = TSE / j2k->cstr_info->tile[thistile].numpix; + + /* PSNR */ + PSNR = 10.0 * log10(Omax2 / MSE); + + /* fill the address range */ + switch (esd->addrm) { + + /* packet mode */ + case (0): + /* nothing, there is none */ + break; + + /* byte range */ + case (1): + /* start address of packet */ + addr1 = (j2k->cstr_info->tile[thistile].packet[thispacket].start_pos) & addrmask; + /* end address of packet */ + addr2 = (j2k->cstr_info->tile[thistile].packet[thispacket].end_pos) & addrmask; + break; + + /* packet range */ + case (2): + /* not implemented here */ + opj_event_msg(j2k->cinfo, EVT_WARNING, "Addressing mode packet_range is not implemented\n"); + break; + + /* unknown addressing method */ + default: + /* not implemented here */ + opj_event_msg(j2k->cinfo, EVT_WARNING, "Unknown addressing mode\n"); + break; + + } + + /* hack for writing relative sensitivity of MH and TPHs */ + if ((esd->senst == 0) && (thispacket == 0)) { + + /* possible MH */ + if ((thistile == 0) && !doneMH) { + /* we have to manage MH addresses */ + addr1 = 0; /* start of MH */ + addr2 = j2k->cstr_info->main_head_end; /* end of MH */ + /* set special dvalue for this MH */ + dvalue = -10.0; + doneMH = OPJ_TRUE; /* don't come here anymore */ + vv--; /* wrap back loop counter */ + + } else if (!doneTPH) { + /* we have to manage TPH addresses */ + addr1 = j2k->cstr_info->tile[thistile].start_pos; + addr2 = j2k->cstr_info->tile[thistile].end_header; + /* set special dvalue for this TPH */ + dvalue = -1.0; + doneTPH = OPJ_TRUE; /* don't come here till the next tile */ + vv--; /* wrap back loop counter */ + } + + } else + doneTPH = OPJ_FALSE; /* reset TPH counter */ + + /* write the addresses to the buffer */ + switch (esd->ad_size) { + + case (0): + /* do nothing */ + break; + + case (2): + /* two bytes */ + *(buf++) = (unsigned char) (addr1 >> 8); + *(buf++) = (unsigned char) (addr1 >> 0); + *(buf++) = (unsigned char) (addr2 >> 8); + *(buf++) = (unsigned char) (addr2 >> 0); + break; + + case (4): + /* four bytes */ + *(buf++) = (unsigned char) (addr1 >> 24); + *(buf++) = (unsigned char) (addr1 >> 16); + *(buf++) = (unsigned char) (addr1 >> 8); + *(buf++) = (unsigned char) (addr1 >> 0); + *(buf++) = (unsigned char) (addr2 >> 24); + *(buf++) = (unsigned char) (addr2 >> 16); + *(buf++) = (unsigned char) (addr2 >> 8); + *(buf++) = (unsigned char) (addr2 >> 0); + break; + + default: + /* do nothing */ + break; + } + + + /* let's fill the value field */ + switch (esd->senst) { + + /* relative sensitivity */ + case (0): + /* we just write down the packet ordering */ + if (dvalue == -10) + /* MH */ + dvalue = MAX_V1 + 1000.0; /* this will cause pfpvalue set to 0xFFFF */ + else if (dvalue == -1) + /* TPH */ + dvalue = MAX_V1 + 1000.0; /* this will cause pfpvalue set to 0xFFFF */ + else + /* packet: first is most important, and then in decreasing order + down to the last, which counts for 1 */ + dvalue = jpwl_pfp_to_double((unsigned short) (j2k->cstr_info->packno - thispacket), esd->se_size); + break; + + /* MSE */ + case (1): + /* !!! WRONG: let's put here disto field of packets !!! */ + dvalue = MSE; + break; + + /* MSE reduction */ + case (2): + dvalue = oldMSE - MSE; + oldMSE = MSE; + break; + + /* PSNR */ + case (3): + dvalue = PSNR; + break; + + /* PSNR increase */ + case (4): + dvalue = PSNR - oldPSNR; + oldPSNR = PSNR; + break; + + /* MAXERR */ + case (5): + dvalue = 0.0; + opj_event_msg(j2k->cinfo, EVT_WARNING, "MAXERR sensitivity mode is not implemented\n"); + break; + + /* TSE */ + case (6): + dvalue = TSE; + break; + + /* reserved */ + case (7): + dvalue = 0.0; + opj_event_msg(j2k->cinfo, EVT_WARNING, "Reserved sensitivity mode is not implemented\n"); + break; + + default: + dvalue = 0.0; + break; + } + + /* compute the pseudo-floating point value */ + pfpvalue = jpwl_double_to_pfp(dvalue, esd->se_size); + + /* write the pfp value to the buffer */ + switch (esd->se_size) { + + case (1): + /* one byte */ + *(buf++) = (unsigned char) (pfpvalue >> 0); + break; + + case (2): + /* two bytes */ + *(buf++) = (unsigned char) (pfpvalue >> 8); + *(buf++) = (unsigned char) (pfpvalue >> 0); + break; + } + + } + + return OPJ_TRUE; } -opj_bool jpwl_esd_write(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) { +opj_bool jpwl_esd_write(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) +{ - /* Marker */ - *(buf++) = (unsigned char) (J2K_MS_ESD >> 8); - *(buf++) = (unsigned char) (J2K_MS_ESD >> 0); + /* Marker */ + *(buf++) = (unsigned char) (J2K_MS_ESD >> 8); + *(buf++) = (unsigned char) (J2K_MS_ESD >> 0); - /* Lesd */ - *(buf++) = (unsigned char) (esd->Lesd >> 8); - *(buf++) = (unsigned char) (esd->Lesd >> 0); + /* Lesd */ + *(buf++) = (unsigned char) (esd->Lesd >> 8); + *(buf++) = (unsigned char) (esd->Lesd >> 0); - /* Cesd */ - if (esd->numcomps >= 257) - *(buf++) = (unsigned char) (esd->Cesd >> 8); - *(buf++) = (unsigned char) (esd->Cesd >> 0); + /* Cesd */ + if (esd->numcomps >= 257) + *(buf++) = (unsigned char) (esd->Cesd >> 8); + *(buf++) = (unsigned char) (esd->Cesd >> 0); - /* Pesd */ - *(buf++) = (unsigned char) (esd->Pesd >> 0); + /* Pesd */ + *(buf++) = (unsigned char) (esd->Pesd >> 0); - /* Data */ - if (esd->numcomps < 257) - memset(buf, 0xAA, (size_t) esd->Lesd - 4); - /*memcpy(buf, esd->data, (size_t) esd->Lesd - 4);*/ - else - memset(buf, 0xAA, (size_t) esd->Lesd - 5); - /*memcpy(buf, esd->data, (size_t) esd->Lesd - 5);*/ + /* Data */ + if (esd->numcomps < 257) + memset(buf, 0xAA, (size_t) esd->Lesd - 4); + /*memcpy(buf, esd->data, (size_t) esd->Lesd - 4);*/ + else + memset(buf, 0xAA, (size_t) esd->Lesd - 5); + /*memcpy(buf, esd->data, (size_t) esd->Lesd - 5);*/ - /* update markers struct */ - j2k_add_marker(j2k->cstr_info, J2K_MS_ESD, -1, esd->Lesd + 2); + /* update markers struct */ + j2k_add_marker(j2k->cstr_info, J2K_MS_ESD, -1, esd->Lesd + 2); - return OPJ_TRUE; + return OPJ_TRUE; } -unsigned short int jpwl_double_to_pfp(double V, int bytes) { - - unsigned short int em, e, m; - - switch (bytes) { - - case (1): - - if (V < MIN_V1) { - e = 0x0000; - m = 0x0000; - } else if (V > MAX_V1) { - e = 0x000F; - m = 0x000F; - } else { - e = (unsigned short int) (floor(log(V) * 1.44269504088896) / 4.0); - m = (unsigned short int) (0.5 + (V / (pow(2.0, (double) (4 * e))))); - } - em = ((e & 0x000F) << 4) + (m & 0x000F); - break; - - case (2): - - if (V < MIN_V2) { - e = 0x0000; - m = 0x0000; - } else if (V > MAX_V2) { - e = 0x001F; - m = 0x07FF; - } else { - e = (unsigned short int) floor(log(V) * 1.44269504088896) + 15; - m = (unsigned short int) (0.5 + 2048.0 * ((V / (pow(2.0, (double) e - 15.0))) - 1.0)); - } - em = ((e & 0x001F) << 11) + (m & 0x07FF); - break; - - default: - - em = 0x0000; - break; - }; - - return em; +unsigned short int jpwl_double_to_pfp(double V, int bytes) +{ + + unsigned short int em, e, m; + + switch (bytes) { + + case (1): + + if (V < MIN_V1) { + e = 0x0000; + m = 0x0000; + } else if (V > MAX_V1) { + e = 0x000F; + m = 0x000F; + } else { + e = (unsigned short int) (floor(log(V) * 1.44269504088896) / 4.0); + m = (unsigned short int) (0.5 + (V / (pow(2.0, (double) (4 * e))))); + } + em = ((e & 0x000F) << 4) + (m & 0x000F); + break; + + case (2): + + if (V < MIN_V2) { + e = 0x0000; + m = 0x0000; + } else if (V > MAX_V2) { + e = 0x001F; + m = 0x07FF; + } else { + e = (unsigned short int) floor(log(V) * 1.44269504088896) + 15; + m = (unsigned short int) (0.5 + 2048.0 * ((V / (pow(2.0, (double) e - 15.0))) - 1.0)); + } + em = ((e & 0x001F) << 11) + (m & 0x07FF); + break; + + default: + + em = 0x0000; + break; + }; + + return em; } -double jpwl_pfp_to_double(unsigned short int em, int bytes) { +double jpwl_pfp_to_double(unsigned short int em, int bytes) +{ - double V; + double V; - switch (bytes) { + switch (bytes) { - case 1: - V = (double) (em & 0x0F) * pow(2.0, (double) (em & 0xF0)); - break; + case 1: + V = (double) (em & 0x0F) * pow(2.0, (double) (em & 0xF0)); + break; - case 2: + case 2: - V = pow(2.0, (double) ((em & 0xF800) >> 11) - 15.0) * (1.0 + (double) (em & 0x07FF) / 2048.0); - break; + V = pow(2.0, (double) ((em & 0xF800) >> 11) - 15.0) * (1.0 + (double) (em & 0x07FF) / 2048.0); + break; - default: - V = 0.0; - break; + default: + V = 0.0; + break; - } + } - return V; + return V; } -opj_bool jpwl_update_info(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int jwmarker_num) { - - int mm; - unsigned long int addlen; - - opj_codestream_info_t *info = j2k->cstr_info; - int tileno, tpno, packno, numtiles = info->th * info->tw, numpacks = info->packno; - - if (!j2k || !jwmarker ) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "J2K handle or JPWL markers list badly allocated\n"); - return OPJ_FALSE; - } - - /* main_head_end: how many markers are there before? */ - addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - if (jwmarker[mm].pos < (unsigned long int) info->main_head_end) - addlen += jwmarker[mm].len + 2; - info->main_head_end += addlen; - - /* codestream_size: always increment with all markers */ - addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - addlen += jwmarker[mm].len + 2; - info->codestream_size += addlen; - - /* navigate through all the tiles */ - for (tileno = 0; tileno < numtiles; tileno++) { - - /* start_pos: increment with markers before SOT */ - addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].start_pos) - addlen += jwmarker[mm].len + 2; - info->tile[tileno].start_pos += addlen; - - /* end_header: increment with markers before of it */ - addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].end_header) - addlen += jwmarker[mm].len + 2; - info->tile[tileno].end_header += addlen; - - /* end_pos: increment with markers before the end of this tile */ - /* code is disabled, since according to JPWL no markers can be beyond TPH */ - addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].end_pos) - addlen += jwmarker[mm].len + 2; - info->tile[tileno].end_pos += addlen; - - /* navigate through all the tile parts */ - for (tpno = 0; tpno < info->tile[tileno].num_tps; tpno++) { - - /* start_pos: increment with markers before SOT */ - addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp[tpno].tp_start_pos) - addlen += jwmarker[mm].len + 2; - info->tile[tileno].tp[tpno].tp_start_pos += addlen; - - /* end_header: increment with markers before of it */ - addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp[tpno].tp_end_header) - addlen += jwmarker[mm].len + 2; - info->tile[tileno].tp[tpno].tp_end_header += addlen; - - /* end_pos: increment with markers before the end of this tile part */ - addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp[tpno].tp_end_pos) - addlen += jwmarker[mm].len + 2; - info->tile[tileno].tp[tpno].tp_end_pos += addlen; - - } - - /* navigate through all the packets in this tile */ - for (packno = 0; packno < numpacks; packno++) { - - /* start_pos: increment with markers before the packet */ - /* disabled for the same reason as before */ - addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - if (jwmarker[mm].pos <= (unsigned long int) info->tile[tileno].packet[packno].start_pos) - addlen += jwmarker[mm].len + 2; - info->tile[tileno].packet[packno].start_pos += addlen; - - /* end_ph_pos: increment with markers before the packet */ - /* disabled for the same reason as before */ - /*addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].packet[packno].end_ph_pos) - addlen += jwmarker[mm].len + 2;*/ - info->tile[tileno].packet[packno].end_ph_pos += addlen; - - /* end_pos: increment if marker is before the end of packet */ - /* disabled for the same reason as before */ - /*addlen = 0; - for (mm = 0; mm < jwmarker_num; mm++) - if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].packet[packno].end_pos) - addlen += jwmarker[mm].len + 2;*/ - info->tile[tileno].packet[packno].end_pos += addlen; - - } - } - - /* reorder the markers list */ - - return OPJ_TRUE; +opj_bool jpwl_update_info(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int jwmarker_num) +{ + + int mm; + unsigned long int addlen; + + opj_codestream_info_t *info = j2k->cstr_info; + int tileno, tpno, packno, numtiles = info->th * info->tw, numpacks = info->packno; + + if (!j2k || !jwmarker ) { + opj_event_msg(j2k->cinfo, EVT_ERROR, "J2K handle or JPWL markers list badly allocated\n"); + return OPJ_FALSE; + } + + /* main_head_end: how many markers are there before? */ + addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + if (jwmarker[mm].pos < (unsigned long int) info->main_head_end) + addlen += jwmarker[mm].len + 2; + info->main_head_end += addlen; + + /* codestream_size: always increment with all markers */ + addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + addlen += jwmarker[mm].len + 2; + info->codestream_size += addlen; + + /* navigate through all the tiles */ + for (tileno = 0; tileno < numtiles; tileno++) { + + /* start_pos: increment with markers before SOT */ + addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].start_pos) + addlen += jwmarker[mm].len + 2; + info->tile[tileno].start_pos += addlen; + + /* end_header: increment with markers before of it */ + addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].end_header) + addlen += jwmarker[mm].len + 2; + info->tile[tileno].end_header += addlen; + + /* end_pos: increment with markers before the end of this tile */ + /* code is disabled, since according to JPWL no markers can be beyond TPH */ + addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].end_pos) + addlen += jwmarker[mm].len + 2; + info->tile[tileno].end_pos += addlen; + + /* navigate through all the tile parts */ + for (tpno = 0; tpno < info->tile[tileno].num_tps; tpno++) { + + /* start_pos: increment with markers before SOT */ + addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp[tpno].tp_start_pos) + addlen += jwmarker[mm].len + 2; + info->tile[tileno].tp[tpno].tp_start_pos += addlen; + + /* end_header: increment with markers before of it */ + addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp[tpno].tp_end_header) + addlen += jwmarker[mm].len + 2; + info->tile[tileno].tp[tpno].tp_end_header += addlen; + + /* end_pos: increment with markers before the end of this tile part */ + addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp[tpno].tp_end_pos) + addlen += jwmarker[mm].len + 2; + info->tile[tileno].tp[tpno].tp_end_pos += addlen; + + } + + /* navigate through all the packets in this tile */ + for (packno = 0; packno < numpacks; packno++) { + + /* start_pos: increment with markers before the packet */ + /* disabled for the same reason as before */ + addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + if (jwmarker[mm].pos <= (unsigned long int) info->tile[tileno].packet[packno].start_pos) + addlen += jwmarker[mm].len + 2; + info->tile[tileno].packet[packno].start_pos += addlen; + + /* end_ph_pos: increment with markers before the packet */ + /* disabled for the same reason as before */ + /*addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].packet[packno].end_ph_pos) + addlen += jwmarker[mm].len + 2;*/ + info->tile[tileno].packet[packno].end_ph_pos += addlen; + + /* end_pos: increment if marker is before the end of packet */ + /* disabled for the same reason as before */ + /*addlen = 0; + for (mm = 0; mm < jwmarker_num; mm++) + if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].packet[packno].end_pos) + addlen += jwmarker[mm].len + 2;*/ + info->tile[tileno].packet[packno].end_pos += addlen; + + } + } + + /* reorder the markers list */ + + return OPJ_TRUE; } #endif /* USE_JPWL */ |
