* Fixed_quality option added : specifying -q psnr1,psnr2,psnr3,... at the command...
authorAntonin Descampe <antonin@gmail.com>
Fri, 7 May 2004 13:50:47 +0000 (13:50 +0000)
committerAntonin Descampe <antonin@gmail.com>
Fri, 7 May 2004 13:50:47 +0000 (13:50 +0000)
* Old -q option is now available with -f

* The INDEX-file structure has been modified and is now like this :
------------------------------
image_width image_height
progression order
tile_width tile_height
nb_tiles_width nb_tiles_height
nb_components
nb_layers
nb_decompositions
foreach resolution_level {[precinct_width,precinct_height]}
main_header_end
codestream_size
foreach tile {
  tileno start_pos end_header end_pos squarred_error_total nb_pixels mean_squarred_error
}
foreach tile {
  foreach packet {
    packetno tileno layerno resno compno precinctno start_pos end_pos SE_reduction
  }
}
SE max
SE total
-----------------------------

codec/image_to_j2k.c
libopenjpeg/j2k.c
libopenjpeg/j2k.h
libopenjpeg/t1.c
libopenjpeg/tcd.c
libopenjpeg/tcd.h

index 5fcfcc57a0534f7379949690b6af7031fc2557c6..cbe329b3b2d46f28760c9ca40547499cd360b739 100644 (file)
@@ -300,6 +300,7 @@ int main(int argc, char **argv)
   cp.comment = NULL;
   cp.disto_alloc = 0;
   cp.fixed_alloc = 0;
+  cp.fixed_quality = 0;                //add fixed_quality
   /* img.PPT=0; */
 
   Tile_arg = 0;
@@ -309,7 +310,7 @@ int main(int argc, char **argv)
 
   while (1) {
     int c = getopt(argc, argv,
-                  "i:o:r:q:t:n:c:b:x:p:s:d:h:P:S:E:M:R:T:C:I");
+                  "i:o:r:q:f:t:n:c:b:x:p:s:d:h:P:S:E:M:R:T:C:I");
     if (c == -1)
       break;
     switch (c) {
@@ -375,7 +376,24 @@ int main(int argc, char **argv)
       cp.matrice = NULL;
       break;
       /* ----------------------------------------------------- */
-    case 'q':                  /* rates fixed */
+    case 'q':                  /* add fixed_quality */
+      s = optarg;
+      while (sscanf(s, "%f", &tcp_init->distoratio[tcp_init->numlayers]) ==
+            1) {
+       tcp_init->numlayers++;
+       while (*s && *s != ',') {
+         s++;
+       }
+       if (!*s)
+         break;
+       s++;
+      }
+      cp.fixed_quality = 1;
+      cp.matrice = NULL;
+      break;
+      /* dda */
+      /* ----------------------------------------------------- */
+    case 'f':                  /* mod fixed_quality (before : -q) */
       s = optarg;
       sscanf(s, "%d", &tcp_init->numlayers);
       s++;
@@ -563,11 +581,11 @@ int main(int argc, char **argv)
     return 1;
   }
 
-  if (cp.disto_alloc & cp.fixed_alloc) {
+  if (!(cp.disto_alloc ^ cp.fixed_alloc ^ cp.fixed_quality)) {
     fprintf(stderr,
-           "Error: option -r and -q can not be used together !!\n");
+           "Error: options -r -q and -f can not be used together !!\n");
     return 1;
-  }
+  } // mod fixed_quality
 
   /* if no rate entered, lossless by default */
   if (tcp_init->numlayers == 0) {
@@ -657,7 +675,10 @@ int main(int argc, char **argv)
     tcp = &cp.tcps[tileno];
     tcp->numlayers = tcp_init->numlayers;
     for (j = 0; j < tcp->numlayers; j++) {
-      tcp->rates[j] = tcp_init->rates[j];
+      if (cp.fixed_quality)   // add fixed_quality
+       tcp->distoratio[j] = tcp_init->distoratio[j];
+      else
+       tcp->rates[j] = tcp_init->rates[j];
     }
     tcp->csty = CSty;
     tcp->prg = Prog_order;
@@ -769,5 +790,6 @@ int main(int argc, char **argv)
     }
   }
 
+  system("pause");
   return 0;
 }
index df14b1736f1999f3e5017ff2fdeeefb77f0a7af4..a4c8630d15ca7ee1d70df2a26df08f58bc42e4a4 100644 (file)
@@ -1079,6 +1079,7 @@ LIBJ2K_API int j2k_encode(j2k_image_t * img, j2k_cp_t * cp, char *outfile,
 
   /* Creation of the index file     */
   if (info_IM.index_on) {
+    double DistoTotal = 0;
     info_IM.codestream_size = cio_tell() + pos_correction;     /* Correction 14/4/03 suite rmq de Patrick */
     INDEX = fopen(index, "w");
 
@@ -1090,43 +1091,45 @@ LIBJ2K_API int j2k_encode(j2k_image_t * img, j2k_cp_t * cp, char *outfile,
     fprintf(INDEX, "%d %d\n", info_IM.Im_w, info_IM.Im_h);
     fprintf(INDEX, "%d\n", info_IM.Prog);
     fprintf(INDEX, "%d %d\n", info_IM.Tile_x, info_IM.Tile_y);
+    fprintf(INDEX, "%d %d\n", j2k_cp->tw, j2k_cp->th);
     fprintf(INDEX, "%d\n", info_IM.Comp);
     fprintf(INDEX, "%d\n", info_IM.Layer);
     fprintf(INDEX, "%d\n", info_IM.Decomposition);
-    fprintf(INDEX, "%d %d\n", info_IM.pdx, info_IM.pdy);
+    for (resno=info_IM.Decomposition;resno>=0;resno--) {
+      fprintf(INDEX, "[%d,%d] ", (1<<info_IM.tile[0].pdx[resno]), (1<<info_IM.tile[0].pdx[resno])); //based on tile 0
+    }
+    fprintf(INDEX,"\n");
     fprintf(INDEX, "%d\n", info_IM.Main_head_end);
     fprintf(INDEX, "%d\n", info_IM.codestream_size);
-    fprintf(INDEX, "%f\n", info_IM.D_max);
     for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
-      fprintf(INDEX, "%d %d %d %d", info_IM.tile[tileno].num_tile,
+      fprintf(INDEX, "%4d %9d %9d %9d %9e %9d %9e\n",
+             info_IM.tile[tileno].num_tile,
              info_IM.tile[tileno].start_pos,
              info_IM.tile[tileno].end_header,
-             info_IM.tile[tileno].end_pos);
-      /*for (layno=0;layno<info_IM.Layer;layno++)
-         fprintf(INDEX, " %f",info_IM.tile[tileno].thresh[layno]);
-       */ fprintf(INDEX, "\n");
+             info_IM.tile[tileno].end_pos, info_IM.tile[tileno].distotile, info_IM.tile[tileno].nbpix,
+             info_IM.tile[tileno].distotile / info_IM.tile[tileno].nbpix);
     }
     for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
+      int start_pos, end_pos;
+      double disto = 0;
       pack_nb = 0;
+      /* fprintf(INDEX,
+             "pkno tileno layerno resno compno precno start_pos   end_pos       deltaSE        \n");*/
       if (info_IM.Prog == 0) { /* LRCP */
        for (layno = 0; layno < info_IM.Layer; layno++) {
          for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
            for (compno = 0; compno < info_IM.Comp; compno++) {
              for (precno = 0;
                   precno <
-                  info_IM.tile[tileno].pw *
-                  info_IM.tile[tileno].ph; precno++) {
-               fprintf(INDEX,
-                       "%d %d %d %d %d %d %d %d %.08f\n",
-                       pack_nb, tileno, layno, resno,
-                       compno, precno,
-                       info_IM.tile[tileno].
-                       packet[pack_nb].start_pos,
-                       info_IM.tile[tileno].
-                       packet[pack_nb].end_pos,
-                       info_IM.tile[tileno].
-                       packet[pack_nb].disto / info_IM.D_max);
-               /*fprintf(INDEX, "%d %d %d %d %d %d %d %d\n", pack_nb, tileno, layno, resno, compno, precno, info_IM.tile[tileno].packet[pack_nb].start_pos, info_IM.tile[tileno].packet[pack_nb].end_pos); */
+                  info_IM.tile[tileno].pw[resno] * info_IM.tile[tileno].ph[resno];
+                  precno++) {
+               start_pos = info_IM.tile[tileno].packet[pack_nb].start_pos;
+               end_pos = info_IM.tile[tileno].packet[pack_nb].end_pos;
+               disto = info_IM.tile[tileno].packet[pack_nb].disto;
+               fprintf(INDEX, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n",
+                       pack_nb, tileno, layno, resno, compno, precno,
+                       start_pos, end_pos, disto);
+               DistoTotal += disto;
                pack_nb++;
              }
            }
@@ -1136,14 +1139,14 @@ LIBJ2K_API int j2k_encode(j2k_image_t * img, j2k_cp_t * cp, char *outfile,
        for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
          for (layno = 0; layno < info_IM.Layer; layno++) {
            for (compno = 0; compno < info_IM.Comp; compno++) {
-             for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
-               /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
-               fprintf(INDEX, "%d %d %d %d %d %d %d %d\n",
-                       pack_nb, tileno, layno, resno,
-                       compno, precno,
-                       info_IM.tile[tileno].
-                       packet[pack_nb].start_pos,
-                       info_IM.tile[tileno].packet[pack_nb].end_pos);
+             for (precno = 0; precno < info_IM.tile[tileno].pw[resno] * info_IM.tile[tileno].ph[resno]; precno++) {
+               start_pos = info_IM.tile[tileno].packet[pack_nb].start_pos;
+               end_pos = info_IM.tile[tileno].packet[pack_nb].end_pos;
+               disto = info_IM.tile[tileno].packet[pack_nb].disto;
+               fprintf(INDEX, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n",
+                       pack_nb, tileno, layno, resno, compno, precno,
+                       start_pos, end_pos, disto);
+               DistoTotal += disto;
                pack_nb++;
              }
            }
@@ -1151,33 +1154,33 @@ LIBJ2K_API int j2k_encode(j2k_image_t * img, j2k_cp_t * cp, char *outfile,
        }
       } else if (info_IM.Prog == 2) {  /* RPCL */
        for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
-         for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
+         for (precno = 0; precno < info_IM.tile[tileno].pw[resno] * info_IM.tile[tileno].ph[resno]; precno++) {
            for (compno = 0; compno < info_IM.Comp; compno++) {
              for (layno = 0; layno < info_IM.Layer; layno++) {
-               /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
-               fprintf(INDEX, "%d %d %d %d %d %d %d %d\n",
-                       pack_nb, tileno, layno, resno,
-                       compno, precno,
-                       info_IM.tile[tileno].
-                       packet[pack_nb].start_pos,
-                       info_IM.tile[tileno].packet[pack_nb].end_pos);
+               start_pos = info_IM.tile[tileno].packet[pack_nb].start_pos;
+               end_pos = info_IM.tile[tileno].packet[pack_nb].end_pos;
+               disto = info_IM.tile[tileno].packet[pack_nb].disto;
+               fprintf(INDEX, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n",
+                       pack_nb, tileno, layno, resno, compno, precno,
+                       start_pos, end_pos, disto);
+               DistoTotal += disto;
                pack_nb++;
              }
            }
          }
        }
       } else if (info_IM.Prog == 3) {  /* PCRL */
-       for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
+       for (precno = 0; precno < info_IM.tile[tileno].pw[resno] * info_IM.tile[tileno].ph[resno]; precno++) {
          for (compno = 0; compno < info_IM.Comp; compno++) {
            for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
              for (layno = 0; layno < info_IM.Layer; layno++) {
-               /* fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
-               fprintf(INDEX, "%d %d %d %d %d %d %d %d\n",
-                       pack_nb, tileno, layno, resno,
-                       compno, precno,
-                       info_IM.tile[tileno].
-                       packet[pack_nb].start_pos,
-                       info_IM.tile[tileno].packet[pack_nb].end_pos);
+               start_pos = info_IM.tile[tileno].packet[pack_nb].start_pos;
+               end_pos = info_IM.tile[tileno].packet[pack_nb].end_pos;
+               disto = info_IM.tile[tileno].packet[pack_nb].disto;
+               fprintf(INDEX, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n",
+                       pack_nb, tileno, layno, resno, compno, precno,
+                       start_pos, end_pos, disto);
+               DistoTotal += disto;
                pack_nb++;
              }
            }
@@ -1186,16 +1189,16 @@ LIBJ2K_API int j2k_encode(j2k_image_t * img, j2k_cp_t * cp, char *outfile,
       } else {                 /* CPRL */
 
        for (compno = 0; compno < info_IM.Comp; compno++) {
-         for (precno = 0; precno < info_IM.pw * info_IM.ph; precno++) {
+         for (precno = 0; precno < info_IM.tile[tileno].pw[resno] * info_IM.tile[tileno].ph[resno]; precno++) {
            for (resno = 0; resno < info_IM.Decomposition + 1; resno++) {
              for (layno = 0; layno < info_IM.Layer; layno++) {
-               /*fprintf(INDEX,"%d %d %d %d %d %d %d %d %.04f\n",pack_nb,tileno,layno,resno,compno,precno,info_IM.tile[tileno].packet[pack_nb].start_pos,info_IM.tile[tileno].packet[pack_nb].end_pos,info_IM.tile[tileno].packet[pack_nb].disto/info_IM.D_max); */
-               fprintf(INDEX, "%d %d %d %d %d %d %d %d\n",
-                       pack_nb, tileno, layno, resno,
-                       compno, precno,
-                       info_IM.tile[tileno].
-                       packet[pack_nb].start_pos,
-                       info_IM.tile[tileno].packet[pack_nb].end_pos);
+               start_pos = info_IM.tile[tileno].packet[pack_nb].start_pos;
+               end_pos = info_IM.tile[tileno].packet[pack_nb].end_pos;
+               disto = info_IM.tile[tileno].packet[pack_nb].disto;
+               fprintf(INDEX, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n",
+                       pack_nb, tileno, layno, resno, compno, precno,
+                       start_pos, end_pos, disto);
+               DistoTotal += disto;
                pack_nb++;
              }
            }
@@ -1203,6 +1206,8 @@ LIBJ2K_API int j2k_encode(j2k_image_t * img, j2k_cp_t * cp, char *outfile,
        }
       }
     }
+    fprintf(INDEX, "SE max : %8e\n", info_IM.D_max);
+    fprintf(INDEX, "SE total : %.8e\n", DistoTotal);
     fclose(INDEX);
   }
 
@@ -1347,7 +1352,7 @@ int j2k_decode_jpt_stream(unsigned char *src, int len, j2k_image_t ** img,
       return 0;
     }
     /* data-bin read -> need to read a new header */
-    if ((unsigned int)(cio_tell() - position) == header.Msg_length) {
+    if ((unsigned int) (cio_tell() - position) == header.Msg_length) {
       jpt_read_Msg_Header(&header);
       position = cio_tell();
       if (header.Class_Id != 4) {      /* 4 : Tile data-bin message */
index dd8176b8b3cc3164311a1552b38f58a38cf572de..30764bc86aad3f01d85f0bbada761016d1bda8fc 100644 (file)
@@ -124,6 +124,7 @@ typedef struct {
   unsigned char *ppt_data;     /* packet header store there for futur use in t2_decode_packet       */
   int ppt;                     /* If ppt == 1 --> there was a PPT marker for the present tile       */
   int ppt_store;               /* Use in case of multiple marker PPT (number of info already store) */
+  float distoratio[100];       /* add fixed_quality */
   j2k_tccp_t *tccps;           /* tile-component coding parameters                                  */
 } j2k_tcp_t;
 
@@ -131,6 +132,7 @@ typedef struct {
   int image_type;              /* 0: PNM, PGM, PPM 1: PGX           */
   int disto_alloc;             /* Allocation by rate/distortion     */
   int fixed_alloc;             /* Allocation by fixed layer         */
+  int fixed_quality;           /* add fixed_quality */
   int reduce_on;               /* option reduce is used if reduce = 1 */
   int reduce_value;            /* if option reduce is used -> original dimension divided by 2^value */
   int tx0, ty0;                        /* XTOsiz, YTOsiz                    */
@@ -158,8 +160,11 @@ typedef struct {
   int start_pos;               /* Start position                                        */
   int end_header;              /* End position of the header                            */
   int end_pos;                 /* End position                                          */
-  int pw, ph;                  /* number of precinct by tile                            */
+  int pw[33], ph[33];          /* precinct number for each resolution level             */
+  int pdx[33], pdy[33];                /* precinct size (in power of 2), in X and Y for each resolution level */
   info_packet *packet;         /* information concerning packets inside tile            */
+  int nbpix;                   /* add fixed_quality                                     */
+  double distotile;            /* add fixed_quality                                     */
 } info_tile;                   /* index struct                                          */
 
 typedef struct {
@@ -174,8 +179,8 @@ typedef struct {
   int Comp;                    /* Component numbers                                     */
   int Layer;                   /* number of layer                                       */
   int Decomposition;           /* number of decomposition                               */
-  int pw, ph;                  /* nombre precinct in X and Y                            */
-  int pdx, pdy;                        /* size of precinct in X and Y                           */
+  //int pw, ph;                        /* nombre precinct in X and Y                            */
+  //int pdx, pdy;                      /* size of precinct in X and Y                           */
   int Main_head_end;           /* Main header position                                  */
   int codestream_size;         /* codestream's size                                     */
   info_tile *tile;             /* information concerning tiles inside image             */
index 2765c41830a701ed5c63b28cb251d301603a4c2d..deb6b98a8637c1614a845bbee3ea761449179629 100644 (file)
@@ -514,24 +514,22 @@ void t1_dec_clnpass(int w, int h, int bpno, int orient, int cblksty)
   }
 }                              /* VSC and  BYPASS by Antonin */
 
-double t1_getwmsedec(int nmsedec, int compno, int level, int orient,
-                    int bpno, int qmfbid, double stepsize)
+double t1_getwmsedec(int nmsedec, int compno, int level, int orient, int bpno, int qmfbid, double stepsize, int numcomps)      //mod fixed_quality
 {
   double w1, w2, wmsedec;
   if (qmfbid == 1) {
-    w1 = mct_getnorm(compno);
+    w1 = (numcomps > 1) ? mct_getnorm(compno) : 1;
     w2 = dwt_getnorm(level, orient);
   } else {                     /* if (qmfbid == 0) */
-    w1 = mct_getnorm_real(compno);
+    w1 = (numcomps > 1) ? mct_getnorm_real(compno) : 1;
     w2 = dwt_getnorm_real(level, orient);
   }
-  wmsedec = w1 * w2 * stepsize * (1 << bpno);
+  wmsedec = w1 * w2 * (stepsize / 8192.0) * (1 << bpno);
   wmsedec *= wmsedec * nmsedec / 8192.0;
   return wmsedec;
 }
 
-void t1_encode_cblk(tcd_cblk_t * cblk, int orient, int compno, int level,
-                   int qmfbid, double stepsize, int cblksty)
+void t1_encode_cblk(tcd_cblk_t * cblk, int orient, int compno, int level, int qmfbid, double stepsize, int cblksty, int numcomps, tcd_tile_t * tile)   //mod fixed_quality
 {
   int i, j;
   int w, h;
@@ -587,9 +585,9 @@ void t1_encode_cblk(tcd_cblk_t * cblk, int orient, int compno, int level,
       break;
     }
 
-    cumwmsedec +=
-      t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid,
-                   stepsize);
+    cumwmsedec += t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps);     //mod fixed_quality
+    tile->distotile += t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps);        //add antonin quality
+
 
     /* Code switch "RESTART" (i.e. TERMALL) */
     if ((cblksty & J2K_CCP_CBLKSTY_TERMALL)
@@ -728,6 +726,8 @@ void t1_encode_cblks(tcd_tile_t * tile, j2k_tcp_t * tcp)
   tcd_precinct_t *prc;
   tcd_cblk_t *cblk;
 
+  tile->distotile = 0;         //add fixed_quality
+
   for (compno = 0; compno < tile->numcomps; compno++) {
     tilec = &tile->comps[compno];
     for (resno = 0; resno < tilec->numresolutions; resno++) {
@@ -787,10 +787,7 @@ void t1_encode_cblks(tcd_tile_t * tile, j2k_tcp_t * tcp)
            } else if (orient == 1) {
              orient = 2;
            }
-           t1_encode_cblk(cblk, orient, compno,
-                          tilec->numresolutions - 1 - resno,
-                          tcp->tccps[compno].qmfbid,
-                          band->stepsize, tcp->tccps[compno].cblksty);
+           t1_encode_cblk(cblk, orient, compno, tilec->numresolutions - 1 - resno, tcp->tccps[compno].qmfbid, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps, tile);       //mod fixed_quality
          }                     /* cblkno */
        }                       /* precno */
       }                                /* bandno */
index 85b0003825cce30641c3ff6f6c348ec32c9af2ba..fb778347797212c0649c069c1477e8a034e14036 100644 (file)
@@ -131,10 +131,10 @@ void tcd_malloc_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno)
     for (j = 0; j < tcp->numlayers; j++) {
       tcp->rates[j] =
        int_ceildiv(tile->numcomps * (tile->x1 - tile->x0) *
-            (tile->y1 -
-             tile->y0) * img->comps[0].prec , (tcp->rates[j] * 8 *
-                                               img->comps[0].dx *
-                                               img->comps[0].dy));
+                   (tile->y1 -
+                    tile->y0) * img->comps[0].prec, (tcp->rates[j] * 8 *
+                                                     img->comps[0].dx *
+                                                     img->comps[0].dy));
       if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) {
        tcp->rates[j] = tcp->rates[j - 1] + 20;
       } else {
@@ -390,10 +390,10 @@ void tcd_init_encode(j2k_image_t * img, j2k_cp_t * cp, int curtileno)
     for (j = 0; j < tcp->numlayers; j++) {
       tcp->rates[j] =
        int_ceildiv(tile->numcomps * (tile->x1 - tile->x0) *
-            (tile->y1 -
-             tile->y0) * img->comps[0].prec , (tcp->rates[j] * 8 *
-                                               img->comps[0].dx *
-                                               img->comps[0].dy));
+                   (tile->y1 -
+                    tile->y0) * img->comps[0].prec, (tcp->rates[j] * 8 *
+                                                     img->comps[0].dx *
+                                                     img->comps[0].dy));
       if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) {
        tcp->rates[j] = tcp->rates[j - 1] + 20;
       } else {
@@ -913,6 +913,9 @@ void tcd_rateallocate_fixed()
 void tcd_makelayer(int layno, double thresh, int final)
 {
   int compno, resno, bandno, precno, cblkno, passno;
+
+  tcd_tile->distolayer[layno] = 0;     //add fixed_quality
+
   for (compno = 0; compno < tcd_tile->numcomps; compno++) {
     tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
     for (resno = 0; resno < tilec->numresolutions; resno++) {
@@ -952,8 +955,12 @@ void tcd_makelayer(int layno, double thresh, int final)
                n = passno + 1;
            }
            layer->numpasses = n - cblk->numpassesinlayers;
-           if (!layer->numpasses)
+
+           if (!layer->numpasses) {
+             layer->disto = 0;
              continue;
+           }
+
            if (cblk->numpassesinlayers == 0) {
              layer->len = cblk->passes[n - 1].rate;
              layer->data = cblk->data;
@@ -969,6 +976,8 @@ void tcd_makelayer(int layno, double thresh, int final)
                cblk->passes[cblk->numpassesinlayers - 1].distortiondec;
            }
 
+           tcd_tile->distolayer[layno] += layer->disto;        //add fixed_quality
+
            if (final)
              cblk->numpassesinlayers = n;
          }
@@ -982,11 +991,17 @@ void tcd_rateallocate(unsigned char *dest, int len, info_image * info_IM)
 {
   int compno, resno, bandno, precno, cblkno, passno, layno;
   double min, max;
+  double cumdisto[100];                //add fixed_quality
+  const double K = 1;          // 1.1; //add fixed_quality
+  double maxSE = 0;
   min = DBL_MAX;
   max = 0;
 
+  tcd_tile->nbpix = 0;         //add fixed_quality
+
   for (compno = 0; compno < tcd_tile->numcomps; compno++) {
     tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];
+    tilec->nbpix = 0;
     for (resno = 0; resno < tilec->numresolutions; resno++) {
       tcd_resolution_t *res = &tilec->resolutions[resno];
       for (bandno = 0; bandno < res->numbands; bandno++) {
@@ -1018,15 +1033,27 @@ void tcd_rateallocate(unsigned char *dest, int len, info_image * info_IM)
                max = rdslope;
              }
            }                   /* passno */
+
+           tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0)); //add fixed_quality
+           tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));    //add fixed_quality
+
          }                     /* cbklno */
        }                       /* precno */
       }                                /* bandno */
     }                          /* resno */
+    maxSE+=(double)(((1<<tcd_img->comps[compno].prec)-1)*((1<<tcd_img->comps[compno].prec)-1))*(tilec->nbpix);
   }                            /* compno */
-  if (info_IM->index_on) {     /* Threshold for Marcela Index */
-    info_IM->tile[tcd_tileno].thresh =
+
+  /* add antonin index */
+  if (info_IM->index_on) {
+    info_tile *info_TL = &info_IM->tile[tcd_tileno];
+    info_TL->nbpix = tcd_tile->nbpix;
+    info_TL->distotile = tcd_tile->distotile;
+    info_TL->thresh =
       (double *) malloc(tcd_tcp->numlayers * sizeof(double));
   }
+  /* dda */
+
   for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
     volatile double lo = min;
     volatile double hi = max;
@@ -1035,25 +1062,43 @@ void tcd_rateallocate(unsigned char *dest, int len, info_image * info_IM)
     volatile double goodthresh;
     volatile int goodlen;
     volatile int i;
+    double distotarget;                //add fixed_quality
+
+    distotarget = tcd_tile->distotile - ((K * maxSE) / pow(10, tcd_tcp->distoratio[layno] / 10));      // add fixed_quality
 
     for (i = 0; i < 32; i++) {
       volatile double thresh = (lo + hi) / 2;
-      int l;
+      int l=0;
+      double distoachieved = 0;        // add fixed_quality
 
       tcd_makelayer(layno, thresh, 0);
 
-      l = t2_encode_packets(tcd_img, tcd_cp, tcd_tileno, tcd_tile,
-                           layno + 1, dest, maxlen, info_IM);
-      /* fprintf(stderr, "rate alloc: len=%d, max=%d\n", l, maxlen); */
-      if (l == -999) {
+      if (tcd_cp->fixed_quality) {     // add fixed_quality
+       distoachieved =
+         layno ==
+         0 ? tcd_tile->distolayer[0] : cumdisto[layno - 1] +
+         tcd_tile->distolayer[layno];
+       if (distoachieved < distotarget) {
+         hi = thresh;
+         continue;
+       }
        lo = thresh;
-       continue;
+      } else {
+       l =
+         t2_encode_packets(tcd_img, tcd_cp, tcd_tileno, tcd_tile,
+                           layno + 1, dest, maxlen, info_IM);
+       /* fprintf(stderr, "rate alloc: len=%d, max=%d\n", l, maxlen); */
+       if (l == -999) {
+         lo = thresh;
+         continue;
+       }
+       hi = thresh;
       }
 
-      hi = thresh;
       success = 1;
       goodthresh = thresh;
       goodlen = l;
+
     }
 
     if (!success) {
@@ -1064,6 +1109,10 @@ void tcd_rateallocate(unsigned char *dest, int len, info_image * info_IM)
       info_IM->tile[tcd_tileno].thresh[layno] = goodthresh;
     }
     tcd_makelayer(layno, goodthresh, 1);
+    cumdisto[layno] =
+      layno ==
+      0 ? tcd_tile->distolayer[0] : cumdisto[layno - 1] +
+      tcd_tile->distolayer[layno]; // add fixed_quality
   }
 }
 
@@ -1071,7 +1120,7 @@ int tcd_encode_tile_pxm(int tileno, unsigned char *dest, int len,
                        info_image * info_IM)
 {
   int compno;
-  int l;
+  int l,i;
   clock_t time7;
   tcd_tile_t *tile;
   j2k_tcp_t *tcp = &tcd_cp->tcps[0];
@@ -1083,16 +1132,16 @@ int tcd_encode_tile_pxm(int tileno, unsigned char *dest, int len,
   tile = tcd_tile;
   /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */
   if (info_IM->index_on) {
-    tcd_tilecomp_t *tilec_idx = &tile->comps[0];       /* old parser version */
-    tcd_resolution_t *res_idx = &tilec_idx->resolutions[0];    /* old parser version */
+    tcd_tilecomp_t *tilec_idx = &tile->comps[0];  //Based on Component 0
+    for (i=0;i<tilec_idx->numresolutions;i++) {
+      tcd_resolution_t *res_idx = &tilec_idx->resolutions[i];
 
-    info_IM->tile[tileno].pw = res_idx->pw;
-    info_IM->tile[tileno].ph = res_idx->ph;
+      info_IM->tile[tileno].pw[i] = res_idx->pw;
+      info_IM->tile[tileno].ph[i] = res_idx->ph;
 
-    info_IM->pw = res_idx->pw; /* old parser version */
-    info_IM->ph = res_idx->ph; /* old parser version */
-    info_IM->pdx = 1 << tccp->prcw[tccp->numresolutions - 1];
-    info_IM->pdy = 1 << tccp->prch[tccp->numresolutions - 1];
+      info_IM->tile[tileno].pdx[i] = tccp->prcw[i];
+      info_IM->tile[tileno].pdy[i] = tccp->prch[i];
+    }
   }
   /* << INDEX */
 
@@ -1190,7 +1239,7 @@ int tcd_encode_tile_pxm(int tileno, unsigned char *dest, int len,
 /*-----------RATE-ALLOCATE------------------*/
   info_IM->index_write = 0;    /* INDEX     */
 
-  if (tcd_cp->disto_alloc)
+  if (tcd_cp->disto_alloc || tcd_cp->fixed_quality)    // mod fixed_quality
     /* Normal Rate/distortion allocation */
     tcd_rateallocate(dest, len, info_IM);
   else
@@ -1220,7 +1269,7 @@ int tcd_encode_tile_pgx(int tileno, unsigned char *dest, int len,
                        info_image * info_IM)
 {
   int compno;
-  int l;
+  int l,i;
   clock_t time;
   tcd_tile_t *tile;
   j2k_tcp_t *tcp = &tcd_cp->tcps[0];
@@ -1232,14 +1281,16 @@ int tcd_encode_tile_pgx(int tileno, unsigned char *dest, int len,
   tile = tcd_tile;
   /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */
   if (info_IM->index_on) {
-    tcd_tilecomp_t *tilec_idx = &tile->comps[0];
-    tcd_resolution_t *res_idx = &tilec_idx->resolutions[0];
-    info_IM->tile[tileno].pw = res_idx->pw;
-    info_IM->tile[tileno].ph = res_idx->ph;
-    info_IM->pw = res_idx->pw; /* old parser version */
-    info_IM->ph = res_idx->ph; /* old parser version */
-    info_IM->pdx = 1 << tccp->prcw[tccp->numresolutions - 1];
-    info_IM->pdy = 1 << tccp->prch[tccp->numresolutions - 1];
+    tcd_tilecomp_t *tilec_idx = &tile->comps[0];  //Based on Component 0
+    for (i=0;i<tilec_idx->numresolutions;i++) {
+      tcd_resolution_t *res_idx = &tilec_idx->resolutions[i];
+
+      info_IM->tile[tileno].pw[i] = res_idx->pw;
+      info_IM->tile[tileno].ph[i] = res_idx->ph;
+
+      info_IM->tile[tileno].pdx[i] = tccp->prcw[i];
+      info_IM->tile[tileno].pdy[i] = tccp->prch[i];
+    }
   }
   /* << INDEX */
 /*---------------TILE-------------------*/
@@ -1333,11 +1384,10 @@ int tcd_encode_tile_pgx(int tileno, unsigned char *dest, int len,
   t1_encode_cblks(tile, tcd_tcp);
 
 /*-----------RATE-ALLOCATE------------------*/
-  info_IM->index_write = 0;    /* INDEX */
 
   info_IM->index_write = 0;    /* INDEX */
 
-  if (tcd_cp->disto_alloc)
+  if (tcd_cp->disto_alloc || tcd_cp->fixed_quality)    // mod fixed_quality
     /* Normal Rate/distortion allocation */
     tcd_rateallocate(dest, len, info_IM);
   else
index 11e541abea4eee9614c4f328140324b672942bd7..236a3a6b05cb3df6366950897933076a38d1d2f0 100644 (file)
@@ -98,12 +98,16 @@ typedef struct {
   int numresolutions;          /* number of resolutions level */
   tcd_resolution_t *resolutions;       /* resolutions information */
   int *data;                   /* data of the component */
+  int nbpix;                   /* add fixed_quality */
 } tcd_tilecomp_t;
 
 typedef struct {
   int x0, y0, x1, y1;          /* dimension of the tile : left upper corner (x0, y0) right low corner (x1,y1) */
   int numcomps;                        /* number of components in tile */
   tcd_tilecomp_t *comps;       /* Components information */
+  int nbpix;                   /* add fixed_quality */
+  double distotile;            /* add fixed_quality */
+  double distolayer[100];      /* add fixed_quality */
 } tcd_tile_t;
 
 typedef struct {