Accepting "j2c" as format for Encoding and Decoding. Modification in image_to_j2k.c.
[openjpeg.git] / libopenjpeg / tcd.c
index 8234020773f5ce52d5d816383f2fa846435ef206..06f021b3bcf17f38bcadfc7a60a1cc83f8967882 100644 (file)
@@ -1,9 +1,11 @@
 /*
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
  * Copyright (c) 2001-2003, David Janssens
  * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
- * Copyright (c) 2005, Herv Drolon, FreeImage Team
- * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006-2007, Parvatha Elangovan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -121,13 +123,6 @@ void tcd_destroy(opj_tcd_t *tcd) {
 void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno) {
        int tileno, compno, resno, bandno, precno, cblkno;
 
-       opj_tcd_tile_t *tile = NULL;            /* pointer to tcd->tile */
-       opj_tcd_tilecomp_t *tilec = NULL;       /* pointer to tcd->tilec */
-       opj_tcd_resolution_t *res = NULL;       /* pointer to tcd->res */
-       opj_tcd_band_t *band = NULL;            /* pointer to tcd->band */
-       opj_tcd_precinct_t *prc = NULL;         /* pointer to tcd->prc */
-       opj_tcd_cblk_t *cblk = NULL;            /* pointer to tcd->cblk */
-
        tcd->image = image;
        tcd->cp = cp;
        tcd->tcd_image->tw = cp->tw;
@@ -143,8 +138,7 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
                int q = curtileno / cp->tw;     /* .. coordonnees de la tile (q,p) q pour ligne et p pour colonne */
 
                /* opj_tcd_tile_t *tile=&tcd->tcd_image->tiles[tileno]; */
-               tcd->tile = tcd->tcd_image->tiles;
-               tile = tcd->tile;
+               opj_tcd_tile_t *tile = tcd->tcd_image->tiles;
 
                /* 4 borders of the tile rescale on the image if necessary */
                tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0);
@@ -157,11 +151,11 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
                /* Modification of the RATE >> */
                for (j = 0; j < tcp->numlayers; j++) {
                        tcp->rates[j] = tcp->rates[j] ? 
-                               int_ceildiv(tile->numcomps 
+                               ((float) (tile->numcomps 
                                        * (tile->x1 - tile->x0) 
                                        * (tile->y1 - tile->y0) 
-                                       * image->comps[0].prec, 
-                                       (tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)
+                                       * image->comps[0].prec))/ 
+                                       (tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)
                                        : 0;
 
                        if (tcp->rates[j]) {
@@ -179,9 +173,7 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
                for (compno = 0; compno < tile->numcomps; compno++) {
                        opj_tccp_t *tccp = &tcp->tccps[compno];
 
-                       /* opj_tcd_tilecomp_t *tilec=&tile->comps[compno]; */
-                       tcd->tilec = &tile->comps[compno];
-                       tilec = tcd->tilec;
+                       opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
 
                        /* border of each tile component (global) */
                        tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx);
@@ -202,9 +194,7 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
                                int cbgwidthexpn, cbgheightexpn;
                                int cblkwidthexpn, cblkheightexpn;
 
-                               /* opj_tcd_resolution_t *res=&tilec->resolutions[resno]; */
-                               tcd->res = &tilec->resolutions[resno];
-                               res = tcd->res;
+                               opj_tcd_resolution_t *res = &tilec->resolutions[resno];
                                
                                /* border for each resolution level (global) */
                                res->x0 = int_ceildivpow2(tilec->x0, levelno);
@@ -255,8 +245,7 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
                                        int gain, numbps;
                                        opj_stepsize_t *ss = NULL;
 
-                                       tcd->band = &res->bands[bandno];
-                                       band = tcd->band;
+                                       opj_tcd_band_t *band = &res->bands[bandno];
 
                                        band->bandno = resno == 0 ? 0 : bandno + 1;
                                        x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0;
@@ -298,9 +287,7 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
                                                int cbgxend = cbgxstart + (1 << cbgwidthexpn);
                                                int cbgyend = cbgystart + (1 << cbgheightexpn);
 
-                                               /* opj_tcd_precinct_t *prc=&band->precincts[precno]; */
-                                               tcd->prc = &band->precincts[precno];
-                                               prc = tcd->prc;
+                                               opj_tcd_precinct_t *prc = &band->precincts[precno];
 
                                                /* precinct size (global) */
                                                prc->x0 = int_max(cbgxstart, band->x0);
@@ -325,8 +312,7 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
                                                        int cblkxend = cblkxstart + (1 << cblkwidthexpn);
                                                        int cblkyend = cblkystart + (1 << cblkheightexpn);
                                                        
-                                                       tcd->cblk = &prc->cblks[cblkno];
-                                                       cblk = tcd->cblk;
+                                                       opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
 
                                                        /* code-block size (global) */
                                                        cblk->x0 = int_max(cblkxstart, prc->x0);
@@ -346,31 +332,20 @@ void tcd_malloc_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int c
 void tcd_free_encode(opj_tcd_t *tcd) {
        int tileno, compno, resno, bandno, precno;
 
-       opj_tcd_tile_t *tile = NULL;            /* pointer to tcd->tile         */
-       opj_tcd_tilecomp_t *tilec = NULL;       /* pointer to tcd->tilec        */
-       opj_tcd_resolution_t *res = NULL;       /* pointer to tcd->res          */
-       opj_tcd_band_t *band = NULL;            /* pointer to tcd->band         */
-       opj_tcd_precinct_t *prc = NULL;         /* pointer to tcd->prc          */
-
        for (tileno = 0; tileno < 1; tileno++) {
-               tcd->tile = tcd->tcd_image->tiles;
-               tile = tcd->tile;
+               opj_tcd_tile_t *tile = tcd->tcd_image->tiles;
 
                for (compno = 0; compno < tile->numcomps; compno++) {
-                       tcd->tilec = &tile->comps[compno];
-                       tilec = tcd->tilec;
+                       opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
 
                        for (resno = 0; resno < tilec->numresolutions; resno++) {
-                               tcd->res = &tilec->resolutions[resno];
-                               res = tcd->res;
+                               opj_tcd_resolution_t *res = &tilec->resolutions[resno];
 
                                for (bandno = 0; bandno < res->numbands; bandno++) {
-                                       tcd->band = &res->bands[bandno];
-                                       band = tcd->band;
+                                       opj_tcd_band_t *band = &res->bands[bandno];
 
                                        for (precno = 0; precno < res->pw * res->ph; precno++) {
-                                               tcd->prc = &band->precincts[precno];
-                                               prc = tcd->prc;
+                                               opj_tcd_precinct_t *prc = &band->precincts[precno];
 
                                                if (prc->incltree != NULL) {
                                                        tgt_destroy(prc->incltree);
@@ -400,13 +375,6 @@ void tcd_free_encode(opj_tcd_t *tcd) {
 void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int curtileno) {
        int tileno, compno, resno, bandno, precno, cblkno;
 
-       opj_tcd_tile_t *tile = NULL;            /* pointer to tcd->tile */
-       opj_tcd_tilecomp_t *tilec = NULL;       /* pointer to tcd->tilec */
-       opj_tcd_resolution_t *res = NULL;       /* pointer to tcd->res */
-       opj_tcd_band_t *band = NULL;            /* pointer to tcd->band */
-       opj_tcd_precinct_t *prc = NULL;         /* pointer to tcd->prc */
-       opj_tcd_cblk_t *cblk = NULL;            /* pointer to tcd->cblk */
-
        for (tileno = 0; tileno < 1; tileno++) {
                opj_tcp_t *tcp = &cp->tcps[curtileno];
                int j;
@@ -414,8 +382,7 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
                int p = curtileno % cp->tw;
                int q = curtileno / cp->tw;
 
-               tcd->tile = tcd->tcd_image->tiles;
-               tile = tcd->tile;
+               opj_tcd_tile_t *tile = tcd->tcd_image->tiles;
                
                /* 4 borders of the tile rescale on the image if necessary */
                tile->x0 = int_max(cp->tx0 + p * cp->tdx, image->x0);
@@ -429,12 +396,12 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
                /* Modification of the RATE >> */
                for (j = 0; j < tcp->numlayers; j++) {
                        tcp->rates[j] = tcp->rates[j] ? 
-                               int_ceildiv(tile->numcomps 
-                               * (tile->x1 - tile->x0) 
-                               * (tile->y1 - tile->y0) 
-                               * image->comps[0].prec, 
-                               (tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy)
-                               : 0;
+                                               ((float) (tile->numcomps 
+                                                               * (tile->x1 - tile->x0) 
+                                                               * (tile->y1 - tile->y0) 
+                                                               * image->comps[0].prec))/ 
+                                               (tcp->rates[j] * 8 * image->comps[0].dx * image->comps[0].dy
+                                               : 0;
 
                        if (tcp->rates[j]) {
                                if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) {
@@ -451,8 +418,7 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
                for (compno = 0; compno < tile->numcomps; compno++) {
                        opj_tccp_t *tccp = &tcp->tccps[compno];
                        
-                       tcd->tilec = &tile->comps[compno];
-                       tilec = tcd->tilec;
+                       opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
 
                        /* border of each tile component (global) */
                        tilec->x0 = int_ceildiv(tile->x0, image->comps[compno].dx);
@@ -472,8 +438,7 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
                                int cbgwidthexpn, cbgheightexpn;
                                int cblkwidthexpn, cblkheightexpn;
                                
-                               tcd->res = &tilec->resolutions[resno];
-                               res = tcd->res;
+                               opj_tcd_resolution_t *res = &tilec->resolutions[resno];
 
                                /* border for each resolution level (global) */
                                res->x0 = int_ceildivpow2(tilec->x0, levelno);
@@ -523,8 +488,7 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
                                        int gain, numbps;
                                        opj_stepsize_t *ss = NULL;
 
-                                       tcd->band = &res->bands[bandno];
-                                       band = tcd->band;
+                                       opj_tcd_band_t *band = &res->bands[bandno];
 
                                        band->bandno = resno == 0 ? 0 : bandno + 1;
                                        x0b = (band->bandno == 1) || (band->bandno == 3) ? 1 : 0;
@@ -557,8 +521,7 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
                                                int cbgxend = cbgxstart + (1 << cbgwidthexpn);
                                                int cbgyend = cbgystart + (1 << cbgheightexpn);
                                                
-                                               tcd->prc = &band->precincts[precno];
-                                               prc = tcd->prc;
+                                               opj_tcd_precinct_t *prc = &band->precincts[precno];
 
                                                /* precinct size (global) */
                                                prc->x0 = int_max(cbgxstart, band->x0);
@@ -592,8 +555,7 @@ void tcd_init_encode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int cur
                                                        int cblkxend = cblkxstart + (1 << cblkwidthexpn);
                                                        int cblkyend = cblkystart + (1 << cblkheightexpn);
 
-                                                       tcd->cblk = &prc->cblks[cblkno];
-                                                       cblk = tcd->cblk;
+                                                       opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
                                                        
                                                        /* code-block size (global) */
                                                        cblk->x0 = int_max(cblkxstart, prc->x0);
@@ -983,7 +945,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_image_in
        int compno, resno, bandno, precno, cblkno, passno, layno;
        double min, max;
        double cumdisto[100];   /* fixed_quality */
-       const double K = 1;             /* 1.1; // fixed_quality */
+       const double K = 1;             /* 1.1; fixed_quality */
        double maxSE = 0;
 
        opj_cp_t *cp = tcd->cp;
@@ -998,14 +960,19 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_image_in
        for (compno = 0; compno < tcd_tile->numcomps; compno++) {
                opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
                tilec->nbpix = 0;
+
                for (resno = 0; resno < tilec->numresolutions; resno++) {
                        opj_tcd_resolution_t *res = &tilec->resolutions[resno];
+
                        for (bandno = 0; bandno < res->numbands; bandno++) {
                                opj_tcd_band_t *band = &res->bands[bandno];
+
                                for (precno = 0; precno < res->pw * res->ph; precno++) {
                                        opj_tcd_precinct_t *prc = &band->precincts[precno];
+
                                        for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
                                                opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];
+
                                                for (passno = 0; passno < cblk->totalpasses; passno++) {
                                                        opj_tcd_pass_t *pass = &cblk->passes[passno];
                                                        int dr;
@@ -1042,28 +1009,29 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_image_in
                        * ((double)(tilec->nbpix));
        } /* compno */
        
-       /* add antonin index */
+       /* index file */
        if(image_info && image_info->index_on) {
-               opj_tile_info_t *info_TL = &image_info->tile[tcd->tcd_tileno];
-               info_TL->nbpix = tcd_tile->nbpix;
-               info_TL->distotile = tcd_tile->distotile;
-               info_TL->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double));
+               opj_tile_info_t *tile_info = &image_info->tile[tcd->tcd_tileno];
+               tile_info->nbpix = tcd_tile->nbpix;
+               tile_info->distotile = tcd_tile->distotile;
+               tile_info->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double));
        }
-       /* dda */
        
        for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
                double lo = min;
                double hi = max;
                int success = 0;
-               int maxlen = tcd_tcp->rates[layno] ? int_min(tcd_tcp->rates[layno], len) : len;
+               /* TODO: remove maxlen */
+               int maxlen = tcd_tcp->rates[layno] ? int_min(((int) ceil(tcd_tcp->rates[layno])), len) : len;
                double goodthresh = 0;
+               double stable_thresh = 0;
                int i;
                double distotarget;             /* fixed_quality */
                
                /* fixed_quality */
                distotarget = tcd_tile->distotile - ((K * maxSE) / pow((float)10, tcd_tcp->distoratio[layno] / 10));
         
-               if ((tcd_tcp->rates[layno]) || (cp->disto_alloc==0)) {
+               if ((tcd_tcp->rates[layno]) || (cp->disto_alloc == 0)) {
                        opj_t2_t *t2 = t2_create(tcd->cinfo, tcd->image, cp);
 
                        for (i = 0; i < 32; i++) {
@@ -1074,26 +1042,46 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_image_in
                                tcd_makelayer(tcd, layno, thresh, 0);
                                
                                if (cp->fixed_quality) {        /* fixed_quality */
-                                       distoachieved = layno == 0 ? 
-                                               tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];
-                                       if (distoachieved < distotarget) {
-                                               hi = thresh;
-                                               continue;
+                                       if(cp->cinema){
+                                               l = t2_encode_packets(t2,tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, image_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC);
+                                               if (l == -999) {
+                                                       lo = thresh;
+                                                       continue;
+                                               }else{
+                       distoachieved = layno == 0 ? 
+                                                       tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];
+                                                       if (distoachieved < distotarget) {
+                                                               hi=thresh; 
+                                                               stable_thresh = thresh;
+                                                               continue;
+                                                       }else{
+                                                               lo=thresh;
+                                                       }
+                                               }
+                                       }else{
+                                               distoachieved = (layno == 0) ? 
+                                                       tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
+                                               if (distoachieved < distotarget) {
+                                                       hi = thresh;
+                                                       stable_thresh = thresh;
+                                                       continue;
+                                               }
+                                               lo = thresh;
                                        }
-                                       lo = thresh;
                                } else {
-                                       l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, image_info);
+                                       l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, image_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC);
+                                       /* TODO: what to do with l ??? seek / tell ??? */
                                        /* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */
                                        if (l == -999) {
                                                lo = thresh;
                                                continue;
                                        }
                                        hi = thresh;
+                                       stable_thresh = thresh;
                                }
-                               
-                               success = 1;
-                               goodthresh = thresh;
                        }
+                       success = 1;
+                       goodthresh = stable_thresh;
                        t2_destroy(t2);
                } else {
                        success = 1;
@@ -1110,7 +1098,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_image_in
                tcd_makelayer(tcd, layno, goodthresh, 1);
         
                /* fixed_quality */
-               cumdisto[layno] = layno == 0 ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];     
+               cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]); 
        }
 
        return true;
@@ -1139,6 +1127,8 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op
        tcd_tcp = tcd->tcp;
        cp = tcd->cp;
 
+       encoding_time = opj_clock();    /* time needed to encode a tile */
+       if(tcd->cur_tp_num == 0){
        /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */
        if(image_info && image_info->index_on) {
                opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0];        /* based on component 0 */
@@ -1158,8 +1148,7 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op
        /* << INDEX */
        
        /*---------------TILE-------------------*/
-       encoding_time = opj_clock();    /* time needed to encode a tile */
-       
+
        for (compno = 0; compno < tile->numcomps; compno++) {
                int x, y;
 
@@ -1235,7 +1224,7 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op
                /* Fixed layer allocation */
                tcd_rateallocate_fixed(tcd);
        }
-       
+       }
        /*--------------TIER2------------------*/
 
        /* INDEX */
@@ -1244,18 +1233,21 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op
        }
 
        t2 = t2_create(tcd->cinfo, image, cp);
-       l = t2_encode_packets(t2, tileno, tile, tcd_tcp->numlayers, dest, len, image_info);
+       l = t2_encode_packets(t2,tileno, tile, tcd_tcp->numlayers, dest, len, image_info,tcd->tp_num,tcd->tp_pos,tcd->cur_pino,FINAL_PASS);
        t2_destroy(t2);
        
        /*---------------CLEAN-------------------*/
 
-       encoding_time = opj_clock() - encoding_time;
-       opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", encoding_time);
        
-       /* cleaning memory */
-       for (compno = 0; compno < tile->numcomps; compno++) {
-               tcd->tilec = &tile->comps[compno];
-               opj_free(tcd->tilec->data);
+       if(tcd->cur_tp_num == tcd->cur_totnum_tp - 1){
+               encoding_time = opj_clock() - encoding_time;
+               opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", encoding_time);
+       
+               /* cleaning memory */
+               for (compno = 0; compno < tile->numcomps; compno++) {
+                       opj_tcd_tilecomp_t *tilec = &tile->comps[compno];
+                       opj_free(tilec->data);
+               }
        }
        
        return l;