reference/ocr-new/RLEPair.cc
changeset 0 6b8091ca909a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/reference/ocr-new/RLEPair.cc	Thu May 18 23:12:51 2006 +0200
@@ -0,0 +1,360 @@
+#include "system.h"
+#include "tcl_interface.h"
+
+
+
+
+/**** RLEPair.cc 
+  Member functions for RLEPairs
+  RLEPair functions defined in the function header
+  rev 10/20 Kathey Marsden 
+*/
+
+
+
+
+RLEPairs::RLEPairs(int rownum)
+:List()
+{
+  numPixels = 0;
+  row = rownum;
+}
+
+
+RLEPairs::~RLEPairs()
+{
+  for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
+    if (ptr->item != NULL)
+      delete (RLEPair *) (ptr->item);
+     }
+
+  while(!IsEmpty())
+    Remove();
+}
+
+void RLEPairs::print_pairs()
+{
+  RLEPair* item;
+  for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
+    item = (RLEPair *)(ptr->item);
+    printf("(%d->%d)", item->start, item->end);
+  }
+  printf("\n");
+}
+
+void RLEPairs::draw_pairs(char * window, double scaleFactor,
+			  int y_coord, char* color, double width)
+{
+  RLEPair* item;
+  scale(y_coord,scaleFactor);
+  for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
+    item = (RLEPair *)(ptr->item);
+    int line_start = item->start;
+    int line_end = item->end;
+    scale(line_start,scaleFactor);
+    scale(line_end, scaleFactor);
+    if(width > 1)
+      docommand("%s create line %d %d %d %d -fill %s -width %d", window, 
+		line_start, y_coord, line_end, y_coord, color, (int)width);
+    else
+      docommand("%s create line %d %d %d %d -fill %s", window, line_start, 
+		y_coord, line_end, y_coord, color);
+  }
+}
+
+void RLEPairs::shift(int bits)
+/*--------------------------------------------------------------
+Primary Purpose: shift a row right by bits
+Arguments: bits: the number of bits to shift by
+Return Value: none
+Effects: ...
+Constraints:
+Rev: 11/1 AR
+
+Someone should write a macro for this for loop. . .
+---------------------------------------------------------------*/
+{
+  RLEPair* item;
+  for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
+	  item = (RLEPair *)(ptr->item);
+	  item->start += bits;
+	  item->end += bits;
+	}
+}
+
+void RLEPairs::fill(unsigned char * contents, int contentsLength,
+		    int contentsRow)
+/*--------------------------------------------------------------
+Primary Purpose:  Take the contents of a line scanned from a 
+TIFF file and put it into this list of RLEPairs
+Arguments: contents is the result of a TIFFReadScanline function
+           contentsLength is the number of unsigned chars in contents
+	   contentsRow is the Row that this interval belongs to
+Effects: Scans contents and for each range of black pixels, adds
+         an RLEPair to the list
+Constraints:
+Rev: 10/20 KM  
+---------------------------------------------------------------*/
+{
+  if(contentsRow != row)
+    printf("Warning: merging to %d what appears to belong at %d\n", row, contentsRow);
+
+  bool inPair = FALSE;      // Flag set to TRUE when Run of black starts
+  short int startCol =0;
+  short int endCol = 0;
+  short int curCol= 0;
+  unsigned char nextChar;
+
+// Deallocate old pairs
+  for(ListElement *ptr = first; ptr != NULL; ptr = ptr->next)
+    removeAt(ptr);
+
+  for (int c = 0; c < contentsLength; c++)
+    {
+      nextChar = contents[c];
+
+
+      if (nextChar == 255)
+        {
+	  endCol = c*8+7;
+	  // If this is a new pair we also have to set  start col
+	  if (!inPair)
+	    {
+	      startCol = c*8;
+	      inPair = TRUE;
+	    }
+	}
+      else if(nextChar == 0)
+	{
+	  if (inPair)
+	    {
+	      RLEPair * pair = new RLEPair(startCol,endCol, contentsRow);
+	      Append(pair);
+	      inPair = FALSE;
+	      numPixels += endCol - startCol +1;
+	    }
+	}
+      else {  // Start Shifting and look at each bit
+
+	// high bit on left
+	for (int i = 7; i >=0; i--)
+	  {
+	    curCol = 7 + c * 8 - i;
+	    /*** Black Pixel handling  */
+	    if ((nextChar>>i)&1)      // if this is a black pixel
+	      {
+		if (!inPair)   // If not in a Pair, Start of a new Pair
+		  {
+		    inPair = TRUE;
+		    startCol = curCol;
+		    endCol = curCol;
+		  }
+		else           // Extend current Pair
+		  endCol = curCol;
+	      }
+	    /*** White Pixel Handling **/
+	    else            // This is a white pixel
+	      if (inPair)   // Close off the Pair add to the list 
+		{
+		  RLEPair * pair = new RLEPair(startCol,endCol, contentsRow);
+		  Append(pair);
+		  inPair = FALSE;
+		  numPixels += endCol - startCol+1;
+		}
+	    // if not in pair just continue
+	  }
+      }
+   }
+}
+
+
+#define DEBUG_PIXELS_BETWEEN 0
+int RLEPairs::pixelsBetween(int startCol, int endCol)
+/*--------------------------------------------------------------
+Return Value:  Returns the number of black pixels between column 
+               startCol and column endCol.
+Constraints:  0 <= startCol < endCol;  endCol < imageWidth  of RLEMap
+Rev: 10/20 KM
+---------------------------------------------------------------*/
+{
+  if (DEBUG_PIXELS_BETWEEN)
+      {
+	printf("Call to pixels between: start = %d, finish = %d\n", startCol, endCol);
+      }
+/*  assert(startCol < endCol); */
+  if(!(startCol < endCol))
+      {
+	printf("Warning, startcol %d not less then endcol %d (setting startcol = endcol)\n", startCol, endCol);
+	startCol = endCol;
+      }
+
+  int count= 0;
+  int pairStart;
+  int pairEnd;
+  RLEPair * item;
+
+  for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
+	  item = (RLEPair *)(ptr->item);
+      	  pairEnd = item->end;
+          pairStart = item->start;
+	  // Don't loop anymore if past endCol
+	  if (pairStart > endCol) break; 
+  
+	    // range starts after this pair
+	  if (pairEnd < startCol) ; // do nothing
+	     // range starts and ends in this pair
+	    else if (pairStart <= startCol && pairEnd >= endCol)
+	      count += endCol - startCol +1;
+	    // range starts in this pair but ends later
+	    else if (pairStart <=  startCol && pairEnd <= endCol)
+	      count += pairEnd - startCol + 1;
+	    // range includes this whole pair
+	    else if (pairStart >= startCol && pairEnd <= endCol)     
+	      count += pairEnd - pairStart + 1;
+	    // range ends in the middle of this pair
+	    else 
+	      count += endCol - pairStart + 1;
+
+	  // printf(" %d , %d  - %d newcount\n", pairStart, pairEnd, count);
+	  }
+	    	  
+
+
+  return count;
+
+}
+
+
+RLEPairs * RLEPairs::extract(int startCol, int endCol)
+/*--------------------------------------------------------------
+Primary Purpose: Makes a copy of a sectionn of this row
+Arguments: startCol - starting column to extract
+           endCol - ending column to extract
+Return Value: a pointer to a new RLEPairs that has been
+extracted from this.
+Constraints: start <= first col of first pair 
+             end <= ending col of lat pair
+Rev:  KM 11/16
+---------------------------------------------------------------*/
+{
+
+  int pairStart;
+  int pairEnd;
+
+  RLEPair * item;
+  RLEPairs * returnPairs = new RLEPairs(row);
+
+
+
+  for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
+	  item = (RLEPair *)(ptr->item);
+      	  pairEnd = item->end;
+          pairStart = item->start;
+	  row = item->row;
+
+	  // Don't loop anymore if past endCol
+	  if (pairStart > endCol) break; 
+  
+	    // range starts after this pair
+	  if (pairEnd < startCol) ; // do nothing
+
+	     // range starts and ends in this pair
+	    else if (pairStart <= startCol && pairEnd >= endCol)
+		{
+          	 RLEPair * addpair = new RLEPair(startCol,endCol, row);
+		 returnPairs->Append(addpair);
+	       }
+	    // range starts in this pair but ends later
+	    else if (pairStart <=  startCol && pairEnd <= endCol)
+		{
+          	 RLEPair * addpair = new RLEPair(startCol,pairEnd, row);
+		 returnPairs->Append(addpair);
+	       }
+
+	    // range includes this whole pair
+	    else if (pairStart >= startCol && pairEnd <= endCol)     
+		{
+          	 RLEPair * addpair = new RLEPair(pairStart,pairEnd, row);
+		 returnPairs->Append(addpair);
+	       }
+	    // range ends in the middle of this pair
+	    else 
+		{
+          	 RLEPair * addpair = new RLEPair(pairStart,endCol, row);
+		 returnPairs->Append(addpair);
+	       }	    
+
+	  }
+/*  printf("Extract returning: ");
+    returnPairs->print_pairs();  */
+  return returnPairs;
+}
+
+
+
+void RLEPairs::merge(RLEPairs * pairs)
+/*--------------------------------------------------------------
+Primary Purpose: Inserts  the black regions of pairs into this.
+Arguments: pairs - RLEPair list to be combined with this one.
+Return Value: A new list that represtents merged data
+Effects: Modifies this to add pairs. deallocates pairs.
+Constraints:
+Rev: 11/16/95
+---------------------------------------------------------------*/
+{
+  if((!pairs) || (pairs->length == 0))
+    return;
+
+  int pairStart;
+  int pairEnd;
+
+  RLEPair * item;
+  int lastCol =  ((RLEPair *) (last->item))->end;
+  int lastColpairs =  ((RLEPair *) (pairs->last->item))->end;
+  if (lastCol < lastColpairs)
+     lastCol = lastColpairs;
+
+
+  int numChars = lastCol/8 + 1;
+  uchar buffer[numChars];
+  for(int i = 0; i < numChars; i++) buffer[i] = 0;
+  
+  for (ListElement * ptr2 = pairs->first; ptr2 != NULL; ptr2 = ptr2->next) 
+      {
+	item = (RLEPair *)(ptr2->item);
+	setRange(buffer,  item->start, item->end);
+      }
+  
+  
+  for (ListElement * ptr=first; ptr != NULL; ptr = ptr->next) 
+	{
+	  item = (RLEPair *)(ptr->item);
+	  setRange(buffer,  item->start, item->end);
+	}
+
+  fill(buffer, numChars, row);
+
+/*  printf("Merged to form: ");
+    print_pairs(); */
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+