[comp.windows.x] XCreateBitmapFromData

mdb@amadeus.UUCP (Mark D. Baushke) (02/05/88)

I have a question about XCreateBitmapFromData().

I have a sequential stream of bytes which I want to make into an icon.
(c.f., GNU Emacs src/sink.h or X.V10R4/xshell/scallopshell.h).

On my Sun, I need to 'swap' the bytes on each 'short' word in order to
make the image look correct. However, I am told that the image is ok
"as is" on uVAX so changing the data to make it look good on a sun
will break it for a VAX... Requiring the application to alter the bit
data depending on the hardware in use is not something I am very fond
of doing.

The behavior occurs because XCreateBitmapFromData() asumes that the
byte_order=FSBFirst.  This assumption works on a uVAX since the words
are stored in LSBFirst. This assumption does not work on a Sun or IBM
RT (and many others as well see list below for BIG_ENDIAN machines)
since the words are stored in MSBFirst order.

My question is this, can we alter the behavior of XCreateBitmapFromData()
by either:

	A) modify XCreateBitmapFromData() to make byte_order
	   assumptions based on whether the hardware is MSBFirst or
	   not by adding '#ifdef BIG_ENDIAN' code (a la GNU Emacs) to
	   lib/X/XCrBFData.c .

or	   

	B) modify the calling sequence of XCreateBitmapFromData() to
	   accept a byte_order argument.

My personal favorite is "A" as this would do the "right thing" most
often without the application writer having to know about which
hardware his code is running on.

From GNU Emacs the following machines are BIG_ENDIAN (lowest-numbered
byte in a word is the most significant byte):

	sun 1	   
	sun 2
	sun 3
	apollo
	amdahl uts
	AT&T UNIX PC model 7300
	Silicon Graphics Iris 2500 Turbos
	ISI 68000's
	targon31
	IBM RTPC
	AT&T 3b
	Celerity
	alliant
	Mips
	Stride Micro System-V.2.2
	Altos 3068 Unix System V Release 2
	Masscomp 5000 series running RTU, ucb universe
	tahoe
	WICAT machines
	Gould with UTX/32 2.0
	TI Nu machines using system V
	NCR Tower 32 running System V.2
	pyramid
	Plexus running System V.2
	Megatest 68000's
	hp9000 series 200 or 300
	gec63
	Dual machines using unisoft port

The following machines are not BIG_ENDIAN (lowest numbered byte is
least significant):

	Vax
	SEQUENT BALANCE machines
	ns16000
	Elxsi machine (running enix)
	HLH Orion

Mark Baushke
silvlis!mdb@sun.com

RWS@ZERMATT.LCS.MIT.EDU (Robert Scheifler) (02/05/88)

XCreateBitmapFromData() does not accept X10 format data.  It only
accepts X11 format data, which is bytes rather than shorts, and hence
does not have machine dependencies.  Run your data in and out of
the bitmap editor to convert it.

newman@ATHENA.MIT.EDU (02/05/88)

You are having byte-order difficulties because you are passing
XCreateBitmapFromData() an array of 'short', when it wants an array of
'char'.  To make your application run portably, you need to convert
your X10-format bitmap files to X11 format.

As you know, X10 bitmap files declared the "_bits" variable as an array
of "short", which is normally 16 bits.  That was fine then, because
X10's XBitmapBitsPut() routine expected 16-bit data too, and the server
took care of any needed byte-swapping if the client and server had
different byte orders.

In X11, however, bitmap files declare the _bits array as an array of
'char'.  This means the data is now in 8-bit format, and is independent
of the client machine's byte order.   That is the format that
XCreateBitmapFromData() wants to see; it assumes that bitmap_unit=8
(NOT that bytes_order=LSBFirst).

To convert an X10 bitmap file to X11 format, use the "bm-convert"
utility to convert your favorite X10-format bitmap file to X11 format. 
 You should find "bm-convert" in the util/ subdirectory of your X11 distribution.

/Ron Newman

mlandau@bbn.com (Matt Landau) (02/05/88)

In comp.windows.x, mdb@amadeus.UUCP (Mark D. Baushke) writes:
>I have a sequential stream of bytes which I want to make into an icon.
>
>On my Sun, I need to 'swap' the bytes on each 'short' word in order to
>make the image look correct. However, I am told that the image is ok
>"as is" on uVAX so changing the data to make it look good on a sun
>will break it for a VAX... Requiring the application to alter the bit
>data depending on the hardware in use is not something I am very fond
>of doing.

One portable way of doing this is to use XCreateImage to make an
XImage structure, then use XPutImage to stuff it into a window or
pixmap.  You get to specify the bit- and byte-sex of the data in
XCreateImage, so this works everywhere.
--
 Matt Landau			Waiting for a flash of enlightenment
 mlandau@bbn.com			  in all this blood and thunder

deboor@bay.Berkeley.EDU.berkeley.edu (Adam R de Boor) (02/05/88)

what you need to do is declare the bitmap as an array of characters, *not* an
array of shorts. You then place the data in in little-endian order and can
use XCreateBitmapFromData just fine. This is the format 'bitmap' puts out. If
your bitmap is in the standard X10 format, you can use the program 'bm-convert'
found in the 'utils' directory of the distribution to convert to the X11
normal form.

a

oj@apollo.uucp (Ellis Oliver Jones) (02/06/88)

Matt Landau's answer to Mark Baushke was right on:
>>I have a sequential stream of bytes which I want to make into an icon.
>>On my Sun, I need to 'swap' the bytes on each 'short' word in order to
>>make the image look correct....

>One portable way of doing this is to use XCreateImage to make an
>XImage structure

But all you *really* need to do is declare a local
XImage structure and initialize the proper fields.  You
can code this up in C so it will work the same on a VAX and a Motorola processor:

 XImage myim;

 myim.format = XYBitmap;    /* causes XCopyPlane behavior on XPutImage */
 myim.data   = @pointer to your own data@;
 myim.width  = @width of data in pixels@;
 myim.height = @height in pixels@;
 myim.bytes_per_line = @whatever the bitmap pitch is@;
 myim.bitmap_unit = 16;  /* short word bitmap */
 myim.bitmap_bit_order = MSBFirst;   /* same for 680x0 and VAX, but depends on frame buffer */
 myim.byte_order = LSBFirst;         /* this is "natural" for a VAX */
 myim.bitmap_pad = @whatever comes at the ends of lines @;
 myim.xoffset = 0;   /*probably*/
 myim.depth = 1;     /* the depth*/
 XPutImage ( dpy, drawable, gc, &myim, srcx, srcy, dstx, dsty, @width@, @height@);

Have fun!  /oj