diff -urN old_x11/idiconv.c x11/idiconv.c --- old_x11/idiconv.c Wed Dec 31 18:00:00 1969 +++ x11/idiconv.c Thu Nov 30 00:05:50 2000 @@ -0,0 +1,427 @@ +/* @(#)idilocal1.c 13.3 (ESO-DMD) 08/21/98 16:09:08 */ +/*=========================================================================== + Copyright (C) 2000 Craig B. Markwardt + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, + MA 02139, USA. + + Correspondence concerning ESO-MIDAS should be addressed as follows: + Internet e-mail: midas@eso.org + Postal address: European Southern Observatory + Data Management Division + Karl-Schwarzschild-Strasse 2 + D 85748 Garching bei Muenchen + GERMANY +===========================================================================*/ + +/*********************************************************************** +* +* file idiconv.c +* +* IDI Device Dependent Routines +* (version for XWindows release 11) +* +* +* V 1.00 001129: C. Markwardt - conversions for 24- and 16-bit visuals +* +* get_plane_offset : convert bitmask to a shift offset +* idi_conv32_24 : convert 32-bit RGB to 24-bit RGB +* idi_conv24_32 : convert 24-bit RGB to 32-bit RGB +* idi_conv32_16 : convert 32-bit RGB to 16-bit RGB +* idi_conv16_32 : convert 16-bit RGB to 32-bit RGB +* idi_putimage : wrapper for XPutImage +* idi_getsubimage : wrapper for XGetSubImage +* +************************************************************************/ + +/* + +*/ + +#include + +#include +#include +#include + + +/* Determine the shift to apply to 8-bit data to align with "mask" */ +int +get_plane_offset(mask, wordsize) + unsigned int mask, wordsize; +{ + int i; + for (i=31; i>=0; i--) + if ( (mask>>i) & 1 ) return (i+1-wordsize); + return 0; +} + + +/* Convert 32-bit input to 24-bit output. The image data sizes are + the same, hence each line output line will be padded by 25%. Note + that this function allocates memory which must be freed by the + caller. */ +unsigned char *idi_conv32_24(image, src) + XImage *image; + unsigned char *src; +{ + unsigned char *dst, *p, *q; + unsigned int nbytes; + unsigned int test = 0x000000ff; + unsigned char *ptest = (unsigned char *)&test; + int lend; + int j, i; + + if ( *ptest == 0xff ) lend = 1; else lend = 0; + + /* Allocate a destination image */ + nbytes = image->bytes_per_line*image->height; + dst = malloc(nbytes); + if (dst == 0) + return 0; + + /* Zero the new image data */ + q = dst; + for (i=0; iheight; j++) { + p = src + image->bytes_per_line*j; + q = dst + image->bytes_per_line*j; + /* Note that for 24-bit data, all we have to do is copy the 3 + lsb's and discard the msb, while otherwise preserving the byte + order. */ + if (lend) { + /* Little-endian - discard msb at end of each source word */ + for (i=0; iwidth; i++) { + *q++ = *p++; *q++ = *p++; *q++ = *p++; + p++; + } + } else { + /* Big-endian - discard msb at beginning of each source word */ + for (i=0; iwidth; i++) { + p++; + *q++ = *p++; *q++ = *p++; *q++ = *p++; + } + } + } + + return dst; +} + +/* Convert 24-bit input to 32-bit output. The image data sizes are + the same, hence each input line must be padded by 25%. Note that + this function allocates memory which must be freed by the + caller. */ +unsigned char *idi_conv24_32(image, src) + XImage *image; + unsigned char *src; +{ + unsigned char *dst, *p, *q; + unsigned int nbytes; + unsigned int test = 0x000000ff; + unsigned char *ptest = (unsigned char *)&test; + int lend; + int j, i; + + /* Test for endian-ness */ + if ( *ptest == 0xff ) lend = 1; else lend = 0; +#if 0 + fprintf(stderr, "%s-endian\n", lend?"little":"big"); + fprintf(stderr, "red_mask = 0x%08x\n", image->red_mask); + fprintf(stderr, "green_mask = 0x%08x\n", image->green_mask); + fprintf(stderr, "blue_mask = 0x%08x\n", image->blue_mask); +#endif + + /* Allocate a destination image */ + nbytes = image->bytes_per_line*image->height; + dst = malloc(nbytes); + if (dst == 0) + return 0; + + /* Zero the new image data */ + q = dst; + for (i=0; iheight; j++) { + p = src + image->bytes_per_line*j; + q = dst + image->bytes_per_line*j; + /* Note that for 24-bit data, all we have to do is copy the 3 + lsb's and discard the msb, while otherwise preserving the byte + order. */ + if (lend > 0) { + /* Little-endian - insert msb at end of each dest word */ + for (i=0; iwidth; i++) { + *q++ = *p++; *q++ = *p++; *q++ = *p++; + q++; + } + } else { + /* Big-endian - insert msb at beginning of each dest word */ + for (i=0; iwidth; i++) { + q++; + *q++ = *p++; *q++ = *p++; *q++ = *p++; + } + } + } + + return dst; +} + +/* Convert 32-bit input to 16-bit output. The image data sizes are + the same, hence each line output line will be padded by 50%. Note + that this function allocates memory which must be freed by the + caller. Also, the conversion from 24-bit to 16-bit is inherently + lossy. */ +unsigned char *idi_conv32_16(image, src, wordsize) + XImage *image; + unsigned char *src; + unsigned int wordsize; +{ + unsigned char *dst, *p, *q; + unsigned short int *qi; + unsigned int *pi; + unsigned int nbytes; + unsigned char r, g, b; + unsigned int rm, gm, bm; /* Red green and blue masks */ + unsigned int ro, go, bo; /* Red green and blue mask offsets */ + unsigned int word; + int j, i; + + rm = image->red_mask; + gm = image->green_mask; + bm = image->blue_mask; + ro = get_plane_offset(rm, wordsize); + go = get_plane_offset(gm, wordsize); + bo = get_plane_offset(bm, wordsize); + if (ro < 0 || go < 0 || bo < 0) + return 0; +#if 0 + fprintf(stderr, "red_offset=%d red_mask=0x%08x\n", ro, rm); + fprintf(stderr, "green_offset=%d green_mask=0x%08x\n", go, gm); + fprintf(stderr, "blue_offset=%d blue_mask=0x%08x\n", bo, bm); +#endif + + /* Allocate a destination image */ + nbytes = image->bytes_per_line*image->height; + dst = malloc(nbytes); + if (dst == 0) + return 0; + + for (i=0, q=dst; iheight; j++) { + p = src + image->bytes_per_line*j; + q = dst + image->bytes_per_line*j; + pi = (unsigned int *) p; + qi = (unsigned short int *) q; + /* Note that for 16-bit output data the red element in the 24-bit + input data will always be in the LSB, given the way that RGBord + is constructed */ + if (ro > 0) { + /* bo must be negative */ + for (i=0; iwidth; i++) { + word = *pi++; + r = word & 0xff; + g = (word >> 8) & 0xff; + b = (word >> 16) & 0xff; + *qi++ = ((r << ro) & rm) | ((g << go) & gm) | ((b >> -bo) & bm); + } + } else { + /* ro must be negative */ + for (i=0; iwidth; i++) { + word = *pi++; + r = word & 0xff; + g = (word >> 8) & 0xff; + b = (word >> 16) & 0xff; + *qi++ = ((r >> -ro) & rm) | ((g << go) & gm) | ((b << bo) & bm); + } + } + } + + return dst; +} + +/* Convert 16-bit input to 32-bit output. The image data sizes are + the same, hence each input line must be padded by 50%. Note that + this function allocates memory which must be freed by the + caller. Also, the conversion from 16-bit to 24-bit assumes that the + low-order bits are zero. */ +unsigned char *idi_conv16_32(image, src, wordsize) + XImage *image; + unsigned char *src; + unsigned int wordsize; +{ + unsigned char *dst, *p, *q; + unsigned short int *pi; + unsigned int *qi; + unsigned int nbytes; + unsigned char r, g, b; + unsigned int rm, gm, bm; /* Red green and blue masks */ + unsigned int ro, go, bo; /* Red green and blue mask offsets */ + unsigned short int word; + int j, i; + + rm = image->red_mask; + gm = image->green_mask; + bm = image->blue_mask; + ro = get_plane_offset(rm, wordsize); + go = get_plane_offset(gm, wordsize); + bo = get_plane_offset(bm, wordsize); + if (ro < 0 || go < 0 || bo < 0) + return 0; + + /* Allocate a destination image */ + nbytes = image->bytes_per_line*image->height; + dst = malloc(nbytes); + if (dst == 0) + return 0; + + for (i=0, q=dst; iheight; j++) { + p = src + image->bytes_per_line*j; + q = dst + image->bytes_per_line*j; + pi = (unsigned short int *) p; + qi = (unsigned int *) q; + /* Note that for 16-bit input data the red element in the 24-bit + output data will always be in the LSB, given the way that + RGBord is constructed */ + if (ro > 0) { + /* bo must be negative */ + for (i=0; iwidth; i++) { + word = *pi++; + r = (word & rm) >> ro; + g = (word & gm) >> go; + b = (word & bm) << -bo; + *qi++ = r | (g << 8) | (b << 16); + } + } else { + /* ro must be negative */ + for (i=0; iwidth; i++) { + word = *pi++; + r = (word & rm) << -ro; + g = (word & gm) >> go; + b = (word & bm) >> bo; + *qi++ = r | (g << 8) | (b << 16); + } + } + } + + return dst; +} + + +/* Wrapper for XPutImage. The arguments are identical. This function + takes an XImage either in 32-bit truecolor or 8-bit pseudocolor and + converts to the appropriate bitsize and depth of the output + drawable. No error checking is done on the arguments. */ +idi_putimage(display, draw, gc, image, sx, sy, dx, dy, width, height) + Display *display; + Drawable draw; + GC gc; + XImage *image; + int sx, sy, dx, dy; + unsigned int width, height; +{ + unsigned char *dst = 0; + unsigned char *src = (unsigned char *)image->data; + int allocated = 0; + int wordsize = 8; + + /* Convert from a standard size, either 8-bit or 32-bit, to the + native pixel size */ + switch (image->bits_per_pixel) { + /* 32-bit true-color, and 8-bit pseudo color are output immediately */ + case 8: + case 32: + break; + case 16: + dst = idi_conv32_16(image, src, wordsize); /* 32 bits to 16 bits */ + break; + case 24: + dst = idi_conv32_24(image, src); /* 32 bits to 24 bits */ + break; + } + + /* Temporarily insert the transformed data into the XImage, Put the + image, and then restore the original data */ + if (dst) image->data = (char *) dst; + XPutImage(display, draw, gc, image, sx, sy, dx, dy, width, height); + image->data = (char *) src; + + if (dst) free(dst); + return; +} + +/* Wrapper for XGetSubImage. The arguments are identical. This + function reads an XImage from the drawable, in the native bitsize + and depth of the drawable, and then converts to either an 8-bit + pseudocolor or 32-bit RGB image. No error checking is done on the + arguments. */ +XImage * +idi_getsubimage(display, draw, x, y, width, height, plane_mask, format, + dimage, dx, dy) + Display *display; + Drawable draw; + int x, y; + unsigned int width, height; + unsigned long plane_mask; + int format; + XImage *dimage; + int dx, dy; +{ + XImage *image; + unsigned char *dst, *p, *q; + unsigned int nbytes, i; + int wordsize = 8; + + /* Do the actual XGetSubImage, which will return in the native + depth and bit_per_pixel of the drawable */ + image = XGetSubImage(display, draw, x, y, width, height, plane_mask, + format, dimage, dx, dy); + + /* Convert to a standard size, either 8-bit or 32-bit */ + switch (image->bits_per_pixel) { + /* 32-bit true-color, and 8-bit pseudo color are done immediately */ + case 8: + case 32: + return image; + break; + case 16: + dst = idi_conv16_32(image, image->data, wordsize); /* 16 bits to 32 bits */ + break; + case 24: + dst = idi_conv24_32(image, image->data); /* 24 bits to 32 bits */ + break; + } + + if (dst == 0) + return image; + + /* Now copy the "destination" image back into the original "source" */ + nbytes = image->bytes_per_line * image->height; + p = dst; + q = (unsigned char *) image->data; + for (i=0; i #include +extern idi_putimage(); +extern XImage *idi_getsubimage(); + static unsigned int tmpxdim, tmpydim; static int discard = 1; @@ -305,6 +308,10 @@ } setup_RGB: + /* A 16-bit truecolor emulation of pseudo should really be >= 256 cells */ + if (myvis[no]->class == TrueColor && Xworkst[no].depth == 16 + && myvis[no]->map_entries <= 256) + myvis[no]->map_entries = 256; Xworkst[no].lutsize = myvis[no]->map_entries; Xworkst[no].nolut = 1; Xworkst[no].visual = 4; @@ -935,7 +942,7 @@ XSetErrorHandler(None); /* use default Error handler */ myima = XCreateImage(mydisp[no],myvis[no],Xworkst[no].depth,ZPixmap, - 0,0,mem->xsize,mem->ysize,np,0); + 0,0,mem->xsize,mem->ysize,np,np*mem->xsize/8); total = myima->bytes_per_line * mem->ysize; myima->data = malloc((unsigned int)total); @@ -954,7 +961,7 @@ else { mem->pixmap = 1; - XPutImage(mydisp[no],mxpix[dspno][memid],gcima[dspno], + idi_putimage(mydisp[no],mxpix[dspno][memid],gcima[dspno], myima,0,0,0,0,mem->xsize,mem->ysize); } @@ -990,7 +997,7 @@ np = 8; myima = XCreateImage(mydisp[no],myvis[no],Xworkst[no].depth,ZPixmap, - 0,0,mem->xsize,mem->ysize,np,0); + 0,0,mem->xsize,mem->ysize,np,np*mem->xsize/8); total = myima->bytes_per_line * mem->ysize; myima->data = malloc((unsigned int)total); @@ -1029,7 +1036,7 @@ /* here we create the structure + allocate memory */ myima = XCreateImage(mydisp[no],myvis[no],Xworkst[no].depth,ZPixmap, - 0,0,tmpx,tmpy,np,0); + 0,0,tmpx,tmpy,np,np*tmpx/8); total = myima->bytes_per_line * tmpy; myima->data = malloc((unsigned int)total); @@ -1054,7 +1061,7 @@ } } -hcopy[dspno] = XGetSubImage(mydisp[no],xdrawable,0,0,tmpx,tmpy, +hcopy[dspno] = idi_getsubimage(mydisp[no],xdrawable,0,0,tmpx,tmpy, np,ZPixmap,hcopy[dspno],0,0); XFlush(mydisp[no]); @@ -1083,7 +1090,7 @@ /* load image zoom mem. into the Window */ - XPutImage(mydisp[no],mwndw[dspno],gcima[dspno],mzima[dspno][memid], + idi_putimage(mydisp[no],mwndw[dspno],gcima[dspno],mzima[dspno][memid], 0,0,0,0,xdim,ydim); else @@ -1092,7 +1099,7 @@ /* first (if flag > 1), load full image mem. into Pixmap */ if (flag > 1) - XPutImage(mydisp[no],mxpix[dspno][memid],gcima[dspno], + idi_putimage(mydisp[no],mxpix[dspno][memid],gcima[dspno], mzima[dspno][memid],0,0,0,0,mem->xsize,mem->ysize); @@ -1121,7 +1128,7 @@ /* load subwindow from image mem. into the Window at corner (dstx,dsty) */ - XPutImage(mydisp[no],mwndw[dspno],gcima[dspno],mxima[dspno][memid], + idi_putimage(mydisp[no],mwndw[dspno],gcima[dspno],mxima[dspno][memid], srcx,srcy,dstx,dsty,xdim,ydim); else @@ -1130,7 +1137,7 @@ /* first (if flag > 1), load full image mem. into Pixmap */ if (flag > 1) - XPutImage(mydisp[no],mxpix[dspno][memid],gcima[dspno], + idi_putimage(mydisp[no],mxpix[dspno][memid],gcima[dspno], mxima[dspno][memid],0,0,0,0,mem->xsize,mem->ysize); diff -urN old_x11/idilocal2.c x11/idilocal2.c --- old_x11/idilocal2.c Tue Sep 8 06:46:10 1998 +++ x11/idilocal2.c Wed Nov 29 23:53:38 2000 @@ -69,6 +69,8 @@ # include # include +extern idi_putimage(); + static int lutoff; static unsigned long int maska; static unsigned int tmpxdim, tmpydim; @@ -558,7 +560,7 @@ else np = 32; myima = XCreateImage(mydisp[no],myvis[no],Xworkst[no].depth,ZPixmap, - 0,0,bar->xsize,bar->ysize,np,0); + 0,0,bar->xsize,bar->ysize,np,np*bar->xsize/8); lutxima[dspno] = myima; total = myima->bytes_per_line * bar->ysize; @@ -651,7 +653,7 @@ } -XPutImage(mydisp[no],lutwnd[dspno],gclut[dspno],lutxima[dspno], +idi_putimage(mydisp[no],lutwnd[dspno],gclut[dspno],lutxima[dspno], 0,0,0,0,bar->xsize,bar->ysize); k = ididev[dspno].lutsect; XSetWindowColormap(mydisp[no],lutwnd[dspno],cmap[no][k]); @@ -684,7 +686,7 @@ { XMoveResizeWindow(mydisp[no],lutwnd[dspno],bar->xoff,bar->yoff, bar->xsize,bar->ysize); - XPutImage(mydisp[no],lutwnd[dspno],gclut[dspno],lutxima[dspno], + idi_putimage(mydisp[no],lutwnd[dspno],gclut[dspno],lutxima[dspno], 0,0,0,0,bar->xsize,bar->ysize); XSetWindowColormap(mydisp[no],lutwnd[dspno],cmap[no][k]); } diff -urN old_x11/idilocal3.c x11/idilocal3.c --- old_x11/idilocal3.c Tue Sep 1 04:10:04 1998 +++ x11/idilocal3.c Wed Nov 29 23:53:59 2000 @@ -647,7 +647,7 @@ if (bar != 0) /* process color bar */ { if (bar->wp != 0) - XPutImage(mydisp[wstno],lutwnd[dispno],gclut[dispno], + idi_putimage(mydisp[wstno],lutwnd[dispno],gclut[dispno], lutxima[dispno],0,0,0,0,bar->xsize,bar->ysize); } conf = ididev[dispno].confptr; @@ -765,7 +765,7 @@ if (ididev[dspno].bar != 0) /* process color bar */ { if (ididev[dspno].bar->wp != 0) - XPutImage(mydisp[nk],lutwnd[dspno],gclut[dspno], + idi_putimage(mydisp[nk],lutwnd[dspno],gclut[dspno], lutxima[dspno],0,0,0,0, ididev[dspno].bar->xsize, ididev[dspno].bar->ysize); diff -urN old_x11/idiutil1.c x11/idiutil1.c --- old_x11/idiutil1.c Mon Sep 28 09:33:24 1998 +++ x11/idiutil1.c Thu Nov 30 00:35:42 2000 @@ -426,37 +426,29 @@ { int rgbpix, shiftmask; - if (RGBflag == 0) /* work on red color */ - { - for (loopi=0; loopi> shiftmask); + *data++ = (unsigned char) (rgbpix >> shiftmask) & 0xff; } ipntra += xsize; } - } } else /* hardcopy - work on all 3 color channels */ @@ -468,7 +460,18 @@ { ipntrb = ipntra; - for (loopk=0; loopk> 16) + | ((word & 0x0000ff) << 16)); + } ipntra += xsize; } @@ -479,109 +482,85 @@ { int rgbpix; register int *ipntra, *ipntrb; + unsigned long int dist, mindist; + unsigned int minind; ipntra = (int *) inpntr; /* no ITT here */ ipntra += (yoff + xoff); - if (ittf == 0) - { - if (hcopflg == 0) /* no display snapshot */ - { - for (loopi=0; loopival[kval]); - } - ipntra += xsize; - } - } - - else - { - offset = Xworkst[no].lutlen; /* highest colour only */ - for (loopi=0; loopi> 8; + db = ((lval & 0xff0000) - (pix & 0xff0000)) >> 16; + /* Euclidean distance, squared */ + dist = dr*dr + dg*dg + db*db; + if (minind == -1 || dist < mindist) + { + mindist = dist; + minind = i; + } + } + /* Apply transfer function and global offset */ + if (ittf == 0) + *data++ = (unsigned char) (minind - lutoff); + else + { + int kval = (minind - lutoff); if (kval < 0) kval = 0; *data++ = (unsigned char) (itt->val[kval]); + } + + next_pix: + ; + } - nexte: - ; - - } - ipntra += xsize; - } - } - } + ipntra += xsize; + } } } diff -urN old_x11/makefile x11/makefile --- old_x11/makefile Tue Jun 16 04:43:38 1998 +++ x11/makefile Wed Nov 29 14:15:46 2000 @@ -24,10 +24,12 @@ LIB = $(LIBDIR)/libidi.a OBJ = idiutil1.o idiutil2.o idilocal1.o idilocal2.o idilocal3.o \ - iic.o iid1.o iid2.o iie.o iig.o iii.o iil.o iim.o iir.o iis.o iiz.o + iic.o iid1.o iid2.o iie.o iig.o iii.o iil.o iim.o iir.o iis.o iiz.o \ + idiconv.o SRC = idiutil1.c idiutil2.c idilocal1.c idilocal2.c idilocal3.o \ - iic.c iid1.c iid2.c iie.c iig.c iii.c iil.c iim.c iir.c iis.c iiz.c + iic.c iid1.c iid2.c iie.c iig.c iii.c iil.c iim.c iir.c iis.c iiz.c \ + idiconv.c # DEPENDENCIES: all: $(MAKEFILE_VMS) $(LIB)