source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/vrippack-0.31/src/vrip/scanPerspRLE.cc @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 35.7 KB
Line 
1/*
2
3Brian Curless
4
5Computer Graphics Laboratory
6Stanford University
7
8---------------------------------------------------------------------
9
10Copyright (1997) The Board of Trustees of the Leland Stanford Junior
11University. Except for commercial resale, lease, license or other
12commercial transactions, permission is hereby given to use, copy,
13modify this software for academic purposes only.  No part of this
14software or any derivatives thereof may be used in the production of
15computer models for resale or for use in a commercial
16product. STANFORD MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
17CONCERNING THIS SOFTWARE.  No support is implied or provided.
18
19*/
20
21
22#include <math.h>
23#include <limits.h>
24#include <stdio.h>
25#include <unistd.h>
26
27#include "vrip.h"
28#include "vripGlobals.h"
29#include "perspective.h"
30#include "resample.h"
31#include "occFunc.h"
32#include "scanPerspRLE.h"
33
34
35static OccScanlineRLE *theOutScanline;
36static OccGridRLE *theInGrid;
37static int currentType;
38static RunLength currentLength;
39static OccElement lastElement;
40
41
42static void initScanline(OccGridRLE *, OccScanlineRLE *);
43static void appendScanlinePortion(OccGridRLE *inGrid, int inType, 
44                                  OccElement *inElement, RunLength length);
45static void appendScanline(OccElement *inElement);
46static void sealScanline();
47
48
49
50
51void
52scanConvertPersp(OccGridRLE *gridIn, OccGridRLE *gridOut, 
53                     OrthoShear *shear, DepthMap *depthMap)
54{
55    float xOff, yOff, res, depth, confidence;
56    OccElement *buf, *scanline;
57    int xx,yy,zz;
58    Vec3f pos, newpos;
59
60    float sampleSpacing = sqrt(1 + shear->sx*shear->sx + shear->sy*shear->sy);
61
62    res = gridIn->resolution;
63
64    gridOut->copyParams(gridIn);
65
66    gridOut->reset();
67
68    for (zz = 0; zz < gridIn->zdim; zz++) {
69        if (!Quiet)
70            printf("\rTraversing slice %d of %d.", zz, gridIn->zdim-1);
71        fflush(stdout);
72        yOff = (gridIn->sliceOrigins[zz][1] - depthMap->origin[1])/res;
73        for (yy = 0; yy < gridIn->ydim; yy++, yOff++) { 
74            buf = scanline = gridIn->getScanline(yy,zz);
75            xOff = (gridIn->sliceOrigins[zz][0] - depthMap->origin[0])/res;
76            for (xx = 0; xx < gridIn->xdim; xx++, xOff++, buf++) {
77
78                pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
79                             yy*res+gridIn->sliceOrigins[zz][1],
80                             gridIn->sliceOrigins[zz][2]);
81                applyPersp(pos, newpos);
82                xOff = (newpos.x - depthMap->origin[0])/res;
83                yOff = (newpos.y - depthMap->origin[1])/res;
84
85#if 0
86                resampleForCarving(depthMap, xOff, yOff,
87                                   &depth, &confidence);
88
89                // Using the full-blown filler!
90                updateCellForCarving(gridIn->sliceOrigins[zz][2], depth,
91                                     sampleSpacing, confidence, buf);
92#else
93
94                resample(depthMap, xOff, yOff, &depth, &confidence);
95                updateCell(gridIn->sliceOrigins[zz][2], depth, 
96                           sampleSpacing, confidence, buf);
97
98#endif
99
100            }
101            gridOut->putScanline(scanline,yy,zz);
102        }
103    }
104    if (!Quiet)
105        printf("\n");
106}
107
108
109void
110scanConvertPerspTree(OccGridRLE *gridIn, OccGridRLE *gridOut, 
111                         OrthoShear *shear, DepthMap *depthMap)
112{
113    float xOff, yOff, res, depth, confidence;
114    OccElement *buf, *scanline;
115    int xx,yy,zz;
116    Vec3f pos, newpos;
117    int *depthRuns, numRuns;
118    float zmin, zmax, xNewOff, y1, y2;
119    int xmin, xmax;
120    OccScanlineRLE *rleScanline;
121
122    float sampleSpacing = sqrt(1 + shear->sx*shear->sx + shear->sy*shear->sy);
123
124    res = gridIn->resolution;
125
126    gridOut->copyParams(gridIn);
127
128    gridOut->reset();
129
130    for (zz = 0; zz < gridIn->zdim; zz++) {
131        if (!Quiet)
132            printf("\rTraversing slice %d of %d.", zz, gridIn->zdim-1);
133        fflush(stdout);
134
135        zmin = gridIn->sliceOrigins[zz][2] - C1/sampleSpacing;
136        zmax = gridIn->sliceOrigins[zz][2] - C5/sampleSpacing;
137
138        yOff = (gridIn->sliceOrigins[zz][1] - depthMap->origin[1])/res;
139        for (yy = 0; yy < gridIn->ydim; yy++, yOff++) { 
140            pos.setValue(0*res+gridIn->sliceOrigins[zz][0],
141                         yy*res+gridIn->sliceOrigins[zz][1],
142                         gridIn->sliceOrigins[zz][2]);
143            applyPersp(pos, newpos);
144            yOff = (newpos.y - depthMap->origin[1])/res;
145
146            pos.setValue(gridIn->xdim*res+gridIn->sliceOrigins[zz][0],
147                         yy*res+gridIn->sliceOrigins[zz][1],
148                         gridIn->sliceOrigins[zz][2]);
149
150            // Huber fix of 4/5/01
151            // look for areas with depth between zmin and zmax in this row
152            if ((int(yOff) >= 0) && (int(yOff) < depthMap->ydim)) {
153               depthRuns = depthMap->getDepthRuns(yOff, zmin, zmax, &numRuns);
154            } else {
155               numRuns = 0;
156            }
157            if (numRuns == 0) {
158                rleScanline = gridIn->getRLEScanline(yy, zz);
159                gridOut->copyScanline(rleScanline, yy, zz);
160                continue;
161
162            }
163            scanline = gridIn->getScanline(yy,zz);
164            for (int i = 0; i < numRuns; i++) {
165
166                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
167                             y1*res + depthMap->origin[1],
168                             gridIn->sliceOrigins[zz][2]);
169                applyInvPersp(pos, newpos);
170                xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
171
172                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
173                             y2*res + depthMap->origin[1],
174                             gridIn->sliceOrigins[zz][2]);
175                applyInvPersp(pos, newpos);
176                xmin = MIN(xmin, int((newpos.x - 
177                                      gridIn->sliceOrigins[zz][0])/res));
178                xmin = MAX(xmin, 0);
179
180
181                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
182                             y1*res + depthMap->origin[1],
183                             gridIn->sliceOrigins[zz][2]);
184//ahaubold
185//              applyInvPersp(pos, newpos);
186                applyInvPersp(pos, newpos);
187                xmax = int(ceil((newpos.x - 
188                                 gridIn->sliceOrigins[zz][0])/res));
189
190                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
191                             y2*res + depthMap->origin[1],
192                             gridIn->sliceOrigins[zz][2]);
193//ahaubold
194//              applyInvPersp(pos, newpos);
195                applyInvPersp(pos, newpos);
196                xmax = MAX(xmax, 
197                           int(ceil((newpos.x - 
198                                     gridIn->sliceOrigins[zz][0])/res)));
199                xmax = int(MIN(xmax*1.1, gridIn->xdim-1));
200
201                buf = scanline + xmin;
202                for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
203                    pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
204                                 yy*res+gridIn->sliceOrigins[zz][1],
205                                 gridIn->sliceOrigins[zz][2]);
206//ahaubold
207//                  applyPersp(pos, newpos);
208                    applyPersp(pos, newpos);
209                    xOff = (newpos.x - depthMap->origin[0])/res;
210                    yOff = (newpos.y - depthMap->origin[1])/res;
211
212                    resample(depthMap, xOff, yOff, &depth, &confidence);
213                    updateCell(gridIn->sliceOrigins[zz][2], depth, 
214                               sampleSpacing, confidence, buf);
215                }
216            }
217            gridOut->putScanline(scanline,yy,zz);
218        }
219    }
220    if (!Quiet)
221        printf("\n");
222}
223
224
225
226void
227scanConvertPerspTreeDragTails(OccGridRLE *gridIn, OccGridRLE *gridOut, 
228                                  OrthoShear *shear, DepthMap *depthMap)
229{
230    float xOff, yOff, res, depth, confidence;
231    OccElement *buf, *scanline;
232    int xx,yy,zz;
233    Vec3f pos, newpos;
234    int *depthRuns, numRuns, oldNumRuns;
235    float zmin, zmax, xNewOff, y1, y2;
236    int xmin, xmax;
237    OccScanlineRLE *rleScanline;
238
239    float sampleSpacing = sqrt(1 + shear->sx*shear->sx + shear->sy*shear->sy);
240
241    res = gridIn->resolution;
242
243    gridOut->copyParams(gridIn);
244
245    gridOut->reset();
246
247    for (zz = 0; zz < gridIn->zdim; zz++) {
248        if (!Quiet)
249            printf("\rTraversing slice %d of %d.", zz, gridIn->zdim-1);
250        fflush(stdout);
251
252        zmin = gridIn->sliceOrigins[zz][2] - C1/sampleSpacing;
253        zmax = gridIn->sliceOrigins[zz][2] - C5/sampleSpacing;
254        yOff = (gridIn->sliceOrigins[zz][1] - depthMap->origin[1])/res;
255        for (yy = 0; yy < gridIn->ydim; yy++, yOff++) { 
256
257            pos.setValue(0*res+gridIn->sliceOrigins[zz][0],
258                         yy*res+gridIn->sliceOrigins[zz][1],
259                         gridIn->sliceOrigins[zz][2]);
260            applyPersp(pos, newpos);
261            y1 = (newpos.y - depthMap->origin[1])/res;
262
263            pos.setValue(gridIn->xdim*res+gridIn->sliceOrigins[zz][0],
264                         yy*res+gridIn->sliceOrigins[zz][1],
265                         gridIn->sliceOrigins[zz][2]);
266            applyPersp(pos, newpos);
267            y2 = (newpos.y - depthMap->origin[1])/res;
268
269            // Split the y-value down the middle
270            yOff = (y1+y2)/2;
271
272            depthRuns = depthMap->getDepthRuns(yOff, zmin, zmax, &numRuns);
273            if (numRuns != 0) {
274                scanline = gridIn->getScanline(yy,zz);
275                for (int i = 0; i < numRuns; i++) {
276
277                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
278                                 y1*res + depthMap->origin[1],
279                                 gridIn->sliceOrigins[zz][2]);
280                    applyInvPersp(pos, newpos);
281                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
282
283                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
284                                 y2*res + depthMap->origin[1],
285                                 gridIn->sliceOrigins[zz][2]);
286                    applyInvPersp(pos, newpos);
287                    xmin = MIN(xmin, int((newpos.x - 
288                                          gridIn->sliceOrigins[zz][0])/res));
289                    xmin = MAX(xmin, 0);
290
291
292                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
293                                 y1*res + depthMap->origin[1],
294                                 gridIn->sliceOrigins[zz][2]);
295                    applyInvPersp(pos, newpos);
296                    xmax = int(ceil((newpos.x - 
297                                     gridIn->sliceOrigins[zz][0])/res));
298
299                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
300                                 y2*res + depthMap->origin[1],
301                                 gridIn->sliceOrigins[zz][2]);
302                    applyInvPersp(pos, newpos);
303                    xmax = MAX(xmax, 
304                               int(ceil((newpos.x - 
305                                         gridIn->sliceOrigins[zz][0])/res)));
306                    xmax = MIN(xmax, gridIn->xdim-1);
307
308                    buf = scanline + xmin;
309                    for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
310
311                        pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
312                                     yy*res+gridIn->sliceOrigins[zz][1],
313                                     gridIn->sliceOrigins[zz][2]);
314                        applyPersp(pos, newpos);
315                        xOff = (newpos.x - depthMap->origin[0])/res;
316                        yOff = (newpos.y - depthMap->origin[1])/res;
317
318                        resampleForCarving(depthMap, xOff, yOff, 
319                                           &depth, &confidence);
320                        updateCellForCarving(gridIn->sliceOrigins[zz][2], 
321                                             depth, 
322                                             sampleSpacing, confidence, buf);
323                    }
324                }
325            }
326            oldNumRuns = numRuns;
327
328            // Points in front of the surface
329            yOff = (y1+y2)/2;
330            depthRuns = depthMap->getDepthRunsUpperBound
331                (yOff, zmin, &numRuns);
332
333            int skip = 0;
334            if (oldNumRuns == 0 && numRuns == 0) {
335                rleScanline = gridIn->getRLEScanline(yy, zz);
336                gridOut->copyScanline(rleScanline, yy, zz);
337                skip = 1;
338            } else if (numRuns == 0) {
339                gridOut->putScanline(scanline,yy,zz);
340                skip = 1;
341            } else if (oldNumRuns == 0) {
342                scanline = gridIn->getScanline(yy,zz);
343                skip = 0;
344            }
345
346            if (!skip) {
347                for (int i = 0; i < numRuns; i++) {
348
349                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
350                                 y1*res + depthMap->origin[1],
351                                 gridIn->sliceOrigins[zz][2]);
352                    applyInvPersp(pos, newpos);
353                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
354
355                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
356                                 y2*res + depthMap->origin[1],
357                                 gridIn->sliceOrigins[zz][2]);
358                    applyInvPersp(pos, newpos);
359                    xmin = MIN(xmin, int((newpos.x - 
360                                          gridIn->sliceOrigins[zz][0])/res));
361                    xmin = MAX(xmin, 0);
362
363
364                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
365                                 y1*res + depthMap->origin[1],
366                                 gridIn->sliceOrigins[zz][2]);
367                    applyInvPersp(pos, newpos);
368                    xmax = int(ceil((newpos.x - 
369                                     gridIn->sliceOrigins[zz][0])/res));
370
371                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
372                                 y2*res + depthMap->origin[1],
373                                 gridIn->sliceOrigins[zz][2]);
374                    applyInvPersp(pos, newpos);
375                    xmax = MAX(xmax, 
376                               int(ceil((newpos.x - 
377                                         gridIn->sliceOrigins[zz][0])/res)));
378                    xmax = MIN(xmax, gridIn->xdim-1);
379
380                    buf = scanline + xmin;
381                    for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
382                        if (buf->totalWeight == 0) {
383                            buf->value = 0;
384                        }
385                    }
386                }
387            }
388
389            oldNumRuns += numRuns;
390
391            yOff = (y1+y2)/2;
392            depthRuns = depthMap->getDepthRunsEdges
393                (yOff, zmin, &numRuns);
394
395            if (oldNumRuns == 0 && numRuns == 0) {
396                rleScanline = gridIn->getRLEScanline(yy, zz);
397                gridOut->copyScanline(rleScanline, yy, zz);
398                continue;
399            } else if (numRuns == 0) {
400                gridOut->putScanline(scanline,yy,zz);
401                continue;
402            } else if (oldNumRuns == 0) {
403                scanline = gridIn->getScanline(yy,zz);
404            }
405
406            for (int i = 0; i < numRuns; i++) {
407
408                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
409                             y1*res + depthMap->origin[1],
410                             gridIn->sliceOrigins[zz][2]);
411                applyInvPersp(pos, newpos);
412                xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
413
414                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
415                             y2*res + depthMap->origin[1],
416                             gridIn->sliceOrigins[zz][2]);
417                applyInvPersp(pos, newpos);
418                xmin = MIN(xmin, int((newpos.x - 
419                                      gridIn->sliceOrigins[zz][0])/res));
420                xmin = MAX(xmin, 0);
421
422
423                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
424                             y1*res + depthMap->origin[1],
425                             gridIn->sliceOrigins[zz][2]);
426                applyInvPersp(pos, newpos);
427                xmax = int(ceil((newpos.x - 
428                                 gridIn->sliceOrigins[zz][0])/res));
429
430                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
431                             y2*res + depthMap->origin[1],
432                             gridIn->sliceOrigins[zz][2]);
433                applyInvPersp(pos, newpos);
434                xmax = MAX(xmax, 
435                           int(ceil((newpos.x - 
436                                     gridIn->sliceOrigins[zz][0])/res)));
437                xmax = MIN(xmax, gridIn->xdim-1);
438
439                buf = scanline + xmin;
440                for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
441
442                    pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
443                                 yy*res+gridIn->sliceOrigins[zz][1],
444                                 gridIn->sliceOrigins[zz][2]);
445                    applyPersp(pos, newpos);
446                    xOff = (newpos.x - depthMap->origin[0])/res;
447                    yOff = (newpos.y - depthMap->origin[1])/res;
448
449                    resampleForCarving(depthMap, xOff, yOff, 
450                                       &depth, &confidence);
451                    updateCellForCarving(gridIn->sliceOrigins[zz][2], depth, 
452                                         sampleSpacing, confidence, buf);
453                }
454            }
455
456            gridOut->putScanline(scanline,yy,zz);
457        }
458    }
459    if (!Quiet)
460        printf("\n");
461}
462
463
464void
465scanConvertPerspTreeTailsOnly(OccGridRLE *gridIn, OccGridRLE *gridOut, 
466                                  OrthoShear *shear, DepthMap *depthMap)
467{
468    float xOff, yOff, res, depth, confidence;
469    OccElement *buf, *scanline;
470    int xx,yy,zz;
471    Vec3f pos, newpos;
472    int *depthRuns, numRuns, oldNumRuns;
473    float zmin, zmax, xNewOff, y1, y2;
474    int xmin, xmax;
475    OccScanlineRLE *rleScanline;
476
477    float sampleSpacing = sqrt(1 + shear->sx*shear->sx + shear->sy*shear->sy);
478
479    res = gridIn->resolution;
480
481    gridOut->copyParams(gridIn);
482
483    gridOut->reset();
484
485    for (zz = 0; zz < gridIn->zdim; zz++) {
486        if (!Quiet)
487            printf("\rTraversing slice %d of %d.", zz, gridIn->zdim-1);
488        fflush(stdout);
489
490        zmin = gridIn->sliceOrigins[zz][2] - C1/sampleSpacing;
491        zmax = gridIn->sliceOrigins[zz][2] - C5/sampleSpacing;
492        yOff = (gridIn->sliceOrigins[zz][1] - depthMap->origin[1])/res;
493        for (yy = 0; yy < gridIn->ydim; yy++, yOff++) { 
494
495            pos.setValue(0*res+gridIn->sliceOrigins[zz][0],
496                         yy*res+gridIn->sliceOrigins[zz][1],
497                         gridIn->sliceOrigins[zz][2]);
498            applyPersp(pos, newpos);
499            y1 = (newpos.y - depthMap->origin[1])/res;
500
501            pos.setValue(gridIn->xdim*res+gridIn->sliceOrigins[zz][0],
502                         yy*res+gridIn->sliceOrigins[zz][1],
503                         gridIn->sliceOrigins[zz][2]);
504            applyPersp(pos, newpos);
505            y2 = (newpos.y - depthMap->origin[1])/res;
506
507            // Split the y-value down the middle
508            yOff = (y1+y2)/2;
509
510            depthRuns = depthMap->getDepthRuns(yOff, zmin, zmax, &numRuns);
511            if (numRuns != 0) {
512                scanline = gridIn->getScanline(yy,zz);
513                for (int i = 0; i < numRuns; i++) {
514
515                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
516                                 y1*res + depthMap->origin[1],
517                                 gridIn->sliceOrigins[zz][2]);
518                    applyInvPersp(pos, newpos);
519                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
520
521                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
522                                 y2*res + depthMap->origin[1],
523                                 gridIn->sliceOrigins[zz][2]);
524                    applyInvPersp(pos, newpos);
525                    xmin = MIN(xmin, int((newpos.x - 
526                                          gridIn->sliceOrigins[zz][0])/res));
527                    xmin = MAX(xmin, 0);
528
529
530                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
531                                 y1*res + depthMap->origin[1],
532                                 gridIn->sliceOrigins[zz][2]);
533                    applyInvPersp(pos, newpos);
534                    xmax = int(ceil((newpos.x - 
535                                     gridIn->sliceOrigins[zz][0])/res));
536
537                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
538                                 y2*res + depthMap->origin[1],
539                                 gridIn->sliceOrigins[zz][2]);
540                    applyInvPersp(pos, newpos);
541                    xmax = MAX(xmax, 
542                               int(ceil((newpos.x - 
543                                         gridIn->sliceOrigins[zz][0])/res)));
544                    xmax = MIN(xmax, gridIn->xdim-1);
545
546                    buf = scanline + xmin;
547                    for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
548
549                        pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
550                                     yy*res+gridIn->sliceOrigins[zz][1],
551                                     gridIn->sliceOrigins[zz][2]);
552                        applyPersp(pos, newpos);
553                        xOff = (newpos.x - depthMap->origin[0])/res;
554                        yOff = (newpos.y - depthMap->origin[1])/res;
555
556                        resampleForCarving(depthMap, xOff, yOff, 
557                                           &depth, &confidence);
558
559                        // Setting confidence to zero only allows for carving
560                        confidence = 0;
561                        updateCellForCarving(gridIn->sliceOrigins[zz][2], 
562                                             depth, 
563                                             sampleSpacing, confidence, buf);
564                    }
565                }
566            }
567            oldNumRuns = numRuns;
568
569            // Points in front of the surface
570            yOff = (y1+y2)/2;
571            depthRuns = depthMap->getDepthRunsUpperBound
572                (yOff, zmin, &numRuns);
573
574            int skip = 0;
575            if (oldNumRuns == 0 && numRuns == 0) {
576                rleScanline = gridIn->getRLEScanline(yy, zz);
577                gridOut->copyScanline(rleScanline, yy, zz);
578                skip = 1;
579            } else if (numRuns == 0) {
580                gridOut->putScanline(scanline,yy,zz);
581                skip = 1;
582            } else if (oldNumRuns == 0) {
583                scanline = gridIn->getScanline(yy,zz);
584                skip = 0;
585            }
586
587            if (!skip) {
588                for (int i = 0; i < numRuns; i++) {
589
590                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
591                                 y1*res + depthMap->origin[1],
592                                 gridIn->sliceOrigins[zz][2]);
593                    applyInvPersp(pos, newpos);
594                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
595
596                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
597                                 y2*res + depthMap->origin[1],
598                                 gridIn->sliceOrigins[zz][2]);
599                    applyInvPersp(pos, newpos);
600                    xmin = MIN(xmin, int((newpos.x - 
601                                          gridIn->sliceOrigins[zz][0])/res));
602                    xmin = MAX(xmin, 0);
603
604
605                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
606                                 y1*res + depthMap->origin[1],
607                                 gridIn->sliceOrigins[zz][2]);
608                    applyInvPersp(pos, newpos);
609                    xmax = int(ceil((newpos.x - 
610                                     gridIn->sliceOrigins[zz][0])/res));
611
612                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
613                                 y2*res + depthMap->origin[1],
614                                 gridIn->sliceOrigins[zz][2]);
615                    applyInvPersp(pos, newpos);
616                    xmax = MAX(xmax, 
617                               int(ceil((newpos.x - 
618                                         gridIn->sliceOrigins[zz][0])/res)));
619                    xmax = MIN(xmax, gridIn->xdim-1);
620
621                    buf = scanline + xmin;
622                    for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
623                        if (buf->totalWeight == 0) {
624                            buf->value = 0;
625                        }
626                    }
627                }
628            }
629
630            oldNumRuns += numRuns;
631
632            yOff = (y1+y2)/2;
633            depthRuns = depthMap->getDepthRunsEdges
634                (yOff, zmin, &numRuns);
635
636            if (oldNumRuns == 0 && numRuns == 0) {
637                rleScanline = gridIn->getRLEScanline(yy, zz);
638                gridOut->copyScanline(rleScanline, yy, zz);
639                continue;
640            } else if (numRuns == 0) {
641                gridOut->putScanline(scanline,yy,zz);
642                continue;
643            } else if (oldNumRuns == 0) {
644                scanline = gridIn->getScanline(yy,zz);
645            }
646
647            for (int i = 0; i < numRuns; i++) {
648
649                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
650                             y1*res + depthMap->origin[1],
651                             gridIn->sliceOrigins[zz][2]);
652                applyInvPersp(pos, newpos);
653                xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
654
655                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
656                             y2*res + depthMap->origin[1],
657                             gridIn->sliceOrigins[zz][2]);
658                applyInvPersp(pos, newpos);
659                xmin = MIN(xmin, int((newpos.x - 
660                                      gridIn->sliceOrigins[zz][0])/res));
661                xmin = MAX(xmin, 0);
662
663
664                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
665                             y1*res + depthMap->origin[1],
666                             gridIn->sliceOrigins[zz][2]);
667                applyInvPersp(pos, newpos);
668                xmax = int(ceil((newpos.x - 
669                                 gridIn->sliceOrigins[zz][0])/res));
670
671                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
672                             y2*res + depthMap->origin[1],
673                             gridIn->sliceOrigins[zz][2]);
674                applyInvPersp(pos, newpos);
675                xmax = MAX(xmax, 
676                           int(ceil((newpos.x - 
677                                     gridIn->sliceOrigins[zz][0])/res)));
678                xmax = MIN(xmax, gridIn->xdim-1);
679
680                buf = scanline + xmin;
681                for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
682
683                    pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
684                                 yy*res+gridIn->sliceOrigins[zz][1],
685                                 gridIn->sliceOrigins[zz][2]);
686                    applyPersp(pos, newpos);
687                    xOff = (newpos.x - depthMap->origin[0])/res;
688                    yOff = (newpos.y - depthMap->origin[1])/res;
689
690
691                    resampleForCarving(depthMap, xOff, yOff, 
692                                       &depth, &confidence);
693
694                    // Setting confidence to zero only allows for carving
695                    confidence = 0;
696                    updateCellForCarving(gridIn->sliceOrigins[zz][2], depth, 
697                                         sampleSpacing, confidence, buf);
698                }
699            }
700
701            gridOut->putScanline(scanline,yy,zz);
702        }
703    }
704    if (!Quiet)
705        printf("\n");
706}
707
708
709
710void
711scanConvertPerspTreeTailsOnlyFast(OccGridRLE *gridIn, OccGridRLE *gridOut, 
712                                      OrthoShear *shear, DepthMap *depthMap)
713{
714    float xOff, yOff, res, depth, confidence;
715    OccElement *buf, *scanline, outElement;
716    int xx,yy,zz;
717    Vec3f pos, newpos;
718    int *depthRuns, numRuns, oldNumRuns;
719    float zmin, zmax, xNewOff, y1, y2;
720    int xmin, xmax;
721    OccScanlineRLE *rleScanline, *outScanline, *inScanline, *tempScanline;
722
723    inScanline = new OccScanlineRLE(gridIn->xdim);
724    outScanline = new OccScanlineRLE(gridIn->xdim);
725
726    float sampleSpacing = sqrt(1 + shear->sx*shear->sx + shear->sy*shear->sy);
727
728    res = gridIn->resolution;
729
730    gridOut->copyParams(gridIn);
731
732    gridOut->reset();
733
734    for (zz = 0; zz < gridIn->zdim; zz++) {
735        if (!Quiet)
736            printf("\rTraversing slice %d of %d.", zz, gridIn->zdim-1);
737        fflush(stdout);
738
739        // Something is really backwards here!
740
741/*
742        zmin = gridIn->sliceOrigins[zz][2] + C5/sampleSpacing;
743        zmax = gridIn->sliceOrigins[zz][2] + 2*C1/sampleSpacing;
744*/
745        zmin = gridIn->sliceOrigins[zz][2] - C1/sampleSpacing;
746        zmax = gridIn->sliceOrigins[zz][2] - C5/sampleSpacing;
747        yOff = (gridIn->sliceOrigins[zz][1] - depthMap->origin[1])/res;
748        for (yy = 0; yy < gridIn->ydim; yy++, yOff++) { 
749
750            pos.setValue(0*res+gridIn->sliceOrigins[zz][0],
751                         yy*res+gridIn->sliceOrigins[zz][1],
752                         gridIn->sliceOrigins[zz][2]);
753            applyPersp(pos, newpos);
754            y1 = (newpos.y - depthMap->origin[1])/res;
755
756            pos.setValue(gridIn->xdim*res+gridIn->sliceOrigins[zz][0],
757                         yy*res+gridIn->sliceOrigins[zz][1],
758                         gridIn->sliceOrigins[zz][2]);
759            applyPersp(pos, newpos);
760            y2 = (newpos.y - depthMap->origin[1])/res;
761
762            // Split the y-value down the middle
763            yOff = (y1+y2)/2;
764
765            depthRuns = depthMap->getDepthRuns(yOff, zmin, zmax, &numRuns);
766            if (numRuns != 0) {
767
768                gridIn->setScanline(yy, zz);
769                RunLength inLength = gridIn->getNextLength();
770                int inType = gridIn->getRunType(&inLength);
771                int nextInOffset = inLength;
772                OccElement *inElement;
773
774                if (inType == OccGridRLE::CONSTANT_DATA)
775                    inElement = gridIn->getNextElement();
776
777                // Prepare output scanline
778                initScanline(gridIn, outScanline);
779                xx = 0;
780
781                for (int i = 0; i < numRuns; i++) {
782
783                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
784                                 y1*res + depthMap->origin[1],
785                                 gridIn->sliceOrigins[zz][2]);
786                    applyInvPersp(pos, newpos);
787                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
788
789                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
790                                 y2*res + depthMap->origin[1],
791                                 gridIn->sliceOrigins[zz][2]);
792                    applyInvPersp(pos, newpos);
793                    xmin = MIN(xmin, int((newpos.x - 
794                                          gridIn->sliceOrigins[zz][0])/res));
795                    xmin = MAX(xmin, 0);
796
797
798                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
799                                 y1*res + depthMap->origin[1],
800                                 gridIn->sliceOrigins[zz][2]);
801                    applyInvPersp(pos, newpos);
802                    xmax = int(ceil((newpos.x - 
803                                     gridIn->sliceOrigins[zz][0])/res));
804
805                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
806                                 y2*res + depthMap->origin[1],
807                                 gridIn->sliceOrigins[zz][2]);
808                    applyInvPersp(pos, newpos);
809                    xmax = MAX(xmax, 
810                               int(ceil((newpos.x - 
811                                         gridIn->sliceOrigins[zz][0])/res)));
812                    xmax = MIN(xmax, gridIn->xdim-1);
813
814                    // Copy over all whole runs that precede the current xmin
815
816                    while (nextInOffset < xmin) {
817                        if (nextInOffset != xx) {
818                            appendScanlinePortion(gridIn, inType, inElement, 
819                                                  nextInOffset - xx);
820                        }
821                        xx = nextInOffset;
822
823                        // Update for next run
824                        inLength = gridIn->getNextLength();
825                        inType = gridIn->getRunType(&inLength);
826                        nextInOffset += inLength; 
827                        if (inType == OccGridRLE::CONSTANT_DATA) {
828                            inElement = gridIn->getNextElement();
829                        }
830                    }
831               
832
833                    // Copy over the remaining portion of the first
834                    // overlapping run
835
836                    if (xx != xmin) {
837                        appendScanlinePortion(gridIn, inType, inElement, 
838                                              xmin - xx);
839                    }
840
841                    xx = xmin;
842                   
843                    // Update the output based on new data combined with
844                    //  old data
845
846                    while (xx <= xmax) {
847
848                        // If old input run is finished, start a new one
849
850                        if (xx == nextInOffset) {
851                            inLength = gridIn->getNextLength();
852                            inType = gridIn->getRunType(&inLength);
853                            nextInOffset += inLength; 
854                            if (inType == OccGridRLE::CONSTANT_DATA) {
855                                inElement = gridIn->getNextElement();
856                            }
857                        }
858
859                        // If varying run, get next element
860
861                        if (inType == OccGridRLE::VARYING_DATA) {
862                            inElement = gridIn->getNextElement();
863                        }
864
865                        // Copy over element and update
866
867                        outElement = *inElement;
868
869                        pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
870                                     yy*res+gridIn->sliceOrigins[zz][1],
871                                     gridIn->sliceOrigins[zz][2]);
872                        applyPersp(pos, newpos);
873                        xOff = (newpos.x - depthMap->origin[0])/res;
874                        yOff = (newpos.y - depthMap->origin[1])/res;
875
876                        resampleForCarving(depthMap, xOff, yOff, 
877                                           &depth, &confidence);
878
879                        // Setting confidence to zero only allows for carving
880                        confidence = 0;
881                        updateCellForCarving(gridIn->sliceOrigins[zz][2], 
882                                             depth, 
883                                             sampleSpacing, confidence, 
884                                             &outElement);
885
886                        // Write element to the output grid
887                        appendScanline(&outElement);
888
889                        xNewOff++;
890                        xx++;
891                    }
892                }
893
894                // Finish up any remaining runs
895
896                while (xx < gridOut->xdim) {
897                    if (nextInOffset != xx) {
898                        appendScanlinePortion(gridIn, inType, inElement, 
899                                              nextInOffset - xx);
900                    }
901                    xx = nextInOffset;
902
903                    // Update for next run
904                    inLength = gridIn->getNextLength();
905                    inType = gridIn->getRunType(&inLength);
906
907                    if (inType == OccGridRLE::END_OF_RUN) {
908                        break;
909                    }
910
911                    nextInOffset += inLength; 
912                    if (inType == OccGridRLE::CONSTANT_DATA) {
913                        inElement = gridIn->getNextElement();
914                    }
915                }
916
917                // Seal off the old run
918                sealScanline();
919
920                gridOut->copyScanline(outScanline, yy, zz);
921                scanline = gridOut->getScanline(yy, zz);
922
923                gridIn->copyScanline(outScanline, yy, zz);
924            }
925
926            oldNumRuns = numRuns;
927
928            // Points in front of the surface
929            yOff = (y1+y2)/2;
930            depthRuns = depthMap->getDepthRunsUpperBound
931                (yOff, zmin, &numRuns);
932
933            int skip = 0;
934            if (oldNumRuns == 0 && numRuns == 0) {
935                rleScanline = gridIn->getRLEScanline(yy, zz);
936                gridOut->copyScanline(rleScanline, yy, zz);
937                skip = 1;
938            } else if (numRuns == 0) {
939                gridOut->copyScanline(outScanline,yy,zz);
940                skip = 1;
941            } else if (oldNumRuns == 0) {
942                skip = 0;
943            }
944
945            if (!skip) {
946
947                gridIn->setScanline(yy, zz);
948                RunLength inLength = gridIn->getNextLength();
949                int inType = gridIn->getRunType(&inLength);
950                int nextInOffset = inLength;
951                OccElement *inElement;
952
953                if (inType == OccGridRLE::CONSTANT_DATA)
954                    inElement = gridIn->getNextElement();
955
956                // Prepare output scanline
957                initScanline(gridIn, outScanline);
958                xx = 0;
959
960                for (int i = 0; i < numRuns; i++) {
961
962                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
963                                 y1*res + depthMap->origin[1],
964                                 gridIn->sliceOrigins[zz][2]);
965                    applyInvPersp(pos, newpos);
966                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
967
968                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
969                                 y2*res + depthMap->origin[1],
970                                 gridIn->sliceOrigins[zz][2]);
971                    applyInvPersp(pos, newpos);
972                    xmin = MIN(xmin, int((newpos.x - 
973                                          gridIn->sliceOrigins[zz][0])/res));
974                    xmin = MAX(xmin, 0);
975
976
977                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
978                                 y1*res + depthMap->origin[1],
979                                 gridIn->sliceOrigins[zz][2]);
980                    applyInvPersp(pos, newpos);
981                    xmax = int(ceil((newpos.x - 
982                                     gridIn->sliceOrigins[zz][0])/res));
983
984                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
985                                 y2*res + depthMap->origin[1],
986                                 gridIn->sliceOrigins[zz][2]);
987                    applyInvPersp(pos, newpos);
988                    xmax = MAX(xmax, 
989                               int(ceil((newpos.x - 
990                                         gridIn->sliceOrigins[zz][0])/res)));
991                    xmax = MIN(xmax, gridIn->xdim-1);
992
993
994                    // Copy over all whole runs that precede the current xmin
995
996                    while (nextInOffset < xmin) {
997                        if (nextInOffset != xx) {
998                            appendScanlinePortion(gridIn, inType, inElement, 
999                                                  nextInOffset - xx);
1000                        }
1001                        xx = nextInOffset;
1002
1003                        // Update for next run
1004                        inLength = gridIn->getNextLength();
1005                        inType = gridIn->getRunType(&inLength);
1006                        nextInOffset += inLength; 
1007                        if (inType == OccGridRLE::CONSTANT_DATA) {
1008                            inElement = gridIn->getNextElement();
1009                        }
1010                    }
1011               
1012
1013                    // Copy over the remaining portion of the first
1014                    // overlapping run
1015
1016                    if (xx != xmin) {
1017                        appendScanlinePortion(gridIn, inType, inElement, 
1018                                              xmin - xx);
1019                    }
1020
1021                    xx = xmin;
1022                   
1023                    // Update the output based on new data combined with
1024                    //  old data
1025
1026                    while (xx <= xmax) {
1027
1028                        // If old input run is finished, start a new one
1029
1030                        if (xx == nextInOffset) {
1031                            inLength = gridIn->getNextLength();
1032                            inType = gridIn->getRunType(&inLength);
1033                            nextInOffset += inLength; 
1034                            if (inType == OccGridRLE::CONSTANT_DATA) {
1035                                inElement = gridIn->getNextElement();
1036                            }
1037                        }
1038
1039                        // If varying run, get next element
1040
1041                        if (inType == OccGridRLE::VARYING_DATA) {
1042                            inElement = gridIn->getNextElement();
1043                        }
1044
1045                        // Copy over element and update
1046
1047                        outElement = *inElement;
1048
1049                        if (outElement.totalWeight == 0)
1050                            outElement.value = 0;
1051
1052                        // Write element to the output grid
1053                        appendScanline(&outElement);
1054
1055                        xNewOff++;
1056                        xx++;
1057                    }
1058                }
1059
1060
1061                // Finish up any remaining runs
1062
1063                while (xx < gridOut->xdim) {
1064                    if (nextInOffset != xx) {
1065                        appendScanlinePortion(gridIn, inType, inElement, 
1066                                              nextInOffset - xx);
1067                    }
1068                    xx = nextInOffset;
1069
1070                    // Update for next run
1071                    inLength = gridIn->getNextLength();
1072                    inType = gridIn->getRunType(&inLength);
1073
1074                    if (inType == OccGridRLE::END_OF_RUN) {
1075                        break;
1076                    }
1077
1078                    nextInOffset += inLength; 
1079                    if (inType == OccGridRLE::CONSTANT_DATA) {
1080                        inElement = gridIn->getNextElement();
1081                    }
1082                }
1083
1084                // Seal off the old run
1085                sealScanline();
1086
1087                gridOut->copyScanline(outScanline, yy, zz);
1088                scanline = gridOut->getScanline(yy, zz);
1089                gridIn->copyScanline(outScanline, yy, zz);
1090            }
1091
1092            oldNumRuns += numRuns;
1093
1094            yOff = (y1+y2)/2;
1095            depthRuns = depthMap->getDepthRunsEdges
1096                (yOff, zmin, &numRuns);
1097
1098            if (oldNumRuns == 0 && numRuns == 0) {
1099                rleScanline = gridIn->getRLEScanline(yy, zz);
1100                gridOut->copyScanline(rleScanline, yy, zz);
1101                continue;
1102            } else if (numRuns == 0) {
1103                gridOut->putScanline(scanline,yy,zz);
1104                continue;
1105            } else if (oldNumRuns == 0) {
1106                scanline = gridIn->getScanline(yy,zz);
1107            }
1108
1109            for (int i = 0; i < numRuns; i++) {
1110
1111                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
1112                             y1*res + depthMap->origin[1],
1113                             gridIn->sliceOrigins[zz][2]);
1114                applyInvPersp(pos, newpos);
1115                xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
1116
1117                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
1118                             y2*res + depthMap->origin[1],
1119                             gridIn->sliceOrigins[zz][2]);
1120                applyInvPersp(pos, newpos);
1121                xmin = MIN(xmin, int((newpos.x - 
1122                                      gridIn->sliceOrigins[zz][0])/res));
1123                xmin = MAX(xmin, 0);
1124
1125
1126                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
1127                             y1*res + depthMap->origin[1],
1128                             gridIn->sliceOrigins[zz][2]);
1129                applyInvPersp(pos, newpos);
1130                xmax = int(ceil((newpos.x - 
1131                                 gridIn->sliceOrigins[zz][0])/res));
1132
1133                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
1134                             y2*res + depthMap->origin[1],
1135                             gridIn->sliceOrigins[zz][2]);
1136                applyInvPersp(pos, newpos);
1137                xmax = MAX(xmax, 
1138                           int(ceil((newpos.x - 
1139                                     gridIn->sliceOrigins[zz][0])/res)));
1140                xmax = MIN(xmax, gridIn->xdim-1);
1141
1142                buf = scanline + xmin;
1143                for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
1144
1145                    pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
1146                                 yy*res+gridIn->sliceOrigins[zz][1],
1147                                 gridIn->sliceOrigins[zz][2]);
1148                    applyPersp(pos, newpos);
1149                    xOff = (newpos.x - depthMap->origin[0])/res;
1150                    yOff = (newpos.y - depthMap->origin[1])/res;
1151
1152
1153                    resampleForCarving(depthMap, xOff, yOff, 
1154                                       &depth, &confidence);
1155
1156                    // Setting confidence to zero only allows for carving
1157                    confidence = 0;
1158                    updateCellForCarving(gridIn->sliceOrigins[zz][2], depth, 
1159                                         sampleSpacing, confidence, buf);
1160                }
1161            }
1162
1163            gridOut->putScanline(scanline,yy,zz);
1164        }
1165    }
1166    if (!Quiet)
1167        printf("\n");
1168
1169   
1170    delete inScanline;
1171    delete outScanline;
1172}
1173
1174
1175
1176
1177static void
1178initScanline(OccGridRLE *inGrid, OccScanlineRLE *scanline)
1179{
1180    theInGrid = inGrid;
1181    theOutScanline = scanline;
1182    theOutScanline->reset();
1183    currentLength = 0;
1184}
1185
1186
1187static void
1188appendScanlinePortion(OccGridRLE *inGrid, int inType, 
1189                      OccElement *inElement, RunLength length)
1190{
1191    int i;
1192
1193    if (currentType == inType && currentLength > 0) {
1194
1195        if (currentType == OccGridRLE::CONSTANT_DATA) {
1196
1197            if (inElement->value == lastElement.value &&
1198                inElement->totalWeight == lastElement.totalWeight) {
1199
1200                // If same constant then just increment length.
1201                currentLength += length;
1202            } else {
1203               
1204                // If different constants, then seal old run and start
1205                // a new one
1206                inGrid->setRunType(&currentLength, currentType);
1207                theOutScanline->putNextLength(currentLength);
1208
1209                theOutScanline->putNextElement(inElement);
1210                lastElement = *inElement;
1211                currentLength = length;
1212            }
1213        } else {
1214
1215            // If old and new are varying, then add on new data
1216            for (i = 0; i < length-1; i++) {
1217                theOutScanline->putNextElement(inGrid->getNextElement());
1218            }
1219            lastElement = *(inGrid->getNextElement());
1220            theOutScanline->putNextElement(&lastElement);
1221            currentLength += length;
1222        }
1223    }
1224    else {
1225        // If different, then seal up the old run and start a
1226        // new one
1227
1228        if (currentLength > 0) {
1229            inGrid->setRunType(&currentLength, currentType);
1230            theOutScanline->putNextLength(currentLength);
1231        }
1232       
1233        if (inType == OccGridRLE::CONSTANT_DATA) {
1234            theOutScanline->putNextElement(inElement);
1235            lastElement = *inElement;
1236        } else {
1237            for (i = 0; i < length-1; i++) {
1238                theOutScanline->putNextElement(inGrid->getNextElement());
1239            }
1240            lastElement = *(inGrid->getNextElement());
1241            theOutScanline->putNextElement(&lastElement);
1242        }
1243        currentLength = length;
1244        currentType = inType;
1245    }
1246}
1247
1248
1249static void
1250appendScanline(OccElement *inElement)
1251{
1252    int i, inType;
1253
1254    inType = theInGrid->decideType(inElement);
1255    if (currentType == inType && currentLength > 0) {
1256        if (currentType == OccGridRLE::CONSTANT_DATA) {
1257            if (inElement->value == lastElement.value &&
1258                inElement->totalWeight == lastElement.totalWeight) {
1259
1260                // If same constant then just increment length.
1261                currentLength++;
1262            } else {
1263
1264                // If different constants, then seal old run and start
1265                // a new one
1266                theInGrid->setRunType(&currentLength, currentType);
1267                theOutScanline->putNextLength(currentLength);
1268                theOutScanline->putNextElement(inElement);
1269                lastElement = *inElement;
1270                currentLength = 1;
1271            }
1272        } else {
1273
1274            // If old and new are varying, then add on new data
1275            theOutScanline->putNextElement(inElement);
1276            lastElement = *inElement;
1277            currentLength++;
1278        }
1279    }
1280    else {
1281        // If different, then seal up the old run and start a
1282        // new one
1283
1284        if (currentLength > 0) {
1285            theInGrid->setRunType(&currentLength, currentType);
1286            theOutScanline->putNextLength(currentLength);
1287        }
1288
1289        lastElement = *inElement;
1290        theOutScanline->putNextElement(inElement);
1291        currentLength = 1;
1292        currentType = inType;
1293    }
1294}
1295
1296
1297static void
1298sealScanline()
1299{
1300    theInGrid->setRunType(&currentLength, currentType);
1301    theOutScanline->putNextLength(currentLength);
1302    theOutScanline->putNextLength(OccGridRLE::END_OF_RUN);         
1303}
1304
1305
Note: See TracBrowser for help on using the repository browser.