0023885: Inclusion of X11 header should be protected with macro
[occt.git] / src / AlienImage / AlienImage_X11XWDAlienData.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 PRO9517 //GG_010997
20 //              1) Le swap ne fonctionne pas correctement sur DEC
21 //              car X11XColor.pixel est int et non long (::Read(),::Write()).
22 //              2) Initialiser la table des couleurs avant d'ecrire
23 //              le fichier temporaire (::Write())
24
25 #define K4      //GG_110398
26 //              Ne pas initialiser una AsciiString avec '\0' dans le
27 //              constructeur de AlienImage_X11XWDAlienData sinon RAISE !
28
29 #define TEST    //GG_140699
30 //              Check file extension, must be ".xwd".
31
32 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
33 # include <X11/Xlib.h>
34 #endif  // WNT
35 #include <Aspect_GenericColorMap.hxx>
36 #include <Image_PseudoColorImage.hxx>
37 #include <AlienImage_MemoryOperations.hxx>
38 #include <AlienImage_X11XColor.hxx>
39 #include <AlienImage_X11XWDAlienData.ixx>
40 #include <Aspect_ColorMapEntry.hxx>
41 #include <Standard.hxx>
42
43 #ifdef TRACE
44 static int Verbose = 0 ;
45 #endif
46
47
48
49 AlienImage_X11XWDAlienData::AlienImage_X11XWDAlienData()
50
51 { myData   = NULL ;
52   myColors = NULL ;
53 }
54
55 void AlienImage_X11XWDAlienData::SetName( const TCollection_AsciiString& aName)
56
57 { myName = aName + TCollection_AsciiString( "\0" ) ;
58   myHeader.header_size = sizeof( myHeader ) + myName.Length() ;
59 }
60
61 const TCollection_AsciiString&  AlienImage_X11XWDAlienData::Name() const
62
63 { return ( myName ) ; }
64
65 void AlienImage_X11XWDAlienData::Clear()
66
67 { Standard_Integer size ;
68
69   myHeader.header_size  = sizeof( myHeader ) ; 
70                                 /* Size of the entire file header (bytes).*/
71   myHeader.file_version = 0 ;   /* XWD_FILE_VERSION */
72   myHeader.pixmap_format= 0;    /* Pixmap format */
73   myHeader.pixmap_depth = 0 ;   /* Pixmap depth */
74   myHeader.pixmap_width = 0 ;   /* Pixmap width */
75   myHeader.pixmap_height= 0 ;   /* Pixmap height */
76   myHeader.xoffset      = 0 ;   /* Bitmap x offset */
77   myHeader.byte_order   = 0;    /* MSBFirst, LSBFirst */
78   myHeader.bitmap_unit  = 0 ;   /* Bitmap unit */
79   myHeader.bitmap_bit_order = 0;        /* MSBFirst, LSBFirst */
80   myHeader.bitmap_pad   = 0 ;   /* Bitmap scanline pad */
81   myHeader.bits_per_pixel = 0 ; /* Bits per pixel */
82   myHeader.bytes_per_line =0 ;  /* Bytes per scanline */
83   myHeader.visual_class = 0 ;   /* Class of colormap */
84   myHeader.red_mask     = 0 ;   /* Z red mask */
85   myHeader.green_mask   = 0 ;   /* Z green mask */
86   myHeader.blue_mask    = 0 ;   /* Z blue mask */
87   myHeader.bits_per_rgb = 0 ;   /* Log2 of distinct color values */
88   myHeader.colormap_entries = 0 ;       /* Number of entries in colormap */
89   myHeader.ncolors      = 0 ;   /* Number of Color structures */
90   myHeader.window_width = 0 ;   /* Window width */
91   myHeader.window_height= 0 ;   /* Window height */
92   myHeader.window_x     = 0 ;   /* Window upper left X coordinate */
93   myHeader.window_y     = 0 ;   /* Window upper left Y coordinate */
94   myHeader.window_bdrwidth =0 ; /* Window border width */
95   
96   myName.Clear() ;
97
98   if ( myData ) {
99         //Free all allocated memory
100         Standard::Free(myData) ;
101         myData   = NULL ;
102   }
103
104   if ( myColors ) {
105         size = ( Standard_Integer ) 
106                         myHeader.ncolors * sizeof( AlienImage_X11XColor ) ;
107         //Free all allocated memory
108         Standard::Free(myColors);
109         myColors = NULL ;
110   }
111
112 }
113
114 Standard_Boolean AlienImage_X11XWDAlienData::Write( OSD_File& file ) const
115
116 { Standard_Integer  size, i ;
117   unsigned long swaptest = 1;
118   AlienImage_X11XWDFileHeader TheHeader = myHeader ;
119
120   if ( myData == NULL )         return( Standard_False ) ;
121   if ( TheHeader.ncolors && 
122        myColors == NULL )       return( Standard_False ) ;
123
124   
125   // Write out TheHeader information
126
127   size = ( Standard_Integer ) TheHeader.header_size - sizeof( TheHeader ) ;
128
129   if ( size ) {
130         // Add '\0' at the end of name
131         TheHeader.header_size++ ;
132   }
133
134   if (*(char *) &swaptest) {
135     AlienImage_X11XWDFileHeader SwapHeader = TheHeader ;
136
137     AlienImage_MemoryOperations::SwapLong( ( Standard_Address ) &SwapHeader, 
138                                            sizeof(SwapHeader));
139     file.Write( &SwapHeader ,  sizeof( SwapHeader ) ) ;
140   }
141   else {
142     const Standard_Address pHeader = ( Standard_Address ) &TheHeader ;
143
144     file.Write( pHeader,  sizeof( TheHeader ) ) ;
145   }
146
147   if ( file.Failed() ) {
148         // ERROR
149         file.Seek( 0, OSD_FromBeginning ) ;
150         return( Standard_False ) ;
151   }
152
153   size = ( Standard_Integer ) TheHeader.header_size - sizeof( TheHeader ) ;
154
155   if ( size ) {
156         char end = '\0' ;
157         Standard_Address pend = Standard_Address( &end ) ;
158
159         file.Write( myName, myName.Length() ) ;
160
161         file.Write( pend, 1 ) ;
162   }
163
164   if ( file.Failed() ) {
165         // ERROR
166         file.Seek( 0, OSD_FromBeginning ) ;
167         return( Standard_False ) ;
168   }
169
170   // write out the color map buffer
171
172   if ( TheHeader.ncolors ) {
173         size = ( Standard_Integer ) TheHeader.ncolors 
174                                         * sizeof( AlienImage_X11XColor ) ;
175
176         if (*(char *) &swaptest) {
177           Standard_Address palloc =  
178                         Standard::Allocate( size ) ;
179 #ifdef PRO9517
180           const AlienImage_X11XColor *p = ( AlienImage_X11XColor * ) myColors ;
181           AlienImage_X11XColor *pp = ( AlienImage_X11XColor * ) palloc ;
182
183           for (i = 0 ; (unsigned int ) i < TheHeader.ncolors; i++,p++,pp++) {
184             pp->pixel = p->pixel;
185             pp->red = p->red;
186             pp->green = p->green;
187             pp->blue = p->blue;
188             pp->flags = p->flags;
189             AlienImage_MemoryOperations::SwapLong (
190                         (Standard_Address) &(pp->pixel), sizeof(int));
191             AlienImage_MemoryOperations::SwapShort(
192                         (Standard_Address) &(pp->red)  , 3 * sizeof(short));
193           }
194 #else
195           const AlienImage_X11XColor *p = ( AlienImage_X11XColor * ) palloc ;
196
197           for (i = 0 ; i < TheHeader.ncolors; i++,p++) {
198                   AlienImage_MemoryOperations::SwapLong (
199                         (Standard_Address) &(p->pixel), sizeof(long));
200                   AlienImage_MemoryOperations::SwapShort(
201                         (Standard_Address) &(p->red)  , 3 * sizeof(short));
202           }
203 #endif
204                 
205           file.Write( palloc, size ) ;
206
207           //Free all allocated memory
208           Standard::Free(palloc) ;
209         }
210         else {
211                 file.Write( myColors, size ) ;
212         }
213
214         if ( file.Failed() ) {
215                 // ERROR
216                 file.Seek( 0, OSD_FromBeginning ) ;
217                 return( Standard_False ) ;
218         }
219
220   }
221
222   if ( DataSize() ) {
223         file.Write( myData, DataSize() ) ;
224
225         if ( file.Failed() ) {
226                 // ERROR
227                 file.Seek( 0, OSD_FromBeginning ) ;
228                 return( Standard_False ) ;
229         }
230
231   }
232
233   return( Standard_True ) ;
234   
235 }
236
237
238 Standard_Boolean AlienImage_X11XWDAlienData::Read( OSD_File& file )
239
240 { Standard_Integer bblcount, i, size ;
241   unsigned long swaptest = 1;
242   Standard_Address pheader = ( Standard_Address ) &myHeader ;
243
244 #ifdef TEST
245   OSD_Path path; file.Path(path); 
246   TCollection_AsciiString ext = path.Extension(); ext.LowerCase();
247   if( ext != ".xwd" ) {
248     TCollection_AsciiString sysname; path.SystemName(sysname);
249 #ifdef TRACE
250     cout << " *** AlienImage_X11XWDAlienData::Read('" << sysname << "'). must have an '.xwd' extension" << endl;
251 #endif
252     return Standard_False;
253   }
254 #endif
255
256   // Read in myHeader information
257
258   file.Read( pheader, sizeof( myHeader ), bblcount ) ;
259
260   if ( file.Failed() || ( bblcount != sizeof( myHeader ) ) ) {
261         // ERROR
262         file.Seek( 0, OSD_FromBeginning ) ;
263         return( Standard_False ) ;
264   }
265
266   if (*(char *) &swaptest) 
267     AlienImage_MemoryOperations::SwapLong( ( Standard_Address ) &myHeader, 
268                                            sizeof(myHeader));
269
270   // check to see if the dump file is in the proper format */
271   if (myHeader.file_version != XWD_FILE_VERSION) {
272         // ERROR "XWD file format version mismatch."
273
274         if (*(char *) &swaptest) 
275           AlienImage_MemoryOperations::SwapLong( ( Standard_Address ) &myHeader,
276                                                   sizeof(myHeader));
277
278         if (myHeader.file_version != XWD_FILE_VERSION) {
279                 // ERROR "XWD file format version mismatch."
280                 file.Seek( 0, OSD_FromBeginning ) ;
281                 return( Standard_False ) ;
282         }
283         else {
284                 // Data come from a swaped computer ??
285                 swaptest = 0 ;
286         }
287   }
288
289   if (myHeader.header_size < sizeof(myHeader)) {
290         // ERROR "XWD header size is too small."
291         file.Seek( 0, OSD_FromBeginning ) ;
292         return( Standard_False ) ;
293   }
294
295 #ifdef TRACE
296   if ( Verbose ) cout << myHeader << endl << flush ;
297 #endif
298
299   // read in window name
300
301   size = ( Standard_Integer ) myHeader.header_size - sizeof( myHeader ) ;
302
303   if ( size > 0 ) {
304 #ifdef K4
305     TCollection_AsciiString name( bblcount ) ;
306 #else
307     TCollection_AsciiString name( bblcount , '\0') ;
308 #endif
309
310     file.Read( name, size ) ; bblcount = name.Length() ;
311 #ifdef WNT
312     --size;
313 #endif  // WNT
314
315     if ( file.Failed() || ( bblcount != size ) ) {
316         // ERROR
317         file.Seek( 0, OSD_FromBeginning ) ;
318         return( Standard_False ) ;
319     }
320
321     myName = name ;
322
323 #ifdef TRACE
324     if ( Verbose ) cout << myName << endl << flush ;
325 #endif
326
327   }
328
329   // read in the color map buffer
330
331   if ( myHeader.ncolors ) {
332         size = ( Standard_Integer ) myHeader.ncolors 
333                         * sizeof( AlienImage_X11XColor ) ;
334
335         myColors = Standard::Allocate( size ) ;
336
337         file.Read( myColors, size, bblcount ) ;
338
339         if ( file.Failed() || ( bblcount != size ) ) {
340                 // ERROR
341                 file.Seek( 0, OSD_FromBeginning ) ;
342                 return( Standard_False ) ;
343         }
344
345         if ( *(char *) &swaptest ) {
346                 AlienImage_X11XColor *p  
347                                 = ( AlienImage_X11XColor * )myColors ;
348                 for (i = 0 ; (unsigned int ) i < myHeader.ncolors; i++,p++) {
349 #ifdef PRO9517
350                   AlienImage_MemoryOperations::SwapLong (
351                         (Standard_Address) &(p->pixel), sizeof(int));
352 #else
353                   AlienImage_MemoryOperations::SwapLong (
354                         (Standard_Address) &(p->pixel), sizeof(long));
355 #endif
356                   AlienImage_MemoryOperations::SwapShort(
357                         (Standard_Address) &(p->red)  , 3 * sizeof(short));
358                 }
359         }
360
361 #ifdef TRACE
362         if ( Verbose )  { 
363           AlienImage_X11XColor *p = ( AlienImage_X11XColor * )myColors;
364
365           for (i = 0 ; i < myHeader.ncolors; i++,p++) {
366                 cout << *p << endl << flush ;
367           }
368
369         }
370 #endif
371   }
372
373   if ( DataSize() ) {
374         myData = Standard::Allocate( DataSize() ) ;
375
376         file.Read( myData, DataSize(), bblcount ) ;
377
378         if ( file.Failed() || ( bblcount != DataSize() ) ) {
379                 // ERROR
380                 file.Seek( 0, OSD_FromBeginning ) ;
381                 return( Standard_False ) ;
382         }
383   }
384
385   return( Standard_True ) ;
386   
387 }
388
389 Handle_Image_Image AlienImage_X11XWDAlienData::ToImage() const
390
391 {   if ( myHeader.pixmap_depth <= 8 && 
392        myHeader.ncolors &&
393        myHeader.pixmap_format == ZPixmap) {
394         return( ToPseudoColorImage() ) ;
395     }
396     else if ( myHeader.visual_class  == TrueColor && 
397               myHeader.pixmap_format == ZPixmap) {
398         return( ToColorImage() ) ;
399     }
400     else {
401          Standard_TypeMismatch_Raise_if( Standard_True,
402          "Attempt to convert a X11XWDAlienData to a unknown Image_Image type");
403
404         return( NULL ) ;
405     }
406 }
407
408 void AlienImage_X11XWDAlienData::FromImage( const Handle_Image_Image& anImage )
409
410 { if ( anImage->Type() == Image_TOI_PseudoColorImage ) {
411         Handle(Image_PseudoColorImage) aPImage =
412                 Handle(Image_PseudoColorImage)::DownCast(anImage) ;
413
414         FromPseudoColorImage( aPImage ) ;
415   }
416   else if ( anImage->Type() == Image_TOI_ColorImage )  {
417         Handle(Image_ColorImage) aCImage =
418                 Handle(Image_ColorImage)::DownCast(anImage) ;
419
420         FromColorImage( aCImage ) ;
421   }
422   else {
423          Standard_TypeMismatch_Raise_if( Standard_True,
424          "Attempt to convert a unknown Image_Image type to a X11XWDAlienData");
425   }
426 }
427
428 //------------------------------------------------------------------------------
429 //              Private Method
430 //------------------------------------------------------------------------------
431
432
433 void AlienImage_X11XWDAlienData::FromPseudoColorImage(
434                         const Handle_Image_PseudoColorImage& anImage)
435
436 { Standard_Integer size, i ;
437
438   /* Size of the entire file header (bytes).*/
439   myHeader.header_size      = sizeof(myHeader) + myName.Length() ;
440   myHeader.file_version     = XWD_FILE_VERSION ;        /* XWD_FILE_VERSION */
441   myHeader.pixmap_format    = ZPixmap ;         /* Pixmap format */
442   myHeader.pixmap_depth     = 8 ;               /* Pixmap depth */
443   myHeader.pixmap_width     = anImage->Width() ;/* Pixmap width */
444   myHeader.pixmap_height    = anImage->Height() ;/* Pixmap height */
445   myHeader.xoffset          = 0 ;               /* Bitmap x offset */
446   myHeader.byte_order       = MSBFirst;         /* MSBFirst, LSBFirst */
447   myHeader.bitmap_unit      = 32 ;              /* Bitmap unit */
448   myHeader.bitmap_bit_order = MSBFirst;         /* MSBFirst, LSBFirst */
449   myHeader.bitmap_pad       = 32 ;              /* Bitmap scanline pad */
450   myHeader.bits_per_pixel   = 8 ;               /* Bits per pixel */
451   /* Bytes per scanline */
452   size = ( Standard_Integer ) ( anImage->Width() * myHeader.bits_per_pixel );
453
454   myHeader.bytes_per_line = size / myHeader.bitmap_unit ;
455   if ( size %  myHeader.bitmap_pad ) myHeader.bytes_per_line += 1 ;
456
457   myHeader.bytes_per_line *= ( myHeader.bitmap_unit / 8 ) ;
458
459   myHeader.visual_class     = PseudoColor ;     /* Class of colormap */
460   myHeader.red_mask         = 0 ;               /* Z red mask */
461   myHeader.green_mask       = 0 ;               /* Z green mask */
462   myHeader.blue_mask        = 0 ;               /* Z blue mask */
463   myHeader.bits_per_rgb     = 8 ;       /* Log2 of distinct color values */
464   myHeader.colormap_entries = 256 ;     /* Number of entries in colormap */
465   myHeader.ncolors          = (anImage->ColorMap())->Size() ;
466                                         /* Number of Color structures */
467   myHeader.window_width     = anImage->Width() ;        /* Window width */
468   myHeader.window_height    = anImage->Height() ;       /* Window height */
469   myHeader.window_x         = 0 ;       /* Window upper left X coordinate */
470   myHeader.window_y         = 0 ;       /* Window upper left Y coordinate */
471   myHeader.window_bdrwidth  = 0 ;       /* Window border width */
472
473   size = ( Standard_Integer ) myHeader.ncolors 
474                                 * sizeof( AlienImage_X11XColor ) ;
475
476   myColors = Standard::Allocate( size ) ;
477
478   AlienImage_X11XColor *p = ( AlienImage_X11XColor * )myColors ;
479   Aspect_ColorMapEntry  aCentry ;
480
481   for ( i = 1 ; (unsigned int ) i <= myHeader.ncolors ; i++, p++ ) {
482         p->pixel = 0 ;
483         p->red   = p->green = p->blue = 0 ;
484         p->flags = 0 ;
485
486         aCentry = (anImage->ColorMap())->Entry( i ) ;
487
488         if ( aCentry.IsAllocated() == Standard_True ) {
489                 p->flags = DoRed | DoGreen | DoBlue ;
490                 p->pixel = aCentry.Index() ;
491                 p->red   = ( unsigned short )
492                                 ( (aCentry.Color()).Red()   * 0xffff + 0.5 ) ;
493                 p->green = ( unsigned short )
494                                 ( (aCentry.Color()).Green() * 0xffff + 0.5 ) ;
495                 p->blue  = ( unsigned short )
496                                 ( (aCentry.Color()).Blue()  * 0xffff + 0.5 ) ;
497         }
498   }
499
500   if ( anImage->Size() ) {
501         Standard_Integer x, y ;
502         
503         myData = Standard::Allocate( DataSize() ) ;
504
505         for ( y = 0 ; (unsigned int ) y < myHeader.pixmap_height ; y++ ) {
506           for ( x = 0 ; (unsigned int ) x < myHeader.pixmap_width ; x++ ) {
507                 SetPixel( x, y, 
508                           ( anImage->Pixel( anImage->LowerX()+x , 
509                                             anImage->LowerY()+y )).Value() ) ;
510           }
511         }
512
513   }
514 }
515
516 void AlienImage_X11XWDAlienData::FromColorImage(
517                         const Handle_Image_ColorImage& anImage)
518
519 { long int size ;;
520
521   /* Size of the entire file header (bytes).*/
522   myHeader.header_size      = sizeof(myHeader) + myName.Length() ;
523   myHeader.file_version     = XWD_FILE_VERSION ;        /* XWD_FILE_VERSION */
524   myHeader.pixmap_format    = ZPixmap ;         /* Pixmap format */
525   myHeader.pixmap_depth     = 24 ;              /* Pixmap depth */
526   myHeader.pixmap_width     = anImage->Width() ;/* Pixmap width */
527   myHeader.pixmap_height    = anImage->Height() ;/* Pixmap height */
528   myHeader.xoffset          = 0 ;               /* Bitmap x offset */
529   myHeader.byte_order       = MSBFirst;         /* MSBFirst, LSBFirst */
530   myHeader.bitmap_unit      = 32 ;              /* Bitmap unit */
531   myHeader.bitmap_bit_order = MSBFirst;         /* MSBFirst, LSBFirst */
532   myHeader.bitmap_pad       = 32 ;              /* Bitmap scanline pad */
533   myHeader.bits_per_pixel   = 32 ;              /* Bits per pixel */
534   /* Bytes per scanline */
535   size = anImage->Width() * myHeader.bits_per_pixel ;
536
537   myHeader.bytes_per_line = size / myHeader.bitmap_unit ;
538   if ( size %  myHeader.bitmap_pad ) myHeader.bytes_per_line += 1 ;
539
540   myHeader.bytes_per_line *= ( myHeader.bitmap_unit / 8 ) ;
541
542   myHeader.visual_class     = TrueColor ;       /* Class of colormap */
543   myHeader.red_mask         = 0xff ;            /* Z red mask */
544   myHeader.green_mask       = 0xff00 ;          /* Z green mask */
545   myHeader.blue_mask        = 0xff0000 ;        /* Z blue mask */
546   myHeader.bits_per_rgb     = 8 ;       /* Log2 of distinct color values */
547   myHeader.colormap_entries = 256 ;     /* Number of entries in colormap */
548   myHeader.ncolors          = 0 ;       /* Number of Color structures */
549   myHeader.window_width     = anImage->Width() ;        /* Window width */
550   myHeader.window_height    = anImage->Height() ;       /* Window height */
551   myHeader.window_x         = 0 ;       /* Window upper left X coordinate */
552   myHeader.window_y         = 0 ;       /* Window upper left Y coordinate */
553   myHeader.window_bdrwidth  = 0 ;       /* Window border width */
554
555
556   myColors = NULL ;
557
558   if ( anImage->Size() ) {
559         Standard_Integer x, y, pix, c ;
560         const Standard_Integer rs = RedShift() ;
561         const Standard_Integer gs = GreenShift() ;
562         const Standard_Integer bs = BlueShift() ;
563         const Standard_Integer ColorRange = 
564                         Standard_Integer( ( 1 << myHeader.bits_per_rgb ) - 1 );
565         Quantity_Color col ;
566         
567         myData = Standard::Allocate( DataSize() ) ;
568
569         for ( y = 0 ; (unsigned int ) y < myHeader.pixmap_height ; y++ ) {
570           for ( x = 0 ; (unsigned int ) x < myHeader.pixmap_width ; x++ ) {
571                 col = anImage->Pixel( anImage->LowerX()+x , 
572                                         anImage->LowerY()+y ).Value() ;
573
574                 pix = 0 ;
575
576                 c = ( Standard_Integer ) ( col.Red() * ColorRange + 0.5 );
577                 c = ( Standard_Integer ) (( c << rs ) & myHeader.red_mask) ;
578                 pix |= c ;
579                 
580                 c = ( Standard_Integer ) ( col.Green() * ColorRange + 0.5 );
581                 c = ( Standard_Integer ) (( c << gs ) & myHeader.green_mask) ;
582                 pix |= c ;
583                 
584                 c = ( Standard_Integer ) ( col.Blue() * ColorRange + 0.5 );
585                 c = ( Standard_Integer ) (( c << bs ) & myHeader.blue_mask) ;
586                 pix |= c ;
587                 
588                 SetPixel( x, y, pix ) ;
589           }
590         }
591
592   }
593 }
594
595 Handle_Image_ColorImage AlienImage_X11XWDAlienData::ToColorImage() const
596
597 { Aspect_ColorPixel CPixel ;
598   Quantity_Color    acolor ;
599   Handle(Image_ColorImage) ret_image = NULL ;
600   Standard_Integer pix,x,y ;
601   Standard_Real r,g,b, maxcol ;
602
603   if ( myHeader.visual_class  == TrueColor && 
604        myHeader.pixmap_format == ZPixmap) {
605     ret_image = new Image_ColorImage( 0,0,
606                         (Standard_Integer)myHeader.pixmap_width,
607                         (Standard_Integer)myHeader.pixmap_height ) ;
608
609     maxcol = ( 1 << myHeader.bits_per_rgb ) - 1 ;
610
611     for ( y = 0 ; (unsigned int ) y < myHeader.pixmap_height ; y++ ) {
612       for ( x = 0 ; (unsigned int ) x < myHeader.pixmap_width ; x++ ) {
613         pix = Pixel( x, y ) ;
614
615         r = ( ( pix & myHeader.red_mask )   >> RedShift() )    / maxcol ;
616         g = ( ( pix & myHeader.green_mask ) >> GreenShift() )  / maxcol ;
617         b = ( ( pix & myHeader.blue_mask )  >> BlueShift() )   / maxcol ;
618         
619         acolor.SetValues( r,g,b, Quantity_TOC_RGB ) ;
620         CPixel.SetValue ( acolor ) ;
621
622         ret_image->SetPixel( ret_image->LowerX()+x , 
623                              ret_image->LowerY()+y, CPixel ) ;
624       }
625     }
626         
627   }
628
629   return( ret_image ) ;
630 }
631
632 Handle_Image_PseudoColorImage AlienImage_X11XWDAlienData::ToPseudoColorImage() 
633                                                                 const
634
635 { Standard_Real r,g,b ;
636   Standard_Integer x, y ;
637   const Standard_Real XRange = Standard_Real( Standard_Integer(0xffff) );
638   const Standard_Integer newColorSize = 
639        Standard_Integer(myHeader.colormap_entries*sizeof(AlienImage_X11XColor));
640   Handle(Image_PseudoColorImage) ret_image = NULL ;
641
642   if ( myHeader.pixmap_depth <= 8 && 
643        myHeader.ncolors &&
644        myHeader.pixmap_format == ZPixmap) {     
645 //    unsigned long int i, j, ncol ;
646     unsigned long int i, ncol ;
647     Aspect_ColorMapEntry Centry ;
648     Quantity_Color       color ;
649     AlienImage_X11XColor *p ;
650     AlienImage_X11XColor *newColor ;
651     Standard_Address     palloc ;
652     Aspect_IndexPixel IPixel ;
653
654     palloc = Standard::Allocate( newColorSize ) ;
655
656     newColor = ( AlienImage_X11XColor * ) palloc ;
657
658     p = ( AlienImage_X11XColor * )myColors;
659
660     for ( i = 0 ; i < myHeader.ncolors ; i++, p++ )     newColor[p->pixel] = *p;
661     for ( i = 0 ; i < myHeader.colormap_entries ; i++ ) newColor[i].flags  = 0 ;
662
663     for ( y = 0 ; (unsigned int ) y < myHeader.pixmap_height ; y++ ) {
664         for ( x = 0 ; (unsigned int ) x < myHeader.pixmap_width ; x++ ) {
665                 newColor[ Pixel( x, y ) ].flags = DoRed | DoGreen | DoBlue ;
666         }
667     }
668
669     for ( i = ncol = 0 ; i < myHeader.colormap_entries ; i++ ) {
670         if ( newColor[i].flags ) ncol++ ;
671     }
672
673     Handle(Aspect_GenericColorMap) colormap = 
674         new Aspect_GenericColorMap();
675
676     for ( i = 0 ; i < myHeader.colormap_entries ; i++ ) {
677         if ( newColor[i].flags ) {
678                 r = ( Standard_Real ) newColor[i].red   / XRange ;
679                 g = ( Standard_Real ) newColor[i].green / XRange ;
680                 b = ( Standard_Real ) newColor[i].blue  / XRange ;
681                 color.SetValues( r,g,b, Quantity_TOC_RGB );
682                 Centry.SetValue( Standard_Integer(newColor[i].pixel), color ) ;
683                 colormap->AddEntry( Centry ) ;
684         }
685     }
686
687     ret_image = new Image_PseudoColorImage( 0,0,
688                                    Standard_Integer(myHeader.pixmap_width),
689                                    Standard_Integer(myHeader.pixmap_height),
690                                    colormap ) ;
691
692     for ( y = 0 ; (unsigned int ) y < myHeader.pixmap_height ; y++ ) {
693       for ( x = 0 ; (unsigned int ) x < myHeader.pixmap_width ; x++ ) {
694         IPixel.SetValue( Pixel( x, y ) ) ;
695         ret_image->SetPixel( ret_image->LowerX()+x , 
696                              ret_image->LowerY()+y, IPixel ) ;
697       }
698     }
699         
700
701     //Free all allocated memory
702     Standard::Free(palloc);
703   }
704
705   return ret_image ;
706
707 }
708
709 Standard_Integer AlienImage_X11XWDAlienData::DataSize() const
710
711
712     if ( myHeader.pixmap_format != ZPixmap)
713       return( myHeader.bytes_per_line * myHeader.pixmap_height 
714                                       * myHeader.pixmap_depth );
715
716     return( myHeader.bytes_per_line * myHeader.pixmap_height);
717 }
718
719 void AlienImage_X11XWDAlienData::SetPixel( 
720         const Standard_Integer x, 
721         const Standard_Integer y, 
722         const Standard_Integer value )
723
724 { unsigned char *p ;
725   unsigned long int pixel_size ;
726  
727   Standard_OutOfRange_Raise_if(
728         ( x < 0 || (unsigned int ) x >= myHeader.pixmap_width ||
729           y < 0 || (unsigned int ) y >= myHeader.pixmap_height ),
730          "Index out of range in X11XWDAlienData::Pixel");
731
732   pixel_size = ( unsigned long int ) myHeader.bytes_per_line / 
733                                      myHeader.pixmap_width;
734  
735   p  = ( unsigned char * ) myData ;
736   p += y * myHeader.bytes_per_line + x * pixel_size ;
737  
738   if ( pixel_size == 1 ) {
739         *p = ( unsigned char ) value ;
740   }
741   else if ( pixel_size == 2 ) {
742         *( ( unsigned short int * ) p ) = ( unsigned short int ) value ;
743   }
744   else if ( pixel_size == 4 ) {
745         *( ( unsigned long int * ) p )  = ( unsigned long int ) value ;
746   }
747 }
748
749 Standard_Integer AlienImage_X11XWDAlienData::Pixel( 
750         const Standard_Integer x, const Standard_Integer y ) const
751
752 { unsigned char *p ;
753   unsigned long int  pixel_size ;
754   unsigned long int pix ;
755   Standard_Integer ret ;
756
757   Standard_OutOfRange_Raise_if(
758         ( x < 0 || (unsigned int ) x >= myHeader.pixmap_width ||
759           y < 0 || (unsigned int ) y >= myHeader.pixmap_height ),
760          "Index out of range in X11XWDAlienData::Pixel");
761
762   pixel_size = ( unsigned long int ) myHeader.bytes_per_line / 
763                                      myHeader.pixmap_width;
764  
765   p  = ( unsigned char * ) myData ;
766   p  += y * myHeader.bytes_per_line + x * pixel_size ;
767  
768   if ( pixel_size == 1 ) {
769         pix = ( unsigned long int ) *p ;
770   }
771   else if ( pixel_size == 2 ) {
772         pix = *( ( unsigned short int * ) p ) ;
773   }
774   else {
775         pix = *( ( unsigned long int * ) p ) ;
776   }
777
778   ret = Standard_Integer ( pix );
779  
780   return( ret ) ;
781  
782 }
783
784 Standard_Integer AlienImage_X11XWDAlienData::RedShift() const
785
786 { Standard_Integer shift = 0 ;
787
788   Standard_TypeMismatch_Raise_if( myHeader.visual_class != TrueColor ,
789           "Attempt to get RedShift from a non TrueColor X11XWDImage" ) ;
790
791   if ( ( myHeader.red_mask >> myHeader.bits_per_rgb ) == 0 ) {
792         shift = 0 ;
793   }
794   else if ( ( myHeader.red_mask >> ( 2 * myHeader.bits_per_rgb ) ) == 0 ) {
795         shift = Standard_Integer( myHeader.bits_per_rgb ) ;
796   }
797   else {
798         shift = Standard_Integer( 2 * myHeader.bits_per_rgb );
799   }
800   return shift ;
801 }
802
803 Standard_Integer AlienImage_X11XWDAlienData::GreenShift() const
804
805 { Standard_Integer shift = 0 ;
806
807   Standard_TypeMismatch_Raise_if( myHeader.visual_class != TrueColor ,
808           "Attempt to get GreenShift from a non TrueColor X11XWDImage" ) ;
809
810   if ( ( myHeader.green_mask >> myHeader.bits_per_rgb ) == 0 ) {
811         shift = 0 ;
812   }
813   else if ( ( myHeader.green_mask >> ( 2 * myHeader.bits_per_rgb ) ) == 0 ) {
814         shift = Standard_Integer( myHeader.bits_per_rgb ) ;
815   }
816   else {
817         shift = Standard_Integer( 2 * myHeader.bits_per_rgb ) ;
818   }
819   return shift ;
820 }
821
822 Standard_Integer AlienImage_X11XWDAlienData::BlueShift() const 
823
824 { Standard_Integer shift = 0 ;
825
826   Standard_TypeMismatch_Raise_if( myHeader.visual_class != TrueColor ,
827           "Attempt to get BlueShift from a non TrueColor X11XWDImage" ) ;
828
829   if ( ( myHeader.blue_mask >> myHeader.bits_per_rgb ) == 0 ) {
830         shift = 0 ;
831   }
832   else if ( ( myHeader.blue_mask >> ( 2 * myHeader.bits_per_rgb ) ) == 0 ) {
833         shift = Standard_Integer( myHeader.bits_per_rgb ) ;
834   }
835   else {
836         shift = Standard_Integer( 2 * myHeader.bits_per_rgb ) ;
837   }
838
839   return shift ;
840 }
841