reference/ocr-simple/RLEPair.cc
changeset 0 6b8091ca909a
equal deleted inserted replaced
-1:000000000000 0:6b8091ca909a
       
     1 #include "system.h"
       
     2 #include "tcl_interface.h"
       
     3 
       
     4 
       
     5 
       
     6 
       
     7 /**** RLEPair.cc 
       
     8   Member functions for RLEPairs
       
     9   RLEPair functions defined in the function header
       
    10   rev 10/20 Kathey Marsden 
       
    11 */
       
    12 
       
    13 
       
    14 
       
    15 
       
    16 RLEPairs::RLEPairs(int rownum)
       
    17 :List()
       
    18 {
       
    19   numPixels = 0;
       
    20   row = rownum;
       
    21 }
       
    22 
       
    23 
       
    24 RLEPairs::~RLEPairs()
       
    25 {
       
    26   for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
       
    27     if (ptr->item != NULL)
       
    28       delete (RLEPair *) (ptr->item);
       
    29      }
       
    30 
       
    31   while(!IsEmpty())
       
    32     Remove();
       
    33 }
       
    34 
       
    35 void RLEPairs::print_pairs()
       
    36 {
       
    37   RLEPair* item;
       
    38   for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
       
    39     item = (RLEPair *)(ptr->item);
       
    40     printf("(%d->%d)", item->start, item->end);
       
    41   }
       
    42   printf("\n");
       
    43 }
       
    44 
       
    45 void RLEPairs::draw_pairs(int y_coord, char* color, double width)
       
    46 {
       
    47   RLEPair* item;
       
    48   scale(y_coord);
       
    49   for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
       
    50     item = (RLEPair *)(ptr->item);
       
    51     int line_start = item->start;
       
    52     int line_end = item->end;
       
    53     scale(line_start);
       
    54     scale(line_end);
       
    55     if(width > 1)
       
    56       docommand(".main_window.display.work_space create line %d %d %d %d -fill %s -width %d", line_start, y_coord, line_end, y_coord, color, (int)width);
       
    57     else
       
    58       docommand(".main_window.display.work_space create line %d %d %d %d -fill %s", line_start, y_coord, line_end, y_coord, color);
       
    59   }
       
    60 }
       
    61 
       
    62 void RLEPairs::shift(int bits)
       
    63 /*--------------------------------------------------------------
       
    64 Primary Purpose: shift a row right by bits
       
    65 Arguments: bits: the number of bits to shift by
       
    66 Return Value: none
       
    67 Effects: ...
       
    68 Constraints:
       
    69 Rev: 11/1 AR
       
    70 
       
    71 Someone should write a macro for this for loop. . .
       
    72 ---------------------------------------------------------------*/
       
    73 {
       
    74   RLEPair* item;
       
    75   for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
       
    76 	  item = (RLEPair *)(ptr->item);
       
    77 	  item->start += bits;
       
    78 	  item->end += bits;
       
    79 	}
       
    80 }
       
    81 
       
    82 void RLEPairs::fill(unsigned char * contents, int contentsLength,
       
    83 		    int contentsRow)
       
    84 /*--------------------------------------------------------------
       
    85 Primary Purpose:  Take the contents of a line scanned from a 
       
    86 TIFF file and put it into this list of RLEPairs
       
    87 Arguments: contents is the result of a TIFFReadScanline function
       
    88            contentsLength is the number of unsigned chars in contents
       
    89 	   contentsRow is the Row that this interval belongs to
       
    90 Effects: Scans contents and for each range of black pixels, adds
       
    91          an RLEPair to the list
       
    92 Constraints:
       
    93 Rev: 10/20 KM  
       
    94 ---------------------------------------------------------------*/
       
    95 {
       
    96   if(contentsRow != row)
       
    97     printf("Warning: merging to %d what appears to belong at %d\n", row, contentsRow);
       
    98 
       
    99   bool inPair = FALSE;      // Flag set to TRUE when Run of black starts
       
   100   short int startCol =0;
       
   101   short int endCol = 0;
       
   102   short int curCol= 0;
       
   103   unsigned char nextChar;
       
   104 
       
   105 // Deallocate old pairs
       
   106   for(ListElement *ptr = first; ptr != NULL; ptr = ptr->next)
       
   107     removeAt(ptr);
       
   108 
       
   109   for (int c = 0; c < contentsLength; c++)
       
   110     {
       
   111       nextChar = contents[c];
       
   112 
       
   113 
       
   114       if (nextChar == 255)
       
   115         {
       
   116 	  endCol = c*8+7;
       
   117 	  // If this is a new pair we also have to set  start col
       
   118 	  if (!inPair)
       
   119 	    {
       
   120 	      startCol = c*8;
       
   121 	      inPair = TRUE;
       
   122 	    }
       
   123 	}
       
   124       else if(nextChar == 0)
       
   125 	{
       
   126 	  if (inPair)
       
   127 	    {
       
   128 	      RLEPair * pair = new RLEPair(startCol,endCol, contentsRow);
       
   129 	      Append(pair);
       
   130 	      inPair = FALSE;
       
   131 	      numPixels += endCol - startCol +1;
       
   132 	    }
       
   133 	}
       
   134       else {  // Start Shifting and look at each bit
       
   135 
       
   136 	// high bit on left
       
   137 	for (int i = 7; i >=0; i--)
       
   138 	  {
       
   139 	    curCol = 7 + c * 8 - i;
       
   140 	    /*** Black Pixel handling  */
       
   141 	    if ((nextChar>>i)&1)      // if this is a black pixel
       
   142 	      {
       
   143 		if (!inPair)   // If not in a Pair, Start of a new Pair
       
   144 		  {
       
   145 		    inPair = TRUE;
       
   146 		    startCol = curCol;
       
   147 		    endCol = curCol;
       
   148 		  }
       
   149 		else           // Extend current Pair
       
   150 		  endCol = curCol;
       
   151 	      }
       
   152 	    /*** White Pixel Handling **/
       
   153 	    else            // This is a white pixel
       
   154 	      if (inPair)   // Close off the Pair add to the list 
       
   155 		{
       
   156 		  RLEPair * pair = new RLEPair(startCol,endCol, contentsRow);
       
   157 		  Append(pair);
       
   158 		  inPair = FALSE;
       
   159 		  numPixels += endCol - startCol+1;
       
   160 		}
       
   161 	    // if not in pair just continue
       
   162 	  }
       
   163       }
       
   164    }
       
   165 }
       
   166 
       
   167 
       
   168 #define DEBUG_PIXELS_BETWEEN 0
       
   169 int RLEPairs::pixelsBetween(int startCol, int endCol)
       
   170 /*--------------------------------------------------------------
       
   171 Return Value:  Returns the number of black pixels between column 
       
   172                startCol and column endCol.
       
   173 Constraints:  0 <= startCol < endCol;  endCol < imageWidth  of RLEMap
       
   174 Rev: 10/20 KM
       
   175 ---------------------------------------------------------------*/
       
   176 {
       
   177   if (DEBUG_PIXELS_BETWEEN)
       
   178       {
       
   179 	printf("Call to pixels between: start = %d, finish = %d\n", startCol, endCol);
       
   180       }
       
   181 /*  assert(startCol < endCol); */
       
   182   if(!(startCol < endCol))
       
   183       {
       
   184 	printf("Warning, startcol %d not less then endcol %d (setting startcol = endcol)\n", startCol, endCol);
       
   185 	startCol = endCol;
       
   186       }
       
   187 
       
   188   int count= 0;
       
   189   int pairStart;
       
   190   int pairEnd;
       
   191   RLEPair * item;
       
   192 
       
   193   for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
       
   194 	  item = (RLEPair *)(ptr->item);
       
   195       	  pairEnd = item->end;
       
   196           pairStart = item->start;
       
   197 	  // Don't loop anymore if past endCol
       
   198 	  if (pairStart > endCol) break; 
       
   199   
       
   200 	    // range starts after this pair
       
   201 	  if (pairEnd < startCol) ; // do nothing
       
   202 	     // range starts and ends in this pair
       
   203 	    else if (pairStart <= startCol && pairEnd >= endCol)
       
   204 	      count += endCol - startCol +1;
       
   205 	    // range starts in this pair but ends later
       
   206 	    else if (pairStart <=  startCol && pairEnd <= endCol)
       
   207 	      count += pairEnd - startCol + 1;
       
   208 	    // range includes this whole pair
       
   209 	    else if (pairStart >= startCol && pairEnd <= endCol)     
       
   210 	      count += pairEnd - pairStart + 1;
       
   211 	    // range ends in the middle of this pair
       
   212 	    else 
       
   213 	      count += endCol - pairStart + 1;
       
   214 
       
   215 	  // printf(" %d , %d  - %d newcount\n", pairStart, pairEnd, count);
       
   216 	  }
       
   217 	    	  
       
   218 
       
   219 
       
   220   return count;
       
   221 
       
   222 }
       
   223 
       
   224 
       
   225 RLEPairs * RLEPairs::extract(int startCol, int endCol)
       
   226 /*--------------------------------------------------------------
       
   227 Primary Purpose: Makes a copy of a sectionn of this row
       
   228 Arguments: startCol - starting column to extract
       
   229            endCol - ending column to extract
       
   230 Return Value: a pointer to a new RLEPairs that has been
       
   231 extracted from this.
       
   232 Constraints: start <= first col of first pair 
       
   233              end <= ending col of lat pair
       
   234 Rev:  KM 11/16
       
   235 ---------------------------------------------------------------*/
       
   236 {
       
   237 
       
   238   int pairStart;
       
   239   int pairEnd;
       
   240 
       
   241   RLEPair * item;
       
   242   RLEPairs * returnPairs = new RLEPairs(row);
       
   243 
       
   244 
       
   245 
       
   246   for (ListElement *ptr = first; ptr != NULL; ptr = ptr->next) {
       
   247 	  item = (RLEPair *)(ptr->item);
       
   248       	  pairEnd = item->end;
       
   249           pairStart = item->start;
       
   250 	  row = item->row;
       
   251 
       
   252 	  // Don't loop anymore if past endCol
       
   253 	  if (pairStart > endCol) break; 
       
   254   
       
   255 	    // range starts after this pair
       
   256 	  if (pairEnd < startCol) ; // do nothing
       
   257 
       
   258 	     // range starts and ends in this pair
       
   259 	    else if (pairStart <= startCol && pairEnd >= endCol)
       
   260 		{
       
   261           	 RLEPair * addpair = new RLEPair(startCol,endCol, row);
       
   262 		 returnPairs->Append(addpair);
       
   263 	       }
       
   264 	    // range starts in this pair but ends later
       
   265 	    else if (pairStart <=  startCol && pairEnd <= endCol)
       
   266 		{
       
   267           	 RLEPair * addpair = new RLEPair(startCol,pairEnd, row);
       
   268 		 returnPairs->Append(addpair);
       
   269 	       }
       
   270 
       
   271 	    // range includes this whole pair
       
   272 	    else if (pairStart >= startCol && pairEnd <= endCol)     
       
   273 		{
       
   274           	 RLEPair * addpair = new RLEPair(pairStart,pairEnd, row);
       
   275 		 returnPairs->Append(addpair);
       
   276 	       }
       
   277 	    // range ends in the middle of this pair
       
   278 	    else 
       
   279 		{
       
   280           	 RLEPair * addpair = new RLEPair(pairStart,endCol, row);
       
   281 		 returnPairs->Append(addpair);
       
   282 	       }	    
       
   283 
       
   284 	  }
       
   285 /*  printf("Extract returning: ");
       
   286     returnPairs->print_pairs();  */
       
   287   return returnPairs;
       
   288 }
       
   289 
       
   290 
       
   291 
       
   292 void RLEPairs::merge(RLEPairs * pairs)
       
   293 /*--------------------------------------------------------------
       
   294 Primary Purpose: Inserts  the black regions of pairs into this.
       
   295 Arguments: pairs - RLEPair list to be combined with this one.
       
   296 Return Value: A new list that represtents merged data
       
   297 Effects: Modifies this to add pairs. deallocates pairs.
       
   298 Constraints:
       
   299 Rev: 11/16/95
       
   300 ---------------------------------------------------------------*/
       
   301 {
       
   302   if((!pairs) || (pairs->length == 0))
       
   303     return;
       
   304 
       
   305   int pairStart;
       
   306   int pairEnd;
       
   307 
       
   308   RLEPair * item;
       
   309   int lastCol =  ((RLEPair *) (last->item))->end;
       
   310   int lastColpairs =  ((RLEPair *) (pairs->last->item))->end;
       
   311   if (lastCol < lastColpairs)
       
   312      lastCol = lastColpairs;
       
   313 
       
   314 
       
   315   int numChars = lastCol/8 + 1;
       
   316   uchar buffer[numChars];
       
   317   for(int i = 0; i < numChars; i++) buffer[i] = 0;
       
   318   
       
   319   for (ListElement * ptr2 = pairs->first; ptr2 != NULL; ptr2 = ptr2->next) 
       
   320       {
       
   321 	item = (RLEPair *)(ptr2->item);
       
   322 	setRange(buffer,  item->start, item->end);
       
   323       }
       
   324   
       
   325   
       
   326   for (ListElement * ptr=first; ptr != NULL; ptr = ptr->next) 
       
   327 	{
       
   328 	  item = (RLEPair *)(ptr->item);
       
   329 	  setRange(buffer,  item->start, item->end);
       
   330 	}
       
   331 
       
   332   fill(buffer, numChars, row);
       
   333 
       
   334 /*  printf("Merged to form: ");
       
   335     print_pairs(); */
       
   336 
       
   337 }
       
   338 
       
   339 
       
   340 
       
   341 
       
   342 
       
   343 
       
   344 
       
   345 
       
   346 
       
   347 
       
   348 
       
   349 
       
   350 
       
   351 
       
   352 
       
   353 
       
   354 
       
   355 
       
   356 
       
   357