fixed "tiffio" header inclusion to use user version on Win32 system only (otherwise...
[openjpeg.git] / jpwl / jpwl_lib.c
index 7ebe236f8811b7b5629ce5dbc3c8d11711971c37..90391b01c58a9f4e0ee8979178c9cede55bd135d 100644 (file)
@@ -32,6 +32,7 @@
 #ifdef USE_JPWL
 
 #include "../libopenjpeg/opj_includes.h"
+#include <limits.h>
 
 /** Minimum and maximum values for the double->pfp conversion */
 #define MIN_V1 0.0
@@ -143,10 +144,15 @@ int jpwl_epbs_add(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int *jwmarker_num,
                        /*      (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(
+               if ((epb_mark = jpwl_epb_create(
                        j2k, /* this encoder handle */
                        latest ? (dL4 < max_postlen) : false, /* is it the latest? */
                        packed, /* is it packed? */
@@ -155,12 +161,12 @@ int jpwl_epbs_add(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int *jwmarker_num,
                        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].epbmark = epb_mark; /* the EPB */
+                               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 */
@@ -194,10 +200,10 @@ jpwl_epb_ms_t *jpwl_epb_create(opj_j2k_t *j2k, bool latest, bool packed, int til
                                                  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 data_len = 0;*/
        unsigned short int L2, L3;
        unsigned long int L1, L4;
-       unsigned char *predata_in = NULL;
+       /*unsigned char *predata_in = NULL;*/
 
        bool insideMH = (tileno == -1);
 
@@ -289,7 +295,7 @@ jpwl_epb_ms_t *jpwl_epb_create(opj_j2k_t *j2k, bool latest, bool packed, int til
        return epb;
 }
 
-void jpwl_epb_write(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); 
@@ -317,6 +323,10 @@ void jpwl_epb_write(jpwl_epb_ms_t *epb, unsigned char *buf) {
        /* 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);
+
 };
 
 
@@ -325,7 +335,7 @@ jpwl_epc_ms_t *jpwl_epc_create(opj_j2k_t *j2k, bool esd_on, bool red_on, bool ep
        jpwl_epc_ms_t *epc = NULL;
 
        /* Alloc space */
-       if (!(epc = (jpwl_epc_ms_t *) malloc((size_t) 1 * sizeof (jpwl_epc_ms_t)))) {
+       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;
        };
@@ -586,6 +596,15 @@ bool jpwl_correct(opj_j2k_t *j2k) {
                                return 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 = false;
+                               opj_event_msg(j2k->cinfo, EVT_WARNING, "Couldn't find the MH EPB: disabling JPWL\n");
+                       }
+
                }
 
        }
@@ -780,6 +799,8 @@ bool jpwl_epb_correct(opj_j2k_t *j2k, unsigned char *buffer, int type, int pre_l
 
        case 3:
                /* automatic setup */
+               opj_event_msg(j2k->cinfo, EVT_ERROR, "Auto. setup not yet implemented\n");
+               return false;
                break;
 
        default:
@@ -901,9 +922,9 @@ bool jpwl_epb_correct(opj_j2k_t *j2k, unsigned char *buffer, int type, int pre_l
        if (((Pepb & 0xF0000000) >> 28) == 0)
                sprintf(str1, "pred"); /* predefined */
        else if (((Pepb & 0xF0000000) >> 28) == 1)
-               sprintf(str1, "crc-%d", 16 * ((Pepb & 0x00000001) + 1)); /* CRC mode */
+               sprintf(str1, "crc-%lu", 16 * ((Pepb & 0x00000001) + 1)); /* CRC mode */
        else if (((Pepb & 0xF0000000) >> 28) == 2)
-               sprintf(str1, "rs(%d,32)", (Pepb & 0x0000FF00) >> 8); /* RS mode */
+               sprintf(str1, "rs(%lu,32)", (Pepb & 0x0000FF00) >> 8); /* RS mode */
        else if (Pepb == 0xFFFFFFFF)
                sprintf(str1, "nometh"); /* RS mode */
        else
@@ -1139,7 +1160,7 @@ bool jpwl_epb_correct(opj_j2k_t *j2k, unsigned char *buffer, int type, int pre_l
        return true;
 }
 
-void jpwl_epc_write(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); 
@@ -1165,6 +1186,10 @@ void jpwl_epc_write(jpwl_epc_ms_t *epc, unsigned char *buf) {
        /* 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);
+
 };
 
 int jpwl_esds_add(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int *jwmarker_num,
@@ -1182,7 +1207,7 @@ jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comp, unsigned char addrm, un
        jpwl_esd_ms_t *esd = NULL;
 
        /* Alloc space */
-       if (!(esd = (jpwl_esd_ms_t *) malloc((size_t) 1 * sizeof (jpwl_esd_ms_t)))) {
+       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;
        };
@@ -1225,7 +1250,7 @@ jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comp, unsigned char addrm, un
                /* 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->num > 65535) ? 4 : 2;
+                       ad_size = (j2k->cstr_info->packno > 65535) ? 4 : 2;
                esd->sensval_size = ad_size + ad_size + se_size; 
                break;
 
@@ -1246,17 +1271,17 @@ jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comp, unsigned char addrm, un
                /* 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->num);
+                       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->num;
+                               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->num;
+                               svalnum = j2k->cstr_info->packno;
                        break;
 
                }
@@ -1311,8 +1336,8 @@ 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, addr2;
-       double dvalue, Omax2, tmp, TSE, MSE, oldMSE, PSNR, oldPSNR;
+       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;
        bool doneMH = false, doneTPH = false;
@@ -1356,9 +1381,9 @@ bool jpwl_esd_fill(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) {
                buf += 7;
 
        /* let's fill the data fields */
-       for (vv = (esd->tileno < 0) ? 0 : (j2k->cstr_info->num * esd->tileno); vv < esd->svalnum; vv++) {
+       for (vv = (esd->tileno < 0) ? 0 : (j2k->cstr_info->packno * esd->tileno); vv < esd->svalnum; vv++) {
 
-               int thistile = vv / j2k->cstr_info->num, thispacket = vv % j2k->cstr_info->num;
+               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)
@@ -1367,7 +1392,7 @@ bool jpwl_esd_fill(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) {
                /* starting tile distortion */
                if (thispacket == 0) {
                        TSE = j2k->cstr_info->tile[thistile].distotile;
-                       oldMSE = TSE / j2k->cstr_info->tile[thistile].nbpix;
+                       oldMSE = TSE / j2k->cstr_info->tile[thistile].numpix;
                        oldPSNR = 10.0 * log10(Omax2 / oldMSE);
                }
 
@@ -1375,7 +1400,7 @@ bool jpwl_esd_fill(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) {
                TSE -= j2k->cstr_info->tile[thistile].packet[thispacket].disto;
 
                /* MSE */
-               MSE = TSE / j2k->cstr_info->tile[thistile].nbpix;
+               MSE = TSE / j2k->cstr_info->tile[thistile].numpix;
 
                /* PSNR */
                PSNR = 10.0 * log10(Omax2 / MSE);
@@ -1484,7 +1509,7 @@ bool jpwl_esd_fill(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) {
                        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->num - thispacket), esd->se_size);
+                               dvalue = jpwl_pfp_to_double((unsigned short) (j2k->cstr_info->packno - thispacket), esd->se_size);
                        break;
 
                /* MSE */
@@ -1555,7 +1580,7 @@ bool jpwl_esd_fill(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) {
        return true;
 }
 
-void jpwl_esd_write(jpwl_esd_ms_t *esd, unsigned char *buf) {
+void jpwl_esd_write(opj_j2k_t *j2k, jpwl_esd_ms_t *esd, unsigned char *buf) {
 
        /* Marker */
        *(buf++) = (unsigned char) (J2K_MS_ESD >> 8); 
@@ -1580,6 +1605,10 @@ void jpwl_esd_write(jpwl_esd_ms_t *esd, unsigned char *buf) {
        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);
+
 }
 
 unsigned short int jpwl_double_to_pfp(double V, int bytes) {
@@ -1658,7 +1687,7 @@ bool jpwl_update_info(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int jwmarker_num)
        unsigned long int addlen;
 
        opj_codestream_info_t *info = j2k->cstr_info;
-       int tileno, tpno, packno, numtiles = info->th * info->tw, numpacks = info->num;
+       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");
@@ -1697,10 +1726,10 @@ bool jpwl_update_info(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int jwmarker_num)
 
                /* 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;
+               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;*/
+                               addlen += jwmarker[mm].len + 2;
                info->tile[tileno].end_pos += addlen;
 
                /* navigate through all the tile parts */
@@ -1709,23 +1738,23 @@ bool jpwl_update_info(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int jwmarker_num)
                        /* 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_start_pos[tpno])
+                               if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp[tpno].tp_start_pos)
                                        addlen += jwmarker[mm].len + 2;
-                       info->tile[tileno].tp_start_pos[tpno] += addlen;
+                       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_end_header[tpno])
+                               if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp[tpno].tp_end_header)
                                        addlen += jwmarker[mm].len + 2;
-                       info->tile[tileno].tp_end_header[tpno] += addlen;
+                       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_end_pos[tpno])
+                               if (jwmarker[mm].pos < (unsigned long int) info->tile[tileno].tp[tpno].tp_end_pos)
                                        addlen += jwmarker[mm].len + 2;
-                       info->tile[tileno].tp_end_pos[tpno] += addlen;
+                       info->tile[tileno].tp[tpno].tp_end_pos += addlen;
 
                }
 
@@ -1734,11 +1763,19 @@ bool jpwl_update_info(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int jwmarker_num)
                        
                        /* 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].start_pos)
+                               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].start_pos += addlen;
+                       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 */
@@ -1751,6 +1788,8 @@ bool jpwl_update_info(opj_j2k_t *j2k, jpwl_marker_t *jwmarker, int jwmarker_num)
                }
        }
 
+       /* reorder the markers list */
+
        return true;
 }