home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume20 / xgrabsc / part01 < prev    next >
Encoding:
Text File  |  1993-08-04  |  56.8 KB  |  1,894 lines

  1. Newsgroups: comp.sources.x
  2. From: bruce@servio.slc.com (Bruce Schuchardt)
  3. Subject: v20i100:  xgrabsc - Grab and dump X displays, Part01/05
  4. Message-ID: <csx-v20i100=xgrabsc.121536@sparky.Sterling.COM>
  5. X-Md4-Signature: 9dfd8693f536238d515968c5c88197a7
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Wed, 4 Aug 1993 17:16:37 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: bruce@servio.slc.com (Bruce Schuchardt)
  12. Posting-number: Volume 20, Issue 100
  13. Archive-name: xgrabsc/part01
  14. Environment: X11
  15. Supersedes: xgrabsc: Volume 18, Issue 52-56
  16.  
  17.  
  18.  Xgrabsc has been posted to comp.sources.x several times.  The most recent
  19.  was v2.1 in Volume 18 Issue 52.  This posting is version 2.3 and is a full
  20.  release, not a patch file.
  21.  
  22.  Version 2.3 fixes many bugs, including these very-often reported bugs:
  23.  
  24.   * Dumping of subwindows in earlier releases just didn't work at all.  In
  25.     this release, you can dump any window by ID.
  26.  
  27.   * Preview images in EPSI files were using 1 for white and 0 for black.
  28.     This is not correct acording to the EPSF 2.0 spec.
  29.  
  30.   * dithering operations were failing with displays having Black=1
  31.   
  32.   * the program would not remove Motif mwm window dressings from a window
  33.   
  34.   * the program did not always grab the correct area when used with
  35.     virtual window managers like tvtwm
  36.  
  37.  It also adds these features:
  38.  
  39.   * faster, more compact color Postscript printing.
  40.  
  41.   * a Motif version of the user-interface.  See the README.2_3 file for
  42.     information on building the Motif version.
  43.   
  44.   * a "-coords" option to specify a fixed area of the screen to grab
  45.   
  46.   * normal xwd output and xwd "-xy" style output, which is more compact.
  47.     The "-xy" style is what xgrabsc used to only support, but some
  48.     programs, such as xwdtoppm couldn't handle this xwd variant.
  49.  
  50.  --
  51.  Bruce Schuchardt
  52.  bruce@slc.com
  53.  
  54.  
  55.  
  56. -----------------------CUT HERE
  57.  
  58. #! /bin/sh
  59. # This is a shell archive.  Remove anything before this line, then unpack
  60. # it by saving it into a file and typing "sh file".  To overwrite existing
  61. # files, type "sh file -c".  You can also feed this as standard input via
  62. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  63. # will see the following message at the end:
  64. #        "End of archive 1 (of 5)."
  65. # Contents:  xgrabsc.2_3 xgrabsc.2_3/convert.hc xgrabsc.2_3/write.hc
  66. # Wrapped by bruce@trout on Mon Jun 28 09:14:50 1993
  67. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  68. if test ! -d 'xgrabsc.2_3' ; then
  69.     echo shar: Creating directory \"'xgrabsc.2_3'\"
  70.     mkdir 'xgrabsc.2_3'
  71. fi
  72. if test -f 'xgrabsc.2_3/convert.hc' -a "${1}" != "-c" ; then 
  73.   echo shar: Will not clobber existing file \"'xgrabsc.2_3/convert.hc'\"
  74. else
  75. echo shar: Extracting \"'xgrabsc.2_3/convert.hc'\" \(9414 characters\)
  76. sed "s/^X//" >'xgrabsc.2_3/convert.hc' <<'END_OF_FILE'
  77. X/*========================================================================
  78. X *
  79. X * Name - convert.hc
  80. X *
  81. X * ccs version:    1.6
  82. X *
  83. X * ccsid:    @(#)convert.hc    1.6 - 04/22/93 16:27:04
  84. X * from:     ccs/s.convert.hc
  85. X * date:     06/28/93 09:14:48
  86. X *
  87. X * Description:  color->black&white conversions for xgrabsc
  88. X *
  89. X *               see cpyright.h for copyright information
  90. X *
  91. X *
  92. X *========================================================================
  93. X */
  94. X
  95. X
  96. X/*
  97. X * convert a pixmap image into a bitmap image
  98. X */
  99. Xpixmap2bitmap(image)
  100. X  imageInfo *image;
  101. X{
  102. X  XImage *ximage = image->ximage;
  103. X  int x, y;
  104. X  word v, black, mid;
  105. X  dw total, blackrgb, midrgb, lowDelta, l;
  106. X  XImage *newImage;
  107. X  byte *newBytes;
  108. X  int usedCount;
  109. X  int blackp, whitep;
  110. X
  111. X  if (ximage->bits_per_pixel == 1  ||  image->numcells < 1)
  112. X    return;
  113. X
  114. X
  115. X  blackp = BlackPixel(hDisplay,hScreen);
  116. X  whitep = WhitePixel(hDisplay,hScreen);
  117. X
  118. X  /* get the darkest color */
  119. X  blackrgb = 0x2FFFD;  /* 3 * 0xFFFF == white */
  120. X  usedCount = total = 0;
  121. X  for (x=0; x<image->numcells; x++) {
  122. X    if (image->used[x]) {
  123. X      l = (unsigned)image->red[x]
  124. X          +(unsigned)image->green[x]
  125. X          +(unsigned)image->blue[x];
  126. X      if (l <= blackrgb) {
  127. X        black = x;
  128. X        blackrgb = l;
  129. X      }
  130. X      total += l;
  131. X      usedCount++;
  132. X    }
  133. X  }
  134. X  /* now find the mid color and use it as the cut-off for black */
  135. X  midrgb = total / usedCount;
  136. X  lowDelta = 0x2FFFD;
  137. X  for (x=0; x<image->numcells; x++) {
  138. X    if (image->used[x]) {
  139. X      l = (unsigned)image->red[x]
  140. X          +(unsigned)image->green[x]
  141. X          +(unsigned)image->blue[x];
  142. X      l -= midrgb;
  143. X      if (l < lowDelta) {
  144. X        mid = x;
  145. X        lowDelta = l;
  146. X      }
  147. X    }
  148. X  }
  149. X  midrgb = (unsigned)image->red[mid]
  150. X           +(unsigned)image->green[mid]
  151. X           +(unsigned)image->blue[mid];
  152. X
  153. X  /* create a bitmap image */
  154. X  x = (ximage->width + 7) / 8;
  155. X  newBytes = (byte *)malloc(x * ximage->height);
  156. X  memset(newBytes, 0, x * ximage->height);
  157. X  newImage = XCreateImage(hDisplay, DefaultVisual(hDisplay, hScreen),
  158. X                1, XYBitmap, 0, newBytes, ximage->width, ximage->height,
  159. X                8, x);
  160. X  if (!newImage) {
  161. X    fprintf(stderr, "%s: unable to create bitmap for conversion\n",
  162. X      programName);
  163. X    XCloseDisplay(hDisplay);
  164. X    exit(3);
  165. X  }
  166. X  /* pound the pixels into it */
  167. X  for (y = 0; y < ximage->height; y++) {
  168. X    for (x = 0; x < ximage->width; x++) {
  169. X      v = XGetPixel(ximage, x, y);
  170. X      l = (dw)image->red[v]+(dw)image->green[v]+(dw)image->blue[v];
  171. X      XPutPixel(newImage, x, y, l<midrgb? blackp : whitep);
  172. X    }
  173. X  }
  174. X  free(ximage->data);
  175. X  memcpy((char *)ximage, (char *)newImage, sizeof(XImage));
  176. X  free(newImage);
  177. X
  178. X  memset((char *)image->used, 0, MAX_CELLS);
  179. X  image->used[whitep] = 1;
  180. X  image->used[blackp] = 1;
  181. X  image->numcells = 2;
  182. X}
  183. X
  184. X
  185. X
  186. X
  187. X
  188. X
  189. X
  190. X#define GRAYS    17 /* ((4 * 4) + 1) patterns for a good dither */
  191. X#define GRAYSTEP ((dw)(65536 / GRAYS))
  192. X
  193. Xstatic byte DitherBits[GRAYS][4] = {
  194. X  0xf, 0xf, 0xf, 0xf,
  195. X  0xe, 0xf, 0xf, 0xf,
  196. X  0xe, 0xf, 0xb, 0xf,
  197. X  0xa, 0xf, 0xb, 0xf,
  198. X  0xa, 0xf, 0xa, 0xf,
  199. X  0xa, 0xd, 0xa, 0xf,
  200. X  0xa, 0xd, 0xa, 0x7,
  201. X  0xa, 0x5, 0xa, 0x7,
  202. X  0xa, 0x5, 0xa, 0x5,
  203. X  0x8, 0x5, 0xa, 0x5,
  204. X  0x8, 0x5, 0x2, 0x5,
  205. X  0x0, 0x5, 0x2, 0x5,
  206. X  0x0, 0x5, 0x0, 0x5,
  207. X  0x0, 0x4, 0x0, 0x5,
  208. X  0x0, 0x4, 0x0, 0x1,
  209. X  0x0, 0x0, 0x0, 0x1,
  210. X  0x0, 0x0, 0x0, 0x0
  211. X  };
  212. X
  213. X/* halftone or dither a color image, changing it into a monochrome
  214. X * image
  215. X */
  216. Xpixmap2halftone(image, dither)
  217. X  imageInfo *image;
  218. X  ditherType dither;    /* type of dithering to perform */
  219. X{
  220. X  XImage *ximage = image->ximage;
  221. X  XImage *newImage;
  222. X  byte   *newBytes, *ditherBits;
  223. X  word   dindex;  /* index into dither array */
  224. X  dw     color;   /* pixel color */
  225. X  word  *index;   /* index into dither array for a given pixel */
  226. X  word   x, y;    /* random counters */
  227. X  word   x4, y4;
  228. X  register word   w, h;
  229. X  register byte  bits;
  230. X  char  *str;
  231. X  dw    intensity;
  232. X  int   maxIntensity, threshold;
  233. X  word  *fsIndex;
  234. X  int   err, i, ximageW, ximageH, rowL;
  235. X  int   *row1, *row2;
  236. X  int blackp = BlackPixel(hDisplay,hScreen);
  237. X  int whitep = WhitePixel(hDisplay,hScreen);
  238. X
  239. X  if (ximage->depth <= 1  ||  dither == NO_DITHER)
  240. X    return;
  241. X
  242. X  ximageW = ximage->width;
  243. X  rowL    = ximageW - 1;
  244. X  ximageH = ximage->height;
  245. X
  246. X  if (verbose) {
  247. X    switch (dither) {
  248. X      case MATRIX_HALFTONE:
  249. X        str = "Matrix halfton";
  250. X        break;
  251. X      case MATRIX_DITHER:
  252. X        str = "Matrix dither";
  253. X        break;
  254. X      case FS_DITHER:
  255. X        str = "Floyd-Steinberg dither";
  256. X        break;
  257. X      default:
  258. X        fprintf(stderr, "%s: unknown type of dithering requested.  Exiting...\n",
  259. X            programName);
  260. X        exit(3);
  261. X    }
  262. X    fprintf(stderr, "%s: %sing image...", programName, str);
  263. X    fflush(stderr);
  264. X  }
  265. X
  266. X  /* create a bitmap image */
  267. X  x = (dither == MATRIX_HALFTONE)? 4 : 1;
  268. X  w = ((ximageW + 7) / 8) * x;
  269. X  h = ximageH * x;
  270. X  newBytes = (byte *)malloc(w * h);
  271. X  memset((char *)newBytes, whitep=1?255:0, w * h);
  272. X  newImage = XCreateImage(hDisplay, DefaultVisual(hDisplay, hScreen),
  273. X                1, XYBitmap, 0, newBytes,
  274. X                ximageW * x,
  275. X                h,
  276. X                8, w);
  277. X  if (!newImage) {
  278. X    fprintf(stderr, "%s: unable to create bitmap for conversion\n",
  279. X      programName);
  280. X    XCloseDisplay(hDisplay);
  281. X    exit(3);
  282. X  }
  283. X
  284. X  /* if the number of possible pixels isn't very large, build an array
  285. X   * which we index by the pixel value to find the dither array index
  286. X   * by color brightness.  we do this in advance so we don't have to do
  287. X   * it for each pixel.  things will break if a pixel value is greater
  288. X   * than (1 << depth), which is bogus anyway.  this calculation is done
  289. X   * on a per-pixel basis if the colormap is too big.
  290. X   */
  291. X
  292. X  if (ximage->depth <= 16) {
  293. X    index= (word *)malloc(sizeof(word) * MAX_CELLS);
  294. X    fsIndex= (word *)malloc(sizeof(word) * MAX_CELLS);
  295. X    if (index)
  296. X      for (x= 0; x < image->numcells; x++) {
  297. X        fsIndex[x] = (word)(0.30 * image->red[x] +
  298. X                          0.59 * image->green[x] +
  299. X                          0.11 * image->blue[x]);
  300. X        index[x] = fsIndex[x]/GRAYSTEP;
  301. X        if (index[x] >= GRAYS)
  302. X          index[x] = GRAYS - 1;
  303. X      }
  304. X  }
  305. X  else
  306. X    index = fsIndex = NULL;
  307. X
  308. X  if (dither == FS_DITHER) {
  309. X    maxIntensity = 65535;
  310. X    threshold = maxIntensity/2;
  311. X    row1 = (int *)malloc(ximageW*sizeof(int));
  312. X    row2 = (int *)malloc(ximageW*sizeof(int));
  313. X    /* initialize row2 */
  314. X    for (x= 0; x < ximageW; x++) {
  315. X      color = XGetPixel(ximage, x, 0);
  316. X      row2[x] = fsIndex? fsIndex[color] :
  317. X                  (dw)(0.30*image->red[color] +
  318. X                   0.59*image->green[color] +
  319. X                   0.11*image->blue[color]);
  320. X    }
  321. X    for (y= 0; y < ximageH; y++) {
  322. X      /* row1 := row2 */
  323. X      memcpy((char *)row1, (char *)row2, ximageW*sizeof(int));
  324. X      /* Fill in next row */
  325. X      if (y != ximageH-1)
  326. X        for (x= 0; x < ximageW; x++) {
  327. X          color = XGetPixel(ximage, x, y+1);
  328. X          row2[x] = fsIndex? fsIndex[color] :
  329. X                      (dw)(0.30*image->red[color] +
  330. X                       0.59*image->green[color] +
  331. X                       0.11*image->blue[color]);
  332. X        }
  333. X      for (x= 0; x < ximageW; x++) {
  334. X        color = XGetPixel(ximage, x, y);
  335. X        if ((i = row1[x]) > threshold)
  336. X          err = i - maxIntensity;
  337. X        else {
  338. X          XPutPixel(newImage, x, y, blackp);
  339. X          err = i;
  340. X        }
  341. X        /* Diagonal gets 1/4 of error. */
  342. X        if (x < rowL)
  343. X      row2[x+1] += err/4;
  344. X
  345. X        /* Right and below get 3/8 of error */
  346. X        err = err*3/8;
  347. X        row2[x] += err;
  348. X        if (x < rowL)
  349. X      row1[x+1] += err;
  350. X      }
  351. X    }
  352. X    if (row1)  free(row1);
  353. X    if (row2)  free(row2);
  354. X  }
  355. X
  356. X
  357. X  else {  /* matrix dither or halftone */
  358. X
  359. X    for (y= 0; y < ximageH; y++) {
  360. X      for (x= 0; x < ximageW; x++) {
  361. X        color = XGetPixel(ximage, x, y);
  362. X        dindex = index? index[color] :
  363. X                    (dw)(0.30*image->red[color] +
  364. X                     0.59*image->green[color] +
  365. X                     0.11*image->blue[color])/GRAYSTEP;
  366. X        if (dindex >= GRAYS)  /* catch rounding errors */
  367. X          dindex= GRAYS - 1;
  368. X        if (dither == MATRIX_DITHER) {
  369. X          if (DitherBits[dindex][y & 3] & (1 << (x & 3)))
  370. X             XPutPixel(newImage, x, y, blackp);
  371. X        }
  372. X        else { /* halftone */
  373. X          /* loop for the four Y bits in the dither pattern, putting all
  374. X           * four X bits in at once.  if you think this would be hard to
  375. X           * change to be an NxN dithering array, you're right, since we're
  376. X           * banking on the fact that we need only shift the mask based on
  377. X           * whether x is odd or not.  an 8x8 array wouldn't even need that,
  378. X           * but blowing an image up by 64x is probably not a feature.
  379. X           */
  380. X          ditherBits = &(DitherBits[dindex][0]);
  381. X          x4 = x * 4;
  382. X          y4 = y * 4;
  383. X          for (h= 0; h < 4; h++) {
  384. X            bits = ditherBits[h];
  385. X            for (w=0; w < 4; w++) {
  386. X              XPutPixel(newImage, x4+w, y4+h, bits & 1 ? blackp : whitep);
  387. X              bits /= 2;
  388. X            }
  389. X          }
  390. X        }
  391. X      }
  392. X    }
  393. X  }
  394. X
  395. X  if (verbose)
  396. X    fputc('\n', stderr);
  397. X
  398. X  free(ximage->data);
  399. X  memcpy((char *)ximage, (char *)newImage, sizeof(XImage));
  400. X  free(newImage);
  401. X  if (index) free(index);
  402. X  if (fsIndex) free(fsIndex);
  403. X
  404. X  memset((char *)image->used, 0, MAX_CELLS);
  405. X  image->used[whitep] = 1;
  406. X  image->used[blackp] = 1;
  407. X  image->numcells = 2;
  408. X}
  409. X
  410. END_OF_FILE
  411. if test 9414 -ne `wc -c <'xgrabsc.2_3/convert.hc'`; then
  412.     echo shar: \"'xgrabsc.2_3/convert.hc'\" unpacked with wrong size!
  413. fi
  414. # end of 'xgrabsc.2_3/convert.hc'
  415. fi
  416. if test -f 'xgrabsc.2_3/write.hc' -a "${1}" != "-c" ; then 
  417.   echo shar: Will not clobber existing file \"'xgrabsc.2_3/write.hc'\"
  418. else
  419. echo shar: Extracting \"'xgrabsc.2_3/write.hc'\" \(42884 characters\)
  420. sed "s/^X//" >'xgrabsc.2_3/write.hc' <<'END_OF_FILE'
  421. X/*========================================================================
  422. X *
  423. X * Name - write.hc
  424. X *
  425. X * ccs version:    1.16
  426. X *
  427. X * ccsid:    @(#)write.hc    1.16 - 06/28/93 09:13:46
  428. X * from:     ccs/s.write.hc
  429. X * date:     06/28/93 09:14:49
  430. X *
  431. X * Description:  output conversions for xgrabsc
  432. X *
  433. X *               see cpyright.h for copyright information
  434. X *
  435. X *
  436. X *========================================================================
  437. X */
  438. X
  439. X
  440. X/* swap the bits in a byte */
  441. Xswapbits(b)
  442. X  byte b;
  443. X{
  444. X  byte b2;
  445. X
  446. X  b2 = 0;
  447. X  b2 |= (b & 0x01) << 7;
  448. X  b2 |= (b & 0x02) << 5;
  449. X  b2 |= (b & 0x04) << 3;
  450. X  b2 |= (b & 0x08) << 1;
  451. X  b2 |= (b & 0x10) >> 1;
  452. X  b2 |= (b & 0x20) >> 3;
  453. X  b2 |= (b & 0x40) >> 5;
  454. X  b2 |= (b & 0x80) >> 7;
  455. X  return b2;
  456. X}
  457. X
  458. X
  459. X
  460. X
  461. X/* swap the bytes in a long int */
  462. Xswapbytes(pDblw)
  463. X  dw *pDblw;
  464. X  {
  465. X  union {
  466. X    dw  dbl;
  467. X    byte bytes[4];
  468. X    } cnv;
  469. X  byte aByte;
  470. X
  471. X  cnv.dbl = *pDblw;
  472. X  aByte = cnv.bytes[0];
  473. X  cnv.bytes[0] = cnv.bytes[3];
  474. X  cnv.bytes[3] = aByte;
  475. X  aByte = cnv.bytes[1];
  476. X  cnv.bytes[1] = cnv.bytes[2];
  477. X  cnv.bytes[2] = aByte;
  478. X  *pDblw = cnv.dbl;
  479. X  }
  480. X
  481. X
  482. X
  483. X/* swap some long ints.  (n is number of BYTES, not number of longs) */
  484. Xswapdws (bp, n)
  485. X  register char *bp;
  486. X  register unsigned n;
  487. X{
  488. X  register char c;
  489. X  register char *ep = bp + n;
  490. X  register char *sp;
  491. X
  492. X  while (bp < ep) {
  493. X    sp = bp + 3;
  494. X    c = *sp;
  495. X    *sp = *bp;
  496. X    *bp++ = c;
  497. X    sp = bp + 1;
  498. X    c = *sp;
  499. X    *sp = *bp;
  500. X    *bp++ = c;
  501. X    bp += 2;
  502. X  }
  503. X}
  504. X
  505. X
  506. X
  507. X/* swap some short ints */
  508. Xswapwords (bp, n)
  509. X  register char *bp;
  510. X  register unsigned n;
  511. X{
  512. X  register char c;
  513. X  register char *ep = bp + n;
  514. X
  515. X  while (bp < ep) {
  516. X    c = *bp;
  517. X    *bp = *(bp + 1);
  518. X    bp++;
  519. X    *bp++ = c;
  520. X  }
  521. X}
  522. X
  523. X
  524. X
  525. X
  526. X
  527. XwriteSimple(image, outfile)
  528. X  imageInfo *image;
  529. X  FILE *outfile;
  530. X{
  531. X  dw width, height, hasColormap, colormapSize;
  532. X  dw swaptest = 1;
  533. X  int i, w, h;
  534. X
  535. X  if (verbose)
  536. X    fprintf(stderr, "%s: writing in simple output format\n", programName);
  537. X  if (image->ximage->depth != 8) {
  538. X    fprintf(stderr, "%s: can't write simple image format if depth is not 8\n",
  539. X            programName);
  540. X    return;
  541. X  }
  542. X  width        = image->ximage->width;
  543. X  height       = image->ximage->height;
  544. X  hasColormap  = 1;
  545. X  colormapSize = image->numcells;
  546. X  if (*(char *)&swaptest==0) {
  547. X    swapdws(&width,        1);
  548. X    swapdws(&height,       1);
  549. X    swapdws(&hasColormap,  1);
  550. X    swapdws(&colormapSize, 1);
  551. X  }
  552. X  fwrite(&width, 4, 1, outfile);
  553. X  fwrite(&height, 4, 1, outfile);
  554. X  fwrite(&hasColormap, 4, 1, outfile);
  555. X  fwrite(&colormapSize, 4, 1, outfile);
  556. X  for (i=0; i<image->numcells; i++)
  557. X    fputc((byte)(image->red[i]>>8), outfile);
  558. X  for (i=0; i<image->numcells; i++)
  559. X    fputc((byte)(image->green[i]>>8), outfile);
  560. X  for (i=0; i<image->numcells; i++)
  561. X    fputc((byte)(image->blue[i]>>8), outfile);
  562. X  for (i=0; i<image->numcells; i++)
  563. X    fputc((byte)(image->used[i]), outfile);
  564. X  for (h=0; h<image->ximage->height; h++)
  565. X    for (w=0; w<image->ximage->width; w++)
  566. X      fputc(XGetPixel(image->ximage, w, h), outfile);
  567. X}
  568. X
  569. X
  570. X
  571. X
  572. X
  573. X
  574. X
  575. X/*
  576. X * makePSImage returns an XImage structure that contains the samples
  577. X * to be written.  If the input image is monochrome, its XImage structure
  578. X * will be returned.  Otherwise a new structure is allocated and returned.
  579. X */
  580. X
  581. XXImage* makePSImage(image, desiredDepth, depth, bpl, spb)
  582. X    imageInfo* image;
  583. X    int desiredDepth;  /* 0 = don't care */
  584. X    int* depth;
  585. X    int* bpl;
  586. X    int* spb;
  587. X{
  588. X    register byte* ptr;
  589. X    int lshift, lmask;
  590. X    long p;
  591. X    int x, y, i;
  592. X    XImage* ximage = image->ximage;
  593. X    XImage* psimage;
  594. X
  595. X  /* use depth as the number of bits in output samples */
  596. X  *depth = ximage->depth;
  597. X  /* postscript only supports 1, 2, 4, or 8 */
  598. X  if (*depth > 8) *depth = 8;     /* max postscript bits/sample */
  599. X  if (*depth < 8 && *depth > 4) *depth = 8;
  600. X  if (*depth == 3) *depth = 4;
  601. X    
  602. X    if (desiredDepth == 0) {
  603. X    desiredDepth = *depth;
  604. X    }
  605. X
  606. X
  607. X  *bpl = ((ximage->width * desiredDepth) + 7) / 8;
  608. X
  609. X  if (*depth == 1)
  610. X    /* Same image */
  611. X    psimage = ximage;
  612. X  else {
  613. X    /* colors have to be changed to luminescence */
  614. X    ptr = (byte *)malloc(ximage->height * *bpl);
  615. X    psimage = XCreateImage(hDisplay, DefaultVisual(hDisplay, hScreen),
  616. X                  desiredDepth, ZPixmap,
  617. X                  0, ptr,
  618. X                  ximage->width, ximage->height,
  619. X                  8, *bpl);
  620. X    if (!psimage) {
  621. X      fprintf(stderr, "%s: could not create image for Postscript conversion\n",
  622. X        programName);
  623. X      exit(3);
  624. X    }
  625. X    /* force the bits_per_pixel to be what is needed */
  626. X    psimage->bits_per_pixel = desiredDepth;
  627. X  }
  628. X
  629. X  *spb = 8 / psimage->bits_per_pixel;    /* samples per byte */
  630. X
  631. X  if (*depth > 1) {
  632. X    /* translate colors into grays */
  633. X    lshift = 16 - psimage->bits_per_pixel;
  634. X    lmask  = (1 << psimage->bits_per_pixel) - 1;
  635. X    for (y = 0; y < ximage->height; y++) {
  636. X      for (x = 0; x < ximage->width; x++) {
  637. X        p = XGetPixel(ximage, x, y);
  638. X        i = (0.30*(double)image->red[p]) +
  639. X            (0.59*(double)image->green[p])+
  640. X            (0.11*(double)image->blue[p]);
  641. X        i = (i >> lshift) & lmask;
  642. X        XPutPixel(psimage, x, y, i);
  643. X      }
  644. X    }
  645. X  }
  646. X  *depth = desiredDepth;  /* The final resolution */
  647. X  return psimage;
  648. X}
  649. X
  650. X
  651. X
  652. X
  653. X
  654. X
  655. X
  656. XwriteOnlyPreview(image, outfile)
  657. X  imageInfo *image;
  658. X  FILE* outfile;
  659. X{
  660. X  XImage* psimage = (XImage *) NULL;
  661. X
  662. X  if (verbose) fprintf(stderr, "%s: generating only EPSI preview comment\n", programName);
  663. X
  664. X  if (image->ximage->depth == 1) {
  665. X    /* First process the image to make it good */
  666. X    int depth, bpl, spb;
  667. X    psimage = makePSImage(image, 1, &depth, &bpl, &spb);
  668. X  }
  669. X
  670. X  writePreview(image, outfile, psimage);
  671. X
  672. X  if (psimage && psimage != image->ximage) {
  673. X    /* Free the allocated PostScript image */
  674. X    free(psimage->data);
  675. X    free(psimage);
  676. X  }
  677. X}
  678. X
  679. X
  680. X
  681. XwritePreview(image, outfile, defaultImage)
  682. X  imageInfo *image;
  683. X  XImage *defaultImage;
  684. X  FILE *outfile;
  685. X{
  686. X  register byte b, *ptr;
  687. X  int depth, bpl, spb;
  688. X  int reverse, x, y;
  689. X  int widthcount, lines;
  690. X  XImage* ximage = image->ximage;
  691. X  XImage* psimage = (XImage *)NULL;
  692. X  imageInfo newImage;
  693. X    
  694. X  newImage.ximage = (XImage*) NULL;
  695. X      
  696. X  if (ximage->depth > 1) {
  697. X    /* Copy the image before doing any changes! */
  698. X    int i;
  699. X    for (i = 0; i < image->numcells; ++i) {
  700. X    newImage.red[i] = image->red[i];
  701. X        newImage.green[i] = image->green[i];
  702. X        newImage.blue[i] = image->blue[i];
  703. X        newImage.used[i] = image->used[i];
  704. X    }
  705. X    newImage.numcells = image->numcells;
  706. X    newImage.ximage = XSubImage(ximage, 0, 0, ximage->width, ximage->height);
  707. X    if (!newImage.ximage) {
  708. X      fprintf(stderr, "%s: unable to create copy of color image\n",
  709. X        programName);
  710. X      XCloseDisplay(hDisplay);
  711. X      exit(3);
  712. X    }
  713. X
  714. X    if (ForceBitmap)
  715. X      pixmap2bitmap(&newImage);
  716. X    else if (Halftone)
  717. X      pixmap2halftone(&newImage, DitherKind);
  718. X    else
  719. X      pixmap2halftone(&newImage, FS_DITHER);
  720. X
  721. X    defaultImage = newImage.ximage;
  722. X    image = &newImage;
  723. X    psimage = makePSImage(&newImage, 1, &depth, &bpl, &spb);
  724. X  }
  725. X  else {
  726. X    /* the image is already monochrome, so use the psimage that's already
  727. X     * been processed */
  728. X    psimage = defaultImage;
  729. X    bpl = (psimage->width + 7) / 8;
  730. X    spb = 8;
  731. X  }
  732. X    
  733. X
  734. X  /* compute the number of lines in the preview output so
  735. X   * apps reading the file can easily skip it */
  736. X  lines = (bpl * psimage->height) / (PREVIEW_CODEWIDTH / 2);
  737. X  if ((bpl * psimage->height) % (PREVIEW_CODEWIDTH / 2) > 0) lines++;
  738. X
  739. X  fprintf(outfile, "%%%%BeginPreview: %d %d %d %d\n%%",
  740. X        psimage->width, psimage->height, psimage->depth, lines);
  741. X
  742. X    
  743. X  /* if the bits haven't been swizzled yet, we have to check for color
  744. X   * reversal */
  745. X  if (psimage == image->ximage)
  746. X    reverse = BlackPixel(hDisplay,hScreen)!=EPSF_BLACK;
  747. X  else
  748. X    reverse = FALSE;
  749. X
  750. X  widthcount = 0;
  751. X  for (y=0; y<psimage->height; y++) {
  752. X    /* note that depth 1 images are already padded to even byte boundaries
  753. X     * under X, so there is no need to shift bits around to do padding of
  754. X     * the preview image */
  755. X    for (x=0, ptr=(byte *)(psimage->data+(y * psimage->bytes_per_line));
  756. X         x<psimage->width;
  757. X         x+=spb, ptr++) {
  758. X      b = *ptr;
  759. X      if (reverse) b = ~b;
  760. X      if (depth == 1  &&  psimage->bitmap_bit_order == LSBFirst)
  761. X        b = swapbits(b);
  762. X      fprintf(outfile, "%02.2x", b);
  763. X      widthcount += 2;
  764. X      if (widthcount >= PREVIEW_CODEWIDTH) {
  765. X    fputs("\n%", outfile);
  766. X        widthcount = 0;
  767. X      }
  768. X    }
  769. X  }
  770. X
  771. X  if (widthcount == 0)
  772. X    fputs("%EndPreview\n", outfile);
  773. X  else
  774. X    fputs("\n%%EndPreview\n", outfile);
  775. X    
  776. X  if (psimage && psimage != defaultImage) {
  777. X    free(psimage->data);
  778. X    free(psimage);
  779. X  }
  780. X  if (newImage.ximage) {
  781. X    XDestroyImage(newImage.ximage);
  782. X  }
  783. X}
  784. X
  785. X
  786. X
  787. X/*
  788. X * Write an image in Postscript format
  789. X */
  790. XwritePostscript(image, outfile, encode, encapsulate, preview,
  791. X  landscape, binary, checkLimits)
  792. X  imageInfo *image;
  793. X  FILE *outfile;
  794. X  int encode;       /* TRUE if we're to encode the Postscript output */
  795. X  int encapsulate;  /* TRUE if encapsulated Postscript output is wanted */
  796. X  int preview;      /* TRUE if EPSI preview image is to be written with EPS output */
  797. X  int landscape;    /* TRUE if landscape format is wanted */
  798. X  int binary;       /* TRUE if binary output is wanted */
  799. X  int checkLimits;  /* TRUE if PS interpreter memory checks should be made */
  800. X{
  801. X  register byte b, *ptr;
  802. X  register int x, y;
  803. X  register int i;
  804. X  XImage *ximage = image->ximage;
  805. X  XImage *psimage;
  806. X  double xdpi, ydpi, xscale, yscale, f;
  807. X  int lshift, lmask;
  808. X  int depth, bpl, spb;
  809. X  int reverse;
  810. X  long p;
  811. X  /* rle variables */
  812. X  int rlecount;
  813. X  byte rlesample;
  814. X  dw  rletotal;
  815. X  int widthcount;
  816. X  int firstSample;
  817. X
  818. X  if (verbose)
  819. X    fprintf(stderr, "%s: formatting Postscript output\n", programName);
  820. X
  821. X  if (preview)
  822. X    encapsulate = TRUE;
  823. X
  824. X  if (encapsulate)
  825. X    landscape = FALSE;  /* landscape uses a transformation matrix */
  826. X
  827. X  psimage = makePSImage(image, 0, &depth, &bpl, &spb);
  828. X
  829. X#ifndef NO_RLE_CHECKS
  830. X  if (encode) {
  831. X    rletotal = 0;
  832. X    rlecount = 0;
  833. X    firstSample = TRUE;
  834. X    for (y=0; y<psimage->height; y++)
  835. X      for (x=0, ptr=(byte *)(psimage->data + (y * psimage->bytes_per_line));
  836. X           x<psimage->width; x+=spb, ptr++) {
  837. X        b = *ptr;
  838. X    if (firstSample || b != rlesample || rlecount==254) {
  839. X      if (!firstSample)
  840. X        rletotal += 2;
  841. X      else
  842. X        firstSample = FALSE;
  843. X      rlecount = 0;
  844. X      rlesample = b;
  845. X    }
  846. X    else
  847. X      rlecount++;
  848. X      }
  849. X    if (!firstSample)
  850. X      rletotal += 2;
  851. X    f = (float)(rletotal) / (float)(psimage->height*bpl);
  852. X    if (verbose)
  853. X      fprintf(stderr, "%s: encoding would change to %5.1f%% of orig size\n",
  854. X            programName, f * 100.0);
  855. X    encode = f <= 0.95;
  856. X  }
  857. X#endif
  858. X
  859. X
  860. X
  861. X  if (verbose)
  862. X    fprintf(stderr, "%s: image will %sbe encoded\n", programName,
  863. X            encode? "" : "not ");
  864. X
  865. X  if (encapsulate) {
  866. X    fprintf(outfile, "%%!PS-Adobe-2.0 EPSF-2.0\n");
  867. X    fprintf(outfile, "%%%%BoundingBox: %d %d %d %d\n",
  868. X                0, 0, psimage->width, psimage->height);
  869. X  }
  870. X  else
  871. X    fprintf(outfile, "%%!PS-Adobe-2.0\n");
  872. X
  873. X  fprintf(outfile, "%%%%Creator: xgrabsc\n");
  874. X  fprintf(outfile, "%%%%Title: %s\n", imageName);
  875. X  if (outfileName)
  876. X    fprintf(outfile, "%%%%File: %s\n", outfileName);
  877. X  time(&p);
  878. X  fprintf(outfile, "%%%%CreationDate: %s", ctime(&p));
  879. X  fprintf(outfile, "%%%%EndComments\n");
  880. X  fprintf(outfile, "%%\n");
  881. X  fprintf(outfile, "%%\n");
  882. X
  883. X  /* if the user wants a preview image, EPS 2.0 says it must go here */
  884. X  if (preview)
  885. X    writePreview(image, outfile, psimage);
  886. X
  887. X
  888. X  fprintf(outfile, "%%%%EndProlog\n");
  889. X  if (encapsulate) {
  890. X    fprintf(outfile, "%%%%Page: 1 1\n");
  891. X  }
  892. X
  893. X  /* standard inch procedure */
  894. X  fputs("/inch {72 mul} def\n", outfile);
  895. X
  896. X
  897. X  /* define a string to hold image bytes */
  898. X  if (encode) {
  899. X    fputs("/rlebuffer 2 string def\n", outfile);
  900. X    fprintf(outfile, "/samples %d string def\n", 256);  /* max bytes per burst */
  901. X  }
  902. X  else
  903. X    fprintf(outfile, "/picstr %d string def\n", bpl);
  904. X
  905. X  if (binary) {
  906. X    fputs("/endstr 1 string def\n", outfile);
  907. X    if (encode) fputs("/ccount 0 def\n", outfile);
  908. X  }
  909. X
  910. X  /* define the image plotting procedure */
  911. X  fputs("/plotimage\n", outfile);
  912. X
  913. X  fprintf(outfile, "{%d %d %d ",
  914. X        psimage->width, psimage->height, psimage->bits_per_pixel);
  915. X
  916. X
  917. X
  918. X  /* transformation matrix */
  919. X  if (landscape)
  920. X    fprintf(outfile, "[0 %d %d 0 0 0]\n", psimage->width, psimage->height);
  921. X  else
  922. X    fprintf(outfile, "[%d 0 0 -%d 0 %d]\n",
  923. X        psimage->width, psimage->height, psimage->height);
  924. X
  925. X  /* line reading function  */
  926. X
  927. X  if (encode) {
  928. X    fputs("% run-length decoding block\n",                                       outfile);
  929. X    if (binary) {
  930. X      fputs("  { currentfile rlebuffer readstring pop pop\n", outfile);
  931. X      fputs("    /ccount ccount 2 add def                 %% count binary chars\n",outfile);
  932. X      fprintf(outfile,
  933. X            "    ccount %d ge                             %% test for full line\n", IMAGE_CODEWIDTH);
  934. X      fputs("    { /ccount 0 def                          %% reset character counter\n",outfile);
  935. X      fputs("      currentfile endstr readline pop pop    %% skip newline\n",outfile);
  936. X      fputs("    } if                                     %% skip newlines after full line\n",outfile);
  937. X    }
  938. X    else
  939. X      fputs("  { currentfile rlebuffer readhexstring pop pop\n",                 outfile);
  940. X    fputs("    rlebuffer 0 get 1 add       %% number of copies of the sample\n", outfile);
  941. X    fputs("    /nsamples exch store        %% save it away\n",                   outfile);
  942. X    fputs("    /lum rlebuffer 1 get store  %% the sample itself\n",              outfile);
  943. X    fputs("    0 1 nsamples 1 sub { samples exch lum put } for\n",               outfile);
  944. X    fputs("    samples 0 nsamples getinterval %% leave the pixels on the stack\n",outfile);
  945. X    fputs("  }\n", outfile);
  946. X  }
  947. X  else {
  948. X    if (binary) {
  949. X      /* Do a "readline" after each "readstring" so we can seperate each
  950. X         scanline of binary data with a "newline" */
  951. X      fputs("   {currentfile picstr readstring pop\n", outfile);
  952. X      fputs("    currentfile endstr readline pop pop}\n", outfile);
  953. X    }
  954. X    else
  955. X      fputs("  {currentfile picstr readhexstring pop}\n", outfile);
  956. X  }
  957. X
  958. X  fputs("  image\n} def\n", outfile);
  959. X
  960. X
  961. X  /* emit some code to check for resource availability */
  962. X  if (!encapsulate  &&  checkLimits) {
  963. X    for (x=0; CheckVM[x] != NULL; x++) {
  964. X      fputs(CheckVM[x], outfile);
  965. X      fputc('\n', outfile);
  966. X    }
  967. X    fprintf(outfile, "\n\n");
  968. X    fprintf(outfile, "%d checkvm\n", psimage->height * bpl);
  969. X  }
  970. X
  971. X  /* save context and move to a nice origin */
  972. X  fputs("gsave\n", outfile);
  973. X
  974. X  if (encapsulate) {
  975. X    /* for encapsulated postscript, we need a scale factor that is equal
  976. X     * to the image width/height in samples */
  977. X    fprintf(outfile, "%d %d scale\n", psimage->width, psimage->height);
  978. X  }
  979. X  else {
  980. X    /* For physical output we need a scale factor that will create
  981. X      * the same size image, and we need to center it on the page.
  982. X      *   -Figure out the physical dimensions on the screen
  983. X      *    and make it come out the same on the printer. */
  984. X    xdpi = (((double)DisplayWidth(hDisplay,hScreen)) * 25.4) /
  985. X            ((double)DisplayWidthMM(hDisplay,hScreen));
  986. X    ydpi = (((double)DisplayHeight(hDisplay,hScreen)) * 25.4) /
  987. X            ((double)DisplayHeightMM(hDisplay,hScreen));
  988. X    xscale = ((double)psimage->width) / xdpi;
  989. X    yscale = ((double)psimage->height) / ydpi;
  990. X    if (landscape) {
  991. X      f = xscale; xscale = yscale; yscale = f;
  992. X    }
  993. X    if (xscale > horizInset) {
  994. X      yscale *= horizInset / xscale;
  995. X      xscale = horizInset;
  996. X    }
  997. X    if (yscale > vertInset) {
  998. X      xscale *= vertInset / yscale;
  999. X      yscale = vertInset;
  1000. X    }
  1001. X    fprintf(outfile, "%1.2g inch %1.2g inch translate\n",
  1002. X                  (pageWidth - xscale) / 2.0, (pageHeight - yscale) / 2.0);
  1003. X    if (landscape)
  1004. X      fprintf(outfile, "%1.2g inch %1.2g inch scale\n", yscale, xscale);
  1005. X    else
  1006. X      fprintf(outfile, "%1.2g inch %1.2g inch scale\n", xscale, yscale);
  1007. X  }
  1008. X
  1009. X
  1010. X
  1011. X  if (binary)
  1012. X    fprintf(outfile,"%%%%BeginBinary: %d\n",
  1013. X        encode ? rletotal+11+rletotal/IMAGE_CODEWIDTH
  1014. X        : ximage->height*(ximage->width+1)+10);
  1015. X
  1016. X  fputs("plotimage\n", outfile);
  1017. X
  1018. X
  1019. X  reverse = depth == 1? BlackPixel(hDisplay,hScreen)==1 : FALSE;
  1020. X  if (encode) {
  1021. X    rletotal = 0;
  1022. X    rlecount = 0;
  1023. X    firstSample = TRUE;
  1024. X  }
  1025. X  widthcount = 0;
  1026. X  for (y=0; y<psimage->height; y++) {
  1027. X    for (x=0, ptr=(byte *)(psimage->data+(y * psimage->bytes_per_line));
  1028. X         x<psimage->width;
  1029. X         x+=spb, ptr++) {
  1030. X      b = *ptr;
  1031. X      if (reverse) b = ~b;
  1032. X      if (depth == 1  &&  psimage->bitmap_bit_order == LSBFirst)
  1033. X        b = swapbits(b);
  1034. X      if (encode) {
  1035. X        if (firstSample || b != rlesample || rlecount==254) {
  1036. X      if (!firstSample) {
  1037. X        if (binary) {
  1038. X          putc((byte)rlecount,outfile);
  1039. X          putc((byte)rlesample,outfile);
  1040. X          widthcount += 2;
  1041. X        }
  1042. X        else {
  1043. X          fprintf(outfile, "%02.2x%02.2x", rlecount, rlesample);
  1044. X          widthcount += 4;
  1045. X        }
  1046. X        rletotal += 2;
  1047. X        if (widthcount >= IMAGE_CODEWIDTH) {
  1048. X          fputc('\n', outfile);
  1049. X          widthcount = 0;
  1050. X        }
  1051. X      }
  1052. X      else
  1053. X        firstSample = FALSE;
  1054. X      rlecount = 0;
  1055. X      rlesample = b;
  1056. X    }
  1057. X    else
  1058. X      rlecount++;
  1059. X      }
  1060. X      else {
  1061. X    if (binary)
  1062. X      putc((byte)b,outfile);
  1063. X    else {
  1064. X          fprintf(outfile, "%02.2x", b);
  1065. X      widthcount += 2;
  1066. X      if (widthcount >= IMAGE_CODEWIDTH) {
  1067. X        fputc('\n', outfile);
  1068. X            widthcount = 0;
  1069. X          }
  1070. X        }
  1071. X      }
  1072. X    }
  1073. X    if (binary && !encode) putc('\n',outfile);
  1074. X  }
  1075. X
  1076. X  if (encode) {
  1077. X    if (!firstSample) {
  1078. X      if (binary) {
  1079. X    putc((byte)rlecount,outfile);
  1080. X    putc((byte)rlesample,outfile);
  1081. X      }
  1082. X      else
  1083. X        fprintf(outfile, "%02.2x%02.2x\n", rlecount, rlesample);
  1084. X      rletotal += 2;
  1085. X    }
  1086. X    putc('\n',outfile);
  1087. X    if (binary) fputs("%%EndBinary\n",outfile);
  1088. X    fputs("%\n", outfile);
  1089. X    fprintf(outfile, "%% Run-length encoding savings = %5.1f%%\n",
  1090. X          100.0 - ((float)(rletotal) * 100.0 / (float)(psimage->height * bpl)));
  1091. X    fputs("%\n", outfile);
  1092. X  }
  1093. X  else if (binary) fputs("%%EndBinary\n",outfile);
  1094. X
  1095. X  fputs("\n\n\ngrestore\nshowpage\n", outfile);
  1096. X  fputs("\n%%Trailer\n", outfile);
  1097. X
  1098. X
  1099. X  if (psimage != ximage) {
  1100. X    free(psimage->data);
  1101. X    free(psimage);
  1102. X  }
  1103. X}
  1104. X
  1105. X
  1106. X
  1107. X
  1108. X
  1109. X/*
  1110. X * Write an image in Color Postscript format
  1111. X */
  1112. XwriteColorPS(image, outfile, encode, encapsulate, preview,
  1113. X  landscape, binary, checkLimits)
  1114. X  imageInfo *image;
  1115. X  FILE *outfile;
  1116. X  int encode;       /* TRUE if we're to encode the Postscript output    */
  1117. X  int encapsulate;  /* TRUE if encapsulated Postscript output is wanted */
  1118. X  int preview;      /* TRUE if EPSI preview image is to be written with EPS output */
  1119. X  int landscape;    /* TRUE if landscape output is wanted               */
  1120. X  int binary;       /* TRUE if binary Postscript output is wanted */
  1121. X  int checkLimits;  /* TRUE if PS interpreter memory checks should be made */
  1122. X{
  1123. X  register byte *ptr, b;
  1124. X  register int x, y;
  1125. X  XImage *ximage = image->ximage;
  1126. X  double xdpi, ydpi, xscale, yscale, f;
  1127. X  double left, top;
  1128. X  int depth, bpl, spb;
  1129. X  long p;
  1130. X  /* rle variables */
  1131. X  int rlecount;
  1132. X  dw  rletotal;
  1133. X  byte rlesample;
  1134. X  int firstSample;
  1135. X  int widthcount;
  1136. X
  1137. X
  1138. X  if (verbose)
  1139. X    fprintf(stderr, "%s: formatting Color Postscript output\n", programName);
  1140. X
  1141. X  if (preview)
  1142. X    encapsulate = TRUE;  /* should have been enforced before this point */
  1143. X
  1144. X  if (encapsulate)
  1145. X    landscape = FALSE;  /* landscape uses a transformation matrix */
  1146. X
  1147. X  depth = 8;                                  /* bits per sample  */
  1148. X  spb   = 1;                                  /* samples per byte */
  1149. X  bpl = ((ximage->width * depth) + 7) / 8;    /* bytes per line   */
  1150. X
  1151. X
  1152. X#ifndef NO_RLE_CHECKS
  1153. X  if (encode) {
  1154. X    rletotal = 0;
  1155. X    rlecount = 0;
  1156. X    firstSample = TRUE;
  1157. X    for (y=0; y<ximage->height; y++)
  1158. X      for (x=0, ptr=(byte *)(ximage->data + (y * ximage->bytes_per_line));
  1159. X           x<ximage->width; x+=spb, ptr++) {
  1160. X        b = *ptr;
  1161. X    if (firstSample || b != rlesample || rlecount==254) {
  1162. X      if (!firstSample)
  1163. X        rletotal += 2;
  1164. X      else
  1165. X        firstSample = FALSE;
  1166. X      rlecount = 0;
  1167. X      rlesample = b;
  1168. X    }
  1169. X    else
  1170. X      rlecount++;
  1171. X      }
  1172. X    rletotal += 2;
  1173. X    f = (float)(rletotal) / (float)(ximage->height*bpl);
  1174. X    if (verbose)
  1175. X      fprintf(stderr, "%s: encoding would change to %5.1f%% of orig size\n",
  1176. X            programName, f * 100.0);
  1177. X    encode = f <= 0.95;
  1178. X  }
  1179. X#endif
  1180. X
  1181. X  if (encapsulate) {
  1182. X    fprintf(outfile, "%%!PS-Adobe-2.0 EPSF-2.0\n");
  1183. X  }
  1184. X  else
  1185. X    fprintf(outfile, "%%!PS-Adobe-2.0\n");
  1186. X
  1187. X  fprintf(outfile, "%%%%Creator: xgrabsc\n");
  1188. X  fprintf(outfile, "%%%%Title: %s\n", imageName);
  1189. X  if (outfileName)
  1190. X    fprintf(outfile, "%%%%File: %s\n", outfileName);
  1191. X  if (encapsulate) {
  1192. X    fprintf(outfile, "%%%%Pages: 1\n");
  1193. X    fprintf(outfile, "%%%%BoundingBox: %d %d %d %d\n",
  1194. X                0, 0, ximage->width, ximage->height);
  1195. X  }
  1196. X  time(&p);
  1197. X  fprintf(outfile, "%%%%CreationDate: %s", ctime(&p));
  1198. X  fprintf(outfile, "%%%%EndComments\n");
  1199. X
  1200. X  /* if the user wants a preview image, EPS 2.0 says it must go here */
  1201. X  if (preview)
  1202. X    writePreview(image, outfile, image->ximage);
  1203. X
  1204. X  fprintf(outfile, "%%%%EndProlog\n");
  1205. X  if (encapsulate) {
  1206. X    fprintf(outfile, "%%%%Page: 1 1\n");
  1207. X  }
  1208. X  fprintf(outfile, "\n\ngsave\n\n");
  1209. X
  1210. X
  1211. X  fputs("/inch {72 mul} def\n", outfile);
  1212. X
  1213. X  /* emit some code to check for resource availability */
  1214. X  if (!encapsulate  &&  checkLimits) {
  1215. X    for (x=0; CheckVM[x] != NULL; x++) {
  1216. X      fputs(CheckVM[x], outfile);
  1217. X      fputc('\n', outfile);
  1218. X    }
  1219. X    fprintf(outfile, "\n\n");
  1220. X    fprintf(outfile, "%d checkvm\n\n", ximage->height * bpl);
  1221. X  }
  1222. X
  1223. X  if (encapsulate) {
  1224. X    /* don't translate the image for encapsulated postscript.  The
  1225. X     * scale should match the data dimensions of the image in samples.  */
  1226. X    fprintf(outfile, "%d %d scale\n", ximage->width, ximage->height);
  1227. X  }
  1228. X  else {
  1229. X    /* For physical output we need a scale factor that will create
  1230. X     * the same size image, and we need to center it on the page.
  1231. X     *   -Figure out the physical dimensions on the screen
  1232. X     *    and make it come out the same on the printer.
  1233. X     */
  1234. X    xdpi = (((double)DisplayWidth(hDisplay,hScreen)) * 25.4) /
  1235. X            ((double)DisplayWidthMM(hDisplay,hScreen));
  1236. X    ydpi = (((double)DisplayHeight(hDisplay,hScreen)) * 25.4) /
  1237. X            ((double)DisplayHeightMM(hDisplay,hScreen));
  1238. X    xscale = ((double)ximage->width) / xdpi;
  1239. X    yscale = ((double)ximage->height) / ydpi;
  1240. X    if (landscape) {
  1241. X      f = xscale; xscale = yscale; yscale = f;
  1242. X    }
  1243. X    if (xscale > horizInset) {
  1244. X      yscale *= horizInset / xscale;
  1245. X      xscale = horizInset;
  1246. X    }
  1247. X    if (yscale > vertInset) {
  1248. X      xscale *= vertInset / yscale;
  1249. X      yscale = vertInset;
  1250. X    }
  1251. X     
  1252. X
  1253. X    left = ((pageWidth - xscale) / 2.0);
  1254. X    top  = ((pageHeight - yscale) / 2.0);
  1255. X    fprintf(outfile, "%1.2g inch %1.2g inch translate\n", left, top);
  1256. X    if (landscape)
  1257. X      fprintf(outfile, "%1.2g inch %1.2g inch scale\n", yscale, xscale);
  1258. X    else
  1259. X      fprintf(outfile, "%1.2g inch %1.2g inch scale\n", xscale, yscale);
  1260. X    fprintf(outfile, "\n\n\n");
  1261. X  }
  1262. X
  1263. X  if (binary) {
  1264. X    fputs("/endstr 1 string def\n", outfile);
  1265. X    fputs("/ccount 0 def\n", outfile);
  1266. X  }
  1267. X
  1268. X  if (encode) {
  1269. X    /* encoded output:
  1270. X     * define a drawcolorimage procedure geared to this image
  1271. X     */
  1272. X    fprintf(outfile, "/rgbstr %d string def\n", 256 * 3); /* max pixels per burst */
  1273. X    fprintf(outfile, "/buffer %d string def\n", 2);
  1274. X    fputs("/rgb (000) def\n", outfile);
  1275. X    fprintf(outfile, "/rgbmap %d string def\n", image->numcells * 3);
  1276. X    fputs("/samples 256 string def\n", outfile);
  1277. X    fputs("\n\n", outfile);
  1278. X
  1279. X    fputs("/drawcolormappedimage {\n", outfile);
  1280. X    fputs("  %% for greyscale printers, convert rgb values into grey samples\n", outfile);
  1281. X    fputs("  %% and use these in the 'image' operator\n", outfile);
  1282. X    fputs("  systemdict /colorimage known userdict /colorimage known or not {\n", outfile);
  1283. X    fputs("    %% convert colors to greyscale\n", outfile);
  1284. X    fprintf(outfile,"    /ncolors %d store\n", image->numcells);
  1285. X    fputs("    /ridx 0 store\n", outfile);
  1286. X    fputs("    /greys ncolors string def\n", outfile);
  1287. X    fputs("    0 1 ncolors 1 sub {\n", outfile);
  1288. X    fputs("      /gidx exch store\n", outfile);
  1289. X    fputs("      rgbmap ridx get .3 mul\n", outfile);
  1290. X    fputs("      rgbmap ridx 1 add get .59 mul add\n", outfile);
  1291. X    fputs("      rgbmap ridx 2 add get .11 mul add\n", outfile);
  1292. X    fputs("      cvi\n", outfile);
  1293. X    fputs("      /agrey exch store\n", outfile);
  1294. X    fputs("      greys gidx agrey put\n", outfile);
  1295. X    fputs("      /ridx ridx 3 add store\n", outfile);
  1296. X    fputs("    } for\n", outfile);
  1297. X    fprintf(outfile, "    %d %d %d", ximage->width, ximage->height,depth);
  1298. X    if (landscape)
  1299. X      fprintf(outfile, "  [0 %d %d 0 0 0]\n", ximage->width, ximage->height);
  1300. X    else
  1301. X      fprintf(outfile, "  [%d 0 0 -%d 0 %d]\n", ximage->width, ximage->height,
  1302. X                                                ximage->height);
  1303. X    if (binary) {
  1304. X      fputs("    { currentfile buffer readstring pop pop    %% run length and index\n", outfile);
  1305. X      fputs("      /ccount ccount 2 add def                 %% count binary chars\n",outfile);
  1306. X      fprintf(outfile,
  1307. X            "      ccount %d ge                             %% test for full line\n", IMAGE_CODEWIDTH);
  1308. X      fputs("      { /ccount 0 def                          %% reset character counter\n",outfile);
  1309. X      fputs("        currentfile endstr readline pop pop    %% skip newline\n",outfile);
  1310. X      fputs("      } if                                     %% skip newlines after full line\n",outfile);
  1311. X    }
  1312. X    else
  1313. X      fputs("    { currentfile buffer readhexstring pop pop\n", outfile);
  1314. X    fputs("      buffer 0 get 1 add\n", outfile);
  1315. X    fputs("      /nsamples exch store\n", outfile);
  1316. X    fputs("      /lum greys buffer 1 get get store\n", outfile);
  1317. X    fputs("      0 1 nsamples 1 sub { samples exch lum put } for\n", outfile);
  1318. X    fputs("      samples 0 nsamples getinterval\n", outfile);
  1319. X    fputs("    } image\n\n", outfile);
  1320. X    fputs("  } {  %% ifelse\n", outfile);
  1321. X    fputs("\n", outfile);
  1322. X    fprintf(outfile, "    %d %d %d", ximage->width, ximage->height,depth);
  1323. X    if (landscape)
  1324. X      fprintf(outfile, "  [0 %d %d 0 0 0]\n", ximage->width, ximage->height);
  1325. X    else
  1326. X      fprintf(outfile, "  [%d 0 0 -%d 0 %d]\n", ximage->width, ximage->height,
  1327. X                                                ximage->height);
  1328. X    fputs("    %% define a block of code to read and decode the rle input stream\n", outfile);
  1329. X    if (binary) {
  1330. X      fputs("    { currentfile buffer readstring pop pop    %% run length and index\n", outfile);
  1331. X      fputs("      /ccount ccount 2 add def                 %% count binary chars\n",outfile);
  1332. X      fprintf(outfile,
  1333. X            "      ccount %d ge                             %% test for full line\n", IMAGE_CODEWIDTH);
  1334. X      fputs("      { /ccount 0 def                          %% reset character counter\n",outfile);
  1335. X      fputs("        currentfile endstr readline pop pop    %% skip newline\n",outfile);
  1336. X      fputs("      } if                                     %% skip newlines after full line\n",outfile);
  1337. X    }
  1338. X    else
  1339. X      fputs("    { currentfile buffer readhexstring pop pop %% run length and index\n", outfile);
  1340. X    fputs("      /npixels buffer 0 get 1 add 3 mul store  %% number of bytes\n", outfile);
  1341. X    fputs("      /color buffer 1 get 3 mul store          %% fix index into rgb map\n", outfile);
  1342. X    fputs("      /rgb rgbmap color 3 getinterval store    %% and get the colors\n", outfile);
  1343. X    fputs("\n", outfile);
  1344. X    fputs("      0 3 npixels 1 sub {                      %% loop to store the rgb bytes\n", outfile);
  1345. X    fputs("        rgbstr exch rgb putinterval\n", outfile);
  1346. X    fputs("      } for\n", outfile);
  1347. X    fputs("      rgbstr 0 npixels getinterval\n", outfile);
  1348. X    fputs("    }\n", outfile);
  1349. X    fputs("    false 3 colorimage\n\n", outfile);
  1350. X    fputs("  } ifelse\n\n", outfile);
  1351. X    fputs("} bind def\n", outfile);
  1352. X  }
  1353. X
  1354. X
  1355. X  else {
  1356. X    /* non-encoded output:
  1357. X     * define a drawcolorimage procedure geared to this image
  1358. X     */
  1359. X    fprintf(outfile, "/buffer %d string def\n", 1);
  1360. X    fprintf(outfile, "/line   %d string def\n", ximage->width);
  1361. X    fprintf(outfile, "/rgbmap %d string def\n", image->numcells * 3);
  1362. X    fputs("\n\n", outfile);
  1363. X
  1364. X    fputs("/onepixel 3 string store\n", outfile);
  1365. X
  1366. X    fputs("/drawcolormappedimage {\n", outfile);
  1367. X
  1368. X    fputs("  systemdict /colorimage known userdict /colorimage known or not {\n", outfile);
  1369. X    fputs("    %% convert colors to greyscale\n", outfile);
  1370. X    fprintf(outfile,"    /ncolors %d store\n", image->numcells);
  1371. X    fputs("    /ridx 0 store\n", outfile);
  1372. X    fputs("    /greys ncolors string def\n", outfile);
  1373. X    fputs("    /linecount 0 store\n", outfile);
  1374. X    fputs("    0 1 ncolors 1 sub {\n", outfile);
  1375. X    fputs("      /gidx exch store\n", outfile);
  1376. X    fputs("      rgbmap ridx get .3 mul\n", outfile);
  1377. X    fputs("      rgbmap ridx 1 add get .59 mul add\n", outfile);
  1378. X    fputs("      rgbmap ridx 2 add get .11 mul add\n", outfile);
  1379. X    fputs("      cvi\n", outfile);
  1380. X    fputs("      /agrey exch store\n", outfile);
  1381. X    fputs("      greys gidx agrey put\n", outfile);
  1382. X    fputs("      /ridx ridx 3 add store\n", outfile);
  1383. X    fputs("    } for\n", outfile);
  1384. X
  1385. X
  1386. X    fprintf(outfile, "    %d %d %d", ximage->width, ximage->height,depth);
  1387. X    if (landscape)
  1388. X      fprintf(outfile, "  [0 %d %d 0 0 0]\n", ximage->width, ximage->height);
  1389. X    else
  1390. X      fprintf(outfile, "  [%d 0 0 -%d 0 %d]\n", ximage->width, ximage->height,
  1391. X                                                ximage->height);
  1392. X
  1393. X    fputs("    %% define a block of code to read and decode the input stream\n", outfile);
  1394. X    if (binary) {
  1395. X      fputs("    { currentfile read not { 0 } if\n", outfile);
  1396. X      fputs("      greys exch 1 getinterval ", outfile);
  1397. X    }
  1398. X    else {
  1399. X      fputs("    { currentfile line readhexstring pop pop\n", outfile);
  1400. X      fprintf(outfile, "      0 1 %d { dup\n", ximage->width-1);
  1401. X      fputs("        line exch get greys exch get\n", outfile);
  1402. X      fputs("        line 3 1 roll put\n", outfile);
  1403. X      fputs("      } for\n", outfile);
  1404. X      fputs("      line\n", outfile);
  1405. X    }
  1406. X    fputs("    } image\n\n", outfile);
  1407. X
  1408. X    fputs("  } {  %% ifelse\n", outfile);
  1409. X    fputs("\n", outfile);
  1410. X
  1411. X    fprintf(outfile, "    %d %d %d", ximage->width, ximage->height,depth);
  1412. X    if (landscape)
  1413. X      fprintf(outfile, "  [0 %d %d 0 0 0]\n", ximage->width, ximage->height);
  1414. X    else
  1415. X      fprintf(outfile, "  [%d 0 0 -%d 0 %d]\n", ximage->width, ximage->height,
  1416. X                                                ximage->height);
  1417. X
  1418. X    fputs("    %% define a block of code to read and decode the input stream\n", outfile);
  1419. X    if (binary) {
  1420. X      fputs("    { rgbmap   currentfile read not { 0 } if   3 mul 3 getinterval \n", outfile);
  1421. X    }
  1422. X    else {
  1423. X      fputs("    { currentfile buffer readhexstring pop pop\n", outfile);
  1424. X      fputs("      rgbmap buffer 0 get 3 mul 3 getinterval   %% color bytes\n", outfile);
  1425. X    }
  1426. X    fputs("    }\n", outfile);
  1427. X    fputs("    false 3 colorimage\n", outfile);
  1428. X    fputs("  } ifelse\n", outfile);
  1429. X    fputs("} bind def\n", outfile);
  1430. X    fprintf(outfile, "\n\n\n");
  1431. X
  1432. X  }
  1433. X
  1434. X
  1435. X  /* write the rgb map */
  1436. X  fputs("%% get the rgb map\n", outfile);
  1437. X  fputs("currentfile rgbmap readhexstring\n", outfile);
  1438. X  for (x=0; x<image->numcells; x++)
  1439. X    fprintf(outfile, "%02.2x%02.2x%02.2x\n",
  1440. X                      (byte)((image->red[x]   >> 8) & 0xff),
  1441. X              (byte)((image->green[x] >> 8) & 0xff),
  1442. X              (byte)((image->blue[x]  >> 8) & 0xff) );
  1443. X  fputs("pop pop\n\n", outfile);
  1444. X
  1445. X
  1446. X  if (binary)
  1447. X    fprintf(outfile,"%%%%BeginBinary: %d\n",
  1448. X        encode ? rletotal+22+rletotal/IMAGE_CODEWIDTH
  1449. X        : ximage->height*ximage->width+22+
  1450. X          (ximage->height*ximage->width)/IMAGE_CODEWIDTH);
  1451. X
  1452. X  fputs("drawcolormappedimage\n", outfile);
  1453. X
  1454. X  /* write the map indexes */
  1455. X  rletotal = 0;
  1456. X  rlecount = 0;
  1457. X  firstSample = TRUE;
  1458. X  widthcount = 0;
  1459. X  for (y=0; y<ximage->height; y++) {
  1460. X    for (x=0, ptr=(byte *)(ximage->data+(y * ximage->bytes_per_line));
  1461. X        x<ximage->width;
  1462. X        x+=spb, ptr++) {
  1463. X      b = *ptr;
  1464. X      if (encode) {
  1465. X        if (firstSample || b != rlesample || rlecount==254) {
  1466. X      if (!firstSample) {
  1467. X        if (binary) {
  1468. X          putc((byte)rlecount,outfile);
  1469. X          putc((byte)rlesample,outfile);
  1470. X          widthcount += 2;
  1471. X        }
  1472. X        else {
  1473. X          fprintf(outfile, "%02.2x%02.2x", rlecount, rlesample);
  1474. X          widthcount += 4;
  1475. X        }
  1476. X        rletotal += 2;
  1477. X        if (widthcount >= IMAGE_CODEWIDTH) {
  1478. X          fputc('\n', outfile);
  1479. X          widthcount = 0;
  1480. X        }
  1481. X      }
  1482. X      else
  1483. X        firstSample = FALSE;
  1484. X      rlecount = 0;
  1485. X      rlesample = b;
  1486. X        }
  1487. X        else
  1488. X      rlecount++;
  1489. X      }
  1490. X      else {
  1491. X    if (binary) {
  1492. X      /* no width wrapping for non-encoded binary */
  1493. X      fputc((byte)b,outfile);
  1494. X    }
  1495. X    else {
  1496. X      fprintf(outfile, "%02.2x", b & 0xFF);
  1497. X      widthcount += 2;
  1498. X      if (widthcount >= IMAGE_CODEWIDTH) {
  1499. X        fputc('\n', outfile);
  1500. X        widthcount = 0;
  1501. X      }
  1502. X    }
  1503. X      }
  1504. X    }
  1505. X  }
  1506. X
  1507. X  if (encode) {
  1508. X    if (!firstSample) {
  1509. X      if (binary) {
  1510. X    fputc((byte)rlecount,outfile);
  1511. X    fputc((byte)rlesample,outfile);
  1512. X      }
  1513. X      else
  1514. X        fprintf(outfile, "%02.2x%02.2x\n", rlecount, rlesample);
  1515. X      rletotal += 2;
  1516. X    }
  1517. X  }
  1518. X  else
  1519. X    fputc('\n', outfile);
  1520. X  if (binary)
  1521. X    fprintf(outfile,"\n%%%%EndBinary\n");
  1522. X
  1523. X  /* print some statistics */
  1524. X  if (encode) {
  1525. X    fputs("\n%\n", outfile);
  1526. X    fprintf(outfile, "%% Run-length encoding savings = %5.1f%%\n",
  1527. X          100.0 - ((float)(rletotal) * 100.0 / (float)(ximage->height * bpl)));
  1528. X  }
  1529. X
  1530. X  fputs("\n%\n", outfile);
  1531. X  fputs("\ngrestore\nshowpage\n%%Trailer\n", outfile);
  1532. X}
  1533. X
  1534. X
  1535. X
  1536. X
  1537. X
  1538. X
  1539. X
  1540. X
  1541. X
  1542. X
  1543. X
  1544. X/*
  1545. X * Write an image in 'puzzle' format, suitable for loading with
  1546. X * "puzzle -picture".
  1547. X */
  1548. XwritePuzzle(image, outfile)
  1549. X  imageInfo *image;
  1550. X  FILE *outfile;
  1551. X{
  1552. X  XImage *ximage = image->ximage;
  1553. X  int nc, width, height, w, h, cidx;
  1554. X  dw swaptest = 1;
  1555. X
  1556. X  if (verbose)
  1557. X    fprintf(stderr, "%s: formatting Puzzle output\n", programName);
  1558. X
  1559. X  if (ximage->depth > 8) {
  1560. X    fprintf(stderr, "%s: Puzzle converter can't handle depth > 8 yet\n",
  1561. X            programName);
  1562. X    return;
  1563. X  }
  1564. X
  1565. X  nc     = image->numcells;
  1566. X  width  = ximage->width;
  1567. X  height = ximage->height;
  1568. X  if (*(char *)&swaptest) {
  1569. X    swapbytes(&width);
  1570. X    swapbytes(&height);
  1571. X  }
  1572. X  fwrite(&width, 4, 1, outfile);
  1573. X  fwrite(&height, 4, 1, outfile);
  1574. X  fputc(nc, outfile);
  1575. X  for (cidx=0; cidx<nc; cidx++) {
  1576. X    fputc(image->red[cidx]>>8,   outfile);
  1577. X    fputc(image->green[cidx]>>8, outfile);
  1578. X    fputc(image->blue[cidx]>>8,  outfile);
  1579. X  }
  1580. X  for (h=0; h<ximage->height; h++)
  1581. X    if (ximage->bits_per_pixel == 8)
  1582. X      fwrite(ximage->data+(h*ximage->bytes_per_line),ximage->width,1,outfile);
  1583. X    else
  1584. X      /* this won't work if depth > 8 */
  1585. X      for (w=0; w<ximage->width; w++)
  1586. X        fputc(XGetPixel(ximage, w, h), outfile);
  1587. X}
  1588. X
  1589. X
  1590. X
  1591. X
  1592. X
  1593. X
  1594. X
  1595. XwriteXWD(image, outfile, xyformat)
  1596. X  imageInfo *image;
  1597. X  FILE *outfile;
  1598. X  int xyformat;
  1599. X{
  1600. X  XImage   *ximage = image->ximage;
  1601. X  XWDFileHeader header;
  1602. X  Visual   *visual = DefaultVisual(hDisplay, hScreen);
  1603. X  XColor    color;
  1604. X  dw        visMask = (visual->red_mask
  1605. X                      | visual->green_mask
  1606. X                      | visual->blue_mask);
  1607. X  dw        swaptest = 1;
  1608. X  int       i, x, y, size;
  1609. X  byte      *ptr;
  1610. X  int        XYtoZ;
  1611. X  byte        b;
  1612. X  int        bc;
  1613. X
  1614. X  if (verbose)
  1615. X    fprintf(stderr, "%s: formatting xwd output\n", programName);
  1616. X
  1617. X  header.header_size    = (CARD32)(sizeof(header)+strlen(imageName)+1);
  1618. X  header.file_version   = (CARD32) XWD_FILE_VERSION;
  1619. X  XYtoZ = (ximage->depth==1 && !xyformat);
  1620. X  header.pixmap_format  = (CARD32)(ximage->depth>1? ZPixmap : (xyformat? XYPixmap : ZPixmap));
  1621. X  header.pixmap_depth   = (CARD32) (XYtoZ? 8 : ximage->depth);
  1622. X  header.pixmap_width   = (CARD32) ximage->width;
  1623. X  header.pixmap_height  = (CARD32) ximage->height;
  1624. X  header.xoffset        = (CARD32) ximage->xoffset;
  1625. X  header.byte_order     = (CARD32) ximage->byte_order;
  1626. X  header.bitmap_unit    = (CARD32) (XYtoZ ? 8 : ximage->bitmap_unit);
  1627. X  header.bitmap_bit_order = (CARD32) (XYtoZ ? MSBFirst : ximage->bitmap_bit_order);
  1628. X  size = XYtoZ ? ximage->bitmap_pad * 8 : ximage->bitmap_pad;
  1629. X  header.bitmap_pad     = (CARD32) size;
  1630. X  header.bits_per_pixel = (CARD32) XYtoZ? 8 : ximage->bits_per_pixel;
  1631. X  size = XYtoZ? ximage->width : ximage->bytes_per_line;
  1632. X  header.bytes_per_line = (CARD32)size;
  1633. X  header.visual_class   = (CARD32)visual->class;
  1634. X  header.red_mask       = (CARD32)visual->red_mask;
  1635. X  header.green_mask     = (CARD32)visual->green_mask;
  1636. X  header.blue_mask      = (CARD32)visual->blue_mask;
  1637. X  header.bits_per_rgb   = (CARD32)visual->bits_per_rgb;
  1638. X  header.colormap_entries = (CARD32)visual->map_entries;
  1639. X  /* ncolors should be image->numcells, but some programs seem to expect
  1640. X   * that it is == colormap_entries.  sigh */
  1641. X  header.ncolors        = header.colormap_entries;
  1642. X  header.window_width   = (CARD32)ximage->width;
  1643. X  header.window_height  = (CARD32)ximage->height;
  1644. X  header.window_x       = 0;
  1645. X  header.window_y       = 0;
  1646. X  header.window_bdrwidth = 0;
  1647. X
  1648. X  if (*(char *) &swaptest)
  1649. X    swapdws(&header, sizeof(header));
  1650. X
  1651. X  fwrite(&header, sizeof(header), 1, outfile);
  1652. X  fwrite(imageName, 1, strlen(imageName)+1, outfile);
  1653. X
  1654. X  if (*(char *) &swaptest)
  1655. X    swapdws(&header, sizeof(header));
  1656. X
  1657. X  for (i=0; i<image->numcells; i++) {
  1658. X    color.pixel = i;
  1659. X    color.red   = image->red[i];
  1660. X    color.green = image->green[i];
  1661. X    color.blue  = image->blue[i];
  1662. X    color.flags = visMask;
  1663. X    color.pad   = 0;
  1664. X    if (*(char *) &swaptest) {
  1665. X      swapdws(&color.pixel, sizeof(color.pixel));
  1666. X      swapwords(&color.red, 3 * sizeof(color.red)); /* assume g and b follow r */
  1667. X    }
  1668. X    fwrite(&color, sizeof(XColor), 1, outfile);
  1669. X  }
  1670. X
  1671. X  /* pad out with black entries */
  1672. X  color.red = color.green = color.blue = 0;
  1673. X  color.flags = visMask;
  1674. X  color.pad = 0;
  1675. X  for (i=image->numcells; i<visual->map_entries; i++) {
  1676. X    color.pixel = i;
  1677. X    if (*(char *) &swaptest)
  1678. X      swapdws(&color.pixel, sizeof(color.pixel));
  1679. X    fwrite(&color, sizeof(XColor), 1, outfile);
  1680. X  }
  1681. X
  1682. X  if (XYtoZ) {
  1683. X    for (y = 0; y < ximage->height; y++) {
  1684. X      for (x = 0; x < ximage->width; x++) {
  1685. X        b = XGetPixel(ximage, x, y);
  1686. X    fputc(b, outfile);
  1687. X      }
  1688. X    }
  1689. X  }
  1690. X  else {
  1691. X    if (ximage->depth == 1  &&  BlackPixel(hDisplay,hScreen) == 0) {
  1692. X      size = ximage->height * ximage->bytes_per_line;
  1693. X      for (i=0, ptr=&ximage->data[0]; i<size; i++, ptr++)
  1694. X        fputc(~(*ptr), outfile);
  1695. X    }
  1696. X    else
  1697. X      fwrite(ximage->data, ximage->height * ximage->bytes_per_line, 1, outfile);
  1698. X  }
  1699. X}
  1700. X
  1701. X
  1702. X
  1703. X
  1704. X
  1705. X/*
  1706. X * Write a monochrome image out in Bitmap format.  XWriteBitmapToFile
  1707. X * requires a Pixmap as input & we'd have to invent one before we could
  1708. X * use it.
  1709. X */
  1710. X
  1711. XwriteXYPixmap(image, outfile)
  1712. X  imageInfo *image;
  1713. X  FILE *outfile;
  1714. X{
  1715. X  XImage *ximage = image->ximage;
  1716. X  int w, h;
  1717. X  byte b, *line;
  1718. X  int lcount;
  1719. X  int reverse = BlackPixel(hDisplay, hScreen) == 0;
  1720. X  int swap    = ximage->bitmap_bit_order != LSBFirst;
  1721. X
  1722. X  if (verbose)
  1723. X    fprintf(stderr, "%s: formatting Bitmap output\n", programName);
  1724. X
  1725. X  if (ximage->depth != 1) {
  1726. X    fprintf(stderr, "%s: can't write polychrome images in XY bitmap format\n",
  1727. X      programName);
  1728. X    return;
  1729. X  }
  1730. X
  1731. X  fprintf(outfile, "#define %s_width %d\n",  imageName, ximage->width);
  1732. X  fprintf(outfile, "#define %s_height %d\n", imageName, ximage->height);
  1733. X  fprintf(outfile, "#define %s_x_hot 0\n",   imageName);
  1734. X  fprintf(outfile, "#define %s_y_hot 0\n",   imageName);
  1735. X  fprintf(outfile, "static char %s_bits[] = {\n", imageName);
  1736. X  lcount = 0;
  1737. X  fputs("  ", outfile);
  1738. X  for (h=0; h<ximage->height; h++) {
  1739. X    line = (byte *)(ximage->data + (h * ximage->bytes_per_line));
  1740. X    for (w=0; w<ximage->width; w+=8) {
  1741. X      b = line[w/8];
  1742. X      if (reverse) b = ~b;
  1743. X      if (swap)    b = swapbits(b);
  1744. X      fprintf(outfile, " 0x%02x", b);
  1745. X      if (h<ximage->height || w+8<ximage->width)
  1746. X        fputc(',', outfile);
  1747. X      lcount++;
  1748. X      if (lcount >= 12) {
  1749. X        fputs("\n  ", outfile);
  1750. X        lcount = 0;
  1751. X      }
  1752. X    }
  1753. X  }
  1754. X  fputs("  };\n", outfile);
  1755. X}
  1756. X
  1757. X
  1758. X
  1759. X
  1760. X
  1761. X
  1762. X
  1763. X
  1764. X/*
  1765. X * Write a color image out in Pixmap format.
  1766. X * Supported output formats are xpm1 (original xpm), xpm2  and xpm3
  1767. X */
  1768. XwriteZPixmap(xpmFormat, image, outfile)
  1769. X  imageInfo *image;
  1770. X  FILE *outfile;
  1771. X{
  1772. X  XImage *ximage = image->ximage;
  1773. X  int nc, width, height, w, h, cidx, cpp;
  1774. X  char mne[MAX_CELLS][3];
  1775. X
  1776. X  if (verbose) {
  1777. X    switch (xpmFormat) {
  1778. X    case 3:
  1779. X      fprintf(stderr, "%s: formatting XPM3 Pixmap output\n", programName);
  1780. X      break;
  1781. X    case 2:
  1782. X      fprintf(stderr, "%s: formatting XPM2 Pixmap output\n", programName);
  1783. X      break;
  1784. X    default:
  1785. X    case 1:
  1786. X      fprintf(stderr, "%s: formatting XPM output\n", programName);
  1787. X      break;
  1788. X    }
  1789. X  }
  1790. X
  1791. X  nc  = image->numcells;
  1792. X  cpp = image->numcells <= 26? 1 : 2;
  1793. X  switch (xpmFormat) {
  1794. X  case 3:
  1795. X    fprintf(outfile, "/* XPM */\nstatic char * %s_name [] = {\n\"%d %d %d %d\",\n",
  1796. X      imageName, ximage->width, ximage->height, image->numcells, cpp);
  1797. X    fputs("/* pixels*/\n", outfile);
  1798. X    break;
  1799. X  case 2:
  1800. X    fprintf(outfile, "! XPM2  \n%d %d %d %d\n", ximage->width,
  1801. X      ximage->height, image->numcells, cpp);
  1802. X    fputs("! pixels\n", outfile);
  1803. X    break;
  1804. X  case 1:
  1805. X  default:
  1806. X    fprintf(outfile, "#define %s_format 1\n",   imageName);
  1807. X    fprintf(outfile, "#define %s_width %d\n",   imageName, ximage->width);
  1808. X    fprintf(outfile, "#define %s_height %d\n",  imageName, ximage->height);
  1809. X    fprintf(outfile, "#define %s_ncolors %d\n", imageName, image->numcells);
  1810. X    fprintf(outfile, "#define %s_chars_per_pixel %d\n",     imageName, cpp);
  1811. X    fprintf(outfile, "static char * %s_colors[] = {\n", imageName);
  1812. X    break;
  1813. X  }
  1814. X
  1815. X  for (cidx=0; cidx<image->numcells; cidx++) {
  1816. X    if (cpp > 1) {
  1817. X      mne[cidx][0] = (char)(cidx / 10) + 'a';
  1818. X      mne[cidx][1] = (char)(cidx % 10) + '0';
  1819. X      mne[cidx][2] = '\0';
  1820. X    }
  1821. X    else {
  1822. X      mne[cidx][0] = (char)cidx + (cidx? 'A' : ' ');
  1823. X      mne[cidx][1] = '\0';
  1824. X    }
  1825. X    switch (xpmFormat) {
  1826. X    case 3:
  1827. X      fprintf(outfile, "\"%s\tc #%4.4x%4.4x%4.4x\",\n",mne[cidx],
  1828. X                image->red[cidx], image->green[cidx], image->blue[cidx]);
  1829. X      break;
  1830. X    case 2:
  1831. X      fprintf(outfile, "%s c #%4.4x%4.4x%4.4x\n", mne[cidx],
  1832. X                image->red[cidx], image->green[cidx], image->blue[cidx]);
  1833. X      break;
  1834. X    default:
  1835. X    case 1:
  1836. X      fprintf(outfile, "\"%s\", \"#%4.4x%4.4x%4.4x\"\n", mne[cidx],
  1837. X                image->red[cidx], image->green[cidx], image->blue[cidx]);
  1838. X      break;
  1839. X    }
  1840. X  }
  1841. X  if (xpmFormat == 1) {
  1842. X    fputs("} ;\n", outfile);
  1843. X    fprintf(outfile, "static char * %s_pixels[] = {\n", imageName);
  1844. X  }
  1845. X  for (h=0; h<ximage->height; h++) {
  1846. X    if (xpmFormat != 2)
  1847. X      fputs("\"", outfile);
  1848. X    for (w=0; w<ximage->width; w++)
  1849. X      fputs(mne[XGetPixel(ximage, w, h)], outfile);
  1850. X    if (xpmFormat == 2)
  1851. X      fputs("\n", outfile);
  1852. X    else
  1853. X      fputs("\",\n", outfile);
  1854. X  }
  1855. X  if (xpmFormat == 3)
  1856. X    fputs("};\n", outfile);
  1857. X  else if (xpmFormat != 2)
  1858. X    fputs("} ;\n", outfile);
  1859. X}
  1860. X
  1861. X
  1862. X
  1863. X
  1864. END_OF_FILE
  1865. if test 42884 -ne `wc -c <'xgrabsc.2_3/write.hc'`; then
  1866.     echo shar: \"'xgrabsc.2_3/write.hc'\" unpacked with wrong size!
  1867. fi
  1868. # end of 'xgrabsc.2_3/write.hc'
  1869. fi
  1870. echo shar: End of archive 1 \(of 5\).
  1871. cp /dev/null ark1isdone
  1872. MISSING=""
  1873. for I in 1 2 3 4 5 ; do
  1874.     if test ! -f ark${I}isdone ; then
  1875.     MISSING="${MISSING} ${I}"
  1876.     fi
  1877. done
  1878. if test "${MISSING}" = "" ; then
  1879.     echo You have unpacked all 5 archives.
  1880.     rm -f ark[1-9]isdone
  1881. else
  1882.     echo You still need to unpack the following archives:
  1883.     echo "        " ${MISSING}
  1884. fi
  1885. ##  End of shell archive.
  1886. exit 0
  1887.  
  1888. exit 0 # Just in case...
  1889. -- 
  1890.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1891. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1892.  "It's intuitively obvious to the |
  1893.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1894.