|
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 |