v12i054: xtiff, Part02/02
dan sears
dbs at kodak.enet.dec.com
Wed Apr 24 16:58:57 AEST 1991
Submitted-by: dbs at kodak.enet.dec.com (dan sears)
Posting-number: Volume 12, Issue 54
Archive-name: xtiff/part02
#!/bin/sh
# this is xtiff.02 (part 2 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file xtiff/athena/xtiff.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 2; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping xtiff/athena/xtiff.c'
else
echo 'x - continuing file xtiff/athena/xtiff.c'
sed 's/^X//' << 'SHAR_EOF' >> 'xtiff/athena/xtiff.c' &&
X }
};
X
Arg formArgs[] = {
X { XtNresizable, True }
};
X
Arg listArgs[] = {
X { XtNresizable, False },
X { XtNborderWidth, 0 },
X { XtNdefaultColumns, 3 },
X { XtNforceColumns, True },
X { XtNlist, (int) buttonStrings },
X { XtNnumberStrings, XtNumber(buttonStrings) },
X { XtNtop, XtChainTop },
X { XtNleft, XtChainLeft },
X { XtNbottom, XtChainTop },
X { XtNright, XtChainLeft }
};
X
Arg labelArgs[] = {
X { XtNresizable, False },
X { XtNwidth, 200 },
X { XtNborderWidth, 0 },
X { XtNjustify, XtJustifyLeft },
X { XtNtop, XtChainTop },
X { XtNleft, XtChainLeft },
X { XtNbottom, XtChainTop },
X { XtNright, XtChainLeft }
};
X
Arg imageArgs[] = {
X { XtNresizable, True },
X { XtNborderWidth, 0 },
X { XtNtop, XtChainTop },
X { XtNleft, XtChainLeft },
X { XtNbottom, XtChainTop },
X { XtNright, XtChainLeft }
};
X
XXtActionsRec actionsTable[] = {
X { "quit", QuitProc },
X { "next", NextProc },
X { "previous", PreviousProc },
X { "notifyresize", ResizeProc }
};
X
char translationsTable[] = "<Key>q: quit() \n \
X <Key>Q: quit() \n \
X <Key>p: previous() \n \
X <Key>P: previous() \n \
X <Key>n: next() \n \
X <Key>N: next() \n \
X <Configure>: notifyresize()";
X
/*
X * X data structures
X */
Colormap xColormap;
Display * xDisplay;
Pixmap xImagePixmap;
Visual * xVisual;
XXImage * xImage;
GC xWinGc;
int xImageDepth, xScreen, xRedMask, xGreenMask, xBlueMask,
X xOffset = 0, yOffset = 0, grabX = -1, grabY = -1;
X
/*
X * TIFF data structures
X */
TIFF * tfFile = NULL;
u_short tfBitsPerSample, tfSamplesPerPixel, tfPlanarConfiguration,
X tfPhotometricInterpretation, tfGrayResponseUnit,
X tfImageDepth, tfImageWidth, tfImageHeight, tfBytesPerRow;
int tfDirectory = 0, tfMultiPage = False;
double tfUnitMap, tfGrayResponseUnitMap[] = {
X -1, -10, -100, -1000, -10000, -100000
X };
X
/*
X * display data structures
X */
double dGamma, *dRed, *dGreen, *dBlue;
X
/*
X * shared data structures
X */
u_short * redMap = NULL, *greenMap = NULL, *blueMap = NULL,
X *grayMap = NULL, colormapSize;
u_char * imageMemory;
char * fileName;
X
void
main(argc, argv)
X int argc;
X char ** argv;
{
X XSetWindowAttributes window_attributes;
X Widget widget_list[3];
X Arg args[5];
X
X setbuf(stdout, NULL); setbuf(stderr, NULL);
X
X shellWidget = XtInitialize(argv[0], "XTiff", shellOptions,
X XtNumber(shellOptions), &argc, argv);
X
X XSetErrorHandler(XTiffErrorHandler);
X
X XtGetApplicationResources(shellWidget, &appData,
X clientResources, XtNumber(clientResources), NULL, 0);
X
X if ((argc <= 1) || (argc > 2) || appData.help)
X Usage();
X
X if (appData.verbose == False) {
X close(2); /* otherwise ignore libtiff error and warning messages */
X (void) open("/dev/null", O_WRONLY);
X }
X
X fileName = argv[1];
X
X xDisplay = XtDisplay(shellWidget);
X xScreen = DefaultScreen(xDisplay);
X
X OpenTIFFFile();
X GetTIFFHeader();
X SimpleGammaCorrection();
X GetVisual();
X GetTIFFImage();
X
X /*
X * Send visual, colormap, depth and iconPixmap to shellWidget.
X * Sending the visual to the shell is only possible with the advent of R4.
X */
X XtSetArg(args[0], XtNvisual, xVisual);
X XtSetArg(args[1], XtNcolormap, xColormap);
X XtSetArg(args[2], XtNdepth,
X xImageDepth == 1 ? DefaultDepth(xDisplay, xScreen) : xImageDepth);
X XtSetArg(args[3], XtNiconPixmap,
X XCreateBitmapFromData(xDisplay, RootWindow(xDisplay, xScreen),
X xtifficon_bits, xtifficon_width, xtifficon_height));
X XtSetArg(args[4], XtNallowShellResize, True);
X XtSetValues(shellWidget, args, 5);
X
X /*
X * widget instance hierarchy
X */
X formWidget = XtCreateManagedWidget("form", formWidgetClass,
X shellWidget, formArgs, XtNumber(formArgs));
X
X widget_list[0] = listWidget = XtCreateWidget("list",
X listWidgetClass, formWidget, listArgs, XtNumber(listArgs));
X
X widget_list[1] = labelWidget = XtCreateWidget("label",
X labelWidgetClass, formWidget, labelArgs, XtNumber(labelArgs));
X
X widget_list[2] = imageWidget = XtCreateWidget("image",
X widgetClass, formWidget, imageArgs, XtNumber(imageArgs));
X
X XtManageChildren(widget_list, XtNumber(widget_list));
X
X /*
X * initial widget sizes - for small images let xtiff size itself
X */
X if (tfImageWidth >= appData.viewportWidth) {
X XtSetArg(args[0], XtNwidth, appData.viewportWidth);
X XtSetValues(shellWidget, args, 1);
X }
X if (tfImageHeight >= appData.viewportHeight) {
X XtSetArg(args[0], XtNheight, appData.viewportHeight);
X XtSetValues(shellWidget, args, 1);
X }
X
X XtSetArg(args[0], XtNwidth, tfImageWidth);
X XtSetArg(args[1], XtNheight, tfImageHeight);
X XtSetValues(imageWidget, args, 2);
X
X /*
X * formWidget uses these constraints but they are stored in the children.
X */
X XtSetArg(args[0], XtNfromVert, listWidget);
X XtSetValues(imageWidget, args, 1);
X XtSetArg(args[0], XtNfromHoriz, listWidget);
X XtSetValues(labelWidget, args, 1);
X
X SetNameLabel();
X
X XtAddCallback(listWidget, XtNcallback, SelectProc, NULL);
X
X XtAddActions(actionsTable, XtNumber(actionsTable));
X XtSetArg(args[0], XtNtranslations,
X XtParseTranslationTable(translationsTable));
X XtSetValues(formWidget, &args[0], 1);
X XtSetValues(imageWidget, &args[0], 1);
X
X /*
X * This is intended to be a little faster than going through
X * the translation manager.
X */
X XtAddEventHandler(imageWidget, ExposureMask | ButtonPressMask
X | ButtonReleaseMask | Button1MotionMask | KeyPressMask,
X False, EventProc, NULL);
X
X XtRealizeWidget(shellWidget);
X
X window_attributes.cursor = XCreateFontCursor(xDisplay, XC_fleur);
X XChangeWindowAttributes(xDisplay, XtWindow(imageWidget),
X CWCursor, &window_attributes);
X
X CreateXImage();
X
X XtMainLoop();
}
X
void
OpenTIFFFile()
{
X if (tfFile != NULL)
X TIFFClose(tfFile);
X
X if ((tfFile = TIFFOpen(fileName, "r")) == NULL) {
X if (appData.verbose)
X fprintf(stderr, "xtiff: can't open %s as a TIFF file\n",
fileName);
X else
X fprintf(stdout, "xtiff: can't open %s as a TIFF file\n",
fileName);
X exit(0);
X }
X
X if (TIFFReadDirectory(tfFile) == True) {
X tfMultiPage = True;
X (void) TIFFSetDirectory(tfFile, tfDirectory = 0);
X } else
X tfMultiPage = False;
}
X
void
GetTIFFHeader()
{
X register int i;
X
X if (!TIFFSetDirectory(tfFile, tfDirectory)) {
X fprintf(stderr, "xtiff: can't seek to directory %d in %s\n",
X tfDirectory, fileName);
X exit(0);
X }
X
X TIFFGetField(tfFile, TIFFTAG_IMAGEWIDTH, &tfImageWidth);
X TIFFGetField(tfFile, TIFFTAG_IMAGELENGTH, &tfImageHeight);
X
X /*
X * If the following tags aren't present then use the TIFF
defaults.
X */
X if (!TIFFGetField(tfFile, TIFFTAG_BITSPERSAMPLE,
&tfBitsPerSample))
X tfBitsPerSample = 1;
X if (!TIFFGetField(tfFile, TIFFTAG_SAMPLESPERPIXEL,
&tfSamplesPerPixel))
X tfSamplesPerPixel = 1;
X if (!TIFFGetField(tfFile, TIFFTAG_PLANARCONFIG,
&tfPlanarConfiguration))
X tfPlanarConfiguration = PLANARCONFIG_CONTIG;
X if (!TIFFGetField(tfFile, TIFFTAG_GRAYRESPONSEUNIT,
&tfGrayResponseUnit))
X tfGrayResponseUnit = 2;
X
X tfUnitMap = tfGrayResponseUnitMap[tfGrayResponseUnit];
X colormapSize = 1 << tfBitsPerSample;
X tfImageDepth = tfBitsPerSample * tfSamplesPerPixel;
X
X dRed = (double *) malloc(colormapSize * sizeof(double));
X dGreen = (double *) malloc(colormapSize * sizeof(double));
X dBlue = (double *) malloc(colormapSize * sizeof(double));
X MCHECK(dRed); MCHECK(dGreen); MCHECK(dBlue);
X
X /*
X * If TIFFTAG_PHOTOMETRIC is not present then assign a reasonable
default.
X * The TIFF 5.0 specification doesn't give a default.
X */
X if (!TIFFGetField(tfFile, TIFFTAG_PHOTOMETRIC,
X &tfPhotometricInterpretation)) {
X if (tfSamplesPerPixel != 1)
X tfPhotometricInterpretation = PHOTOMETRIC_RGB;
X else if (tfBitsPerSample == 1)
X tfPhotometricInterpretation = PHOTOMETRIC_MINISBLACK;
X else if (TIFFGetField(tfFile, TIFFTAG_COLORMAP,
X &redMap, &greenMap, &blueMap)) {
X tfPhotometricInterpretation = PHOTOMETRIC_PALETTE;
X free(redMap); free(greenMap); free(blueMap);
X redMap = greenMap = blueMap = NULL;
X } else
X tfPhotometricInterpretation = PHOTOMETRIC_MINISBLACK;
X }
X
X /*
X * Given TIFFTAG_PHOTOMETRIC extract or create the response
curves.
X */
X switch (tfPhotometricInterpretation) {
X case PHOTOMETRIC_RGB:
X if (!TIFFGetField(tfFile, TIFFTAG_COLORRESPONSECURVE,
X &redMap, &greenMap, &blueMap)) {
X redMap = (u_short *) malloc(colormapSize *
sizeof(u_short));
X greenMap = (u_short *) malloc(colormapSize *
sizeof(u_short));
X blueMap = (u_short *) malloc(colormapSize *
sizeof(u_short));
X MCHECK(redMap); MCHECK(greenMap); MCHECK(blueMap);
X for (i = 0; i < colormapSize; i++)
X dRed[i] = dGreen[i] = dBlue[i]
X = (double) SCALE(i, colormapSize - 1);
X } else {
X CheckAndCorrectColormap();
X for (i = 0; i < colormapSize; i++) {
X dRed[i] = (double) redMap[i];
X dGreen[i] = (double) greenMap[i];
X dBlue[i] = (double) blueMap[i];
X }
X }
X break;
X case PHOTOMETRIC_PALETTE:
X if (!TIFFGetField(tfFile, TIFFTAG_COLORMAP,
X &redMap, &greenMap, &blueMap)) {
X redMap = (u_short *) malloc(colormapSize *
sizeof(u_short));
X greenMap = (u_short *) malloc(colormapSize *
sizeof(u_short));
X blueMap = (u_short *) malloc(colormapSize *
sizeof(u_short));
X MCHECK(redMap); MCHECK(greenMap); MCHECK(blueMap);
X for (i = 0; i < colormapSize; i++)
X dRed[i] = dGreen[i] = dBlue[i]
X = (double) SCALE(i, colormapSize - 1);
X } else {
X CheckAndCorrectColormap();
X for (i = 0; i < colormapSize; i++) {
X dRed[i] = (double) redMap[i];
X dGreen[i] = (double) greenMap[i];
X dBlue[i] = (double) blueMap[i];
X }
X }
X break;
X case PHOTOMETRIC_MINISWHITE:
X redMap = (u_short *) malloc(colormapSize * sizeof(u_short));
X greenMap = (u_short *) malloc(colormapSize * sizeof(u_short));
X blueMap = (u_short *) malloc(colormapSize * sizeof(u_short));
X MCHECK(redMap); MCHECK(greenMap); MCHECK(blueMap);
X if (!TIFFGetField(tfFile, TIFFTAG_GRAYRESPONSECURVE,
&grayMap))
X for (i = 0; i < colormapSize; i++)
X dRed[i] = dGreen[i] = dBlue[i]
X = (double) SCALE(colormapSize - 1 - i, colormapSize
- 1);
X else {
X dRed[colormapSize - 1] = dGreen[colormapSize - 1]
X = dBlue[colormapSize - 1] = 0;
X for (i = 0; i < colormapSize - 1; i++)
X dRed[i] = dGreen[i] = dBlue[i] = 65535.0 -
X (65535.0 * pow(10.0, (double) grayMap[i] /
tfUnitMap));
X }
X break;
X case PHOTOMETRIC_MINISBLACK:
X redMap = (u_short *) malloc(colormapSize * sizeof(u_short));
X greenMap = (u_short *) malloc(colormapSize * sizeof(u_short));
X blueMap = (u_short *) malloc(colormapSize * sizeof(u_short));
X MCHECK(redMap); MCHECK(greenMap); MCHECK(blueMap);
X if (!TIFFGetField(tfFile, TIFFTAG_GRAYRESPONSECURVE,
&grayMap))
X for (i = 0; i < colormapSize; i++) {
X dRed[i] = dGreen[i] = dBlue[i]
X = (double) SCALE(i, colormapSize - 1);
X }
X else {
X dRed[0] = dGreen[0] = dBlue[0] = 0;
X for (i = 1; i < colormapSize; i++)
X dRed[i] = dGreen[i] = dBlue[i] =
X (65535.0 * pow(10.0, (double) grayMap[i] /
tfUnitMap));
X }
X break;
X default:
X fprintf(stderr,
X "xtiff: can't display photometric interpretation type
%d\n",
X tfPhotometricInterpretation);
X exit(0);
X }
}
X
void
SetNameLabel()
{
X char buffer[BUFSIZ];
X Arg args[1];
X
X if (tfMultiPage)
X sprintf(buffer, "%s - page %d", fileName, tfDirectory);
X else
X strcpy(buffer, fileName);
X XtSetArg(args[0], XtNlabel, buffer);
X XtSetValues(labelWidget, args, 1);
}
X
/*
X * Many programs get TIFF colormaps wrong. They use 8-bit colormaps
instead of
X * 16-bit colormaps. This function is a heuristic to detect and
correct this.
X */
void
CheckAndCorrectColormap()
{
X register int i;
X
X for (i = 0; i < colormapSize; i++)
X if ((redMap[i] > 255) || (greenMap[i] > 255) || (blueMap[i] >
255))
X return;
X
X for (i = 0; i < colormapSize; i++) {
X redMap[i] = SCALE(redMap[i], 255);
X greenMap[i] = SCALE(greenMap[i], 255);
X blueMap[i] = SCALE(blueMap[i], 255);
X }
}
X
void
SimpleGammaCorrection()
{
X register int i;
X
X dGamma = appData.gamma;
X
X for (i = 0; i < colormapSize; i++) {
X if (((tfPhotometricInterpretation == PHOTOMETRIC_MINISWHITE)
X && (i == colormapSize - 1))
X || ((tfPhotometricInterpretation ==
PHOTOMETRIC_MINISBLACK)
X && (i == 0)))
X redMap[i] = greenMap[i] = blueMap[i] = 0;
X else {
X redMap[i] = ROUND((pow(dRed[i] / 65535.0, 1.0 / dGamma) *
65535.0));
X greenMap[i] = ROUND((pow(dGreen[i] / 65535.0, 1.0 / dGamma)
* 65535.0));
X blueMap[i] = ROUND((pow(dBlue[i] / 65535.0, 1.0 / dGamma) *
65535.0));
X }
X }
X
X free(dRed); free(dGreen); free(dBlue);
}
X
/*
X * Current limitation: the visual is set initially by the first file.
X * It cannot be changed.
X */
void
GetVisual()
{
X register XColor *colors = NULL;
X register u_long *pixels = NULL;
X register int i;
X
X switch (tfImageDepth) {
X /*
X * X really wants a 32-bit image with the fourth channel unused,
X * but the visual structure thinks it's 24-bit. bitmap_unit is
32.
X */
X case 32:
X case 24:
X if (SearchVisualList(24, DirectColor, &xVisual) == False) {
X fprintf(stderr, "xtiff: 24-bit DirectColor visual not
available\n");
X exit(0);
X }
X
X colors = (XColor *) malloc(3 * colormapSize * sizeof(XColor));
X MCHECK(colors);
X
X for (i = 0; i < colormapSize; i++) {
X colors[i].pixel = (u_long) (i << 16) + (i << 8) + i;
X colors[i].red = redMap[i];
X colors[i].green = greenMap[i];
X colors[i].blue = blueMap[i];
X colors[i].flags = DoRed | DoGreen | DoBlue;
X }
X
X xColormap = XCreateColormap(xDisplay, RootWindow(xDisplay,
xScreen),
X xVisual, AllocAll);
X XStoreColors(xDisplay, xColormap, colors, colormapSize);
X break;
X case 8:
X case 4:
X case 2:
X /*
X * We assume that systems with 24-bit visuals also have 8-bit
visuals.
X * We don't promote from 8-bit PseudoColor to 24/32 bit
DirectColor.
X */
X switch (tfPhotometricInterpretation) {
X case PHOTOMETRIC_MINISWHITE:
X case PHOTOMETRIC_MINISBLACK:
X if (SearchVisualList((int) tfImageDepth, GrayScale,
&xVisual) == True)
X break;
X case PHOTOMETRIC_PALETTE:
X if (SearchVisualList((int) tfImageDepth, PseudoColor,
&xVisual) == True)
X break;
X default:
X fprintf(stderr, "xtiff: Unsupported TIFF/X
configuration\n");
X exit(0);
X }
X
X colors = (XColor *) malloc(colormapSize * sizeof(XColor));
X MCHECK(colors);
X
X for (i = 0; i < colormapSize; i++) {
X colors[i].pixel = (u_long) i;
X colors[i].red = redMap[i];
X colors[i].green = greenMap[i];
X colors[i].blue = blueMap[i];
X colors[i].flags = DoRed | DoGreen | DoBlue;
X }
X
X /*
X * xtiff's colormap allocation is private. It does not
attempt
X * to detect whether any existing colormap entries are
suitable
X * for its use. This will cause colormap flashing.
Furthermore,
X * background and foreground are taken from the environment.
X * For example, the foreground color may be red when the
visual
X * is GrayScale. If the colormap is completely populated,
X * Xt will not be able to allocate fg and bg.
X */
X if (tfImageDepth == 8)
X xColormap = XCreateColormap(xDisplay, RootWindow(xDisplay,
xScreen),
X xVisual, AllocAll);
X else {
X xColormap = XCreateColormap(xDisplay, RootWindow(xDisplay,
xScreen),
X xVisual, AllocNone);
X pixels = (u_long *) malloc(colormapSize * sizeof(u_long));
X MCHECK(pixels);
X (void) XAllocColorCells(xDisplay, xColormap, True,
X NULL, 0, pixels, colormapSize);
X free(pixels);
X }
X XStoreColors(xDisplay, xColormap, colors, colormapSize);
X break;
X case 1:
X xImageDepth = 1;
X xVisual = DefaultVisual(xDisplay, xScreen);
X xColormap = DefaultColormap(xDisplay, xScreen);
X break;
X default:
X fprintf(stderr, "xtiff: unsupported image depth %d\n",
tfImageDepth);
X exit(0);
X }
X
X if (colors != NULL)
X free(colors);
X if (grayMap != NULL)
X free(grayMap);
X if (redMap != NULL)
X free(redMap);
X if (greenMap != NULL)
X free(greenMap);
X if (blueMap != NULL)
X free(blueMap);
X
X colors = NULL; grayMap = redMap = greenMap = blueMap = NULL;
}
X
Boolean
SearchVisualList(image_depth, visual_class, visual)
X int image_depth, visual_class;
X Visual **visual;
{
X XVisualInfo template_visual, *visual_list;
X int i, n_visuals;
X
X template_visual.screen = xScreen;
X visual_list = XGetVisualInfo(xDisplay, VisualScreenMask,
X &template_visual, &n_visuals);
X
X if (n_visuals == 0) {
X fprintf(stderr, "xtiff: visual list not available\n");
X exit(0);
X }
X
X for (i = 0; i < n_visuals; visual_list++, i++) {
X if ((visual_list->class == visual_class)
X && (visual_list->depth >= image_depth)) {
X *visual = visual_list->visual;
X xImageDepth = visual_list->depth;
X xRedMask = visual_list->red_mask;
X xGreenMask = visual_list->green_mask;
X xBlueMask = visual_list->blue_mask;
X XFree((char *) visual_list);
X return True;
X }
X }
X
X XFree((char *) visual_list);
X return False;
}
X
void
GetTIFFImage()
{
X int pixel_map[3], red_shift, green_shift, blue_shift;
X register u_char *scan_line, *output_p, *input_p;
X register int i, j, s;
X
X scan_line = (u_char *) malloc(tfBytesPerRow =
TIFFScanlineSize(tfFile));
X MCHECK(scan_line);
X
X if ((tfImageDepth == 32) || (tfImageDepth == 24)) {
X output_p = imageMemory = (u_char *)
X malloc(tfImageWidth * tfImageHeight * 4);
X MCHECK(imageMemory);
X
X /*
X * Handle different color masks for different frame buffers.
X */
X if (ImageByteOrder(xDisplay) == LSBFirst) { /* DECstation 5000
*/
X red_shift = pixel_map[0] = xRedMask == 0xFF000000 ? 3
X : (xRedMask == 0xFF0000 ? 2 : (xRedMask == 0xFF00 ? 1 :
0));
X green_shift = pixel_map[1] = xGreenMask == 0xFF000000 ? 3
X : (xGreenMask == 0xFF0000 ? 2 : (xGreenMask == 0xFF00 ?
1 : 0));
X blue_shift = pixel_map[2] = xBlueMask == 0xFF000000 ? 3
X : (xBlueMask == 0xFF0000 ? 2 : (xBlueMask == 0xFF00 ? 1
: 0));
X } else { /* Ardent */
X red_shift = pixel_map[0] = xRedMask == 0xFF000000 ? 0
X : (xRedMask == 0xFF0000 ? 1 : (xRedMask == 0xFF00 ? 2 :
3));
X green_shift = pixel_map[0] = xGreenMask == 0xFF000000 ? 0
X : (xGreenMask == 0xFF0000 ? 1 : (xGreenMask == 0xFF00 ?
2 : 3));
X blue_shift = pixel_map[0] = xBlueMask == 0xFF000000 ? 0
X : (xBlueMask == 0xFF0000 ? 1 : (xBlueMask == 0xFF00 ? 2
: 3));
X }
X
X if (tfPlanarConfiguration == PLANARCONFIG_CONTIG) {
X for (i = 0; i < tfImageHeight; i++) {
X if (TIFFReadScanline(tfFile, scan_line, i, 0) < 0)
X break;
X for (input_p = scan_line, j = 0; j < tfImageWidth; j++)
{
X *(output_p + red_shift) = *input_p++;
X *(output_p + green_shift) = *input_p++;
X *(output_p + blue_shift) = *input_p++;
X output_p += 4;
X if (tfSamplesPerPixel == 4) /* skip the fourth
channel */
X input_p++;
X }
X }
X } else {
X for (s = 0; s < tfSamplesPerPixel; s++) {
X if (s == 3) /* skip the fourth channel */
X continue;
X for (i = 0; i < tfImageHeight; i++) {
X if (TIFFReadScanline(tfFile, scan_line, i, s) < 0)
X break;
X input_p = scan_line;
X output_p = imageMemory + (i*tfImageWidth*4) +
pixel_map[s];
X for (j = 0; j < tfImageWidth; j++, output_p += 4)
X *output_p = *input_p++;
X }
X }
X }
X } else {
X if (xImageDepth == tfImageDepth) {
X output_p = imageMemory = (u_char *)
X malloc(tfBytesPerRow * tfImageHeight);
X MCHECK(imageMemory);
X
X for (i = 0; i < tfImageHeight; i++, output_p +=
tfBytesPerRow)
X if (TIFFReadScanline(tfFile, output_p, i, 0) < 0)
X break;
X } else if ((xImageDepth == 8) && (tfImageDepth == 4)) {
X output_p = imageMemory = (u_char *)
X malloc(tfBytesPerRow * 2 * tfImageHeight + 2);
X MCHECK(imageMemory);
X
X /*
X * If a scanline is of odd size the inner loop below will
overshoot.
X * This is handled very simply by recalculating the start
point at
X * each scanline and padding imageMemory a little at the
end.
X */
X for (i = 0; i < tfImageHeight; i++) {
X if (TIFFReadScanline(tfFile, scan_line, i, 0) < 0)
X break;
X output_p = &imageMemory[i * tfImageWidth];
X input_p = scan_line;
X for (j = 0; j < tfImageWidth; j += 2, input_p++) {
X *output_p++ = *input_p >> 4;
X *output_p++ = *input_p & 0xf;
X }
X }
X } else if ((xImageDepth == 8) && (tfImageDepth == 2)) {
X output_p = imageMemory = (u_char *)
X malloc(tfBytesPerRow * 4 * tfImageHeight + 4);
X MCHECK(imageMemory);
X
X for (i = 0; i < tfImageHeight; i++) {
X if (TIFFReadScanline(tfFile, scan_line, i, 0) < 0)
X break;
X output_p = &imageMemory[i * tfImageWidth];
X input_p = scan_line;
X for (j = 0; j < tfImageWidth; j += 4, input_p++) {
X *output_p++ = *input_p >> 6;
X *output_p++ = (*input_p >> 4) & 3;
X *output_p++ = (*input_p >> 2) & 3;
X *output_p++ = *input_p & 3;
X }
X }
X } else if ((xImageDepth == 4) && (tfImageDepth == 2)) {
X output_p = imageMemory = (u_char *)
X malloc(tfBytesPerRow * 2 * tfImageHeight + 2);
X MCHECK(imageMemory);
X
X for (i = 0; i < tfImageHeight; i++) {
X if (TIFFReadScanline(tfFile, scan_line, i, 0) < 0)
X break;
X output_p = &imageMemory[i * tfImageWidth];
X input_p = scan_line;
X for (j = 0; j < tfImageWidth; j += 4, input_p++) {
X *output_p++ = ((*input_p>>6) << 4) | ((*input_p >>
4) & 3);
X *output_p++ = (((*input_p>>2) & 3) << 4) |
(*input_p & 3);
X }
X }
X } else {
X fprintf(stderr,
X "xtiff: can't handle %d-bit TIFF file on an %d-bit
display\n",
X tfImageDepth, xImageDepth);
X exit(0);
X }
X }
X
X free(scan_line);
}
X
void
CreateXImage()
{
X XGCValues gc_values;
X GC bitmap_gc;
X
X xOffset = yOffset = 0;
X grabX = grabY = -1;
X
X xImage = XCreateImage(xDisplay, xVisual, xImageDepth,
X xImageDepth == 1 ? XYBitmap : ZPixmap, /* offset */ 0,
X (char *) imageMemory, tfImageWidth, tfImageHeight,
X /* bitmap_pad */ 8, /* bytes_per_line */ 0);
X
X /*
X * libtiff converts LSB data into MSB but doesn't change the
FillOrder tag.
X */
X if (xImageDepth == 1)
X xImage->bitmap_bit_order = MSBFirst;
X if (xImageDepth <= 8)
X xImage->byte_order = MSBFirst;
X
X /*
X * create an appropriate GC
X */
X gc_values.function = GXcopy;
X gc_values.plane_mask = AllPlanes;
X if (tfPhotometricInterpretation == PHOTOMETRIC_MINISBLACK) {
X gc_values.foreground = XWhitePixel(xDisplay, xScreen);
X gc_values.background = XBlackPixel(xDisplay, xScreen);
X } else {
X gc_values.foreground = XBlackPixel(xDisplay, xScreen);
X gc_values.background = XWhitePixel(xDisplay, xScreen);
X }
X xWinGc = XCreateGC(xDisplay, XtWindow(shellWidget),
X GCFunction | GCPlaneMask | GCForeground | GCBackground,
&gc_values);
X
X /*
X * create the pixmap and load the image
X */
X if (appData.usePixmap == True) {
X xImagePixmap = XCreatePixmap(xDisplay, RootWindow(xDisplay,
xScreen),
X xImage->width, xImage->height, xImageDepth);
X
X /*
X * According to the O'Reilly X Protocol Reference Manual, page
53,
X * "A pixmap depth of one is always supported and listed, but
windows
X * of depth one might not be supported." Therefore we create a
pixmap
X * of depth one and use XCopyPlane(). This is idiomatic.
X */
X if (xImageDepth == 1) { /* just pass the bits through
*/
X gc_values.foreground = 1; /* foreground describes set
bits */
X gc_values.background = 0; /* background describes clear
bits */
X bitmap_gc = XCreateGC(xDisplay, xImagePixmap,
X GCForeground | GCBackground, &gc_values);
X XPutImage(xDisplay, xImagePixmap, bitmap_gc, xImage,
X 0, 0, 0, 0, xImage->width, xImage->height);
X } else
X XPutImage(xDisplay, xImagePixmap, xWinGc, xImage,
X 0, 0, 0, 0, xImage->width, xImage->height);
X XDestroyImage(xImage);
X }
}
X
XXtCallbackProc
SelectProc(w, unused_1, unused_2)
X Widget w;
X caddr_t unused_1;
X caddr_t unused_2;
{
X XawListReturnStruct *list_return;
X
X list_return = XawListShowCurrent(w);
X
X switch (list_return->list_index) {
X case ButtonQuit:
X QuitProc();
X break;
X case ButtonPreviousPage:
X PreviousProc();
X break;
X case ButtonNextPage:
X NextProc();
X break;
X default:
X fprintf(stderr, "error in SelectProc\n");
X exit(0);
X }
X XawListUnhighlight(w);
}
X
void
QuitProc(void)
{
X exit(0);
}
X
void
NextProc()
{
X PageProc(ButtonNextPage);
}
X
void
PreviousProc()
{
X PageProc(ButtonPreviousPage);
}
X
void
PageProc(direction)
X int direction;
{
X XEvent fake_event;
X Arg args[4];
X
X switch (direction) {
X case ButtonPreviousPage:
X if (tfDirectory > 0)
X TIFFSetDirectory(tfFile, --tfDirectory);
X else
X return;
X break;
X case ButtonNextPage:
X if (TIFFReadDirectory(tfFile) == True)
X tfDirectory++;
X else
X return;
X break;
X default:
X fprintf(stderr, "error in PageProc\n");
X exit(0);
X }
X
X xOffset = yOffset = 0;
X grabX = grabY = -1;
X
X GetTIFFHeader();
X SetNameLabel();
X GetTIFFImage();
X
X if (appData.usePixmap == True)
X XFreePixmap(xDisplay, xImagePixmap);
X else
X XDestroyImage(xImage);
X
X CreateXImage();
X
X /*
X * Using XtSetValues() to set the widget size causes a resize.
X * This resize gets propagated up to the parent shell.
X * In order to disable this visually disconcerting effect,
X * shell resizing is temporarily disabled.
X */
X XtSetArg(args[0], XtNallowShellResize, False);
X XtSetValues(shellWidget, args, 1);
X
X XtSetArg(args[0], XtNwidth, tfImageWidth);
X XtSetArg(args[1], XtNheight, tfImageHeight);
X XtSetValues(imageWidget, args, 2);
X
X XtSetArg(args[0], XtNallowShellResize, True);
X XtSetValues(shellWidget, args, 1);
X
X XClearWindow(xDisplay, XtWindow(imageWidget));
X
X fake_event.type = Expose;
X fake_event.xexpose.x = fake_event.xexpose.y = 0;
X fake_event.xexpose.width = tfImageWidth; /* the window will clip
*/
X fake_event.xexpose.height = tfImageHeight;
X EventProc(imageWidget, NULL, &fake_event);
}
X
void
EventProc(widget, unused, event)
X Widget widget;
X caddr_t unused;
X XEvent *event;
{
X int ih, iw, ww, wh, sx, sy, w, h, dx, dy;
X Dimension w_width, w_height;
X XEvent next_event;
X Arg args[2];
X
X if (event->type == MappingNotify) {
X XRefreshKeyboardMapping((XMappingEvent *) event);
X return;
X }
X
X if (!XtIsRealized(widget))
X return;
X
X if ((event->type == ButtonPress) || (event->type ==
ButtonRelease))
X if (event->xbutton.button != Button1)
X return;
X
X iw = tfImageWidth; /* avoid sign problems */
X ih = tfImageHeight;
X
X /*
X * The grabX and grabY variables record where the user grabbed the
image.
X * They also record whether the mouse button is down or not.
X */
X if (event->type == ButtonPress) {
X grabX = event->xbutton.x;
X grabY = event->xbutton.y;
X return;
X }
X
X /*
X * imageWidget is a Core widget and doesn't get resized.
X * So we calculate the size of its viewport here.
X */
X XtSetArg(args[0], XtNwidth, &w_width);
X XtSetArg(args[1], XtNheight, &w_height);
X XtGetValues(shellWidget, args, 2);
X ww = w_width;
X wh = w_height;
X XtGetValues(listWidget, args, 2);
X wh -= w_height;
X
X switch (event->type) {
X case Expose:
X dx = event->xexpose.x;
X dy = event->xexpose.y;
X sx = dx + xOffset;
X sy = dy + yOffset;
X w = MIN(event->xexpose.width, iw);
X h = MIN(event->xexpose.height, ih);
X break;
X case KeyPress:
X if ((grabX >= 0) || (grabY >= 0)) /* Mouse button is still down
*/
X return;
X switch (XLookupKeysym((XKeyEvent *) event, /* KeySyms index */
0)) {
X case XK_Up:
X if (ih < wh) /* Don't scroll if the window fits the
image. */
X return;
X sy = yOffset + appData.translate;
X sy = MIN(ih - wh, sy);
X if (sy == yOffset) /* Filter redundant stationary
refreshes. */
X return;
X yOffset = sy;
X sx = xOffset;
X dx = dy = 0;
X w = ww; h = wh;
X break;
X case XK_Down:
X if (ih < wh)
X return;
X sy = yOffset - appData.translate;
X sy = MAX(sy, 0);
X if (sy == yOffset)
X return;
X yOffset = sy;
X sx = xOffset;
X dx = dy = 0;
X w = ww; h = wh;
X break;
X case XK_Left:
X if (iw < ww)
X return;
X sx = xOffset + appData.translate;
X sx = MIN(iw - ww, sx);
X if (sx == xOffset)
X return;
X xOffset = sx;
X sy = yOffset;
X dx = dy = 0;
X w = ww; h = wh;
X break;
X case XK_Right:
X if (iw < ww)
X return;
X sx = xOffset - appData.translate;
X sx = MAX(sx, 0);
X if (sx == xOffset)
X return;
X xOffset = sx;
X sy = yOffset;
X dx = dy = 0;
X w = ww; h = wh;
X break;
X default:
X return;
X }
X break;
X case MotionNotify:
X /*
X * MotionEvent compression. Ignore multiple motion events.
X * Ignore motion events if the mouse button is up.
X */
X if (XPending(xDisplay)) /* Xlib doesn't flush the output buffer
*/
X if (XtPeekEvent(&next_event))
X if (next_event.type == MotionNotify)
X return;
X if ((grabX < 0) || (grabY < 0))
X return;
X sx = xOffset + grabX - (int) event->xmotion.x;
X if (sx >= (iw - ww)) /* clamp x motion but allow y motion
*/
X sx = iw - ww;
X sx = MAX(sx, 0);
X sy = yOffset + grabY - (int) event->xmotion.y;
X if (sy >= (ih - wh)) /* clamp y motion but allow x motion */
X sy = ih - wh;
X sy = MAX(sy, 0);
X if ((sx == xOffset) && (sy == yOffset))
X return;
X dx = dy = 0;
X w = ww; h = wh;
X break;
X case ButtonRelease:
X xOffset = xOffset + grabX - (int) event->xbutton.x;
X xOffset = MIN(iw - ww, xOffset);
X xOffset = MAX(xOffset, 0);
X yOffset = yOffset + grabY - (int) event->xbutton.y;
X yOffset = MIN(ih - wh, yOffset);
X yOffset = MAX(yOffset, 0);
X grabX = grabY = -1;
X default:
X return;
X }
X
X if (appData.usePixmap == True) {
X if (xImageDepth == 1)
X XCopyPlane(xDisplay, xImagePixmap, XtWindow(widget),
X xWinGc, sx, sy, w, h, dx, dy, 1);
X else
X XCopyArea(xDisplay, xImagePixmap, XtWindow(widget),
X xWinGc, sx, sy, w, h, dx, dy);
X } else
X XPutImage(xDisplay, XtWindow(widget), xWinGc, xImage,
X sx, sy, dx, dy, w, h);
}
X
void
ResizeProc()
{
X Dimension w_width, w_height;
X int xo, yo, ww, wh;
X XEvent fake_event;
X Arg args[2];
X
X if ((xOffset == 0) && (yOffset == 0))
X return;
X
X XtSetArg(args[0], XtNwidth, &w_width);
X XtSetArg(args[1], XtNheight, &w_height);
X XtGetValues(shellWidget, args, 2);
X ww = w_width;
X wh = w_height;
X XtGetValues(listWidget, args, 2);
X wh -= w_height;
X
X xo = xOffset; yo = yOffset;
X
X if ((xOffset + ww) >= tfImageWidth)
X xOffset = MAX((int) tfImageWidth - ww, 0);
X if ((yOffset + wh) >= tfImageHeight)
X yOffset = MAX((int) tfImageHeight - wh, 0);
X
X /*
X * Send an ExposeEvent if the origin changed.
X * We have to do this because of the use and semantics of bit
gravity.
X */
X if ((xo != xOffset) || (yo != yOffset)) {
X fake_event.type = Expose;
X fake_event.xexpose.x = fake_event.xexpose.y = 0;
X fake_event.xexpose.width = tfImageWidth;
X fake_event.xexpose.height = tfImageHeight;
X EventProc(imageWidget, NULL, &fake_event);
X }
}
X
int
XXTiffErrorHandler(display, error_event)
X Display *display;
X XErrorEvent *error_event;
{
X char message[80];
X
X /*
X * Some X servers limit the size of pixmaps.
X */
X if ((error_event->error_code == BadAlloc)
X && (error_event->request_code == X_CreatePixmap))
X fprintf(stderr, "xtiff: requested pixmap too big for
display\n");
X else {
X XGetErrorText(display, error_event->error_code, message, 80);
X fprintf(stderr, "xtiff: error code %s\n", message);
X }
X
X exit(0);
}
X
void
Usage()
{
X fprintf(stderr, "Usage xtiff: [options] tiff-file\n");
X fprintf(stderr, "\tstandard Xt options\n");
X fprintf(stderr, "\t[-help]\n");
X fprintf(stderr, "\t[-gamma gamma]\n");
X fprintf(stderr, "\t[-usePixmap (True | False)]\n");
X fprintf(stderr, "\t[-viewportWidth pixels]\n");
X fprintf(stderr, "\t[-viewportHeight pixels]\n");
X fprintf(stderr, "\t[-translate pixels]\n");
X fprintf(stderr, "\t[-verbose (True | False)]\n");
X exit(0);
}
SHAR_EOF
echo 'File xtiff/athena/xtiff.c is complete' &&
chmod 0644 xtiff/athena/xtiff.c ||
echo 'restore of xtiff/athena/xtiff.c failed'
Wc_c="`wc -c < 'xtiff/athena/xtiff.c'`"
test 42696 -eq "$Wc_c" ||
echo 'xtiff/athena/xtiff.c: original size 42696, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= xtiff/athena/xtiff.man ==============
if test -f 'xtiff/athena/xtiff.man' -a X"$1" != X"-c"; then
echo 'x - skipping xtiff/athena/xtiff.man (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting xtiff/athena/xtiff.man (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xtiff/athena/xtiff.man' &&
.TH XTIFF 1 "December 20, 1990" "X Version 11"
.SH NAME
xtiff \- view a TIFF file in an X window
.SH SYNOPSIS
.B xtiff
[
.IR "standard Xt options"
]
[
.IR "\-gamma gamma"
]
[
.IR "\-usePixmap (False | True)"
]
[
.IR "\-viewportWidth pixels"
]
[
.IR "\-viewportHeight pixels"
]
[
.IR "\-translate pixels"
]
[
.IR "\-verbose (False | True)"
]
.IR file
.SH DESCRIPTION
.IR xtiff
is a TIFF viewer for X based on the
.IR libtiff (3)
package.
It displays a TIFF file in an X window
that can be resized and panned.
On appropriate display hardware
it can handle 24-bit RGB color TIFF files,
8, 4 and 2-bit palette color TIFF files
and 8, 4, 2 and 1-bit grayscale TIFF files.
The
.IR Next
and
.IR Previous
buttons allow the user to view different pages
in a multi-page TIFF file.
.PP
If the image is larger than the window,
you can pan around the image with the mouse or arrow keys.
Grab the image by pressing down
and holding the left mouse button
and then drag the mouse
to expose a different region of the image.
The arrow keys provide another method for moving
a large image inside a smaller window.
.PP
.IR xtiff
manages the negotiation between the needs of an image
and the visual capabilities made available by an X server.
If necessary,
it will promote an image to a deeper visual,
but it will not demote an image by quantizing and/or dithering.
In that case it will fail to display the image.
.PP
.IR xtiff
reads the
.IR "Gray Response Curve" ,
.IR "Gray Response Unit"
and
.IR "Color Response Curve"
tags in a TIFF file.
The data in these tags describe gamma compensation or image companding.
Together with the
.IR \-gamma
option or the NTSC default gamma value of 2.2,
the image will be gamma corrected and displayed.
.PP
For example, if a TIFF file has been prepared for a typical display,
it has a gamma compensation of 2.2 built into either the image
or preferably the
.IR "Color Response Curve"
tag.
This is a device-dependent image and,
in this case, the value for the
.IR \-gamma
command line option should be 1.0.
If the
.IR "Color Response Curve"
tag describes a companded but otherwise device-independent image
then the command line gamma should be set according to the monitor.
.PP
Unfortunately there is no way of knowing a priori whether or not
an image is device-independent without knowing its ancestry.
If the image conforms to the TIFF 5.0 specification
it should be device-independent;
but many scanner and image processing programs
do not adhere rigorously to the standard.
.SH BUTTONS AND KEYS
By default,
.IR xtiff
has certain buttons and keys bound to certain functions.
.TP 8
.B Left Mouse Button
Drags the image around the window.
.TP 8
.B N \fRor\fP n
Identical to the
.IR Next
function.
.TP 8
.B N \fRor\fP n
Identical to the
.IR Previous
function.
.TP 8
.B Q \fRor\fP q
Identical to the
.IR Quit
function.
.TP 8
.B arrow keys
Pressing one of the arrow keys translates the image
by an amount specified by the
.IR translate
option.
.SH OPTIONS
All options are resources and can be set
by either the command line or the
.IR \&.Xdefaults
file.
.TP 8
.B -gamma gamma
Specifies the value used
to build compensation tables
for simple gamma correction.
.TP 8
.B -usePixmap (False | True)
Indicates that
.IR xtiff
should not use a pixmap to store the image on a server.
This option is necessary
because some servers impose size limitations on pixmaps.
Not using a pixmap is slower because the image must be stored
on the client side and transferred for each exposure or refresh.
Default: True.
.TP 8
.B -viewportWidth pixels
Indicates the width of the image viewport.
Default: 700 or image width, whichever is less.
.TP 8
.B -viewportHeight pixels
Indicates the height of the image viewport.
Default: 500 or image height, whichever is less.
.TP 8
.B -translate pixels
Indicates the step size that the arrow keys use for translating an
image.
Default: 20 pixels.
.TP 8
.B -verbose (False | True)
Indicates whether
.IR xtiff
displays
.IR libtiff
error messages.
Default: False.
.SH SEE ALSO
.IR libtiff (3),
.br
.IR "Tag Image File Format Specification \(em Revision 5.0" ,
Aldus Corporation,
August 8, 1988.
.br
.IR "The Spirit of TIFF Class F" ,
Cygnet Technologies,
revised March 29, 1990.
.SH LIMITATIONS
.IR xtiff
does not support the complete repertoire of all possible TIFF files
on all possible visual/depth combinations.
.PP
.IR xtiff
supports TIFF class B (bilevel),
class G (grayscale),
class P (palette color),
class R (RGB color) and class F (FAX).
.PP
Only the top-left orientation is supported.
This is both the X orientation and the TIFF default.
.PP
Gamma correction is simple and there is no colorimetry support.
.PP
.IR xtiff
assumes that servers with 24-bit visuals also have 8-bit visuals.
An 8-bit image is not promoted to 24-bit on the client side.
.PP
There is no support for
.IR StaticGray ,
.IR StaticColor
or
.IR TrueColor
visuals except for 1-bit images.
There is no support for 3/3/2
.IR DirectColor
visuals.
.PP
When displaying 8-bit images,
.IR xtiff
creates and populates a private colormap
with the TIFF colormap or response curve.
.IR Xt
will complain about failing to allocate colors
for the foreground and background colors.
.IR xtiff
can't allow this because the colormap is already full.
.IR Xt
should find the nearest substitutes and use them but it doesn't.
SHAR_EOF
chmod 0644 xtiff/athena/xtiff.man ||
echo 'restore of xtiff/athena/xtiff.man failed'
Wc_c="`wc -c < 'xtiff/athena/xtiff.man'`"
test 5315 -eq "$Wc_c" ||
echo 'xtiff/athena/xtiff.man: original size 5315, current size'
"$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= xtiff/athena/xtifficon.h ==============
if test -f 'xtiff/athena/xtifficon.h' -a X"$1" != X"-c"; then
echo 'x - skipping xtiff/athena/xtifficon.h (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting xtiff/athena/xtifficon.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xtiff/athena/xtifficon.h' &&
#define xtifficon_width 32
#define xtifficon_height 32
static char xtifficon_bits[] = {
X 0xff, 0x00, 0x00, 0xc0, 0xfe, 0x01, 0x7e, 0xc0, 0xfc, 0x03, 0x7e,
0x60,
X 0xf8, 0x07, 0x06, 0x30, 0xf8, 0x07, 0x1e, 0x18, 0xf0, 0x0f, 0x1e,
0x0c,
X 0xe0, 0x1f, 0x06, 0x06, 0xc0, 0x3f, 0x06, 0x06, 0xc0, 0x3f, 0x06,
0x03,
X 0x80, 0x7f, 0x80, 0x01, 0x00, 0xff, 0xc0, 0x00, 0x00, 0xfe, 0x61,
0x00,
X 0x00, 0xfe, 0x31, 0x7e, 0x7e, 0xfc, 0x33, 0x7e, 0x7e, 0xf8, 0x1b,
0x06,
X 0x18, 0xf0, 0x0d, 0x1e, 0x18, 0xf0, 0x0e, 0x1e, 0x18, 0x60, 0x1f,
0x06,
X 0x18, 0xb0, 0x3f, 0x06, 0x18, 0x98, 0x7f, 0x06, 0x18, 0x98, 0x7f,
0x00,
X 0x00, 0x0c, 0xff, 0x00, 0x00, 0x06, 0xfe, 0x01, 0x00, 0x63, 0xfc,
0x03,
X 0x80, 0x61, 0xfc, 0x03, 0xc0, 0x60, 0xf8, 0x07, 0xc0, 0x60, 0xf0,
0x0f,
X 0x60, 0x60, 0xe0, 0x1f, 0x30, 0x60, 0xe0, 0x1f, 0x18, 0x60, 0xc0,
0x3f,
X 0x0c, 0x60, 0x80, 0x7f, 0x06, 0x00, 0x00, 0xff};
SHAR_EOF
chmod 0644 xtiff/athena/xtifficon.h ||
echo 'restore of xtiff/athena/xtifficon.h failed'
Wc_c="`wc -c < 'xtiff/athena/xtifficon.h'`"
test 890 -eq "$Wc_c" ||
echo 'xtiff/athena/xtifficon.h: original size 890, current size'
"$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= xtiff/athena/Imakefile ==============
if test -f 'xtiff/athena/Imakefile' -a X"$1" != X"-c"; then
echo 'x - skipping xtiff/athena/Imakefile (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting xtiff/athena/Imakefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xtiff/athena/Imakefile' &&
#
# Imakefile -- to generate a Makefile for xtiff, use:
# /usr/local/X11/mit/config/imake \
# -I/usr/local/X11/mit/config \
# -DTOPDIR=/usr/local/X11/mit \
# -DCURDIR=/usr/local/X11/mit \
# -DDESTDIR=/usr/local/X11/mit
#
X
X SYS_LIBRARIES = -lm
X LOCAL_LIBRARIES = XawClientLibs
X DEPLIBS = XawClientDepLibs
X TIFF = ../2.3/libtiff
X EXTRA_LIBRARIES = $(TIFF)/libtiff.a
X EXTRA_INCLUDES = -I$(TIFF)
X
SimpleProgramTarget(xtiff)
SHAR_EOF
chmod 0644 xtiff/athena/Imakefile ||
echo 'restore of xtiff/athena/Imakefile failed'
Wc_c="`wc -c < 'xtiff/athena/Imakefile'`"
test 468 -eq "$Wc_c" ||
echo 'xtiff/athena/Imakefile: original size 468, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= xtiff/athena/patchlevel.h ==============
if test -f 'xtiff/athena/patchlevel.h' -a X"$1" != X"-c"; then
echo 'x - skipping xtiff/athena/patchlevel.h (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting xtiff/athena/patchlevel.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xtiff/athena/patchlevel.h' &&
#define PATCHLEVEL 0
SHAR_EOF
chmod 0644 xtiff/athena/patchlevel.h ||
echo 'restore of xtiff/athena/patchlevel.h failed'
Wc_c="`wc -c < 'xtiff/athena/patchlevel.h'`"
test 21 -eq "$Wc_c" ||
echo 'xtiff/athena/patchlevel.h: original size 21, current size'
"$Wc_c"
rm -f _shar_wnt_.tmp
fi
rm -f _shar_seq_.tmp
echo You have unpacked the last part
exit 0
--
Dan Heller
O'Reilly && Associates Z-Code Software Comp-sources-x:
Senior Writer President comp-sources.x at uunet.uu.net
argv at ora.com argv at zipcode.com
More information about the Comp.sources.x
mailing list