mdb@silvlis.COM (Mark D. Baushke) (06/04/88)
After getting a copy of "The Poskanzer Bitmap Collection" and finding
the disk consumption to be more than I was willing to use (making it
available for both X11 and sunview users was another consideration), I
converted all of the bitmaps from xbm format to sun's run-length
encoded image format (using xbmtopbm | pbmtorast | /usr/lib/rasfilters/convert.2).
The entire bitmap collection only takes about 6.5MB in run-length
encoded images.
I hacked on xsetroot to add a "-rast" option to read in these
run-length encoded images. (Mostly by borrowing some code from Jef's
pbm package.)
The function XCreateBitmapFromSunPixrectData is based on
XCreateBitmapFromData.
This method also loads the background much faster than the "-bitmap"
option.
So for those running on sun hardware...enjoy. (You will need to modify
the Makefile to add -lpixrect to LDFLAGS or /usr/lib/libpixrect.a to
LOCAL_LIBRARIES.)
*** xsetroot.c.orig Thu Feb 25 21:12:18 1988
--- xsetroot.c Fri Jun 3 12:26:28 1988
***************
*** 6,11 ****
--- 6,14 ----
#include <stdio.h>
#include "X11/bitmaps/gray"
+ #ifdef sun
+ #include <pixrect/pixrect_hs.h>
+ #endif
/*
* xsetroot.c MIT Project Athena, X Window system root window
* parameter setting utility. This program will set
***************
*** 13,18 ****
--- 16,23 ----
*
* Author: Mark Lillibridge, MIT Project Athena
* 11-Jun-87
+ * Modified: Mark Baushke <mdb@silvlis.com>, to add -rast option
+ * 3-Jun-88
*/
char *index();
***************
*** 45,50 ****
--- 50,56 ----
fprintf(stderr, " -solid <color>\n");
fprintf(stderr, " -gray or -grey\n");
fprintf(stderr, " -bitmap <filename>\n");
+ fprintf(stderr, " -rast <filename>\n");
fprintf(stderr, " -mod <x> <y>\n");
exit(1);
/*NOTREACHED*/
***************
*** 51,56 ****
--- 57,65 ----
}
Pixmap MakeModulaBitmap(), ReadBitmapFile();
+ #ifdef sun
+ Pixmap ReadSunRasterFile(), XCreateBitmapFromSunPixrectData();
+ #endif /* sun */
XColor NameToXColor();
unsigned long NameToPixel();
***************
*** 69,74 ****
--- 78,84 ----
Cursor cursor;
int gray = 0;
char *bitmap_file = NULL;
+ char *rast_file = NULL;
int mod_x = 0;
int mod_y = 0;
register int i;
***************
*** 131,136 ****
--- 141,159 ----
excl++;
continue;
}
+ if (!strcmp("-rast", argv[i])) {
+ #ifdef sun
+ if (++i>=argc) usage();
+ rast_file = argv[i];
+ excl++;
+ continue;
+ #else
+ fprintf(stderr, "%s: "-rast" option not implemented.\n",
+ program_name);
+ if (++i>=argc) usage();
+ continue;
+ #endif /* sun */
+ }
if (!strcmp("-mod", argv[i])) {
if (++i>=argc) usage();
mod_x = atoi(argv[i]);
***************
*** 150,157 ****
--- 173,186 ----
/* Check for multiple use of exclusive options */
if (excl > 1) {
+ #ifdef sun
+ fprintf(stderr,
+ "%s: choose only one of {solid, gray, bitmap, rast, mod}\n",
+ program_name);
+ #else
fprintf(stderr, "%s: choose only one of {solid, gray, bitmap, mod}\n",
program_name);
+ #endif /* sun */
usage();
}
***************
*** 196,201 ****
--- 225,238 ----
SetBackgroundToBitmap(bitmap, ww, hh);
}
+ #ifdef sun
+ /* Handle -rast option */
+ if (rast_file) {
+ bitmap = ReadSunRasterFile(rast_file, &ww, &hh);
+ SetBackgroundToBitmap(bitmap, ww, hh);
+ }
+ #endif /* sun */
+
/* Handle set background to a modula pattern */
if (mod_x) {
bitmap = MakeModulaBitmap(mod_x, mod_y);
***************
*** 435,437 ****
--- 472,607 ----
exit(1);
/*NOTREACHED*/
}
+
+ #ifdef sun
+ char *malloc();
+
+ Pixmap ReadSunRasterFile(filename, width, height)
+ char *filename;
+ unsigned int *width, *height;
+ {
+ Pixmap bitmap;
+ int status;
+ int rows, cols, linebytes;
+ short *data;
+ FILE *file;
+ struct rasterfile header;
+ struct pixrect *pr, *pr_load_image();
+ int firsttime, value, i, data_length;
+
+ file = fopen(filename, "r");
+ if (file == NULL) {
+ fprintf(stderr, "%s: can't open file: %s\n", program_name,
+ filename);
+ exit(1);
+ }
+
+ cols = rows = -1;
+
+ /* Get the raster file's header. */
+ if (pr_load_header(file, &header) != 0) {
+ fprintf(stderr, "%s: Unable to read in raster file header.\n",
+ filename);
+ exit(1);
+ }
+
+ /* can only handle monochrome bitmaps. */
+ if (header.ras_depth != 1) {
+ fprintf(stderr, "%s: Invalid depth.\n", filename);
+ exit(1);
+ }
+
+ cols = header.ras_width;
+ rows = header.ras_height;
+ if (cols <= 0) {
+ fprintf(stderr, "%s: Invalid width: %d.\n", filename, cols);
+ exit(1);
+ }
+
+ if (rows <= 0) {
+ fprintf(stderr, "%s: Invalid height: %d.\n", filename, rows);
+ exit(1);
+ }
+
+ /* If there is a color map, skip over it. */
+ if (header.ras_maptype != RMT_NONE && header.ras_maplength != 0) {
+ if (pr_load_colormap(file, &header, NULL) != 0) {
+ fprintf(stderr, "%s: Unable to skip colormap data.\n", filename);
+ exit(1);
+ }
+ }
+
+ /* Now load the data. The pixrect returned is a memory pixrect. */
+ if ((pr = pr_load_image(file, &header, NULL)) == NULL) {
+ fprintf(stderr,
+ "Unable to read in the image from the raster file: %s.\n",
+ filename);
+ exit(1);
+ }
+ fclose(file);
+
+ linebytes = ((struct mpr_data *)pr->pr_data)->md_linebytes;
+ data = ((struct mpr_data *)pr->pr_data)->md_image;
+
+ *width = cols;
+ *height = rows;
+ bitmap = XCreateBitmapFromSunPixrectData(dpy, root, (char *) data,
+ *width, *height, linebytes);
+ if (!bitmap) {
+ fprintf(stderr, "%s: insufficient memory for bitmap: %s",
+ program_name, filename);
+ exit(1);
+ }
+ return(bitmap);
+ }
+
+
+ /*
+ * XCreateBitmapFromSunPixrectData: Routine to make a pixmap of depth 1 from user supplied data.
+ * D is any drawable on the same screen that the pixmap will be used in.
+ * Data is a pointer to the bit data, and
+ * width & height give the size in bits of the pixmap.
+ *
+ * The following format is assumed for data:
+ *
+ * format=XYPixmap
+ * bit_order=MSBFirst
+ * byte_order=MSBFirst
+ * padding=8
+ * bitmap_unit=8
+ * xoffset=0
+ * rows are rounded up to 16-bit boundaries
+ */
+ Pixmap XCreateBitmapFromSunPixrectData(display, d, data, width,
+ height, linebytes)
+ Display *display;
+ Drawable d;
+ char *data;
+ unsigned int width, height;
+ int linebytes;
+ {
+ XImage ximage;
+ GC gc;
+ Pixmap pix;
+
+ pix = XCreatePixmap(display, d, width, height, 1);
+ if (!pix)
+ return(0);
+ gc = XCreateGC(display, pix, (unsigned long)0, (XGCValues *)0);
+ ximage.height = height;
+ ximage.width = width;
+ ximage.depth = 1;
+ ximage.xoffset = 0;
+ ximage.format = XYPixmap;
+ ximage.data = data;
+ ximage.byte_order = MSBFirst;
+ ximage.bitmap_unit = 8;
+ ximage.bitmap_bit_order = MSBFirst;
+ ximage.bitmap_pad = 8;
+ ximage.bytes_per_line = (linebytes == 0) ? (((width+15)>>3) & ~1) : linebytes;
+
+ XPutImage(display, pix, gc, &ximage, 0, 0, 0, 0, width, height);
+ XFreeGC(display, gc);
+ return(pix);
+ }
+ #endif /* sun */
------------------------------------------------------------------------------
Mark D. Baushke Internet: mdb%silvlis.com@sun.com
Silvar-Lisco, Inc. Nameservers: mdb@silvlis.com
1080 Marsh Road Usenet: {pyramid,sun}!silvlis!mdb
Menlo Park, CA 94025-1053 Telephone: +1 415 853-6411 / +1 415 969-8328