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