1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
19 // Modified 27/12/98 : FMN ; PERF: OPTIMISATION LOADER (LOPTIM)
21 #include <Aspect_ColorRampColorMap.hxx>
22 #include <Standard_TypeMismatch.hxx>
23 #include <ImageUtility.ixx>
28 static Handle(Aspect_ColorRampColorMap) TheBWColorMap =
29 new Aspect_ColorRampColorMap(0,2,Quantity_Color(1.,1.,1.,Quantity_TOC_RGB));
31 static Handle(Aspect_ColorRampColorMap)& _TheBWColorMap() {
32 static Handle(Aspect_ColorRampColorMap) TheBWColorMap =
33 new Aspect_ColorRampColorMap(0,2,Quantity_Color(1.,1.,1.,Quantity_TOC_RGB));
36 #define TheBWColorMap _TheBWColorMap()
40 static void Rescale( const Handle(Image_PseudoColorImage) aPImage )
42 { Aspect_IndexPixel PMin, PMax ;
43 Standard_Integer dim, base ;
44 Quantity_Color aColor ;
45 Standard_Real scale, offset ; ;
47 Handle(Aspect_ColorRampColorMap)::
48 DownCast(aPImage->ColorMap())->ColorRampDefinition( base, dim, aColor );
50 aPImage->Extrema( PMin, PMax ) ;
52 if ( PMax.Value() == PMin.Value() ) return ;
54 scale = Standard_Real( dim-1 ) / Standard_Real( PMax.Value() - PMin.Value()) ;
55 offset = Standard_Real( base ) - Standard_Real( PMin.Value() ) * scale ;
57 aPImage->Rescale( scale, offset ) ;
61 Handle(Image_PseudoColorImage) ImageUtility::PixelColorDiff(
62 const Handle(Image_Image)& Image1,
63 const Handle(Image_Image)& Image2 )
65 return PixelColorDiff( Image1, Image2, TheBWColorMap ) ;
68 Handle(Image_PseudoColorImage) ImageUtility::PixelColorDiff(
69 const Handle(Image_Image)& Image1,
70 const Handle(Image_Image)& Image2,
71 const Handle(Aspect_ColorRampColorMap)& TheColorMap )
73 { Handle(Image_PseudoColorImage) RetImage = NULL ;
74 Standard_Integer x,y, Error, BasePixel, RampLength ;
75 Standard_Integer LX, LY, UX, UY ;
76 Standard_Integer LX1, LY1, UX1, UY1 ;
77 Standard_Integer LX2, LY2, UX2, UY2 ;
78 Aspect_IndexPixel aPixel;
79 Standard_Real r1,g1,b1, r2,g2,b2 ;
80 Quantity_Color aColor ;
82 TheColorMap->ColorRampDefinition( BasePixel, RampLength, aColor ) ;
84 Aspect_IndexPixel Pixel0(BasePixel);
85 Aspect_IndexPixel Pixel1(BasePixel+RampLength-1);
87 LX1 = Image1->LowerX() ;
88 LY1 = Image1->LowerY() ;
90 UX1 = Image1->UpperX() ;
91 UY1 = Image1->UpperY() ;
93 LX2 = Image2->LowerX() ;
94 LY2 = Image2->LowerY() ;
96 UX2 = Image2->UpperX() ;
97 UY2 = Image2->UpperY() ;
99 LX = Image1->LowerX() ; LX = Min( LX, Image2->LowerX() ) ;
100 LY = Image1->LowerY() ; LY = Min( LY, Image2->LowerY() ) ;
102 UX = Image1->UpperX() ; UX = Max( UX, Image2->UpperX() ) ;
103 UY = Image1->UpperY() ; UY = Max( UY, Image2->UpperY() ) ;
105 RetImage = new Image_PseudoColorImage( LX, LY,
106 (UX-LX)+1, (UY-LY)+1,
110 if ( RampLength == 2 ) { //B&W ColorMap
111 for ( y = LY ; y <= UY ; y++ ) {
112 for ( x = LX ; x <= UX ; x++ ) {
113 if ( ( x >= LX1 && x >= LX2 ) && ( x <= UX1 && x <= UX2 ) &&
114 ( y >= LY1 && y >= LY2 ) && ( y <= UY1 && y <= UY2 ) ) {
115 if ( Image1->PixelColor(x,y) == Image2->PixelColor(x,y) ) {
116 RetImage->SetPixel( x,y, Pixel0 ) ;
123 for ( y = LY ; y <= UY ; y++ ) {
124 for ( x = LX ; x <= UX ; x++ ) {
125 if ( ( x >= LX1 && x >= LX2 ) && ( x <= UX1 && x <= UX2 ) &&
126 ( y >= LY1 && y >= LY2 ) && ( y <= UY1 && y <= UY2 ) ) {
127 Image1->PixelColor(x,y).Values( r1,g1,b1, Quantity_TOC_RGB ) ;
128 Image2->PixelColor(x,y).Values( r2,g2,b2, Quantity_TOC_RGB ) ;
133 Standard_Integer( (Abs(r1-r2)+Abs(g1-g2)+Abs(b1-b2))/3.
137 aPixel.SetValue( Error ) ;
139 RetImage->SetPixel( x,y, aPixel ) ;
143 Rescale( RetImage ) ;
149 void ImageUtility::PixelColorDiff(
150 const Handle(Image_Image)& Image1,
151 const Handle(Image_Image)& Image2,
152 const Handle(Aspect_ColorRampColorMap)& TheColorMap,
153 Handle(Image_PseudoColorImage)& RedDiff,
154 Handle(Image_PseudoColorImage)& GreenDiff,
155 Handle(Image_PseudoColorImage)& BlueDiff )
157 { Standard_Integer x,y, Error, BasePixel, RampLength ;
158 Standard_Integer LX, LY, UX, UY ;
159 Standard_Integer LX1, LY1, UX1, UY1 ;
160 Standard_Integer LX2, LY2, UX2, UY2 ;
161 Aspect_IndexPixel aPixel;
162 Standard_Real r1,g1,b1, r2,g2,b2 ;
163 Quantity_Color aColor ;
165 TheColorMap->ColorRampDefinition( BasePixel, RampLength, aColor ) ;
167 Aspect_IndexPixel Pixel0(BasePixel);
168 Aspect_IndexPixel Pixel1(BasePixel+RampLength-1);
170 LX1 = Image1->LowerX() ;
171 LY1 = Image1->LowerY() ;
173 UX1 = Image1->UpperX() ;
174 UY1 = Image1->UpperY() ;
176 LX2 = Image2->LowerX() ;
177 LY2 = Image2->LowerY() ;
179 UX2 = Image2->UpperX() ;
180 UY2 = Image2->UpperY() ;
182 LX = Image1->LowerX() ; LX = Min( LX, Image2->LowerX() ) ;
183 LY = Image1->LowerY() ; LY = Min( LY, Image2->LowerY() ) ;
185 UX = Image1->UpperX() ; UX = Max( UX, Image2->UpperX() ) ;
186 UY = Image1->UpperY() ; UY = Max( UY, Image2->UpperY() ) ;
188 RedDiff = new Image_PseudoColorImage( LX, LY,
189 (UX-LX)+1, (UY-LY)+1,
193 GreenDiff = new Image_PseudoColorImage( LX, LY,
194 (UX-LX)+1, (UY-LY)+1,
198 BlueDiff = new Image_PseudoColorImage( LX, LY,
199 (UX-LX)+1, (UY-LY)+1,
203 if ( RampLength == 2 ) { //B&W ColorMap
204 for ( y = LY ; y <= UY ; y++ ) {
205 for ( x = LX ; x <= UX ; x++ ) {
206 if ( ( x >= LX1 && x >= LX2 ) && ( x <= UX1 && x <= UX2 ) &&
207 ( y >= LY1 && y >= LY2 ) && ( y <= UY1 && y <= UY2 ) ) {
208 Image1->PixelColor(x,y).Values( r1,g1,b1, Quantity_TOC_RGB ) ;
209 Image2->PixelColor(x,y).Values( r2,g2,b2, Quantity_TOC_RGB ) ;
211 if ( r1 == r2 ) RedDiff->SetPixel ( x,y, Pixel0 ) ;
212 if ( g1 == g2 ) GreenDiff->SetPixel( x,y, Pixel0 ) ;
213 if ( b1 == b2 ) BlueDiff->SetPixel ( x,y, Pixel0 ) ;
219 for ( y = LY ; y <= UY ; y++ ) {
220 for ( x = LX ; x <= UX ; x++ ) {
221 if ( ( x >= LX1 && x >= LX2 ) && ( x <= UX1 && x <= UX2 ) &&
222 ( y >= LY1 && y >= LY2 ) && ( y <= UY1 && y <= UY2 ) ) {
223 Image1->PixelColor(x,y).Values( r1,g1,b1, Quantity_TOC_RGB ) ;
224 Image2->PixelColor(x,y).Values( r2,g2,b2, Quantity_TOC_RGB ) ;
226 Error = BasePixel + Standard_Integer( Abs(r1-r2)*(RampLength-1) );
228 aPixel.SetValue( Error ) ; RedDiff->SetPixel( x,y, aPixel ) ;
230 Error = BasePixel + Standard_Integer( Abs(g1-g2)*(RampLength-1) );
232 aPixel.SetValue( Error ) ; GreenDiff->SetPixel( x,y, aPixel ) ;
234 Error = BasePixel + Standard_Integer( Abs(b1-b2)*(RampLength-1) );
236 aPixel.SetValue( Error ) ; BlueDiff->SetPixel( x,y, aPixel ) ;
241 Rescale( GreenDiff ) ;
242 Rescale( BlueDiff ) ;