0023912: TDataStd_ExtStringArray::Value() returns a copy of TCollection_ExtendedStrin...
[occt.git] / src / Image / Image_AveragePixelInterpolation.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
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.
8 //
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.
11 //
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.
18
19 #include <Image_AveragePixelInterpolation.ixx>
20
21
22 Image_AveragePixelInterpolation::Image_AveragePixelInterpolation() {}
23
24 Standard_Boolean Image_AveragePixelInterpolation::Interpolate( 
25         const Handle(Image_Image)& aImage,
26         const Standard_Real FX, const Standard_Real FY,
27         const Standard_Integer LowX,
28         const Standard_Integer LowY,
29         const Standard_Integer UpX,
30         const Standard_Integer UpY,
31         Aspect_Pixel& aPixel ) const
32
33
34
35   if ( aImage->IsKind(STANDARD_TYPE(Image_DIndexedImage))) {
36
37         return Interpolate( Handle(Image_DIndexedImage)::DownCast( aImage ),
38                         FX,FY,LowX,LowY,UpX,UpY,(Aspect_IndexPixel &)aPixel ) ;
39
40   }
41   else if ( aImage->IsKind(STANDARD_TYPE(Image_DColorImage))) {
42
43         return Interpolate( Handle(Image_DColorImage)::DownCast( aImage ),
44                         FX,FY,LowX,LowY,UpX,UpY,(Aspect_ColorPixel &)aPixel ) ;
45   }
46   else {
47         return Image_PixelInterpolation::Interpolate( aImage,
48                         FX,FY,LowX,LowY,UpX,UpY,aPixel ) ;
49   }
50 }
51
52 Standard_Boolean Image_AveragePixelInterpolation::Interpolate( 
53         const Handle(Image_DColorImage)& aImage,
54         const Standard_Real FX, const Standard_Real FY,
55         const Standard_Integer LowX,
56         const Standard_Integer LowY,
57         const Standard_Integer UpX,
58         const Standard_Integer UpY,
59         Aspect_ColorPixel& aPixel ) const
60
61 { Standard_Integer NX[3], NY[3] ;
62   Standard_Real    NZ[3] ;
63   Standard_Real    R,G,B ;
64   static Quantity_Color Col ;
65   Standard_Boolean SamePixels = 1 ;
66
67   if ( FX < 0. ) NX[0] = Standard_Integer(FX-0.5) ;
68   else           NX[0] = Standard_Integer(FX+0.5) ;
69
70   if ( FY < 0. ) NY[0] = Standard_Integer(FY-0.5) ;
71   else           NY[0] = Standard_Integer(FY+0.5) ;
72
73   if ( NX[0] < LowX || NX[0] > UpX ||
74        NY[0] < LowY || NY[0] > UpY ) {
75         return Standard_False ;
76   }
77   else if ( ( FX-NX[0] ) == 0. && ( FY-NY[0] ) == 0. ) {
78         aImage->Pixel( NX[0], NY[0], aPixel );
79         return Standard_True ;
80   }
81   else {
82
83         if ( ( FX-NX[0] ) >= 0. )       { NX[1] = NX[0]+1 ; NY[1] = NY[0] ; }
84         else                            { NX[1] = NX[0]-1 ; NY[1] = NY[0] ; }
85         if ( ( FY-NY[0] ) >= 0. )       { NX[2] = NX[0]   ; NY[2] = NY[0]+1 ; }
86         else                            { NX[2] = NX[0]   ; NY[2] = NY[0]-1 ; }
87
88         if ( NX[1] < LowX || NX[1] > UpX || NY[1] < LowY || NY[1] > UpY ||
89              NX[2] < LowX || NX[2] > UpX || NY[2] < LowY || NY[2] > UpY ) {
90                 aImage->Pixel( NX[0], NY[0], aPixel );
91         }
92         else {
93                 NZ[0] = aImage->Pixel( NX[0],NY[0] ).Value().Red() ;
94                 NZ[1] = aImage->Pixel( NX[1],NY[1] ).Value().Red() ;
95                 NZ[2] = aImage->Pixel( NX[2],NY[2] ).Value().Red() ;
96
97                 if ( NZ[0] == NZ[1] && NZ[0] == NZ[2] ) {
98                         R = NZ[0] ;
99                 }
100                 else {
101                         R = ( NZ[0] + NZ[1] + NZ[2] ) / 3. ;
102                         SamePixels = 0 ;
103                 }
104
105                 NZ[0] = aImage->Pixel( NX[0],NY[0] ).Value().Green() ;
106                 NZ[1] = aImage->Pixel( NX[1],NY[1] ).Value().Green() ;
107                 NZ[2] = aImage->Pixel( NX[2],NY[2] ).Value().Green() ;
108
109                 if ( NZ[0] == NZ[1] && NZ[0] == NZ[2] ) {
110                         G = NZ[0] ;
111                 }
112                 else {
113                         G = ( NZ[0] + NZ[1] + NZ[2] ) / 3. ;
114                         SamePixels = 0 ;
115                 }
116
117                 NZ[0] = aImage->Pixel( NX[0],NY[0] ).Value().Blue() ;
118                 NZ[1] = aImage->Pixel( NX[1],NY[1] ).Value().Blue() ;
119                 NZ[2] = aImage->Pixel( NX[2],NY[2] ).Value().Blue() ;
120
121                 if ( NZ[0] == NZ[1] && NZ[0] == NZ[2] ) {
122                         B = NZ[0] ;
123                 }
124                 else {
125                         B = ( NZ[0] + NZ[1] + NZ[2] ) / 3. ;
126                         SamePixels = 0 ;
127                 }
128
129                 if ( SamePixels ) {
130                         aPixel.SetValue( aImage->Pixel( NX[0],NY[0] ).Value() );
131                 }
132                 else {
133                         Col.SetValues(  R, G, B, Quantity_TOC_RGB ) ;
134
135                         aPixel.SetValue( Col ) ;
136                 }
137         }
138
139         return Standard_True ;
140   }
141 }
142
143 Standard_Boolean Image_AveragePixelInterpolation::Interpolate( 
144         const Handle(Image_DIndexedImage)& aImage,
145         const Standard_Real FX, const Standard_Real FY,
146         const Standard_Integer LowX,
147         const Standard_Integer LowY,
148         const Standard_Integer UpX,
149         const Standard_Integer UpY,
150         Aspect_IndexPixel& aPixel ) const
151
152 { Standard_Integer NX[3], NY[3] ;
153   Standard_Real    NZ[3] ;
154
155
156   if ( FX < 0. ) NX[0] = Standard_Integer(FX-0.5) ;
157   else           NX[0] = Standard_Integer(FX+0.5) ;
158
159   if ( FY < 0. ) NY[0] = Standard_Integer(FY-0.5) ;
160   else           NY[0] = Standard_Integer(FY+0.5) ;
161
162   if ( NX[0] < LowX || NX[0] > UpX ||
163        NY[0] < LowY || NY[0] > UpY ) {
164         return Standard_False ;
165   }
166   else if ( ( FX-NX[0] ) == 0. && ( FY-NY[0] ) == 0. ) {
167         aImage->Pixel( NX[0], NY[0], aPixel );
168         return Standard_True ;
169   }
170   else {
171
172         if ( ( FX-NX[0] ) >= 0. )       { NX[1] = NX[0]+1 ; NY[1] = NY[0] ; }
173         else                            { NX[1] = NX[0]-1 ; NY[1] = NY[0] ; }
174         if ( ( FY-NY[0] ) >= 0. )       { NX[2] = NX[0]   ; NY[2] = NY[0]+1 ; }
175         else                            { NX[2] = NX[0]   ; NY[2] = NY[0]-1 ; }
176
177         if ( NX[1] < LowX || NX[1] > UpX || NY[1] < LowY || NY[1] > UpY ||
178              NX[2] < LowX || NX[2] > UpX || NY[2] < LowY || NY[2] > UpY ) {
179                 aImage->Pixel( NX[0], NY[0], aPixel );
180         }
181         else {
182                 NZ[0] = aImage->Pixel( NX[0],NY[0] ).Value() ;
183                 NZ[1] = aImage->Pixel( NX[1],NY[1] ).Value() ;
184                 NZ[2] = aImage->Pixel( NX[2],NY[2] ).Value() ;
185
186                 if ( NZ[0] == NZ[1] && NZ[0] == NZ[2] ) {
187                   aPixel.SetValue( Standard_Integer( NZ[0] ) ) ;
188                 }
189                 else {
190                   aPixel.SetValue( Standard_Integer((NZ[0]+NZ[1]+NZ[2])/3.) ) ;
191                 }
192
193         }
194
195         return Standard_True ;
196   }
197 }
198
199 //##############################################################################
200
201 #ifdef OLD
202 Standard_Boolean Image_AveragePixelInterpolation::Interpolate( 
203         const Handle(Image_DColorImage)& aImage,
204         const Standard_Real FX, const Standard_Real FY,
205         const Standard_Integer LowX,
206         const Standard_Integer LowY,
207         const Standard_Integer UpX,
208         const Standard_Integer UpY,
209         Aspect_ColorPixel& aPixel ) const
210
211 { Standard_Integer NX = Standard_Integer(FX) ;
212   Standard_Integer NY = Standard_Integer(FY) ;
213   Standard_Integer X,Y ;
214   Standard_Real SD, SR, SG, SB, R, G, B ;
215
216   if ( NX < ( LowX-1 ) || NX > UpX || 
217        NY < ( LowY-1 ) || NY > UpY ) {
218         return Standard_False ;
219   }
220   else {
221
222         if ( FX < 0. ) NX-- ;
223         if ( FY < 0. ) NY-- ;
224
225         SR = SG = SB = SD = 0. ;
226
227         // (0,0)
228         X = NX ; Y = NY ;
229
230         if ( !( X < LowX || X > UpX || 
231                 Y < LowY || Y > UpY ) ) {
232           aImage->Pixel( X,Y ).Value().Values( R, G, B, Quantity_TOC_RGB ) ;
233
234           SR += R ; SG += G ; SB += B ; SD += 1. ;
235         }
236
237         // (1,0)
238         X = NX+1 ; Y = NY ;
239
240         if ( !( X < LowX || X > UpX || Y < LowY || Y > UpY ) ) {
241           aImage->Pixel( X,Y ).Value().Values( R, G, B, Quantity_TOC_RGB ) ;
242
243           SR += R ; SG += G ; SB += B ; SD += 1. ;
244         }
245
246         // (0,1)
247         X = NX ; Y = NY+1 ;
248
249         if ( !( X < LowX || X > UpX || 
250                 Y < LowY || Y > UpY ) ) {
251           aImage->Pixel( X,Y ).Value().Values( R, G, B, Quantity_TOC_RGB ) ;
252
253           SR += R ; SG += G ; SB += B ; SD += 1. ;
254         }
255
256         // (1,1)
257         X = NX+1 ; Y = NY+1 ;
258
259         if ( !( X < LowX || X > UpX || 
260                 Y < LowY || Y > UpY ) ) {
261           aImage->Pixel( X,Y ).Value().Values( R, G, B, Quantity_TOC_RGB ) ;
262
263           SR += R ; SG += G ; SB += B ; SD += 1. ;
264         }
265
266         // Result
267         if ( SD != 0. ) {
268           SR /= SD ; SG /= SD ; SB /= SD ;
269
270           aPixel.SetValue( Quantity_Color( SR, SG, SB, Quantity_TOC_RGB ) ) ;
271
272           return Standard_True ;
273         }
274         else {
275           return Standard_False ;
276         }
277   }
278 }
279
280 Standard_Boolean Image_AveragePixelInterpolation::Interpolate( 
281         const Handle(Image_DIndexedImage)& aImage,
282         const Standard_Real FX, const Standard_Real FY,
283         const Standard_Integer LowX,
284         const Standard_Integer LowY,
285         const Standard_Integer UpX,
286         const Standard_Integer UpY,
287         Aspect_IndexPixel& aPixel ) const
288
289 { Standard_Integer NX = Standard_Integer(FX) ;
290   Standard_Integer NY = Standard_Integer(FY) ;
291   Standard_Integer X,Y ;
292   Standard_Real SD, SP ;
293
294   if ( NX < ( LowX-1 ) || NX > UpX || 
295        NY < ( LowY-1 ) || NY > UpY ) {
296         return Standard_False ;
297   }
298   else {
299
300         if ( FX < 0. ) NX-- ;
301         if ( FY < 0. ) NY-- ;
302
303         SP = SD = 0. ;
304
305         // (0,0)
306         X = NX ; Y = NY ;
307
308         if ( !( X < LowX || X > UpX || 
309                 Y < LowY || Y > UpY ) ) {
310           SP += aImage->Pixel( X,Y ).Value() ; SD += 1. ;
311         }
312
313         // (1,0)
314         X = NX+1 ; Y = NY ;
315
316         if ( !( X < LowX || X > UpX || 
317                 Y < LowY || Y > UpY ) ) {
318           SP += aImage->Pixel( X,Y ).Value() ; SD += 1. ;
319         }
320
321         // (0,1)
322         X = NX ; Y = NY+1 ;
323
324         if ( !( X < LowX || X > UpX || 
325                 Y < LowY || Y > UpY ) ) {
326           SP += aImage->Pixel( X,Y ).Value() ; SD += 1. ;
327         }
328
329         // (1,1)
330         X = NX+1 ; Y = NY+1 ;
331
332         if ( !( X < LowX || X > UpX || 
333                 Y < LowY || Y > UpY ) ) {
334           SP += aImage->Pixel( X,Y ).Value() ; SD += 1. ;
335         }
336
337         // Result
338
339         if ( SD != 0. ) {
340           SP /= SD ;
341
342           aPixel.SetValue( Standard_Integer(SP+0.5) ) ;
343
344           return Standard_True ;
345         }
346         else {
347           return Standard_False ;
348         }
349   }
350 }
351 #endif