📄 xtiff.c
字号:
| (*input_p & 3)) + basePixel; } } } else { fprintf(stderr, "xtiff: can't handle %d-bit TIFF file on an %d-bit display\n", tfImageDepth, xImageDepth); exit(0); } } free(scan_line);}voidCreateXImage(){ XGCValues gc_values; GC bitmap_gc; xOffset = yOffset = 0; grabX = grabY = -1; xImage = XCreateImage(xDisplay, xVisual, xImageDepth, xImageDepth == 1 ? XYBitmap : ZPixmap, /* offset */ 0, (char *) imageMemory, tfImageWidth, tfImageHeight, /* bitmap_pad */ 8, /* bytes_per_line */ 0); /* * libtiff converts LSB data into MSB but doesn't change the FillOrder tag. */ if (xImageDepth == 1) xImage->bitmap_bit_order = MSBFirst; if (xImageDepth <= 8) xImage->byte_order = MSBFirst; /* * create an appropriate GC */ gc_values.function = GXcopy; gc_values.plane_mask = AllPlanes; if (tfPhotometricInterpretation == PHOTOMETRIC_MINISBLACK) { gc_values.foreground = XWhitePixel(xDisplay, xScreen); gc_values.background = XBlackPixel(xDisplay, xScreen); } else { gc_values.foreground = XBlackPixel(xDisplay, xScreen); gc_values.background = XWhitePixel(xDisplay, xScreen); } xWinGc = XCreateGC(xDisplay, XtWindow(shellWidget), GCFunction | GCPlaneMask | GCForeground | GCBackground, &gc_values); /* * create the pixmap and load the image */ if (appData.usePixmap == True) { xImagePixmap = XCreatePixmap(xDisplay, RootWindow(xDisplay, xScreen), xImage->width, xImage->height, xImageDepth); /* * According to the O'Reilly X Protocol Reference Manual, page 53, * "A pixmap depth of one is always supported and listed, but windows * of depth one might not be supported." Therefore we create a pixmap * of depth one and use XCopyPlane(). This is idiomatic. */ if (xImageDepth == 1) { /* just pass the bits through */ gc_values.foreground = 1; /* foreground describes set bits */ gc_values.background = 0; /* background describes clear bits */ bitmap_gc = XCreateGC(xDisplay, xImagePixmap, GCForeground | GCBackground, &gc_values); XPutImage(xDisplay, xImagePixmap, bitmap_gc, xImage, 0, 0, 0, 0, xImage->width, xImage->height); } else XPutImage(xDisplay, xImagePixmap, xWinGc, xImage, 0, 0, 0, 0, xImage->width, xImage->height); XDestroyImage(xImage); free(imageMemory); }}XtCallbackProcSelectProc(w, unused_1, unused_2) Widget w; caddr_t unused_1; caddr_t unused_2;{ XawListReturnStruct *list_return; list_return = XawListShowCurrent(w); switch (list_return->list_index) { case ButtonQuit: QuitProc(); break; case ButtonPreviousPage: PreviousProc(); break; case ButtonNextPage: NextProc(); break; default: fprintf(stderr, "error in SelectProc\n"); exit(0); } XawListUnhighlight(w);}voidQuitProc(void){ exit(0);}voidNextProc(){ PageProc(ButtonNextPage);}voidPreviousProc(){ PageProc(ButtonPreviousPage);}voidPageProc(direction) int direction;{ XEvent fake_event; Arg args[4]; switch (direction) { case ButtonPreviousPage: if (tfDirectory > 0) TIFFSetDirectory(tfFile, --tfDirectory); else return; break; case ButtonNextPage: if (TIFFReadDirectory(tfFile) == True) tfDirectory++; else return; break; default: fprintf(stderr, "error in PageProc\n"); exit(0); } xOffset = yOffset = 0; grabX = grabY = -1; GetTIFFHeader(); SetNameLabel(); GetTIFFImage(); if (appData.usePixmap == True) XFreePixmap(xDisplay, xImagePixmap); else XDestroyImage(xImage); CreateXImage(); /* * Using XtSetValues() to set the widget size causes a resize. * This resize gets propagated up to the parent shell. * In order to disable this visually disconcerting effect, * shell resizing is temporarily disabled. */ XtSetArg(args[0], XtNallowShellResize, False); XtSetValues(shellWidget, args, 1); XtSetArg(args[0], XtNwidth, tfImageWidth); XtSetArg(args[1], XtNheight, tfImageHeight); XtSetValues(imageWidget, args, 2); XtSetArg(args[0], XtNallowShellResize, True); XtSetValues(shellWidget, args, 1); XClearWindow(xDisplay, XtWindow(imageWidget)); fake_event.type = Expose; fake_event.xexpose.x = fake_event.xexpose.y = 0; fake_event.xexpose.width = tfImageWidth; /* the window will clip */ fake_event.xexpose.height = tfImageHeight; EventProc(imageWidget, NULL, &fake_event);}voidEventProc(widget, unused, event) Widget widget; caddr_t unused; XEvent *event;{ int ih, iw, ww, wh, sx, sy, w, h, dx, dy; Dimension w_width, w_height; XEvent next_event; Arg args[2]; if (event->type == MappingNotify) { XRefreshKeyboardMapping((XMappingEvent *) event); return; } if (!XtIsRealized(widget)) return; if ((event->type == ButtonPress) || (event->type == ButtonRelease)) if (event->xbutton.button != Button1) return; iw = tfImageWidth; /* avoid sign problems */ ih = tfImageHeight; /* * The grabX and grabY variables record where the user grabbed the image. * They also record whether the mouse button is down or not. */ if (event->type == ButtonPress) { grabX = event->xbutton.x; grabY = event->xbutton.y; return; } /* * imageWidget is a Core widget and doesn't get resized. * So we calculate the size of its viewport here. */ XtSetArg(args[0], XtNwidth, &w_width); XtSetArg(args[1], XtNheight, &w_height); XtGetValues(shellWidget, args, 2); ww = w_width; wh = w_height; XtGetValues(listWidget, args, 2); wh -= w_height; switch (event->type) { case Expose: dx = event->xexpose.x; dy = event->xexpose.y; sx = dx + xOffset; sy = dy + yOffset; w = MIN(event->xexpose.width, iw); h = MIN(event->xexpose.height, ih); break; case KeyPress: if ((grabX >= 0) || (grabY >= 0)) /* Mouse button is still down */ return; switch (XLookupKeysym((XKeyEvent *) event, /* KeySyms index */ 0)) { case XK_Up: if (ih < wh) /* Don't scroll if the window fits the image. */ return; sy = yOffset + appData.translate; sy = MIN(ih - wh, sy); if (sy == yOffset) /* Filter redundant stationary refreshes. */ return; yOffset = sy; sx = xOffset; dx = dy = 0; w = ww; h = wh; break; case XK_Down: if (ih < wh) return; sy = yOffset - appData.translate; sy = MAX(sy, 0); if (sy == yOffset) return; yOffset = sy; sx = xOffset; dx = dy = 0; w = ww; h = wh; break; case XK_Left: if (iw < ww) return; sx = xOffset + appData.translate; sx = MIN(iw - ww, sx); if (sx == xOffset) return; xOffset = sx; sy = yOffset; dx = dy = 0; w = ww; h = wh; break; case XK_Right: if (iw < ww) return; sx = xOffset - appData.translate; sx = MAX(sx, 0); if (sx == xOffset) return; xOffset = sx; sy = yOffset; dx = dy = 0; w = ww; h = wh; break; default: return; } break; case MotionNotify: /* * MotionEvent compression. Ignore multiple motion events. * Ignore motion events if the mouse button is up. */ if (XPending(xDisplay)) /* Xlib doesn't flush the output buffer */ if (XtPeekEvent(&next_event)) if (next_event.type == MotionNotify) return; if ((grabX < 0) || (grabY < 0)) return; sx = xOffset + grabX - (int) event->xmotion.x; if (sx >= (iw - ww)) /* clamp x motion but allow y motion */ sx = iw - ww; sx = MAX(sx, 0); sy = yOffset + grabY - (int) event->xmotion.y; if (sy >= (ih - wh)) /* clamp y motion but allow x motion */ sy = ih - wh; sy = MAX(sy, 0); if ((sx == xOffset) && (sy == yOffset)) return; dx = dy = 0; w = ww; h = wh; break; case ButtonRelease: xOffset = xOffset + grabX - (int) event->xbutton.x; xOffset = MIN(iw - ww, xOffset); xOffset = MAX(xOffset, 0); yOffset = yOffset + grabY - (int) event->xbutton.y; yOffset = MIN(ih - wh, yOffset); yOffset = MAX(yOffset, 0); grabX = grabY = -1; default: return; } if (appData.usePixmap == True) { if (xImageDepth == 1) XCopyPlane(xDisplay, xImagePixmap, XtWindow(widget), xWinGc, sx, sy, w, h, dx, dy, 1); else XCopyArea(xDisplay, xImagePixmap, XtWindow(widget), xWinGc, sx, sy, w, h, dx, dy); } else XPutImage(xDisplay, XtWindow(widget), xWinGc, xImage, sx, sy, dx, dy, w, h);}voidResizeProc(){ Dimension w_width, w_height; int xo, yo, ww, wh; XEvent fake_event; Arg args[2]; if ((xOffset == 0) && (yOffset == 0)) return; XtSetArg(args[0], XtNwidth, &w_width); XtSetArg(args[1], XtNheight, &w_height); XtGetValues(shellWidget, args, 2); ww = w_width; wh = w_height; XtGetValues(listWidget, args, 2); wh -= w_height; xo = xOffset; yo = yOffset; if ((xOffset + ww) >= tfImageWidth) xOffset = MAX((int) tfImageWidth - ww, 0); if ((yOffset + wh) >= tfImageHeight) yOffset = MAX((int) tfImageHeight - wh, 0); /* * Send an ExposeEvent if the origin changed. * We have to do this because of the use and semantics of bit gravity. */ if ((xo != xOffset) || (yo != yOffset)) { fake_event.type = Expose; fake_event.xexpose.x = fake_event.xexpose.y = 0; fake_event.xexpose.width = tfImageWidth; fake_event.xexpose.height = tfImageHeight; EventProc(imageWidget, NULL, &fake_event); }}intXTiffErrorHandler(display, error_event) Display *display; XErrorEvent *error_event;{ char message[80]; /* * Some X servers limit the size of pixmaps. */ if ((error_event->error_code == BadAlloc) && (error_event->request_code == X_CreatePixmap)) fprintf(stderr, "xtiff: requested pixmap too big for display\n"); else { XGetErrorText(display, error_event->error_code, message, 80); fprintf(stderr, "xtiff: error code %s\n", message); } exit(0);}voidUsage(){ fprintf(stderr, "Usage xtiff: [options] tiff-file\n"); fprintf(stderr, "\tstandard Xt options\n"); fprintf(stderr, "\t[-help]\n"); fprintf(stderr, "\t[-gamma gamma]\n"); fprintf(stderr, "\t[-usePixmap (True | False)]\n"); fprintf(stderr, "\t[-viewportWidth pixels]\n"); fprintf(stderr, "\t[-viewportHeight pixels]\n"); fprintf(stderr, "\t[-translate pixels]\n"); fprintf(stderr, "\t[-verbose (True | False)]\n"); exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -