Improvement in the context rows for the upsampler.
authorviric@mandarina
Sun, 03 Dec 2006 21:55:32 +0100
changeset 74 832681041034
parent 73 2b5c70dbfc9b
child 75 327eef3fe747
Improvement in the context rows for the upsampler. It allows more than 1 row before and 1 row after the postprocessed row.
src/jpeg-7a/jdmainct.c
--- a/src/jpeg-7a/jdmainct.c	Sun Nov 26 16:53:17 2006 +0100
+++ b/src/jpeg-7a/jdmainct.c	Sun Dec 03 21:55:32 2006 +0100
@@ -17,6 +17,11 @@
 #include "jinclude.h"
 #include "jpeglib.h"
 
+enum { 
+	bcrgroups = 1,
+	fcrgroups = 1
+};
+static const int crgroups = bcrgroups + fcrgroups + 1;
 
 /*
  * In the current system design, the main buffer need never be a full-image
@@ -118,7 +123,7 @@
   JSAMPARRAY buffer[MAX_COMPONENTS];
 
   boolean buffer_full;		/* Have we gotten an iMCU row from decoder? */
-  JDIMENSION rowgroup_ctr;	/* counts row groups output to postprocessor */
+  int rowgroup_ctr;	/* counts row groups output to postprocessor */
 
   /* Remaining fields are only used in the context case. */
 
@@ -127,7 +132,7 @@
 
   int whichptr;			/* indicates which pointer set is now in use */
   int context_state;		/* process_data state machine status */
-  JDIMENSION rowgroups_avail;	/* row groups available to postprocessor */
+  int rowgroups_avail;	/* row groups available to postprocessor */
   JDIMENSION iMCU_row_ctr;	/* counts iMCU rows to detect image top/bot */
 } my_main_controller;
 
@@ -182,10 +187,10 @@
      */
     xbuf = (JSAMPARRAY)
       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				  2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
-    xbuf += rgroup;		/* want one row group at negative offsets */
+				  2 * (rgroup * (M + 2*crgroups) + fcrgroups) * SIZEOF(JSAMPROW));
+    xbuf += rgroup * (bcrgroups + fcrgroups);		/* want one row group at negative offsets */
     main->xbuffer[0][ci] = xbuf;
-    xbuf += rgroup * (M + 4);
+    xbuf += rgroup * (M + 2*crgroups);
     main->xbuffer[1][ci] = xbuf;
   }
 }
@@ -214,21 +219,21 @@
     xbuf1 = main->xbuffer[1][ci];
     /* First copy the workspace pointers as-is */
     buf = main->buffer[ci];
-    for (i = 0; i < rgroup * (M + 2); i++) {
+    for (i = 0; i < rgroup * (M + crgroups); i++) {
       xbuf0[i] = xbuf1[i] = buf[i];
     }
     /* In the second list, put the last four row groups in swapped order */
-    for (i = 0; i < rgroup * 2; i++) {
-      xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
-      xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
+    for (i = 0; i < rgroup * crgroups; i++) {
+      xbuf1[rgroup*(M-crgroups) + i] = buf[rgroup*M + i];
+      xbuf1[rgroup*M + i] = buf[rgroup*(M-crgroups) + i];
     }
     /* The wraparound pointers at top and bottom will be filled later
      * (see set_wraparound_pointers, below).  Initially we want the "above"
      * pointers to duplicate the first actual data line.  This only needs
      * to happen in xbuffer[0].
      */
-    for (i = 0; i < rgroup; i++) {
-      xbuf0[i - rgroup] = xbuf0[0];
+    for (i = 0; i < rgroup*(bcrgroups + fcrgroups); i++) {
+      xbuf0[i - rgroup*(bcrgroups + fcrgroups)] = xbuf0[0];
     }
   }
 }
@@ -252,11 +257,13 @@
       cinfo->min_DCT_scaled_size; /* height of a row group of component */
     xbuf0 = main->xbuffer[0][ci];
     xbuf1 = main->xbuffer[1][ci];
+    for (i = 0; i < rgroup*(bcrgroups + fcrgroups); i++) {
+      xbuf0[i - rgroup*(bcrgroups + fcrgroups)] = xbuf0[rgroup*(M+1) + i];
+      xbuf1[i - rgroup*(bcrgroups + fcrgroups)] = xbuf1[rgroup*(M+1) + i];
+    }
     for (i = 0; i < rgroup; i++) {
-      xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
-      xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
-      xbuf0[rgroup*(M+2) + i] = xbuf0[i];
-      xbuf1[rgroup*(M+2) + i] = xbuf1[i];
+      xbuf0[rgroup*(M+crgroups) + i] = xbuf0[i];
+      xbuf1[rgroup*(M+crgroups) + i] = xbuf1[i];
     }
   }
 }
@@ -375,6 +382,98 @@
   }
 }
 
+static void
+showpointers(j_decompress_ptr cinfo, int which, int ci)
+{
+	my_main_ptr main = (my_main_ptr) cinfo->main;
+	int i;
+  	int M = cinfo->min_DCT_scaled_size;
+	int rgroup;
+  	jpeg_component_info *compptr;
+	fprintf(stderr, "Pointers for %i[ci=%i]:\n", which, ci);
+
+	compptr = &cinfo->comp_info[ci];
+	rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+		cinfo->min_DCT_scaled_size; /* height of a row group of component */
+
+	for(i=-(bcrgroups + fcrgroups); i<rgroup * (M+2*crgroups) - (bcrgroups + fcrgroups); i++)
+	{
+		fprintf(stderr, " xbuf%i[%2i]: %i\n", which, i,
+				(main->xbuffer[which][ci][i] -
+				main->buffer[ci][0]) /
+				(main->buffer[ci][1] - main->buffer[ci][0]));
+	}
+}
+
+static int storearray[3][300];
+
+static void
+storecontext(j_decompress_ptr cinfo, JSAMPIMAGE xbufs)
+{
+  my_main_ptr main = (my_main_ptr) cinfo->main;
+  int ci, i, rgroup;
+  int M = cinfo->min_DCT_scaled_size;
+	int xrow;
+  jpeg_component_info *compptr;
+  JSAMPARRAY buf, xbuf;
+  int realrow[3]; /* per component */
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++)
+  {
+    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+      cinfo->min_DCT_scaled_size; /* height of a row group of component */
+    buf = main->buffer[ci];
+    xbuf = xbufs[ci];
+    /* Calculate the realrow according to imcu */
+    realrow[ci] = main->iMCU_row_ctr * rgroup * cinfo->min_DCT_scaled_size;
+    for(i=0; i<compptr->v_samp_factor * compptr->DCT_scaled_size; i++)
+    {
+    	xrow = (xbuf[i] - buf[0]) / (buf[1] - buf[0]);
+      fprintf(stderr, " [ci=%i] Storing row %i in buffer pos %i\n",
+        ci, realrow[ci], xrow);
+      storearray[ci][xrow] = realrow[ci]++;
+    }
+  }
+}
+
+static void checkcontext(j_decompress_ptr cinfo, JSAMPIMAGE xbufs,
+    int row_ctr, int rows_available)
+{
+  my_main_ptr main = (my_main_ptr) cinfo->main;
+  int ci, i, j, rgroup;
+  int M = cinfo->min_DCT_scaled_size;
+	int xrow;
+  jpeg_component_info *compptr;
+  JSAMPARRAY buf, xbuf;
+  int baserow;
+
+  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+       ci++, compptr++)
+  {
+    int realrow;
+
+    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+      cinfo->min_DCT_scaled_size; /* height of a row group of component */
+    buf = main->buffer[ci];
+    xbuf = xbufs[ci];
+    /* Calculate the realrow according to imcu */
+    baserow = rgroup * row_ctr;
+    realrow = (xbuf[baserow] - buf[0]) / (buf[1] - buf[0]);
+    fprintf(stderr, "  ci=%i baserow=%i realrow=%i\n", ci, baserow, realrow);
+    for(i=-bcrgroups; i<=fcrgroups; i++)
+    {
+      for(j=0; j<rgroup; j++)
+      {
+    	  xrow = (xbuf[baserow+i*rgroup+j] - buf[0]) / (buf[1] - buf[0]);
+        realrow = storearray[ci][xrow];
+        fprintf(stderr, " involved row[ci=%i]: %i xrow=%i\n", ci, realrow,
+            xrow);
+      }
+    }
+  }
+}
+
 
 /*
  * Process some data.
@@ -390,6 +489,10 @@
 
   /* Read input data if we haven't filled the main buffer yet */
   if (! main->buffer_full) {
+    fprintf(stderr,"Readbuffer: (bef) r_ctr=%i r_a=%i o_r_c=%i o_r_a=%i ptr=%i\n",
+		    main->rowgroup_ctr, main->rowgroups_avail,
+		    *out_row_ctr, out_rows_avail, main->whichptr);
+    storecontext(cinfo, main->xbuffer[main->whichptr]);
     if (! (*cinfo->coef->decompress_data) (cinfo,
 					   main->xbuffer[main->whichptr]))
       return;			/* suspension forced, can do nothing more */
@@ -404,10 +507,19 @@
    */
   switch (main->context_state) {
   case CTX_POSTPONED_ROW:
+    fprintf(stderr,"CPR: (bef) r_ctr=%i r_a=%i o_r_c=%i o_r_a=%i\n",
+		    main->rowgroup_ctr, main->rowgroups_avail,
+		    *out_row_ctr, out_rows_avail);
+    showpointers(cinfo, main->whichptr, 1);
+    checkcontext(cinfo, main->xbuffer[main->whichptr], main->rowgroup_ctr,
+      main->rowgroups_avail);
     /* Call postprocessor using previously set pointers for postponed row */
     (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],
 			&main->rowgroup_ctr, main->rowgroups_avail,
 			output_buf, out_row_ctr, out_rows_avail);
+    fprintf(stderr,"CPR: (aft) r_ctr=%i r_a=%i o_r_c=%i o_r_a=%i\n",
+		    main->rowgroup_ctr, main->rowgroups_avail,
+		    *out_row_ctr, out_rows_avail);
     if (main->rowgroup_ctr < main->rowgroups_avail)
       return;			/* Need to suspend */
     main->context_state = CTX_PREPARE_FOR_IMCU;
@@ -415,9 +527,15 @@
       return;			/* Postprocessor exactly filled output buf */
     /*FALLTHROUGH*/
   case CTX_PREPARE_FOR_IMCU:
+    fprintf(stderr,"CPFI: (bef) r_ctr=%i r_a=%i, o_r_c=%i\n",
+		    main->rowgroup_ctr, main->rowgroups_avail,
+		    *out_row_ctr);
     /* Prepare to process first M-1 row groups of this iMCU row */
-    main->rowgroup_ctr = 0;
-    main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
+    if (main->iMCU_row_ctr == 1)
+    	main->rowgroup_ctr = 0;
+    else
+    	main->rowgroup_ctr = -fcrgroups;
+    main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - fcrgroups - 1);
     /* Check for bottom of image: if so, tweak pointers to "duplicate"
      * the last sample row, and adjust rowgroups_avail to ignore padding rows.
      */
@@ -426,10 +544,19 @@
     main->context_state = CTX_PROCESS_IMCU;
     /*FALLTHROUGH*/
   case CTX_PROCESS_IMCU:
+    fprintf(stderr,"CPI: (bef) r_ctr=%i r_a=%i o_r_c=%i o_r_a=%i\n",
+		    main->rowgroup_ctr, main->rowgroups_avail,
+		    *out_row_ctr, out_rows_avail);
+    showpointers(cinfo, main->whichptr, 1);
+    checkcontext(cinfo, main->xbuffer[main->whichptr], main->rowgroup_ctr,
+      main->rowgroups_avail);
     /* Call postprocessor using previously set pointers */
     (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],
 			&main->rowgroup_ctr, main->rowgroups_avail,
 			output_buf, out_row_ctr, out_rows_avail);
+    fprintf(stderr,"CPI: (aft) r_ctr=%i r_a=%i o_r_c=%i o_r_a=%i\n",
+		    main->rowgroup_ctr, main->rowgroups_avail,
+		    *out_row_ctr, out_rows_avail);
     if (main->rowgroup_ctr < main->rowgroups_avail)
       return;			/* Need to suspend */
     /* After the first iMCU, change wraparound pointers to normal state */
@@ -440,8 +567,8 @@
     main->buffer_full = FALSE;
     /* Still need to process last row group of this iMCU row, */
     /* which is saved at index M+1 of the other xbuffer */
-    main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
-    main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
+    main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + crgroups - 1 - fcrgroups);
+    main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + crgroups - fcrgroups);
     main->context_state = CTX_POSTPONED_ROW;
   }
 }
@@ -495,7 +622,7 @@
     if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */
       ERREXIT(cinfo, JERR_NOTIMPL);
     alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
-    ngroups = cinfo->min_DCT_scaled_size + 2;
+    ngroups = cinfo->min_DCT_scaled_size + crgroups;
   } else {
     ngroups = cinfo->min_DCT_scaled_size;
   }