0023912: TDataStd_ExtStringArray::Value() returns a copy of TCollection_ExtendedStrin...
[occt.git] / src / AlienImage / AlienImage_EuclidAlienData.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 #define TEST    //GG_140699
20 //              Check file extension, must be ".PIX".
21
22 #include <Aspect_GenericColorMap.hxx>
23 #include <Image_Convertor.hxx>
24 #include <Image_PseudoColorImage.hxx>
25 #include <AlienImage_EuclidAlienData.ixx>
26 #include <Aspect_ColorMapEntry.hxx>
27 #include <Standard.hxx>
28
29 #define xTRACE
30
31 #ifdef TRACE
32 static int Verbose = 1 ;
33 #endif
34
35 static const unsigned int EndOfPixelLine  = 65535 ;
36 static const unsigned int EndOfPixelField = 65534 ;
37
38 #ifdef PAGESIZE         // HPUX COMPATIBILLITY
39 #undef PAGESIZE
40 #endif
41 #define MAXCOUL  896
42 #define PAGESIZE 512
43
44 #define FIRST_EUCLID_IMAGE_COLOR 37
45 #define LAST_EUCLID_IMAGE_COLOR  180
46
47 #define ColorsSize() ( MAXCOUL*sizeof(int) ) 
48 #define COLOR(i) ( (( int * )myColors)[i-1] ) // Fortran Array Binding 
49
50 //------------------------------------------------------------------------------
51 //              Public Method
52 //------------------------------------------------------------------------------
53
54 AlienImage_EuclidAlienData::AlienImage_EuclidAlienData()
55
56 {
57   myX1 = myY1 = myX2 = myY2 = myNumberOfColor = 0 ;
58   myColors = NULL ;
59   myPixelsIsDef = Standard_False ;
60 }
61
62 void AlienImage_EuclidAlienData::Clear()
63
64
65   if ( myColors ) {
66         // Free memory
67         Standard::Free(myColors) ;
68         myColors = NULL ;
69   }
70
71   myPixelsIsDef = Standard_False ;
72
73   myX1 = myY1 = myX2 = myY2 = myNumberOfColor = 0 ;
74 }
75
76
77 Standard_Boolean AlienImage_EuclidAlienData::Read( OSD_File& file )
78
79 { Standard_Integer bblcount, i ;
80
81 #ifdef TEST
82   OSD_Path path; file.Path(path);
83   TCollection_AsciiString ext = path.Extension(); ext.LowerCase();
84   if( ext != ".pix" ) {
85     TCollection_AsciiString sysname; path.SystemName(sysname);
86 #ifdef TRACE
87     cout << " *** AlienImage_EuclidAlienData::Read('" << sysname << "'). must have an '.PIX' extension" << endl;
88 #endif
89     return Standard_False;
90   }
91 #endif
92
93   if ( myColors == NULL ) 
94         myColors = Standard::Allocate( ColorsSize() ) ;
95
96   // Read in Header information
97
98   file.Read( myColors, ColorsSize(), bblcount ) ;
99
100   if ( file.Failed() || ( bblcount != ColorsSize() ) ) {
101         // ERROR
102         file.Seek( 0, OSD_FromBeginning ) ;
103         return( Standard_False ) ;
104   }
105
106   myNumberOfColor = COLOR(1)+1 ;
107   myX1            = COLOR(2) ;
108   myY1            = COLOR(3) ;
109   myX2            = COLOR(4) ;
110   myY2            = COLOR(5) ;
111
112 #ifdef TRACE
113   if ( Verbose ) {
114         cout << "EuclidAlienData::Read(" << myNumberOfColor-1 << "," <<
115                                             myX1 << "," <<
116                                             myY1 << "," <<
117                                             myX2 << "," <<
118                                             myY2 << ")\n" << flush ;
119   }
120 #endif
121
122   myPixels = new TColStd_HArray2OfInteger( myX1, myX2, myY1, myY2, 0 ) ;
123   myPixelsIsDef = Standard_True ;
124
125   Standard_Boolean K_FLAG, K_LIGNE;
126   Standard_Integer INCRE, JNCRE, ILIGNE, NUMBLK, NMOT, NPIX, IPIXCR;
127   int LINPIX[(PAGESIZE*128)/sizeof(int)] ;
128   Standard_Address pLINPIX = ( Standard_Address ) LINPIX ;
129
130   K_FLAG  = Standard_True ;
131   K_LIGNE = Standard_False ;
132
133   INCRE   = myX1 ;
134   JNCRE   = 1 ;
135   ILIGNE  = myY1 ;
136
137   NUMBLK = 8 ;
138   NMOT   = (PAGESIZE*128) ;
139
140   file.Seek( PAGESIZE*(NUMBLK-1), OSD_FromBeginning ) ;
141   file.Read( pLINPIX, NMOT*sizeof(int), bblcount ) ;
142
143   NUMBLK += 128 ;
144
145   if ( file.Failed() ) {
146         // ERROR
147         file.Seek( 0, OSD_FromBeginning ) ;
148         return( Standard_False ) ;
149   }
150
151   while( K_FLAG ) {
152         while( !K_LIGNE ) {
153                 NPIX   = LINPIX[JNCRE-1] & 0xffff ;
154                 IPIXCR = ( LINPIX[JNCRE-1] >> 16 ) & 0xffff ;
155                 if ( IPIXCR == (Standard_Integer ) EndOfPixelLine ) {
156                         K_LIGNE = Standard_True ;
157                 }
158                 else if ( IPIXCR < 512 ) {
159                         for( i = 0 ; i < NPIX ; i++ ) {
160                                 myPixels->SetValue(INCRE,ILIGNE,IPIXCR & 0xff);
161                                 INCRE++ ;
162                         }
163
164                         JNCRE++ ;
165
166                         if ( JNCRE >= NMOT ) {
167                           file.Seek( PAGESIZE*(NUMBLK-1), OSD_FromBeginning ) ;
168                           file.Read( pLINPIX, NMOT*sizeof(int),bblcount );
169
170                           NUMBLK += 128 ;
171                           JNCRE   = 1 ;
172
173                           if ( file.Failed() ){         // ERROR
174                                 file.Seek( 0, OSD_FromBeginning ) ;
175                                 return( Standard_False ) ;
176                           }
177                         }
178                 }
179                 else {
180                         K_LIGNE = Standard_True ;
181                 }
182         }
183         // Next Line
184         K_LIGNE = Standard_False ;
185         ILIGNE++ ;
186         INCRE   = myX1 ;
187
188         JNCRE++ ;
189         IPIXCR = ( LINPIX[JNCRE-1] >> 16 ) & 0xffff ;
190         if ( IPIXCR == (Standard_Integer ) EndOfPixelField )
191           K_FLAG = Standard_False ; // End of Image
192   }
193
194   return Standard_True ;
195   
196 }
197
198 Standard_Boolean AlienImage_EuclidAlienData::Write( OSD_File& file ) const
199
200 { Standard_Integer x, y ;
201   Standard_Integer NUMBLK, NMOT, NPIX, MAXMOT ;
202   Standard_Integer ITSTPIX ;
203   int LINPIX[(PAGESIZE*128)/sizeof(int)] ;
204
205   if ( myNumberOfColor == 0 || myColors == NULL || ! myPixelsIsDef ) 
206         return Standard_False ;
207
208   MAXMOT = (PAGESIZE*128) / sizeof(int) ;
209
210   // Write in Header information
211
212   file.Write( myColors, ColorsSize() ) ;
213
214   if ( file.Failed() ) {
215         // ERROR
216         file.Seek( 0, OSD_FromBeginning ) ;
217         return( Standard_False ) ;
218   }
219
220   NUMBLK = 8 ;
221   NMOT   = 0 ;
222
223   for ( y = myY1 ; y <= myY2 ; y++ ) {
224         x = myX1 ;
225         ITSTPIX = myPixels->Value( x, y ) ;
226         x++ ;
227
228         while( x <= myX2 ) {
229                 NPIX = 1 ;
230
231                 while ( myPixels->Value( x, y ) == ITSTPIX ) {
232                         NPIX++ ;
233                         x++ ;
234                         if ( x > myX2 ) break ;// End of Pixel Line
235                 }
236
237                 LINPIX[NMOT] = ( ( ( ITSTPIX&0xff ) << 16 ) & 0xffff0000 ) | 
238                                  ( NPIX & 0xffff );
239                 NMOT++ ;
240
241                 if ( NMOT >= MAXMOT ) {
242                         file.Seek( PAGESIZE*(NUMBLK-1), OSD_FromBeginning ) ;
243                         file.Write( ( void *)LINPIX, NMOT*sizeof(int) );
244
245                         NMOT   = 0 ;
246                         NUMBLK += 128 ;
247                 }
248
249                 if ( x <= myX2 ) {
250                   ITSTPIX = myPixels->Value( x, y ) ;
251                   x++ ;
252
253                   if ( x == myX2 ) {// Last Pixel 
254                     LINPIX[NMOT] = ( ( (ITSTPIX&0xff)<<16 ) & 0xffff0000 ) |
255                                         ( 1 & 0xffff );
256                     NMOT++ ;
257
258                     if ( NMOT >= MAXMOT ) {
259                         file.Seek( PAGESIZE*(NUMBLK-1), OSD_FromBeginning ) ;
260                         file.Write( ( void *)LINPIX, NMOT*sizeof(int) );
261
262                         NMOT   = 0 ;
263                         NUMBLK += 128 ;
264                     }
265                   }
266                 }
267         }
268
269         // End of Pixel Line
270         LINPIX[NMOT] = ( ( EndOfPixelLine<<16 ) & 0xffff0000 ) | 
271                          ( 0 & 0xffff );
272         NMOT++ ;
273
274         if ( NMOT >= MAXMOT ) {
275                 file.Seek( PAGESIZE*(NUMBLK-1), OSD_FromBeginning ) ;
276                 file.Write( ( void *)LINPIX, NMOT*sizeof(int) );
277
278                 NMOT   = 0 ;
279                 NUMBLK += 128 ;
280         }
281   }
282
283   // End of Pixel Field
284   LINPIX[NMOT] = ( ( EndOfPixelField<<16 ) & 0xffff0000 ) | 
285                    ( 0 & 0xffff );
286   NMOT++ ;
287
288   file.Seek( PAGESIZE*(NUMBLK-1), OSD_FromBeginning ) ;
289   file.Write( ( void *)LINPIX, NMOT*sizeof(int) );
290
291   return Standard_False ;
292
293 }
294
295 Handle_Image_Image AlienImage_EuclidAlienData::ToImage() const
296
297 { Standard_Real r,g,b ;
298   Standard_Integer x, y, i ;
299   Aspect_IndexPixel IPixel ;
300   Aspect_ColorMapEntry Centry ;
301   Quantity_Color       color ;
302
303   if ( myNumberOfColor == 0 || myColors == NULL || ! myPixelsIsDef ) 
304         return NULL ;
305
306   Handle(Aspect_GenericColorMap) colormap = new Aspect_GenericColorMap() ;
307   Handle(Image_PseudoColorImage) PImage = 
308         new Image_PseudoColorImage( myX1, myY1, 
309                                    (myX2-myX1)+1, (myY2-myY1)+1, colormap ) ;
310   Handle(Image_Image) RetImage = PImage ;
311
312   // Get Colors
313
314   for ( i = 0 ; i < myNumberOfColor ; i++ ) {
315         r = ( Standard_Real ) COLOR(129+3*i) / 255. ;
316         g = ( Standard_Real ) COLOR(130+3*i) / 255. ;
317         b = ( Standard_Real ) COLOR(131+3*i) / 255. ;
318
319         color.SetValues( r,g,b, Quantity_TOC_RGB );
320
321         Centry.SetValue( i, color ) ;
322
323         colormap->AddEntry( Centry ) ;
324   }
325
326   for ( y = myY1 ; y <= myY2 ; y++ ) {
327         for ( x = myX1 ; x <= myX2 ; x++ ) {
328                 IPixel.SetValue( myPixels->Value( x, y ) ) ;
329                 PImage->SetPixel( x,myY2+myY1-y, IPixel ) ;
330         }
331   }
332
333
334   return RetImage ;
335
336 }
337
338
339 void AlienImage_EuclidAlienData::FromImage( const Handle_Image_Image& anImage )
340
341
342   if ( anImage->Type() == Image_TOI_PseudoColorImage ) {
343         Handle(Image_PseudoColorImage) aPImage =
344                 Handle(Image_PseudoColorImage)::DownCast(anImage) ;
345
346         FromPseudoColorImage( aPImage ) ;
347   }
348   else if ( anImage->Type() == Image_TOI_ColorImage )  {
349         Handle(Image_ColorImage) aCImage =
350                 Handle(Image_ColorImage)::DownCast(anImage) ;
351
352         FromColorImage( aCImage ) ;
353   }
354   else {
355          Standard_TypeMismatch_Raise_if( Standard_True,
356          "Attempt to convert a unknown Image_Image type to a EuclidAlienImage");
357   }
358 }
359
360 //------------------------------------------------------------------------------
361 //              Private Method
362 //------------------------------------------------------------------------------
363
364 void AlienImage_EuclidAlienData::FromColorImage(
365                         const Handle_Image_ColorImage& anImage)
366
367 { Image_Convertor Convertor ;
368   Handle(Aspect_ColorMap) aCmap = 
369     anImage->ChooseColorMap(LAST_EUCLID_IMAGE_COLOR-FIRST_EUCLID_IMAGE_COLOR+1);
370   Handle(Image_PseudoColorImage) aPImage = Convertor.Convert( anImage, aCmap ) ;
371
372   FromPseudoColorImage( aPImage ) ;
373 }
374
375 void AlienImage_EuclidAlienData::FromPseudoColorImage(
376                         const Handle_Image_PseudoColorImage& PImage)
377
378
379 {
380   if ( myColors == NULL ) 
381         myColors = Standard::Allocate( ColorsSize() ) ;
382
383   //
384   // Euclid ColorMap goes from 0 to 255
385   // We must define all colors form 0 to 255 in a EUCLID .PIX file
386   //
387
388   Standard_Real r,g,b ;
389   Standard_Integer x, y, i, index ;
390   Aspect_IndexPixel IPixel ;
391   Aspect_ColorMapEntry Centry ;
392
393   Handle(Aspect_ColorMap) colormap = PImage->ColorMap() ;
394
395   for ( i = 1 ; i <= MAXCOUL ; i++ ) {
396         COLOR(i) = 0 ;
397   }
398
399   myX1 = PImage->LowerX() ; myX2 = PImage->UpperX() ;
400   myY1 = PImage->LowerY() ; myY2 = PImage->UpperY() ;
401
402   myPixels = new TColStd_HArray2OfInteger( myX1, myX2, myY1, myY2, 0 ) ;
403   myPixelsIsDef = Standard_True ;
404
405   myNumberOfColor = 0 ;
406
407   // Get Colors
408
409   for ( i = 1 ; i <= colormap->Size() ; i++ ) {
410         Centry = colormap->Entry( i ) ;
411         index = Centry.Index() ;
412         if ( index >= 0 && index <= 255 ) {
413                 myNumberOfColor = Max( myNumberOfColor, index ) ;
414                 Centry.Color().Values( r,g,b, Quantity_TOC_RGB ) ;
415
416                 COLOR(129+3*index) = ( int ) ( r * 255. + 0.5 ) ;
417                 COLOR(130+3*index) = ( int ) ( g * 255. + 0.5 ) ;
418                 COLOR(131+3*index) = ( int ) ( b * 255. + 0.5 ) ;
419         }
420   }
421
422   COLOR(1) = myNumberOfColor ;
423   COLOR(2) = myX1;
424   COLOR(3) = myY1 ; 
425   COLOR(4) = myX2 ;
426   COLOR(5) = myY2 ; 
427
428   for ( y = myY1 ; y <= myY2 ; y++ ) {
429         for ( x = myX1 ; x <= myX2 ; x++ ) {
430                 PImage->Pixel( x,myY2+myY1-y, IPixel ) ;
431                 myPixels->SetValue( x, y, IPixel.Value() ) ;
432         }
433   }
434 }
435