Move the sources to trunk
[opencv] / apps / VMDemo / PixelToPixelMorpher.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41 #include "stdafx.h"
42 #include <malloc.h>
43 #include <assert.h>
44 #include <memory.h>
45 #include <stdio.h>
46 #include <math.h>
47 #include "SubdivMorpher.h"
48
49 #define MAX_DIFFERENCE 20
50 #define COEFF_OCC 30
51 #define COEFF_MATCH 30
52 #define COEFF_MATCH_2 64
53 #define END_OF_PATH 1000000000
54
55 #define MAX3(xxx1,xxx2,xxx3) ( ( ( (xxx1) > (xxx2) ) && ( (xxx1) > xxx3 ) ) ? (xxx1) : ( ( (xxx2) > (xxx3) ) ? (xxx2) : (xxx3) ) )
56 #define MAX2(xxx1,xxx2) ( ( (xxx1) > (xxx2) ) ? (xxx1) : (xxx2) )
57 #define MIN3(xxx1,xxx2,xxx3) ( ( ( (xxx1) < (xxx2) ) && ( (xxx1) < xxx3 ) ) ? (xxx1) : ( ( (xxx2) < (xxx3) ) ? (xxx2) : (xxx3) ) )
58 #define MIN2(xxx1,xxx2) ( ( (xxx1) < (xxx2) ) ? (xxx1) : (xxx2) )
59
60 // This function allocates memory for FindFullCorr function
61 //      width               - width of image
62 //      height              - height of image
63 //      type                - type of memory for allocate ( the size of memory depends on it )
64 //      maxPixelDifference  - maximum value of pixel difference on two images
65 int* CCvPixelToPixelMorpher::corrAlloc( int width, int height, corrArrayType type, int maxPixelDifference )
66 {
67     int* pointer;
68     switch( type )
69     {
70     case CORR_ARRAY:
71         {
72             pointer = ( int* ) malloc( width * height * 2 * sizeof( int ) );
73         }
74         break;
75     case NUM_CORR_ARRAY:
76         {
77             pointer = ( int* ) malloc( height * sizeof( int ) );
78         }
79         break;
80     case CORR_EDGES:
81         {
82             int i;
83             int width_1 = width - 1;
84
85             pointer = ( int* ) malloc( width * 2 * sizeof( int ) );
86             for( i = 0; i < width; i ++ ) {
87                 pointer[ i * 2 ]      = i - maxPixelDifference;
88                 pointer[ i * 2 + 1 ]  = i + maxPixelDifference;
89             } // for( i = 0; i < width; i ++ )
90             for( i = 0; i < width; i ++ ) {
91                 if( pointer[ i * 2 ] < 0 ) {
92                     pointer[ i * 2 ]      = 0;
93                 }
94                 if( pointer[ i * 2 + 1 ] >= width ) {
95                     pointer[ i * 2 + 1 ]  = width_1;
96                 }
97             } // for( i = 0; i < width; i ++ )
98
99         } // case CORR_EDGES:
100         break;
101     case CORR_TEMP:
102         {
103             pointer = ( int* ) malloc( width * width * 4 * sizeof( int ) );
104         }
105         break;
106     default:
107         {
108             pointer = 0;
109         }
110
111     } // switch( type )
112
113     return pointer;
114 } // corrAlloc
115
116 // This function searches correspondences for full image
117 //      _leftImage              - pointer to 3-channel left image
118 //      _leftLineStep           - size of one line on the left image in bytes
119 //      _rightImage             - pointer to 3-channel right image
120 //      _rightLineStep          - size of one line on the right image in bytes
121 //      _corrArray              - output integer array of correspondences ( size (width)X(height)X(2) ).
122 //                                each element of its array consists of two integer values, one of
123 //                                which represents number of pixel on the left image and the other
124 //                                corresponding to it point on the right image
125 //      _numCorrArray           - output array with numbers of finded correspondences on each line
126 //      width                   - width of images
127 //      height                  - height of images
128 //      maxPixelDifference      - maximum value of pixel difference on two images
129 void CCvPixelToPixelMorpher::FindFullCorr( unsigned char* _leftImage,
130                    int _leftLineStep,
131                    unsigned char* _rightImage,
132                    int _rightLineStep,
133                    int* _corrArray,
134                    int* _numCorrArray,
135                    int width,
136                    int height,
137                    int maxPixelDifference
138                  )
139 {
140     //int     width2 = width * width;
141     //int     tempMemorySize = width2 * 4 * sizeof( int );
142     int*    tempMemory;
143
144     tempMemory  = corrAlloc( width, height, CORR_TEMP );
145
146     int*    edges   = corrAlloc( width, height, CORR_EDGES, maxPixelDifference );
147
148     int j;
149
150     // lines cycle - processes each line
151     for( j = 0; j < height; j ++ )
152     {
153         FindCorr( _leftImage + _leftLineStep * j,
154                   _rightImage + _rightLineStep * j,
155                   _corrArray + width * 2 * j,
156                   _numCorrArray + j,
157                   width,
158                   edges,
159                   tempMemory
160                 );
161     } // for( j = 0; j < height; j ++ )
162
163     free( edges );
164     free( tempMemory );
165
166 } // FindFullCorr
167
168 // This function searches correspondence for one line only
169 //      _leftLine
170 void CCvPixelToPixelMorpher::FindCorr( unsigned char* _leftLine,
171                unsigned char* _rightLine,
172                int* _corrArray,
173                int* numCorrArray,
174                int width,
175                int* edges,
176                int* tempArray
177              )
178 {
179     int     width2      = width * width;
180     int     width_1     = width - 1;
181     int*    xArray      = tempArray;                // array, which shows the best previous point in path
182     int*    yArray      = tempArray + width2;       // array, which shows the best previous point in path
183     int*    costArray   = tempArray + width2 * 2;   // array of costs table
184     int*    distArray   = tempArray + width2 * 3;   // array of distances between points on two images
185
186     int blockSize = width2 * sizeof( int );
187     memset( ( void* ) xArray, 0, blockSize );               // filling by zero
188     memset( ( void* ) yArray, 0, blockSize );               // filling by zero
189     memset( ( void* ) distArray, 0, blockSize );            // filling by zero
190
191     int i;
192     int j;
193     int iTemp;
194     int jTemp;
195
196     int currCost;
197     int bestHorCost;
198
199     int srcOffset;
200     int destOffset;
201     int futureCost;
202
203     // filling cost table by very big value ( initialization )
204     for( j = 0; j < width; j ++ )
205     {
206         for( i = edges[ j * 2 ]; i <= edges[ j * 2 + 1 ]; i ++ )
207         {
208             costArray[ j * width + i ] = 2000000000;    // filling by very big value
209
210         } // for( i = edges[ j * 2 ]; i < edges[ j * 2 + 1 ]; i ++ )
211
212     } // for( j = 0; j < width; j ++ )
213
214     // computing distances for all pairs of points ( between points on left image and on right image )
215     for( j = 0; j < width; j ++ )
216     {
217         for( i = edges[ j * 2 ]; i <= edges[ j * 2 + 1 ]; i ++ )
218         {
219             distArray[ j * width + i ] = distance( _leftLine, _rightLine, width, j, i );
220
221         } // for( i = edges[ j * 2 ]; i < edges[ j * 2 + 1 ]; i ++ )
222
223     } // for( j = 0; j < width; j ++ )
224
225     // filling left upper corner
226     for( i = edges[ 0 ]; i <= edges[ 1 ]; i ++ )
227     {
228         // horizontal line
229         xArray[ i ]             = END_OF_PATH;
230         costArray[ i ]          = *( distArray + i );
231         // vertical line
232         xArray[ i * width ]     = END_OF_PATH;
233         costArray[ i * width ]  = *( distArray + i * width );
234     } // for( i = edges[ 0 ]; i <= edges[ 1 ]; i ++ )
235
236     // normal dynamic programming
237     for( j = 0; j < width_1; j ++ )
238     {
239         bestHorCost = costArray[ j * width + edges[ j * 2 ] ];
240         //bestHorCost = 2000000000;
241         for( i = edges[ j * 2 ]; i <= edges[ j * 2 + 1 ]; i ++ )
242         {
243             srcOffset   = j * width + i;
244             currCost    = costArray[ srcOffset ];
245             if( currCost - COEFF_MATCH < bestHorCost + COEFF_OCC )
246             {
247                 bestHorCost = currCost;
248
249                 // filling the next horizontal line
250
251                 // first point
252                 if( i != width - 1 )
253                 {
254                     destOffset  = j * width + ( i + width + 1 );
255                     futureCost  = currCost + distArray[ destOffset ];
256                     if( ( xArray[ srcOffset ] == i - 1 ) && ( yArray[ srcOffset ] == j - 1 ) ) {
257                         futureCost -= COEFF_MATCH;
258                     }
259                     if( ( xArray[ srcOffset ] != i - 1 ) || ( yArray[ srcOffset ] != j - 1 ) ) {
260                         futureCost -= COEFF_MATCH_2;
261                     }
262                     if( costArray[ destOffset ] >= futureCost ) {
263                         costArray[ destOffset ]     = futureCost;
264                         xArray[ destOffset ]        = i;
265                         yArray[ destOffset ]        = j;
266                     }
267                 }
268                 // residuary points ( if they exist )
269                 for( iTemp = i + 2; iTemp <= edges[ j * 2 + 3 ]; iTemp ++ )
270                 {
271                     destOffset  = j * width + ( iTemp + width );
272                     futureCost  = currCost + COEFF_OCC + distArray[ destOffset ];
273                     if( costArray[ destOffset ] >= futureCost ) {
274                         costArray[ destOffset ]     = futureCost;
275                         xArray[ destOffset ]        = i;
276                         yArray[ destOffset ]        = j;
277                     }
278
279                 } // for( iTemp = i + 2; iTemp <= edges[ j * 2 + 3 ]; iTemp ++ )
280
281             } // if( currCost - COEFF_MATCH < bestHorCost + COEFF_OCC )
282
283             // filling the next vertical line
284             if( i != width_1 )
285             {
286                 for( jTemp = j + 2; jTemp <= edges[ i * 2 + 3 ]; jTemp ++ )
287                 {
288                     destOffset  = jTemp * width + ( i + 1 );
289                     futureCost  = currCost + COEFF_OCC + distArray[ destOffset ];
290                     if( costArray[ destOffset ] >= futureCost ) {
291                         costArray[ destOffset ]     = futureCost;
292                         xArray[ destOffset ]        = i;
293                         yArray[ destOffset ]        = j;
294                     }
295                 } // for( jTemp = j + 2; jTemp <= edges[ i * 2 + 3 ]; jTemp ++ )
296
297             } // if( i != width_1 )
298
299         } // for( i = edges[ j * 2 ]; i <= edges[ j * 2 + 1 ]; i ++ )
300
301     } // for( j = 1; j < width; j ++ )
302
303     // constraction of back path
304
305     // searching for best initial point in the low right corner
306     jTemp   = width - 1;
307     i       = jTemp;
308     j       = jTemp;
309     int bestCost = costArray[ j * width + i ];
310     for( iTemp = edges[ width * 2 - 2 ]; iTemp < edges[ width * 2 - 1 ]; iTemp ++ )
311     {
312         if( costArray[ jTemp * width + iTemp ] < bestCost ) {
313             i           = iTemp;
314             j           = jTemp;
315             bestCost    = costArray[ jTemp * width + iTemp ];
316         }
317     }
318     iTemp   = width - 1;
319     for( jTemp = edges[ width * 2 - 2 ]; jTemp < edges[ width * 2 - 1 ]; jTemp ++ )
320     {
321         if( costArray[ jTemp * width + iTemp ] < bestCost ) {
322             i           = iTemp;
323             j           = jTemp;
324             bestCost    = costArray[ jTemp * width + iTemp ];
325         }
326     }
327
328     // filling back path
329     *( numCorrArray )  = 0;
330     _corrArray[ *( numCorrArray ) ]     = j;
331     ( *( numCorrArray ) ) ++;
332     _corrArray[ *( numCorrArray ) ]     = i;
333     ( *( numCorrArray ) ) ++;
334
335     srcOffset   = j * width + i;
336     while( xArray[ srcOffset ] != END_OF_PATH )
337     {
338         i   = xArray[ srcOffset ];
339         j   = yArray[ srcOffset ];
340         _corrArray[ *( numCorrArray ) ]     = j;
341         ( *( numCorrArray ) ) ++;
342         _corrArray[ *( numCorrArray ) ]     = i;
343         ( *( numCorrArray ) ) ++;
344         srcOffset   = j * width + i;
345     } // while( xArray[ j * width + i ] != END_OF_PATH )
346
347     *( numCorrArray ) /= 2;
348
349 } // FindCorr
350
351 // This function produces morphing of two images into one image, which includes morphed
352 // image or depth map
353 //      _leftImage              - pointer to left image
354 //      _leftLineStep           - size of line on left image in bytes
355 //      _rightImage             - pointer to right image
356 //      _rightLineStep          - size of line on right image in bytes
357 //      _resultImage            - pointer to result morphed image
358 //      _resultLineStep         - size of line on result image in bytes
359 //      _corrArray              - pointer to array with correspondences
360 //      _numCorrArray           - pointer to array with numbers correspondeces on each line
361 //      width                   - width of images
362 //      height                  - height of images
363 //      alpha                   - position of virtual camera ( 0 corresponds to left image, 1 - to right one )
364 //      imageNeed               - defines your wishes. if you want to see normal morphed image you have to set
365 //                                this parameter to morphNormalImage ( this is default value ), else if you want
366 //                                to see depth map you have to set this parameter to morphDepthMap and set the
367 //                                next parameter ( maxPixelDifference ) to real value
368 //      maxPixelDifference      - maximum value of pixel difference on two images
369 void CCvPixelToPixelMorpher::Morph( unsigned char* _leftImage,
370             int _leftLineStep,
371             unsigned char* _rightImage,
372             int _rightLineStep,
373             unsigned char* _resultImage,
374             int _resultLineStep,
375             int* _corrArray,
376             int* _numCorrArray,
377             int width,
378             int height,
379             float alpha,
380             morphImageType imageNeed,
381             int maxDifference
382           )
383 {
384     unsigned char* leftArray    = _leftImage;
385     unsigned char* middleArray  = _resultImage;
386     unsigned char* rightArray   = _rightImage;
387     int leftLineSize            = _leftLineStep;
388     int middleLineSize          = _resultLineStep;
389     int rightLineSize           = _rightLineStep;
390
391     int lineNumber;
392     unsigned char* leftTemp;
393     unsigned char* middleTemp;
394     unsigned char* rightTemp;
395     int leftPixel;
396     int prevLeftPixel;
397     int middlePixel;
398     int prevMiddlePixel;
399     int rightPixel;
400     int prevRightPixel;
401     int leftPixel3;
402     int middlePixel3;
403     int rightPixel3;
404     int i;
405     int j;
406     int tempIndex;
407     int* result;
408     int number;
409     float alpha1        = 1.0f - alpha;
410     
411     for( lineNumber = 0; lineNumber < height; lineNumber ++ )
412     {
413         leftTemp    = leftArray + leftLineSize * lineNumber;
414         middleTemp  = middleArray + middleLineSize * lineNumber;
415         rightTemp   = rightArray + rightLineSize * lineNumber;
416         memset( ( void* )middleTemp, 0, middleLineSize );
417
418         result = _corrArray + width * 2 * lineNumber;
419         number = _numCorrArray[ lineNumber ];
420         
421         prevLeftPixel   = result[ number * 2 - 2 ];
422         prevMiddlePixel = (int)( result[ number * 2 - 2 ] * alpha1 + result[ number * 2 - 1 ] * alpha );
423         prevRightPixel  = result[ number * 2 - 1 ];
424         for( i = number - 1; i >= 0; i -- )
425         {
426             leftPixel       = result[ i * 2 ];
427             rightPixel      = result[ i * 2 + 1 ];
428             middlePixel     = (int)( leftPixel * alpha1 + rightPixel * alpha );
429             leftPixel3      = leftPixel * 3;
430             middlePixel3    = middlePixel * 3;
431             rightPixel3     = rightPixel * 3;
432             
433             if( imageNeed == morphDepthMap ) {
434                 int t   = leftPixel - rightPixel + maxDifference;
435                 t       = t < 0 ? -t : t;
436                 t       = t * 255 / maxDifference / 2;
437                 middleTemp[ middlePixel3 ]      = ( unsigned char )t;
438                 middleTemp[ middlePixel3 + 1 ]  = ( unsigned char )t;
439                 middleTemp[ middlePixel3 + 2 ]  = ( unsigned char )t;
440             } // if( imageNeed == morphDepthMap )
441             else
442             {
443                 middleTemp[ middlePixel3 ] =
444                     (unsigned char)( leftTemp[ leftPixel3 ] * alpha1 + rightTemp[ rightPixel3 ] * alpha );
445                 middleTemp[ middlePixel3 + 1 ] =
446                     (unsigned char)( leftTemp[ leftPixel3 + 1 ] * alpha1 + rightTemp[ rightPixel3 + 1 ] * alpha );
447                 middleTemp[ middlePixel3 + 2 ] =
448                     (unsigned char)( leftTemp[ leftPixel3 + 2 ] * alpha1 + rightTemp[ rightPixel3 + 2 ] * alpha );
449
450                 if( middlePixel - prevMiddlePixel > 1 ) // occlusion
451                 {
452                     if( leftPixel - prevLeftPixel > 1 )
453                     {
454                         int LenSrc  = leftPixel - prevLeftPixel - 2;
455                         int LenDest = middlePixel - prevMiddlePixel - 1;
456                         for( j = prevMiddlePixel + 1; j < middlePixel; j ++ )
457                         {
458                             tempIndex   = prevLeftPixel + 1 + LenSrc * ( j - prevMiddlePixel - 1 ) / LenDest;
459                             middleTemp[ j * 3 ]     = leftTemp[ tempIndex * 3 ];
460                             middleTemp[ j * 3 + 1 ] = leftTemp[ tempIndex * 3 + 1 ];
461                             middleTemp[ j * 3 + 2 ] = leftTemp[ tempIndex * 3 + 2 ];
462                         }
463                     } // if( leftPixel - prevLeftPixel > 1 )
464                     else
465                     {
466                         int LenSrc  = rightPixel - prevRightPixel - 2;
467                         int LenDest = middlePixel - prevMiddlePixel - 1;
468                         for( j = prevMiddlePixel + 1; j < middlePixel; j ++ )
469                         {
470                             tempIndex   = prevRightPixel + 1 + LenSrc * ( j - prevMiddlePixel - 1 ) / LenDest;
471                             middleTemp[ j * 3 ]     = rightTemp[ tempIndex * 3 ];
472                             middleTemp[ j * 3 + 1 ] = rightTemp[ tempIndex * 3 + 1 ];
473                             middleTemp[ j * 3 + 2 ] = rightTemp[ tempIndex * 3 + 2 ];
474                         }
475                     } // if( leftPixel - prevLeftPixel > 1 ) else
476                     
477                 } // if( middlePixel - prevMiddlePixel > 1 )
478
479             } // if( imageNeed == morphDepthMap ) else
480             prevLeftPixel   = leftPixel;
481             prevRightPixel  = rightPixel;
482             prevMiddlePixel = middlePixel;
483         } // for( i = number - 1; i >= 0; i -- )
484         
485     } // for( lineNumber = 0; lineNumber < LeftImage -> m_Raster -> GetHeight() )
486
487 } // Morph
488
489 // This function calculates color difference between two points ( one on the left image and one on the other )
490 //      _leftLine               - pointer to line on the left image
491 //      _rightLine              - pointer to line on the right image
492 //      lineSize                - width of line in points
493 //      x                       - index of interesting point on the left image
494 //      y                       - index of interesting point on the right image
495 int CCvPixelToPixelMorpher::distance( unsigned char* _leftLine,
496                                       unsigned char* _rightLine,
497                                       int lineSize,
498                                       int x,
499                                       int y
500                                     )
501 {
502     int IrMaxRed;
503     int IrMinRed;
504     int IrMaxGreen;
505     int IrMinGreen;
506     int IrMaxBlue;
507     int IrMinBlue;
508
509     int IlMaxRed;
510     int IlMinRed;
511     int IlMaxGreen;
512     int IlMinGreen;
513     int IlMaxBlue;
514     int IlMinBlue;
515
516     int DlRed;
517     int DlGreen;
518     int DlBlue;
519
520     int DrRed;
521     int DrGreen;
522     int DrBlue;
523
524     int DRed;
525     int DGreen;
526     int DBlue;
527
528     int dist;
529
530     int temp1;
531     int temp2;
532
533
534     int xState = 0;
535     int yState = 0;
536     int state;
537
538     assert( lineSize > 0 );
539
540     _Color* leftPixel       = ( _Color* )( _leftLine ) + x;
541     _Color* rightPixel      = ( _Color* )( _rightLine ) + y;
542
543     if( lineSize == 1 ) {
544         DRed = leftPixel->red - rightPixel->red;
545         DRed = MAX2( DRed, -DRed );
546         DGreen = leftPixel->green - rightPixel->green;
547         DGreen = MAX2( DGreen, -DGreen );
548         DBlue = leftPixel->blue - rightPixel->blue;
549         DBlue = MAX2( DBlue, -DBlue );
550         return MAX3( DRed, DGreen, DBlue );
551     }
552
553     if( x == 0 ) {
554         xState = -1;
555     }
556     else if( x == lineSize - 1 )
557     {
558         xState = 1;
559     }
560
561     if( y == 0 ) {
562         yState = -1;
563     }
564     else if( y == lineSize - 1 )
565     {
566         yState = 1;
567     }
568
569     state = yState * 3 + xState;
570
571     switch( state )
572     {
573     case 0: // xState = yState = 0
574         {
575             // Red
576             temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
577             temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
578             IlMaxRed = MAX3( leftPixel->red, temp1, temp2 );
579             IlMinRed = MIN3( leftPixel->red, temp1, temp2 );
580             temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
581             temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
582             IrMaxRed = MAX3( rightPixel->red, temp1, temp2 );
583             IrMinRed = MIN3( rightPixel->red, temp1, temp2 );
584             // Green
585             temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
586             temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
587             IlMaxGreen = MAX3( leftPixel->green, temp1, temp2 );
588             IlMinGreen = MIN3( leftPixel->green, temp1, temp2 );
589             temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
590             temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
591             IrMaxGreen = MAX3( rightPixel->green, temp1, temp2 );
592             IrMinGreen = MIN3( rightPixel->green, temp1, temp2 );
593             // Blue
594             temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
595             temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
596             IlMaxBlue = MAX3( leftPixel->blue, temp1, temp2 );
597             IlMinBlue = MIN3( leftPixel->blue, temp1, temp2 );
598             temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
599             temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
600             IrMaxBlue = MAX3( rightPixel->blue, temp1, temp2 );
601             IrMinBlue = MIN3( rightPixel->blue, temp1, temp2 );
602
603             // Red
604             temp1 = leftPixel->red - IrMaxRed;
605             temp2 = IrMinRed - leftPixel->red;
606             DlRed = MAX3( 0, temp1, temp2 );
607             temp1 = rightPixel->red - IlMaxRed;
608             temp2 = IlMinRed - rightPixel->red;
609             DrRed = MAX3( 0, temp1, temp2 );
610             // Green
611             temp1 = leftPixel->green - IrMaxGreen;
612             temp2 = IrMinGreen - leftPixel->green;
613             DlGreen = MAX3( 0, temp1, temp2 );
614             temp1 = rightPixel->green - IlMaxGreen;
615             temp2 = IlMinGreen - rightPixel->green;
616             DrGreen = MAX3( 0, temp1, temp2 );
617             // Blue
618             temp1 = leftPixel->blue - IrMaxBlue;
619             temp2 = IrMinBlue - leftPixel->blue;
620             DlBlue = MAX3( 0, temp1, temp2 );
621             temp1 = rightPixel->blue - IlMaxBlue;
622             temp2 = IlMinBlue - rightPixel->blue;
623             DrBlue = MAX3( 0, temp1, temp2 );
624
625         } // case 0
626         break;
627     case -1: // xState = -1, yState = 0
628         {
629             // Red
630             temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
631             IlMaxRed = MAX2( leftPixel->red, temp2 );
632             IlMinRed = MIN2( leftPixel->red, temp2 );
633             temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
634             temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
635             IrMaxRed = MAX3( rightPixel->red, temp1, temp2 );
636             IrMinRed = MIN3( rightPixel->red, temp1, temp2 );
637             // Green
638             temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
639             IlMaxGreen = MAX2( leftPixel->green, temp2 );
640             IlMinGreen = MIN2( leftPixel->green, temp2 );
641             temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
642             temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
643             IrMaxGreen = MAX3( rightPixel->green, temp1, temp2 );
644             IrMinGreen = MIN3( rightPixel->green, temp1, temp2 );
645             // Blue
646             temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
647             IlMaxBlue = MAX2( leftPixel->blue, temp2 );
648             IlMinBlue = MIN2( leftPixel->blue, temp2 );
649             temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
650             temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
651             IrMaxBlue = MAX3( rightPixel->blue, temp1, temp2 );
652             IrMinBlue = MIN3( rightPixel->blue, temp1, temp2 );
653
654             // Red
655             temp1 = leftPixel->red - IrMaxRed;
656             temp2 = IrMinRed - leftPixel->red;
657             DlRed = MAX3( 0, temp1, temp2 );
658             temp1 = rightPixel->red - IlMaxRed;
659             temp2 = IlMinRed - rightPixel->red;
660             DrRed = MAX3( 0, temp1, temp2 );
661             // Green
662             temp1 = leftPixel->green - IrMaxGreen;
663             temp2 = IrMinGreen - leftPixel->green;
664             DlGreen = MAX3( 0, temp1, temp2 );
665             temp1 = rightPixel->green - IlMaxGreen;
666             temp2 = IlMinGreen - rightPixel->green;
667             DrGreen = MAX3( 0, temp1, temp2 );
668             // Blue
669             temp1 = leftPixel->blue - IrMaxBlue;
670             temp2 = IrMinBlue - leftPixel->blue;
671             DlBlue = MAX3( 0, temp1, temp2 );
672             temp1 = rightPixel->blue - IlMaxBlue;
673             temp2 = IlMinBlue - rightPixel->blue;
674             DrBlue = MAX3( 0, temp1, temp2 );
675
676         } // case -1
677         break;
678     case 1: // xState = 1, yState = 0
679         {
680             // Red
681             temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
682             IlMaxRed = MAX2( leftPixel->red, temp1 );
683             IlMinRed = MIN2( leftPixel->red, temp1 );
684             temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
685             temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
686             IrMaxRed = MAX3( rightPixel->red, temp1, temp2 );
687             IrMinRed = MIN3( rightPixel->red, temp1, temp2 );
688             // Green
689             temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
690             IlMaxGreen = MAX2( leftPixel->green, temp1 );
691             IlMinGreen = MIN2( leftPixel->green, temp1 );
692             temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
693             temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
694             IrMaxGreen = MAX3( rightPixel->green, temp1, temp2 );
695             IrMinGreen = MIN3( rightPixel->green, temp1, temp2 );
696             // Blue
697             temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
698             IlMaxBlue = MAX2( leftPixel->blue, temp1 );
699             IlMinBlue = MIN2( leftPixel->blue, temp1 );
700             temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
701             temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
702             IrMaxBlue = MAX3( rightPixel->blue, temp1, temp2 );
703             IrMinBlue = MIN3( rightPixel->blue, temp1, temp2 );
704
705             // Red
706             temp1 = leftPixel->red - IrMaxRed;
707             temp2 = IrMinRed - leftPixel->red;
708             DlRed = MAX3( 0, temp1, temp2 );
709             temp1 = rightPixel->red - IlMaxRed;
710             temp2 = IlMinRed - rightPixel->red;
711             DrRed = MAX3( 0, temp1, temp2 );
712             // Green
713             temp1 = leftPixel->green - IrMaxGreen;
714             temp2 = IrMinGreen - leftPixel->green;
715             DlGreen = MAX3( 0, temp1, temp2 );
716             temp1 = rightPixel->green - IlMaxGreen;
717             temp2 = IlMinGreen - rightPixel->green;
718             DrGreen = MAX3( 0, temp1, temp2 );
719             // Blue
720             temp1 = leftPixel->blue - IrMaxBlue;
721             temp2 = IrMinBlue - leftPixel->blue;
722             DlBlue = MAX3( 0, temp1, temp2 );
723             temp1 = rightPixel->blue - IlMaxBlue;
724             temp2 = IlMinBlue - rightPixel->blue;
725             DrBlue = MAX3( 0, temp1, temp2 );
726
727         } // case 1
728         break;
729     case -3: // xState = 0, yState = -1
730         {
731             // Red
732             temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
733             temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
734             IlMaxRed = MAX3( leftPixel->red, temp1, temp2 );
735             IlMinRed = MIN3( leftPixel->red, temp1, temp2 );
736             temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
737             IrMaxRed = MAX2( rightPixel->red, temp2 );
738             IrMinRed = MIN2( rightPixel->red, temp2 );
739             // Green
740             temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
741             temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
742             IlMaxGreen = MAX3( leftPixel->green, temp1, temp2 );
743             IlMinGreen = MIN3( leftPixel->green, temp1, temp2 );
744             temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
745             IrMaxGreen = MAX2( rightPixel->green, temp2 );
746             IrMinGreen = MIN2( rightPixel->green, temp2 );
747             // Blue
748             temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
749             temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
750             IlMaxBlue = MAX3( leftPixel->blue, temp1, temp2 );
751             IlMinBlue = MIN3( leftPixel->blue, temp1, temp2 );
752             temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
753             IrMaxBlue = MAX2( rightPixel->blue, temp2 );
754             IrMinBlue = MIN2( rightPixel->blue, temp2 );
755
756             // Red
757             temp1 = leftPixel->red - IrMaxRed;
758             temp2 = IrMinRed - leftPixel->red;
759             DlRed = MAX3( 0, temp1, temp2 );
760             temp1 = rightPixel->red - IlMaxRed;
761             temp2 = IlMinRed - rightPixel->red;
762             DrRed = MAX3( 0, temp1, temp2 );
763             // Green
764             temp1 = leftPixel->green - IrMaxGreen;
765             temp2 = IrMinGreen - leftPixel->green;
766             DlGreen = MAX3( 0, temp1, temp2 );
767             temp1 = rightPixel->green - IlMaxGreen;
768             temp2 = IlMinGreen - rightPixel->green;
769             DrGreen = MAX3( 0, temp1, temp2 );
770             // Blue
771             temp1 = leftPixel->blue - IrMaxBlue;
772             temp2 = IrMinBlue - leftPixel->blue;
773             DlBlue = MAX3( 0, temp1, temp2 );
774             temp1 = rightPixel->blue - IlMaxBlue;
775             temp2 = IlMinBlue - rightPixel->blue;
776             DrBlue = MAX3( 0, temp1, temp2 );
777
778         } // case -3
779         break;
780     case 3: // xState = 0, yState = 1
781         {
782             // Red
783             temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
784             temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
785             IlMaxRed = MAX3( leftPixel->red, temp1, temp2 );
786             IlMinRed = MIN3( leftPixel->red, temp1, temp2 );
787             temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
788             IrMaxRed = MAX2( rightPixel->red, temp1 );
789             IrMinRed = MIN2( rightPixel->red, temp1 );
790             // Green
791             temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
792             temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
793             IlMaxGreen = MAX3( leftPixel->green, temp1, temp2 );
794             IlMinGreen = MIN3( leftPixel->green, temp1, temp2 );
795             temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
796             IrMaxGreen = MAX2( rightPixel->green, temp1 );
797             IrMinGreen = MIN2( rightPixel->green, temp1 );
798             // Blue
799             temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
800             temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
801             IlMaxBlue = MAX3( leftPixel->blue, temp1, temp2 );
802             IlMinBlue = MIN3( leftPixel->blue, temp1, temp2 );
803             temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
804             IrMaxBlue = MAX2( rightPixel->blue, temp1 );
805             IrMinBlue = MIN2( rightPixel->blue, temp1 );
806
807             // Red
808             temp1 = leftPixel->red - IrMaxRed;
809             temp2 = IrMinRed - leftPixel->red;
810             DlRed = MAX3( 0, temp1, temp2 );
811             temp1 = rightPixel->red - IlMaxRed;
812             temp2 = IlMinRed - rightPixel->red;
813             DrRed = MAX3( 0, temp1, temp2 );
814             // Green
815             temp1 = leftPixel->green - IrMaxGreen;
816             temp2 = IrMinGreen - leftPixel->green;
817             DlGreen = MAX3( 0, temp1, temp2 );
818             temp1 = rightPixel->green - IlMaxGreen;
819             temp2 = IlMinGreen - rightPixel->green;
820             DrGreen = MAX3( 0, temp1, temp2 );
821             // Blue
822             temp1 = leftPixel->blue - IrMaxBlue;
823             temp2 = IrMinBlue - leftPixel->blue;
824             DlBlue = MAX3( 0, temp1, temp2 );
825             temp1 = rightPixel->blue - IlMaxBlue;
826             temp2 = IlMinBlue - rightPixel->blue;
827             DrBlue = MAX3( 0, temp1, temp2 );
828
829         } // case 3
830         break;
831     case -2: // xState = 1, yState = -1
832         {
833             // Red
834             temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
835             IlMaxRed = MAX2( leftPixel->red, temp1 );
836             IlMinRed = MIN2( leftPixel->red, temp1 );
837             temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
838             IrMaxRed = MAX2( rightPixel->red, temp2 );
839             IrMinRed = MIN2( rightPixel->red, temp2 );
840             // Green
841             temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
842             IlMaxGreen = MAX2( leftPixel->green, temp1 );
843             IlMinGreen = MIN2( leftPixel->green, temp1 );
844             temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
845             IrMaxGreen = MAX2( rightPixel->green, temp2 );
846             IrMinGreen = MIN2( rightPixel->green, temp2 );
847             // Blue
848             temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
849             IlMaxBlue = MAX2( leftPixel->blue, temp1 );
850             IlMinBlue = MIN2( leftPixel->blue, temp1 );
851             temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
852             IrMaxBlue = MAX2( rightPixel->blue, temp2 );
853             IrMinBlue = MIN2( rightPixel->blue, temp2 );
854
855             // Red
856             temp1 = leftPixel->red - IrMaxRed;
857             temp2 = IrMinRed - leftPixel->red;
858             DlRed = MAX3( 0, temp1, temp2 );
859             temp1 = rightPixel->red - IlMaxRed;
860             temp2 = IlMinRed - rightPixel->red;
861             DrRed = MAX3( 0, temp1, temp2 );
862             // Green
863             temp1 = leftPixel->green - IrMaxGreen;
864             temp2 = IrMinGreen - leftPixel->green;
865             DlGreen = MAX3( 0, temp1, temp2 );
866             temp1 = rightPixel->green - IlMaxGreen;
867             temp2 = IlMinGreen - rightPixel->green;
868             DrGreen = MAX3( 0, temp1, temp2 );
869             // Blue
870             temp1 = leftPixel->blue - IrMaxBlue;
871             temp2 = IrMinBlue - leftPixel->blue;
872             DlBlue = MAX3( 0, temp1, temp2 );
873             temp1 = rightPixel->blue - IlMaxBlue;
874             temp2 = IlMinBlue - rightPixel->blue;
875             DrBlue = MAX3( 0, temp1, temp2 );
876
877         } // case -2
878         break;
879     case 2: // xState = -1, yState = 1
880         {
881             // Red
882             temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
883             IlMaxRed = MAX2( leftPixel->red, temp2 );
884             IlMinRed = MIN2( leftPixel->red, temp2 );
885             temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
886             IrMaxRed = MAX2( rightPixel->red, temp1 );
887             IrMinRed = MIN2( rightPixel->red, temp1 );
888             // Green
889             temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
890             IlMaxGreen = MAX2( leftPixel->green, temp2 );
891             IlMinGreen = MIN2( leftPixel->green, temp2 );
892             temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
893             IrMaxGreen = MAX2( rightPixel->green, temp1 );
894             IrMinGreen = MIN2( rightPixel->green, temp1 );
895             // Blue
896             temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
897             IlMaxBlue = MAX2( leftPixel->blue, temp2 );
898             IlMinBlue = MIN2( leftPixel->blue, temp2 );
899             temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
900             IrMaxBlue = MAX2( rightPixel->blue, temp1 );
901             IrMinBlue = MIN2( rightPixel->blue, temp1 );
902
903             // Red
904             temp1 = leftPixel->red - IrMaxRed;
905             temp2 = IrMinRed - leftPixel->red;
906             DlRed = MAX3( 0, temp1, temp2 );
907             temp1 = rightPixel->red - IlMaxRed;
908             temp2 = IlMinRed - rightPixel->red;
909             DrRed = MAX3( 0, temp1, temp2 );
910             // Green
911             temp1 = leftPixel->green - IrMaxGreen;
912             temp2 = IrMinGreen - leftPixel->green;
913             DlGreen = MAX3( 0, temp1, temp2 );
914             temp1 = rightPixel->green - IlMaxGreen;
915             temp2 = IlMinGreen - rightPixel->green;
916             DrGreen = MAX3( 0, temp1, temp2 );
917             // Blue
918             temp1 = leftPixel->blue - IrMaxBlue;
919             temp2 = IrMinBlue - leftPixel->blue;
920             DlBlue = MAX3( 0, temp1, temp2 );
921             temp1 = rightPixel->blue - IlMaxBlue;
922             temp2 = IlMinBlue - rightPixel->blue;
923             DrBlue = MAX3( 0, temp1, temp2 );
924
925         } // case 2
926         break;
927     case -4: // xState = -1, yState = -1
928         {
929             // Red
930             temp2 = ( (leftPixel + 1)->red + leftPixel->red ) >> 1;
931             IlMaxRed = MAX2( leftPixel->red, temp2 );
932             IlMinRed = MIN2( leftPixel->red, temp2 );
933             temp2 = ( (rightPixel + 1)->red + rightPixel->red ) >> 1;
934             IrMaxRed = MAX2( rightPixel->red, temp2 );
935             IrMinRed = MIN2( rightPixel->red, temp2 );
936             // Green
937             temp2 = ( (leftPixel + 1)->green + leftPixel->green ) >> 1;
938             IlMaxGreen = MAX2( leftPixel->green, temp2 );
939             IlMinGreen = MIN2( leftPixel->green, temp2 );
940             temp2 = ( (rightPixel + 1)->green + rightPixel->green ) >> 1;
941             IrMaxGreen = MAX2( rightPixel->green, temp2 );
942             IrMinGreen = MIN2( rightPixel->green, temp2 );
943             // Blue
944             temp2 = ( (leftPixel + 1)->blue + leftPixel->blue ) >> 1;
945             IlMaxBlue = MAX2( leftPixel->blue, temp2 );
946             IlMinBlue = MIN2( leftPixel->blue, temp2 );
947             temp2 = ( (rightPixel + 1)->blue + rightPixel->blue ) >> 1;
948             IrMaxBlue = MAX2( rightPixel->blue, temp2 );
949             IrMinBlue = MIN2( rightPixel->blue, temp2 );
950
951             // Red
952             temp1 = leftPixel->red - IrMaxRed;
953             temp2 = IrMinRed - leftPixel->red;
954             DlRed = MAX3( 0, temp1, temp2 );
955             temp1 = rightPixel->red - IlMaxRed;
956             temp2 = IlMinRed - rightPixel->red;
957             DrRed = MAX3( 0, temp1, temp2 );
958             // Green
959             temp1 = leftPixel->green - IrMaxGreen;
960             temp2 = IrMinGreen - leftPixel->green;
961             DlGreen = MAX3( 0, temp1, temp2 );
962             temp1 = rightPixel->green - IlMaxGreen;
963             temp2 = IlMinGreen - rightPixel->green;
964             DrGreen = MAX3( 0, temp1, temp2 );
965             // Blue
966             temp1 = leftPixel->blue - IrMaxBlue;
967             temp2 = IrMinBlue - leftPixel->blue;
968             DlBlue = MAX3( 0, temp1, temp2 );
969             temp1 = rightPixel->blue - IlMaxBlue;
970             temp2 = IlMinBlue - rightPixel->blue;
971             DrBlue = MAX3( 0, temp1, temp2 );
972
973         } // case -4
974         break;
975     case 4: // xState = 1, yState = 1
976     default:
977         {
978             // Red
979             temp1 = ( (leftPixel - 1)->red + leftPixel->red ) >> 1;
980             IlMaxRed = MAX2( leftPixel->red, temp1 );
981             IlMinRed = MIN2( leftPixel->red, temp1 );
982             temp1 = ( (rightPixel - 1)->red + rightPixel->red ) >> 1;
983             IrMaxRed = MAX2( rightPixel->red, temp1 );
984             IrMinRed = MIN2( rightPixel->red, temp1 );
985             // Green
986             temp1 = ( (leftPixel - 1)->green + leftPixel->green ) >> 1;
987             IlMaxGreen = MAX2( leftPixel->green, temp1 );
988             IlMinGreen = MIN2( leftPixel->green, temp1 );
989             temp1 = ( (rightPixel - 1)->green + rightPixel->green ) >> 1;
990             IrMaxGreen = MAX2( rightPixel->green, temp1 );
991             IrMinGreen = MIN2( rightPixel->green, temp1 );
992             // Blue
993             temp1 = ( (leftPixel - 1)->blue + leftPixel->blue ) >> 1;
994             IlMaxBlue = MAX2( leftPixel->blue, temp1 );
995             IlMinBlue = MIN2( leftPixel->blue, temp1 );
996             temp1 = ( (rightPixel - 1)->blue + rightPixel->blue ) >> 1;
997             IrMaxBlue = MAX2( rightPixel->blue, temp1 );
998             IrMinBlue = MIN2( rightPixel->blue, temp1 );
999
1000             // Red
1001             temp1 = leftPixel->red - IrMaxRed;
1002             temp2 = IrMinRed - leftPixel->red;
1003             DlRed = MAX3( 0, temp1, temp2 );
1004             temp1 = rightPixel->red - IlMaxRed;
1005             temp2 = IlMinRed - rightPixel->red;
1006             DrRed = MAX3( 0, temp1, temp2 );
1007             // Green
1008             temp1 = leftPixel->green - IrMaxGreen;
1009             temp2 = IrMinGreen - leftPixel->green;
1010             DlGreen = MAX3( 0, temp1, temp2 );
1011             temp1 = rightPixel->green - IlMaxGreen;
1012             temp2 = IlMinGreen - rightPixel->green;
1013             DrGreen = MAX3( 0, temp1, temp2 );
1014             // Blue
1015             temp1 = leftPixel->blue - IrMaxBlue;
1016             temp2 = IrMinBlue - leftPixel->blue;
1017             DlBlue = MAX3( 0, temp1, temp2 );
1018             temp1 = rightPixel->blue - IlMaxBlue;
1019             temp2 = IlMinBlue - rightPixel->blue;
1020             DrBlue = MAX3( 0, temp1, temp2 );
1021
1022         } // case 4
1023     } // switch( state )
1024
1025     DRed = MIN2( DlRed, DrRed );
1026     DGreen = MIN2( DlGreen, DrGreen );
1027     DBlue = MIN2( DlBlue, DrBlue );
1028     //DRed = MAX2( DlRed, DrRed );
1029     //DGreen = MAX2( DlGreen, DrGreen );
1030     //DBlue = MAX2( DlBlue, DrBlue );
1031
1032     dist = MAX3( DRed, DGreen, DBlue );
1033     //dist = ( DRed + DGreen + DBlue ) / 3;
1034     //dist = ( DRed + DGreen + DBlue ) + MAX3( DRed, DGreen, DBlue );
1035     //dist = DRed;
1036
1037     return dist;
1038 }
1039
1040 bool  CCvPixelToPixelMorpher::OnCalculateStereo()
1041 {
1042     CvSize imageSizeLeft = GetImageSize( m_left_img ),
1043            imageSizeRight = GetImageSize( m_right_img );
1044
1045     if( ( imageSizeLeft.width != imageSizeRight.width )
1046         || ( imageSizeLeft.height != imageSizeRight.height ) )
1047     {
1048         return false;
1049     }
1050
1051     if( m_corr ) {
1052         free( m_corr );
1053         m_corr = NULL;
1054     }
1055     m_corr = corrAlloc( m_left_img -> width,
1056         m_left_img -> height,
1057         CORR_ARRAY );
1058     if( m_corrNum ) {
1059         free( m_corrNum );
1060         m_corrNum = NULL;
1061     }
1062     m_corrNum = corrAlloc( m_left_img -> width,
1063         m_right_img -> height,
1064         NUM_CORR_ARRAY );
1065
1066     // Find correspondence for full image and store it to corr array
1067     FindFullCorr( ( unsigned char* )m_left_img -> imageData,
1068                   m_left_img -> widthStep,
1069                   ( unsigned char* )m_right_img -> imageData,
1070                   m_right_img -> widthStep,
1071                   m_corr,
1072                   m_corrNum,
1073                   m_left_img -> width,
1074                   m_left_img -> height,
1075                   m_maxPixelDifference
1076                 );
1077
1078     m_isStereoReady = true;
1079
1080     return true;
1081 }
1082
1083 bool  CCvPixelToPixelMorpher::OnCalculateVirtualImage()
1084 {
1085     // Output image to ResultImage window
1086     Morph( ( unsigned char* )m_left_img -> imageData,
1087            m_left_img ->widthStep,
1088            ( unsigned char* )m_right_img -> imageData,
1089            m_right_img -> widthStep,
1090            ( unsigned char* )m_virtual_img -> imageData,
1091            m_virtual_img -> widthStep,
1092            m_corr,
1093            m_corrNum,
1094            m_left_img -> width,
1095            m_left_img -> height,
1096            m_pan );
1097
1098     m_isVirtualImageReady = true;
1099
1100     return true;
1101 }
1102
1103 bool  CCvPixelToPixelMorpher::OnCalculateDisparity()
1104 {
1105     Morph( ( unsigned char* )m_left_img -> imageData,
1106            m_left_img ->widthStep,
1107            ( unsigned char* )m_right_img -> imageData,
1108            m_right_img -> widthStep,
1109            ( unsigned char* )m_disparity_img -> imageData,
1110            m_disparity_img -> widthStep,
1111            m_corr,
1112            m_corrNum,
1113            m_left_img -> width,
1114            m_left_img -> height,
1115            m_pan,
1116            morphDepthMap,
1117            m_maxPixelDifference );
1118
1119     return true;
1120 }
1121
1122 bool  CCvPixelToPixelMorpher::OnCalculateDisparityImage()
1123 {
1124     Morph( ( unsigned char* )m_left_img -> imageData,
1125            m_left_img ->widthStep,
1126            ( unsigned char* )m_right_img -> imageData,
1127            m_right_img -> widthStep,
1128            ( unsigned char* )m_disparity_img -> imageData,
1129            m_disparity_img -> widthStep,
1130            m_corr,
1131            m_corrNum,
1132            m_left_img -> width,
1133            m_left_img -> height,
1134            m_pan,
1135            morphDepthMap,
1136            m_maxPixelDifference );
1137
1138     return true;
1139 }
1140
1141 CCvPixelToPixelMorpher::CCvPixelToPixelMorpher()
1142 {
1143     m_maxPixelDifference = MAX_DIFFERENCE;
1144     m_corr = m_corrNum = 0;
1145     m_isStereoReady = false;
1146     m_isVirtualImageReady = false;
1147     m_isDisparityReady = false;
1148     //m_isDisparityImageReady = false;
1149 }