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