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