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 #define TEST //GG_140699
20 // Check file extension, must be ".aida".
22 #include <TCollection_AsciiString.hxx>
23 #include <Image_Convertor.hxx>
24 #include <Aspect_GenericColorMap.hxx>
25 #include <Aspect_ColorCubeColorMap.hxx>
26 #include <AlienImage_AidaAlienData.ixx>
27 #include <Aspect_ColorMapEntry.hxx>
32 static int Verbose = 0 ;
36 AlienImage_AidaAlienData::AlienImage_AidaAlienData()
39 myDataIsDef = Standard_False ;
40 myColorsIsDef = Standard_False ;
41 myDitheringColorMap = new Aspect_ColorCubeColorMap( 40, 5,1, 8,6, 3,54 ) ;
42 myDitheringMethod = Image_DM_NearestColor ;
45 void AlienImage_AidaAlienData::Clear()
48 myDataIsDef = Standard_False ;
49 myColorsIsDef = Standard_False ;
52 Standard_Boolean AlienImage_AidaAlienData::Write( OSD_File& file ) const
54 { Standard_Integer r,c ;
55 TCollection_AsciiString out ;
58 unsigned long int rc,gc,bc ;
59 TCollection_AsciiString Space = " " ;
61 if ( ! myDataIsDef ) return( Standard_False ) ;
62 if ( ! myColorsIsDef ) return( Standard_False ) ;
64 out = TCollection_AsciiString( "#BC(" ) +
65 TCollection_AsciiString( myData->RowLength() ) +
67 TCollection_AsciiString( myData->ColLength() ) +
68 TCollection_AsciiString( " #[\n" ) ;
70 file.Write( out, out.Length() ) ;
72 if ( file.Failed() ) {
74 file.Seek( 0, OSD_FromBeginning ) ;
75 return( Standard_False ) ;
78 for ( r = myData->LowerRow() ; r <= myData->UpperRow() ; r++ ) {
79 out = TCollection_AsciiString( "#*" ) ;
80 for ( c = myData->LowerCol() ; c <= myData->UpperCol() ; c++ ) {
81 p = ( unsigned char ) myData->Value( r, c ) ;
82 sprintf( hexa , "%.2x", p ) ;
83 out += TCollection_AsciiString( hexa ) ;
85 out += TCollection_AsciiString( "\n" ) ;
87 file.Write( out, out.Length() ) ;
89 if ( file.Failed() ) {
91 file.Seek( 0, OSD_FromBeginning ) ;
92 return( Standard_False ) ;
96 out = TCollection_AsciiString( "](\n" ) ;
98 file.Write( out, out.Length() ) ;
100 if ( file.Failed() ) {
102 file.Seek( 0, OSD_FromBeginning ) ;
103 return( Standard_False ) ;
106 // write out the color map buffer
107 for ( c = 1 ; c <= myColors->Size() ; c++ ) {
108 rc = (long unsigned int )( myColors->Entry(c).Color().Red() * 32767 + 0.5 );
109 gc = (long unsigned int )( myColors->Entry(c).Color().Green() * 32767 + 0.5 );
110 bc = (long unsigned int )( myColors->Entry(c).Color().Blue() * 32767 + 0.5 );
112 out = TCollection_AsciiString( "#[" ) +
113 TCollection_AsciiString( myColors->Entry(c).Index() ) + Space +
114 TCollection_AsciiString( Standard_Integer(rc) ) + Space +
115 TCollection_AsciiString( Standard_Integer(gc) ) + Space +
116 TCollection_AsciiString( Standard_Integer(bc) ) + Space +
117 TCollection_AsciiString( "()]\n" ) ;
119 file.Write( out, out.Length() ) ;
121 if ( file.Failed() ) {
123 file.Seek( 0, OSD_FromBeginning ) ;
124 return( Standard_False ) ;
129 out = TCollection_AsciiString( "))" ) ;
131 file.Write( out, out.Length() ) ;
133 if ( file.Failed() ) {
135 file.Seek( 0, OSD_FromBeginning ) ;
136 return( Standard_False ) ;
139 return( Standard_True ) ;
144 Standard_Boolean AlienImage_AidaAlienData::Read( OSD_File& file )
146 { TCollection_AsciiString tmp, in ;
147 Standard_Integer loc1, loc2, width, height, i, bblcount, l ,value ;
148 TCollection_AsciiString HexaSet = "0123456789ABCDEFabcdef" ;
149 int r,g,b,pixel,status ;
150 Handle(Aspect_GenericColorMap) GenCmap = NULL ;
153 OSD_Path path; file.Path(path);
154 TCollection_AsciiString ext = path.Extension(); ext.LowerCase();
155 if( ext != ".aida" ) {
156 TCollection_AsciiString sysname; path.SystemName(sysname);
158 cout << " *** AlienImage_AidaAlienData::Read('" << sysname << "'). must have an '.aida' extension" << endl;
160 return Standard_False;
166 // Extract AidaBYTEMAPS type "#BC"
171 } while( !file.Failed() && tmp != TCollection_AsciiString( "#" ) ) ;
173 if ( file.Failed() ) {
174 file.Seek( 0, OSD_FromBeginning ) ;
175 return( Standard_False ) ; // ERROR
179 file.Read( tmp, 2 ) ;
181 if ( file.Failed() ) {
182 file.Seek( 0, OSD_FromBeginning ) ;
183 return( Standard_False ) ; // ERROR
187 if ( tmp != TCollection_AsciiString( "BC" ) ) {
188 file.Seek( 0, OSD_FromBeginning ) ;
189 return( Standard_False ) ; // ERROR
192 // Get "(" Start of AidaBYTEMAPS size definition
195 } while( !file.Failed() && tmp != TCollection_AsciiString( "(" ) ) ;
197 if ( file.Failed() ) {
198 file.Seek( 0, OSD_FromBeginning ) ;
199 return( Standard_False ) ; // ERROR
203 // Get "#" Start of AidaBYTEMAPS Pixel definition
209 if ( tmp.IsAscii() ) {
212 } while( !file.Failed() && tmp != TCollection_AsciiString( "#" ) ) ;
214 if ( file.Failed() ) {
215 file.Seek( 0, OSD_FromBeginning ) ;
216 return( Standard_False ) ; // ERROR
220 // Extract Image size in "Width Height #"
224 if ( ( loc2 = in.Location( 1, ' ', loc1, in.Length() ) ) == 0 ) {
225 file.Seek( 0, OSD_FromBeginning ) ;
226 return( Standard_False ) ; // ERROR
229 if ( ( loc1 ) > ( loc2-1 ) ) {
230 file.Seek( 0, OSD_FromBeginning ) ;
231 return( Standard_False ) ; // ERROR
235 tmp = in.SubString( loc1, loc2-1 ) ;
237 if ( !tmp.IsIntegerValue() ) {
238 file.Seek( 0, OSD_FromBeginning ) ;
239 return( Standard_False ) ; // ERROR
242 if ( ( width = tmp.IntegerValue() ) <= 0 ) {
243 file.Seek( 0, OSD_FromBeginning ) ;
244 return( Standard_False ) ; // ERROR
247 tmp = in.SubString( loc2, in.Length()-1 ) ;
249 if ( !tmp.IsIntegerValue() ) {
250 file.Seek( 0, OSD_FromBeginning ) ;
251 return( Standard_False ) ; // ERROR
255 if ( ( height = tmp.IntegerValue() ) <= 0 ) {
256 file.Seek( 0, OSD_FromBeginning ) ;
257 return( Standard_False ) ; // ERROR
263 cout << "Width,Height :" << width << "," << height << endl << flush ;
266 AllocData( width, height ) ;
268 // Get "[" start of AidaBYTEMAPS Pixel definition
272 } while( !file.Failed() && tmp != TCollection_AsciiString( "[" ) ) ;
274 if ( file.Failed() ) {
275 file.Seek( 0, OSD_FromBeginning ) ;
276 return( Standard_False ) ; // ERROR
280 // Extract Pixel lines "#*................."
283 for ( i = 0 ; i < height ; i++ ) {
288 } while( !file.Failed() && tmp != TCollection_AsciiString( "#" ) ) ;
290 if ( file.Failed() ) {
291 file.Seek( 0, OSD_FromBeginning ) ;
292 return( Standard_False ) ; // ERROR
298 if ( file.Failed() ) {
299 file.Seek( 0, OSD_FromBeginning ) ;
300 return( Standard_False ) ; // ERROR
303 if ( tmp != TCollection_AsciiString( "*" ) ) {
304 file.Seek( 0, OSD_FromBeginning ) ;
305 return( Standard_False ) ; // ERROR
312 while ( bblcount < (2*width) ) {// Two byte per PIXEL
315 if ( file.Failed() ) {
316 file.Seek( 0, OSD_FromBeginning ) ;
317 return( Standard_False ) ; // ERROR
320 if ( tmp.IsAscii() ) {
321 if ( tmp.FirstLocationInSet( HexaSet, 1, 1 ) ) {
322 in += tmp ; bblcount++ ;
325 // Get Next line character before end of current line
326 file.Seek( 0, OSD_FromBeginning ) ;
327 return( Standard_False ) ; // ERROR
334 cout << "Get one line :\"" << in << "\"\n" << flush ;
337 for ( l = 0 ; l < in.Length() ; l += 2 ) {
338 tmp = in.SubString( l+1, l+2 ) ;
340 value = ( Standard_Integer )strtol( tmp.ToCString(), NULL, 16 );
342 SetPixel( l/2 , i, value ) ;
345 cout << "SetPixel(" << l/2 << "," << i << "," << value << ")\n" <<flush;
350 // Get "]" end of Aida image data
353 } while( !file.Failed() && tmp != TCollection_AsciiString( "]" ) ) ;
355 if ( file.Failed() ) {
356 file.Seek( 0, OSD_FromBeginning ) ;
357 return( Standard_False ) ; // ERROR
360 // Get "(" start of Aida colors definition or ")" end of Aida ByteMaps
363 } while( !file.Failed() &&
364 tmp != TCollection_AsciiString( "(" ) &&
365 tmp != TCollection_AsciiString( ")" ) ) ;
367 if ( file.Failed() ) {
368 file.Seek( 0, OSD_FromBeginning ) ;
369 return( Standard_False ) ; // ERROR
372 if ( tmp == TCollection_AsciiString( ")" ) ) {
373 return( Standard_True ) ; // No Color definition ERROR ??
376 // Find Color definition "#[ Red Green Blue ... ]" color is from 0->32767
378 myColors = GenCmap = new Aspect_GenericColorMap() ;
379 myColorsIsDef = Standard_True ;
382 // Get "#" start of a Aida color definition or
383 // Get ")" end of Aida colors definition
386 } while( !file.Failed() &&
387 tmp != TCollection_AsciiString( "#" ) &&
388 tmp != TCollection_AsciiString( ")" ) ) ;
390 if ( file.Failed() ) {
391 file.Seek( 0, OSD_FromBeginning ) ;
392 return( Standard_False ) ; // ERROR
395 if ( tmp == TCollection_AsciiString( "#" ) ) {
397 // Get "[" start of a Aida color definition
400 } while( !file.Failed() && tmp != TCollection_AsciiString( "[" ) ) ;
402 if ( file.Failed() ) {
403 file.Seek( 0, OSD_FromBeginning ) ;
404 return( Standard_False ) ; // ERROR
407 // Get "]" end of a Aida color definition
412 if ( tmp.IsAscii() && tmp != TCollection_AsciiString( "]" ) ) {
415 } while( !file.Failed() && tmp != TCollection_AsciiString( "]" ) ) ;
417 if ( file.Failed() ) {
418 file.Seek( 0, OSD_FromBeginning ) ;
419 return( Standard_False ) ; // ERROR
422 status = sscanf( in.ToCString(), "%d %d %d %d", &pixel,&r,&g,&b ) ;
426 Aspect_ColorMapEntry( pixel,
427 Quantity_Color( r/32767.,g/32767.,b/32767.,
428 Quantity_TOC_RGB ) ) ) ;
434 cout << in << endl << flush ;
438 } while ( !file.Failed() && tmp != TCollection_AsciiString( ")" ) ) ;
441 if ( file.Failed() ) {
442 file.Seek( 0, OSD_FromBeginning ) ;
443 return( Standard_False ) ; // ERROR
447 return( Standard_True ) ;
451 Handle_Image_Image AlienImage_AidaAlienData::ToImage() const
453 { Standard_Integer x,y ;
454 Handle(Image_PseudoColorImage) aPImage =
455 new Image_PseudoColorImage( 0, 0,
456 myData->RowLength(), myData->ColLength(),
459 for( y = 0 ; y < aPImage->Height() ; y++ ) {
460 for( x = 0 ; x < aPImage->Width() ; x++ ) {
461 aPImage->SetPixel( aPImage->LowerX()+x,
462 aPImage->LowerY()+y, Pixel( x, y ) ) ;
469 void AlienImage_AidaAlienData::FromImage( const Handle_Image_Image& anImage )
471 { if ( anImage->IsInstance(STANDARD_TYPE(Image_PseudoColorImage)) ) {
472 Handle(Image_PseudoColorImage) aPImage =
473 Handle(Image_PseudoColorImage)::DownCast(anImage) ;
475 FromPseudoColorImage( aPImage ) ;
477 else if ( anImage->IsInstance(STANDARD_TYPE(Image_ColorImage)) ) {
478 Handle(Image_ColorImage) aCImage =
479 Handle(Image_ColorImage)::DownCast(anImage) ;
481 FromColorImage( aCImage ) ;
484 Standard_TypeMismatch_Raise_if( Standard_True,
485 "Attempt to convert a unknown Image_Image type to a AidaAlienData");
489 void AlienImage_AidaAlienData::SetColorImageDitheringMethod(
490 const Image_DitheringMethod aMethod ,
491 const Handle(Aspect_ColorMap)& aColorMap )
493 { myDitheringMethod = aMethod ; myDitheringColorMap = aColorMap ; }
495 //------------------------------------------------------------------------------
497 //------------------------------------------------------------------------------
500 void AlienImage_AidaAlienData::FromPseudoColorImage(
501 const Handle_Image_PseudoColorImage& anImage)
503 { Standard_Integer x,y ;
505 AllocData( anImage->Width(), anImage->Height() ) ;
507 myColors = anImage->ColorMap() ;
508 myColorsIsDef = Standard_True ;
510 for ( y = 0 ; y < anImage->Height() ; y++ ) {
511 for ( x = 0 ; x < anImage->Width() ; x++ ) {
514 anImage->Pixel( anImage->LowerX()+x,
515 anImage->LowerY()+y ).Value() ) ;
520 void AlienImage_AidaAlienData::FromColorImage(
521 const Handle_Image_ColorImage& anImage)
523 { Image_Convertor Convertor ;
525 Handle(Image_PseudoColorImage) aPImage =
526 new Image_PseudoColorImage( anImage->LowerX(), anImage->LowerY(),
527 anImage->Width(), anImage->Height(),
528 myDitheringColorMap ) ;
530 Convertor.SetDitheringMethod( myDitheringMethod ) ;
532 aPImage = Convertor.Convert( anImage, myDitheringColorMap ) ;
534 FromPseudoColorImage( aPImage ) ;
537 void AlienImage_AidaAlienData::AllocData(
538 const Standard_Integer dx,
539 const Standard_Integer dy )
541 myData = new TColStd_HArray2OfInteger( 0, dy-1 , 0, dx-1 ) ;
542 myDataIsDef = Standard_True ;
545 void AlienImage_AidaAlienData::SetPixel(
546 const Standard_Integer x,
547 const Standard_Integer y,
548 const Standard_Integer value )
550 myData->SetValue( y, x, value ) ;
553 Standard_Integer AlienImage_AidaAlienData::Pixel(
554 const Standard_Integer x, const Standard_Integer y ) const
556 { return myData->Value( y, x ) ; }