Re: XForms: Pixmap!

Stephen Huyssoon (huyssoons@advancia.com)
Fri, 12 Feb 1999 09:48:13 -0600

# To subscribers of the xforms list from Stephen Huyssoon <huyssoons@advancia.com> :

This is a multi-part message in MIME format.
--------------5822E7EA4F3EBD0B1154FD56
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Claudio Andrade Macedo wrote:

> # To subscribers of the xforms list from cmacedo@infonet.com.br (Claudio Andrade Macedo) :
>
> How a pixmap is represented? is it a char **matrix ???
> How can I create one by myself???

The answers to such juicy X questions can be found in a good X Window System
programmersmanual. I suggest "X Window System" by Robert Scheifler & James Gettys.

X is the foundation for XForms. Boingo!

More particularly, you must create an XImage structure, fill it in, create a pixmap of the
right size,
transfer the image in the XImage to the pixmap, use XCopyArea to draw the pixmap to a window.

For your amusement, shall I include a little program I wrote?

But of course I shall.

Oh, the image data is contained in a char array, which should be thought of as a 2x2 matrix
of either
(1) colormap indexes or (2) pixels, based upon the color model you are using. The color
model determines
your choice of colormap (or no colormap).

You really can't get around learning the X color model.
Just learn it first and be happy.

Allow me to give you some advice.
Use the true color color model, 24 bits or 32 bits per pixel if you can.
Really, that comes to be 8 bits for each of red, green, and blue.

Greetings, and Good Day.

--
  (Stephen Huyssoon)
>=========================================>
  (huyssoons@advancia.com)

To Infinity and Beyond! -- Me and Buzz Lightyear

The Truth cannot be proven nor disproven, it simply Is.

Julia's Law of Software Development: Business is business and programming is not. -- Julia

Burt's Principle for Programming: Less is more, and cheese is a fundamental ingredient.

--------------5822E7EA4F3EBD0B1154FD56 Content-Type: text/plain; charset=us-ascii; name="bmp.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="bmp.h"

//////////////////////////////////////////////////////////////////////////////// // // File: bmp.h // // Version: 1.00 // Version date: 3 March 1998 // Comments: // This code allows for some use of Microsoft bmp images in the X // environment. // // Programmer: Stephen Huyssoon // ////////////////////////////////////////////////////////////////////////////////

#ifndef BMP_H #define BMP_H 1

//------------------------------------------------------------------------------ // Include Directives

// X11 #include <X11/Xlib.h> #include <X11/Xutil.h>

// c++ #include <fstream.h>

//------------------------------------------------------------------------------ // Preprocessor Define Directives

#define BI_RGB 0L #define BI_RLE8 1L #define BI_RLE4 2L #define BI_BITFIELDS 3L

#define writeNV(v) #v "=" << (v)

#define wordreverse( w ) \ ( \ (( (w) & 0x00FF ) << 8 ) + \ (( (w) & 0xFF00 ) >> 8 ) \ )

#define dwordreverse( w ) \ ( \ (( (w) & 0x000000FF ) << 24 ) + \ (( (w) & 0x0000FF00 ) << 8 ) + \ (( (w) & 0x00FF0000 ) >> 8 ) + \ (( (w) & 0xFF000000 ) >> 24 ) \ )

//------------------------------------------------------------------------------ // Linux definitions for BYTE..

typedef unsigned char BYTE; // UCHAR_MAX 255U

typedef unsigned short int WORD; // USHRT_MAX 65535

typedef unsigned int DWORD; // UINT_MAX 4294967295U typedef int LONG;

//------------------------------------------------------------------------------ // Helper Functions

#define reverseenable 0

template <class T> inline void readtype( ifstream & ifs, T & t ) { ifs.read( (char*) & t , sizeof( T )); #if reverseenable switch( sizeof( T )) { case 4: t = dwordreverse( t ); break; case 2: t = wordreverse( t ); break; default: break; } #endif }

inline void release_ximage( XImage * xi ) { delete [] xi->data; xi->data = 0; XDestroyImage( xi ); }

//------------------------------------------------------------------------------ // Class bmpimage

class BITMAPFILEHEADER { public: WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; };

class BITMAPINFOHEADER { public: DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; };

class RGBQUAD { public: BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; };

class bmpimage { public:

BITMAPFILEHEADER fh; BITMAPINFOHEADER ih; RGBQUAD * ct; BYTE * px;

char alive;

bmpimage( char * filename ); ~bmpimage();

void writehdr( ostream & );

XImage * makeximage( Display *, Window ); Pixmap makepixmap( Display *, Window, GC, XImage *, short int & width, short int & height ); };

#endif

--------------5822E7EA4F3EBD0B1154FD56 Content-Type: text/plain; charset=us-ascii; name="bmp.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="bmp.cpp"

// c++ //#include <iostream.h> //#include <fstream.h>

// X //#include <X11/Xlib.h>

// bmp #include <bmp.h>

#define logfile cout

bmpimage::bmpimage (

char * filename ) { long int m_px;

short int slpad; short int slwidth;

short int y;

//BITMAPFILEHEADER fh; //BITMAPINFOHEADER ih; //RGBQUAD * ct; ct = 0; //BYTE * px; px = 0;

//char alive; alive = 0;

ifstream ifs( filename, ios::in|ios::nocreate );

if ( ! ifs.good() ) { logfile << "Could not open image file with name " << filename << ".\n"; return; }

readtype( ifs, fh.bfType ); readtype( ifs, fh.bfSize ); readtype( ifs, fh.bfReserved1 ); readtype( ifs, fh.bfReserved2 ); readtype( ifs, fh.bfOffBits );

if ( ! ifs.good() ) { logfile << "An error occurred while reading the BITMAPFILEHEADER.\n"; return; }

if ( fh.bfType != 0x4D42 ) { logfile << "Not an MS Windows BMP file.\n"; return; }

readtype( ifs, ih.biSize ); readtype( ifs, ih.biWidth ); readtype( ifs, ih.biHeight ); readtype( ifs, ih.biPlanes ); readtype( ifs, ih.biBitCount ); readtype( ifs, ih.biCompression ); readtype( ifs, ih.biSizeImage ); readtype( ifs, ih.biXPelsPerMeter ); readtype( ifs, ih.biYPelsPerMeter ); readtype( ifs, ih.biClrUsed ); readtype( ifs, ih.biClrImportant );

if ( ! ifs.good() ) { logfile << "An error occurred while reading the BITMAPINFOHEADER.\n"; return; }

if ( ih.biBitCount != 24 ) { logfile << "Cannot read a " << ih.biBitCount << " bbp image, can read only a 24 bbp image.\n"; return; }

if (( ih.biCompression != BI_RGB ) && ( ih.biCompression != BI_BITFIELDS )) { logfile << "Cannot read a compressed image file.\n"; return; }

#if 1 writehdr( logfile ); #endif

ifs.seekg( fh.bfOffBits , ios::beg );

m_px = 3 * ih.biWidth * ih.biHeight ; px = new BYTE [ m_px ]; if ( px == 0 ) { logfile << "We were not granted memory for bitmap pixel data.\n"; return; }

slwidth = 3 * ih.biWidth; slpad = ( 4 - ( slwidth % 4 )) % 4 ;

for ( y = ih.biHeight - 1 ; y >= 0 ; y -- ) { ifs.read( px + ( y * slwidth ), slwidth ); if (( y > 0 ) && ( slpad > 0 )) ifs.seekg( slpad, ios::cur ); }

if ( ! ifs.good() ) { logfile << "An error was encountered while reading the bitmap pixel data.\n"; return; }

alive = 1; }

bmpimage::~bmpimage() { if ( ct != 0 ) delete [] ct; if ( px != 0 ) delete [] px; }

void bmpimage::writehdr( ostream & os ) { os

#if 0 << writeNV( sizeof( BYTE )) << "\n" << writeNV( sizeof( WORD )) << "\n" << writeNV( sizeof( DWORD )) << "\n" << writeNV( sizeof( LONG )) << "\n" #endif

<< writeNV( fh.bfType ) << "\n" << writeNV( fh.bfSize ) << "\n" << writeNV( fh.bfReserved1 ) << "\n" << writeNV( fh.bfReserved2 ) << "\n" << writeNV( fh.bfOffBits ) << "\n"

<< writeNV( ih.biSize ) << "\n" << writeNV( ih.biWidth ) << "\n" << writeNV( ih.biHeight ) << "\n" << writeNV( ih.biPlanes ) << "\n" << writeNV( ih.biBitCount ) << "\n" << writeNV( ih.biCompression ) << "\n" << writeNV( ih.biSizeImage ) << "\n" << writeNV( ih.biXPelsPerMeter ) << "\n" << writeNV( ih.biYPelsPerMeter ) << "\n" << writeNV( ih.biClrUsed ) << "\n" << writeNV( ih.biClrImportant ) << "\n"

<< flush; }

XImage * bmpimage::makeximage (

Display * dpy, Window win ){ Status s; XWindowAttributes xwa;

unsigned long rmsk; unsigned long gmsk; unsigned long bmsk;

short int rshf; short int gshf; short int bshf;

BYTE * p; BYTE * q; long int i; long int mi;

char * imdt; short int bpl; XImage * xi;

s = XGetWindowAttributes( dpy /* display */, win /* w */, & xwa /* window_attributes_return */ );

if ( s == 0 ) { logfile << "XGetWindowAttributes() failed.\n"; return 0; }

if (( xwa.depth == 8 ) && ( xwa.visual->c_class == TrueColor )) { logfile << "Using an 8 bit true color visual.\n";

imdt = new char [ ih.biWidth * ih.biHeight ] ; if ( imdt == 0 ) { logfile << "We were not granted image data storage.\n"; return 0; }

rmsk = xwa.visual->red_mask; gmsk = xwa.visual->green_mask; bmsk = xwa.visual->blue_mask;

rshf = 0 ; while (( rmsk & 0x80 ) == 0 ) { rshf ++ ; rmsk = rmsk << 1 ; } gshf = 0 ; while (( gmsk & 0x80 ) == 0 ) { gshf ++ ; gmsk = gmsk << 1 ; } bshf = 0 ; while (( bmsk & 0x80 ) == 0 ) { bshf ++ ; bmsk = bmsk << 1 ; }

rmsk = xwa.visual->red_mask; gmsk = xwa.visual->green_mask; bmsk = xwa.visual->blue_mask;

p = px; q = (BYTE*)imdt; mi = ih.biWidth * ih.biHeight ; for ( i = 0 ; i < mi ; i ++ ) { *q = (( p[2] >> rshf ) & rmsk ) + (( p[1] >> gshf ) & gmsk ) + (( p[0] >> bshf ) & bmsk ) ; p += 3; q += 1; } bpl = ih.biWidth; logfile << "Created an image with " << mi << " pixels.\n"; } else if (( xwa.depth == 24 ) && ( xwa.visual->c_class == TrueColor )) { logfile << "Using a 24 bit true color visual.\n";

imdt = new char [ 4 * ih.biWidth * ih.biHeight ] ; if ( imdt == 0 ) { logfile << "We were not granted image data storage.\n"; return 0; }

rmsk = xwa.visual->red_mask; gmsk = xwa.visual->green_mask; bmsk = xwa.visual->blue_mask;

rshf = 0 ; while (( rmsk & 0x1 ) == 0 ) { rshf ++ ; rmsk = rmsk >> 1 ; } gshf = 0 ; while (( gmsk & 0x1 ) == 0 ) { gshf ++ ; gmsk = gmsk >> 1 ; } bshf = 0 ; while (( bmsk & 0x1 ) == 0 ) { bshf ++ ; bmsk = bmsk >> 1 ; }

rmsk = xwa.visual->red_mask; gmsk = xwa.visual->green_mask; bmsk = xwa.visual->blue_mask;

p = px; q = (BYTE*)imdt; mi = ih.biWidth * ih.biHeight ; for ( i = 0 ; i < mi ; i ++ ) { * (DWORD *) q = ( p[2] << rshf ) + ( p[1] << gshf ) + ( p[0] << bshf ); p += 3; q += 4; } bpl = 4 * ih.biWidth; logfile << "Created an image with " << mi << " pixels.\n"; } else { // Visual not supported. logfile << "Visual not supported.\n"; return 0; }

xi = XCreateImage ( dpy /* display */, xwa.visual /* visual */, xwa.depth /* depth */, ZPixmap /* format */, 0 /* offset */, imdt /* data */, ih.biWidth /* width */, ih.biHeight /* height */, XBitmapPad( dpy ) /* bitmap_pad */, bpl /* bytes_per_line */ );

if ( xi == 0 ) { logfile << "Image creation failed.\n"; return 0; }

return xi; }

Pixmap bmpimage::makepixmap (

Display * dpy, Window win, GC gc, XImage * xi, short int & width, short int & height ) { Pixmap pm; int s;

pm = XCreatePixmap ( dpy /* display */, win /* d */, xi->width /* width */, xi->height /* height */, xi->depth /* depth */ );

if ( pm == 0 ) { logfile << "XCreatePixmap() failed.\n"; width = 0; height = 0; return 0; }

width = xi->width; height = xi->height;

s = XPutImage ( dpy /* display */, pm /* d */, gc /* gc */, xi /* image */, 0 /* src_x */, 0 /* src_y */, 0 /* dest_x */, 0 /* dest_y */, xi->width /* width */, xi->height /* height */ );

if ( s != 0 ) { logfile << "XPutImage() failed.\n"; }

return pm; }

--------------5822E7EA4F3EBD0B1154FD56 Content-Type: text/plain; charset=us-ascii; name="bmpimagetester.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="bmpimagetester.cpp"

// c++ #include <iostream.h>

// X11 //#include <X11/Intrinsic.h> //#include <X11/StringDefs.h>

// Xm #include <Xm/Xm.h>

// bmp #include <bmp.h>

Widget app_shellwidget; XtAppContext app_appcontext; char * app_applicationclassname = "bmpimagetester"; char * app_fallbackresources [] = { (char*) 0 };

int main (

int argc, char** argv ) { XImage * xi;

GC gc;

Pixmap pm; short int pmwidth; short int pmheight;

app_shellwidget = XtVaAppInitialize( /* obsolete */

& app_appcontext /* app_context_return */, app_applicationclassname /* application_class */,

0 /* options */, 0 /* num_options */,

& argc /* argc_in_out */, argv /* argv_in_out */,

app_fallbackresources /* fallback_resources */,

0

);

XtRealizeWidget( app_shellwidget );

// bmpimagetester <bmp file name> // 0 1

if ( argc != 2 ) { cout << "bmpimagetester <bmp file name>\n"; exit( 1 ); }

bmpimage I( argv[1] );

gc = XCreateGC( XtDisplay( app_shellwidget ), XtWindow( app_shellwidget ), 0, 0 ); xi = I.makeximage( XtDisplay( app_shellwidget ), XtWindow( app_shellwidget )); pm = I.makepixmap( XtDisplay( app_shellwidget ), XtWindow( app_shellwidget ), gc, xi, pmwidth, pmheight );

XtVaSetValues( app_shellwidget, XmNwidth, pmwidth, XmNheight, pmheight, XmNbackgroundPixmap, pm, 0 );

XtAppMainLoop( app_appcontext );

return 0; }

--------------5822E7EA4F3EBD0B1154FD56--

_________________________________________________ To unsubscribe, send the message "unsubscribe" to xforms-request@bob.usuf2.usuhs.mil or see http://bob.usuf2.usuhs.mil/mailserv/xforms.html XForms Home Page: http://bragg.phys.uwm.edu/xforms List Archive: http://bob.usuf2.usuhs.mil/mailserv/list-archives/