darken@seas.gwu.edu (Rudolph Darken) (02/28/91)
I am in desperate need of assistance with XCopyPlane and the format of X bitmap files. First, if I have an 8 bit/pixel pixmap, what do I need to do to copy that to a visible window? It's the 'plane' parameter that's confusing me. Next, say I want to save my 8 bit/pixel pixmap into a bitmap file. Can this be done? And if so, will my 8 bits be preserved? It seems that the definition of a bitmap would not allow this. If this won't work, are there any suggestions as to how to save a color image to disk for future use in an X application? Thanks very much for any help. Rudy Darken darken@seas.gwu.edu
mouse@lightning.mcrcim.mcgill.EDU (02/28/91)
> I am in desperate need of assistance with XCopyPlane and the format > of X bitmap files. First, if I have an 8 bit/pixel pixmap, what do I > need to do to copy that to a visible window? If the window is 8 bits deep, you can use XCopyArea. However, for this to do what you probably want, you have to make sure the window's colormap is correct for the picture. How easy this is depends in part on the visual in use. Choosing visuals and dealing with colormaps is another topic entirely; I won't go into it now. If the window is not 8 bits deep, it's more difficult. (In both the following cases, if what you want is not covered, you will probably have to manipulate the picture in the client to generate a new picture of the appropriate depth and display the result with XPutImage and/or XCopyArea.) If the window is only one bit deep, you can use XCopyPlane to select one bitplane of your image and display it. You have limited control over how it's displayed with the GC's function parameter. If the window is neither 1 bit nor 8 bits deep, you can generate a new picture by using XCopyPlane to pick a plane out of the 8-bit picture and store it in a bitmap, then use XCopyPlane to merge it with a deeper picture elsewhere, repeating for each plane you want to copy. (I don't see any way to do this without handling each plane separately, unfortunately.) You need to use either the plane-mask in the GC to restrict writes in the target to the bitplane you want to set, or you can diddle the foreground and background values and set the function to do the appropriate thing. > It's the 'plane' parameter that's confusing me. This sounds as though you think you want to use XCopyArea, and you may well be right. What does the plane parameter do? Well, let's take a simple example. Suppose you have a 6x3x8 pixmap whose pixel values in binary are 11000000 00111101 01010100 11111100 01101001 01101110 00111000 10010001 10100101 00010110 11011110 11111001 00111011 01001110 01111110 01011011 01000001 01111110 Now, you want to create a 6x3x4 pixmap containing just the top four bits of the original pixmap. I'll demonstrate things for just one of the four bits (bit 6, 00100000); the other are similar, with just the particular choice of bit changed. I assume the source and destination pixmaps already exist. First, you create a 6x3x1 bitmap on the same screen as the pixmap. You will also need two GCs created on this screen, one of depth 1 (to use when writing into the bitmap) and one of depth 4 (for use when writing into the 6x3x4 pixmap). For these, you can just pass the corresponding pixmap/bitmap as the drawable argument to XCreateGC. Then you XCopyPlane with src = the 6x3x8 pixmap dest = the 6x3x1 bitmap gc = the depth-1 GC, with the following settings: foreground = 1 background = 0 function = GXcopy src_x = 0 src_y = 0 width = 6 height = 3 dest_x = 0 dest_y = 0 plane = the bit, 00100000 This causes each pixel in the bitmap to contain the 00100000 bit from the original pixmap's corresponding pixel: 0 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 0 1 Then to copy it into the 0010 bit of the destination pixmap, you issue another XCopyArea with src = the 6x3x1 bitmap dest = the 6x3x4 pixmap gc = the depth-4 GC, with the following settings: foreground = 0010 background = 0 function = GXor src_x = 0 src_y = 0 width = 6 height = 3 dest_x = 0 dest_y = 0 plane = 1 (the low (and only) bit of the bitmap) This assumes the 0010 bit in the 6x3x4 pixmap is already cleared. If not, you may have to instead set the depth-4 GC up with foreground = 0010 (or anything else with that bit set) background = 0 (or anything with bit 0010 clear) function = GXcopy plane-mask = 0010 This will normally be substantially slower than using GXor; you might find it faster to instead clear the 0010 bit by doing a XFillRectangle of the whole 6x3x4 pixmap with the GC set to foreground = 0010 function = GXandInverted Playing with the function, plane-mask, etc, lets you get lots of different effects, most of which are not useful.... > Next, say I want to save my 8 bit/pixel pixmap into a bitmap file. No can do - bitmap files store bitmaps, not pixmaps. There is a file format that can deal with pixmaps, the XPM format. I don't really know much more about it, except that you can get lots of stuff about it from the usual X archive sources. > [...], are there any suggestions as to how to save a color image to > disk for future use in an X application? If you want an interchange format comparable to xbm format, xpm is probably best. If you just want to save it for later use (by the same program on the same machine), do whatever seems convenient - for example, just write out the raw data area you're storing it in. There are lots of possible things to do, and various tradeoffs you have to make.... der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
mouse@lightning.mcrcim.mcgill.EDU (02/28/91)
I said: > 0 1 1 1 0 0 > 1 1 0 1 1 1 > 1 0 1 1 0 1 but that was the wrong bit, 00010000 instead of 00100000. I should have said: 0 1 0 1 1 1 1 0 1 0 0 1 1 0 1 0 0 1 Sorry about that. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu