0023022: This is desirable to access OpenGl extensions and core API (1.2+) in one...
[occt.git] / src / ImageUtility / ImageUtility.cxx
1 // Modified     27/12/98 : FMN ; PERF: OPTIMISATION LOADER (LOPTIM)
2 //
3
4 #include <Aspect_ColorRampColorMap.hxx>
5 #include <Standard_TypeMismatch.hxx>
6 #include <ImageUtility.ixx>
7
8
9 #define LOPTIM
10 #ifndef LOPTIM
11 static Handle(Aspect_ColorRampColorMap) TheBWColorMap = 
12     new Aspect_ColorRampColorMap(0,2,Quantity_Color(1.,1.,1.,Quantity_TOC_RGB));
13 #else 
14 static Handle(Aspect_ColorRampColorMap)& _TheBWColorMap() {
15     static Handle(Aspect_ColorRampColorMap) TheBWColorMap = 
16         new Aspect_ColorRampColorMap(0,2,Quantity_Color(1.,1.,1.,Quantity_TOC_RGB));
17 return TheBWColorMap;
18 }
19 #define TheBWColorMap _TheBWColorMap()
20 #endif // LOPTIM
21
22
23 static void Rescale( const Handle(Image_PseudoColorImage) aPImage )
24
25 { Aspect_IndexPixel PMin, PMax ;
26   Standard_Integer dim, base ;
27   Quantity_Color aColor ;
28   Standard_Real scale, offset ; ;
29
30   Handle(Aspect_ColorRampColorMap)::
31         DownCast(aPImage->ColorMap())->ColorRampDefinition( base, dim, aColor );
32
33   aPImage->Extrema( PMin, PMax ) ;
34
35   if ( PMax.Value() == PMin.Value() ) return ;
36
37   scale = Standard_Real( dim-1 ) / Standard_Real( PMax.Value() - PMin.Value()) ;
38   offset = Standard_Real( base ) - Standard_Real( PMin.Value() ) * scale ;
39
40   aPImage->Rescale( scale, offset ) ; 
41
42 }
43
44 Handle(Image_PseudoColorImage) ImageUtility::PixelColorDiff( 
45                      const Handle(Image_Image)& Image1,
46                      const Handle(Image_Image)& Image2 )
47
48   return PixelColorDiff( Image1, Image2, TheBWColorMap ) ;
49 }
50
51 Handle(Image_PseudoColorImage) ImageUtility::PixelColorDiff( 
52                 const Handle(Image_Image)& Image1,
53                 const Handle(Image_Image)& Image2,
54                 const Handle(Aspect_ColorRampColorMap)& TheColorMap )
55
56 { Handle(Image_PseudoColorImage) RetImage = NULL ;
57   Standard_Integer x,y, Error, BasePixel, RampLength ;
58   Standard_Integer LX, LY, UX, UY ;
59   Standard_Integer LX1, LY1, UX1, UY1 ;
60   Standard_Integer LX2, LY2, UX2, UY2 ;
61   Aspect_IndexPixel aPixel;
62   Standard_Real r1,g1,b1, r2,g2,b2 ;
63   Quantity_Color aColor ;
64
65   TheColorMap->ColorRampDefinition( BasePixel, RampLength, aColor ) ;
66
67   Aspect_IndexPixel Pixel0(BasePixel);
68   Aspect_IndexPixel Pixel1(BasePixel+RampLength-1);
69
70   LX1 = Image1->LowerX() ; 
71   LY1 = Image1->LowerY() ; 
72
73   UX1 = Image1->UpperX() ; 
74   UY1 = Image1->UpperY() ; 
75
76   LX2 = Image2->LowerX() ; 
77   LY2 = Image2->LowerY() ; 
78
79   UX2 = Image2->UpperX() ; 
80   UY2 = Image2->UpperY() ; 
81
82   LX = Image1->LowerX() ; LX = Min( LX, Image2->LowerX() ) ;
83   LY = Image1->LowerY() ; LY = Min( LY, Image2->LowerY() ) ;
84
85   UX = Image1->UpperX() ; UX = Max( UX, Image2->UpperX() ) ;
86   UY = Image1->UpperY() ; UY = Max( UY, Image2->UpperY() ) ;
87
88   RetImage = new Image_PseudoColorImage( LX, LY, 
89                                          (UX-LX)+1, (UY-LY)+1, 
90                                         TheColorMap, 
91                                         Pixel1 ) ;
92
93   if ( RampLength == 2 ) { //B&W ColorMap
94         for ( y = LY ; y <= UY ; y++ ) {
95           for ( x = LX ; x <= UX ; x++ ) {
96             if ( ( x >= LX1 && x >= LX2 ) && ( x <= UX1 && x <= UX2 ) &&
97                  ( y >= LY1 && y >= LY2 ) && ( y <= UY1 && y <= UY2 ) ) {
98                 if ( Image1->PixelColor(x,y) == Image2->PixelColor(x,y) ) {
99                     RetImage->SetPixel( x,y, Pixel0 ) ;
100                 }
101             }
102           }
103          }
104   }
105   else {
106         for ( y = LY ; y <= UY ; y++ ) {
107           for ( x = LX ; x <= UX ; x++ ) {
108             if ( ( x >= LX1 && x >= LX2 ) && ( x <= UX1 && x <= UX2 ) &&
109                  ( y >= LY1 && y >= LY2 ) && ( y <= UY1 && y <= UY2 ) ) {
110               Image1->PixelColor(x,y).Values( r1,g1,b1, Quantity_TOC_RGB ) ;
111               Image2->PixelColor(x,y).Values( r2,g2,b2, Quantity_TOC_RGB ) ;
112
113               Error = BasePixel ;
114
115               Error += 
116                 Standard_Integer( (Abs(r1-r2)+Abs(g1-g2)+Abs(b1-b2))/3. 
117                                         *(RampLength-1)
118                                 );
119
120               aPixel.SetValue( Error ) ;
121
122               RetImage->SetPixel( x,y, aPixel ) ;
123             }
124           }
125         }
126         Rescale( RetImage ) ;
127   }
128
129   return RetImage ;
130 }
131
132 void ImageUtility::PixelColorDiff( 
133                 const Handle(Image_Image)& Image1,
134                 const Handle(Image_Image)& Image2,
135                 const Handle(Aspect_ColorRampColorMap)& TheColorMap,
136                 Handle(Image_PseudoColorImage)& RedDiff,
137                 Handle(Image_PseudoColorImage)& GreenDiff,
138                 Handle(Image_PseudoColorImage)& BlueDiff )
139
140 { Standard_Integer x,y, Error, BasePixel, RampLength ;
141   Standard_Integer LX, LY, UX, UY ;
142   Standard_Integer LX1, LY1, UX1, UY1 ;
143   Standard_Integer LX2, LY2, UX2, UY2 ;
144   Aspect_IndexPixel aPixel;
145   Standard_Real r1,g1,b1, r2,g2,b2 ;
146   Quantity_Color aColor ;
147
148   TheColorMap->ColorRampDefinition( BasePixel, RampLength, aColor ) ;
149
150   Aspect_IndexPixel Pixel0(BasePixel);
151   Aspect_IndexPixel Pixel1(BasePixel+RampLength-1);
152
153   LX1 = Image1->LowerX() ; 
154   LY1 = Image1->LowerY() ; 
155
156   UX1 = Image1->UpperX() ; 
157   UY1 = Image1->UpperY() ; 
158
159   LX2 = Image2->LowerX() ; 
160   LY2 = Image2->LowerY() ; 
161
162   UX2 = Image2->UpperX() ; 
163   UY2 = Image2->UpperY() ; 
164
165   LX = Image1->LowerX() ; LX = Min( LX, Image2->LowerX() ) ;
166   LY = Image1->LowerY() ; LY = Min( LY, Image2->LowerY() ) ;
167
168   UX = Image1->UpperX() ; UX = Max( UX, Image2->UpperX() ) ;
169   UY = Image1->UpperY() ; UY = Max( UY, Image2->UpperY() ) ;
170
171   RedDiff = new Image_PseudoColorImage( LX, LY, 
172                                          (UX-LX)+1, (UY-LY)+1, 
173                                         TheColorMap, 
174                                         Pixel1 ) ;
175
176   GreenDiff = new Image_PseudoColorImage( LX, LY, 
177                                          (UX-LX)+1, (UY-LY)+1, 
178                                         TheColorMap, 
179                                         Pixel1 ) ;
180
181   BlueDiff = new Image_PseudoColorImage( LX, LY, 
182                                          (UX-LX)+1, (UY-LY)+1, 
183                                         TheColorMap, 
184                                         Pixel1 ) ;
185
186   if ( RampLength == 2 ) { //B&W ColorMap
187         for ( y = LY ; y <= UY ; y++ ) {
188           for ( x = LX ; x <= UX ; x++ ) {
189             if ( ( x >= LX1 && x >= LX2 ) && ( x <= UX1 && x <= UX2 ) &&
190                  ( y >= LY1 && y >= LY2 ) && ( y <= UY1 && y <= UY2 ) ) {
191               Image1->PixelColor(x,y).Values( r1,g1,b1, Quantity_TOC_RGB ) ;
192               Image2->PixelColor(x,y).Values( r2,g2,b2, Quantity_TOC_RGB ) ;
193
194               if ( r1 == r2 ) RedDiff->SetPixel  ( x,y, Pixel0 ) ;
195               if ( g1 == g2 ) GreenDiff->SetPixel( x,y, Pixel0 ) ;
196               if ( b1 == b2 ) BlueDiff->SetPixel ( x,y, Pixel0 ) ;
197             }
198           }
199          }
200   }
201   else {
202         for ( y = LY ; y <= UY ; y++ ) {
203           for ( x = LX ; x <= UX ; x++ ) {
204             if ( ( x >= LX1 && x >= LX2 ) && ( x <= UX1 && x <= UX2 ) &&
205                   ( y >= LY1 && y >= LY2 ) && ( y <= UY1 && y <= UY2 ) ) {
206               Image1->PixelColor(x,y).Values( r1,g1,b1, Quantity_TOC_RGB ) ;
207               Image2->PixelColor(x,y).Values( r2,g2,b2, Quantity_TOC_RGB ) ;
208
209               Error = BasePixel + Standard_Integer( Abs(r1-r2)*(RampLength-1) );
210
211               aPixel.SetValue( Error ) ; RedDiff->SetPixel( x,y, aPixel ) ;
212
213               Error = BasePixel + Standard_Integer( Abs(g1-g2)*(RampLength-1) );
214
215               aPixel.SetValue( Error ) ; GreenDiff->SetPixel( x,y, aPixel ) ;
216
217               Error = BasePixel + Standard_Integer( Abs(b1-b2)*(RampLength-1) );
218
219               aPixel.SetValue( Error ) ; BlueDiff->SetPixel( x,y, aPixel ) ;
220             }
221           }
222         }
223         Rescale( RedDiff ) ;
224         Rescale( GreenDiff ) ;
225         Rescale( BlueDiff ) ;
226   }
227 }