📄 rpng2-x.c
字号:
} } else if (!strncmp(*argv, "-usleep", 2)) { if (!*++argv) ++error; else { usleep_duration = (ulg)atol(*argv); demo_timing = TRUE; } } else if (!strncmp(*argv, "-pause", 2)) { pause_after_pass = TRUE; } else if (!strncmp(*argv, "-timing", 2)) { timing = TRUE;#if (defined(__i386__) || defined(_M_IX86)) } else if (!strncmp(*argv, "-nommxfilters", 7)) { rpng2_info.nommxfilters = TRUE; } else if (!strncmp(*argv, "-nommxcombine", 7)) { rpng2_info.nommxcombine = TRUE; } else if (!strncmp(*argv, "-nommxinterlace", 7)) { rpng2_info.nommxinterlace = TRUE; } else if (!strcmp(*argv, "-nommx")) { rpng2_info.nommxfilters = TRUE; rpng2_info.nommxcombine = TRUE; rpng2_info.nommxinterlace = TRUE;#endif } else { if (**argv != '-') { filename = *argv; if (argv[1]) /* shouldn't be any more args after filename */ ++error; } else ++error; /* not expecting any other options */ } } if (!filename) { ++error; } else if (!(infile = fopen(filename, "rb"))) { fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); ++error; } else { incount = fread(inbuf, 1, INBUFSIZE, infile); if (incount < 8 || !readpng2_check_sig(inbuf, 8)) { fprintf(stderr, PROGNAME ": [%s] is not a PNG file: incorrect signature\n", filename); ++error; } else if ((rc = readpng2_init(&rpng2_info)) != 0) { switch (rc) { case 2: fprintf(stderr, PROGNAME ": [%s] has bad IHDR (libpng longjmp)\n", filename); break; case 4: fprintf(stderr, PROGNAME ": insufficient memory\n"); break; default: fprintf(stderr, PROGNAME ": unknown readpng2_init() error\n"); break; } ++error; } else { display = XOpenDisplay(displayname); if (!display) { readpng2_cleanup(&rpng2_info); fprintf(stderr, PROGNAME ": can't open X display [%s]\n", displayname? displayname : "default"); ++error; } } if (error) fclose(infile); } /* usage screen */ if (error) { fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); readpng2_version_info(); fprintf(stderr, "\n" "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n"#if (defined(__i386__) || defined(_M_IX86)) " %*s [[-nommxfilters] [-nommxcombine] [-nommxinterlace] | -nommx]\n"#endif " %*s [-usleep dur | -timing] [-pause] file.png\n\n" " xdpy\tname of the target X display (e.g., ``hostname:0'')\n" " exp \ttransfer-function exponent (``gamma'') of the display\n" "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" "\t\t to the product of the lookup-table exponent (varies)\n" "\t\t and the CRT exponent (usually 2.2); must be positive\n" " bg \tdesired background color in 7-character hex RGB format\n" "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" "\t\t used with transparent images; overrides -bgpat\n" " pat \tdesired background pattern number (1-%d); used with\n" "\t\t transparent images; overrides -bgcolor\n"#if (defined(__i386__) || defined(_M_IX86)) " -nommx*\tdisable optimized MMX routines for decoding row filters,\n" "\t\t combining rows, and expanding interlacing, respectively\n"#endif " dur \tduration in microseconds to wait after displaying each\n" "\t\t row (for demo purposes)\n" " -timing\tenables delay for every block read, to simulate modem\n" "\t\t download of image (~36 Kbps)\n" " -pause\tpauses after displaying each pass until key pressed\n" "\nPress Q, Esc or mouse button 1 (within image window, after image\n" "is displayed) to quit.\n" "\n", PROGNAME,#if (defined(__i386__) || defined(_M_IX86)) strlen(PROGNAME), " ",#endif strlen(PROGNAME), " ", default_display_exponent, num_bgpat); exit(1); } /* set the title-bar string, but make sure buffer doesn't overflow */ alen = strlen(appname); flen = strlen(filename); if (alen + flen + 3 > 1023) sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); else sprintf(titlebar, "%s: %s", appname, filename); /* set some final rpng2_info variables before entering main data loop */ if (have_bg) { unsigned r, g, b; /* this approach quiets compiler warnings */ sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); rpng2_info.bg_red = (uch)r; rpng2_info.bg_green = (uch)g; rpng2_info.bg_blue = (uch)b; } else rpng2_info.need_bgcolor = TRUE; rpng2_info.done = FALSE; rpng2_info.mainprog_init = rpng2_x_init; rpng2_info.mainprog_display_row = rpng2_x_display_row; rpng2_info.mainprog_finish_display = rpng2_x_finish_display; /* OK, this is the fun part: call readpng2_decode_data() at the start of * the loop to deal with our first buffer of data (read in above to verify * that the file is a PNG image), then loop through the file and continue * calling the same routine to handle each chunk of data. It in turn * passes the data to libpng, which will invoke one or more of our call- * backs as decoded data become available. We optionally call sleep() for * one second per iteration to simulate downloading the image via an analog * modem. */ for (;;) { Trace((stderr, "about to call readpng2_decode_data()\n")) if (readpng2_decode_data(&rpng2_info, inbuf, incount)) ++error; Trace((stderr, "done with readpng2_decode_data()\n")) if (error || feof(infile) || rpng2_info.done) break; if (timing) sleep(1); incount = fread(inbuf, 1, INBUFSIZE, infile); } /* clean up PNG stuff and report any decoding errors */ fclose(infile); Trace((stderr, "about to call readpng2_cleanup()\n")) readpng2_cleanup(&rpng2_info); if (error) { fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n"); exit(3); } /* wait for the user to tell us when to quit */ do XNextEvent(display, &e); while (!(e.type == ButtonPress && e.xbutton.button == Button1) && !(e.type == KeyPress && /* v--- or 1 for shifted keys */ ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) )); /* we're done: clean up all image and X resources and go away */ Trace((stderr, "about to call rpng2_x_cleanup()\n")) rpng2_x_cleanup(); return 0;}/* this function is called by readpng2_info_callback() in readpng2.c, which * in turn is called by libpng after all of the pre-IDAT chunks have been * read and processed--i.e., we now have enough info to finish initializing */static void rpng2_x_init(void){ ulg i; ulg rowbytes = rpng2_info.rowbytes; Trace((stderr, "beginning rpng2_x_init()\n")) Trace((stderr, " rowbytes = %ld\n", rpng2_info.rowbytes)) Trace((stderr, " width = %ld\n", rpng2_info.width)) Trace((stderr, " height = %ld\n", rpng2_info.height)) rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height); if (!rpng2_info.image_data) { readpng2_cleanup(&rpng2_info); return; } rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *)); if (!rpng2_info.row_pointers) { free(rpng2_info.image_data); rpng2_info.image_data = NULL; readpng2_cleanup(&rpng2_info); return; } for (i = 0; i < rpng2_info.height; ++i) rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes; /* do the basic X initialization stuff, make the window, and fill it with * the user-specified, file-specified or default background color or * pattern */ if (rpng2_x_create_window()) { /* GRR TEMPORARY HACK: this is fundamentally no different from cases * above; libpng should longjmp() back to us when png_ptr goes away. * If we/it segfault instead, seems like a libpng bug... */ /* we're here via libpng callback, so if window fails, clean and bail */printf("readpng2_cleanup.\n"); readpng2_cleanup(&rpng2_info); rpng2_x_cleanup(); exit(2); }}static int rpng2_x_create_window(void){ ulg bg_red = rpng2_info.bg_red; ulg bg_green = rpng2_info.bg_green; ulg bg_blue = rpng2_info.bg_blue; ulg bg_pixel = 0L; ulg attrmask; int need_colormap = FALSE; int screen, pad; uch *xdata; Window root; XEvent e; XGCValues gcvalues; XSetWindowAttributes attr; XSizeHints *size_hints; XTextProperty windowName, *pWindowName = &windowName; XTextProperty iconName, *pIconName = &iconName; XVisualInfo visual_info; XWMHints *wm_hints; Trace((stderr, "beginning rpng2_x_create_window()\n")) screen = DefaultScreen(display); depth = DisplayPlanes(display, screen); root = RootWindow(display, screen);#ifdef DEBUG XSynchronize(display, True);#endif if (depth != 16 && depth != 24 && depth != 32) { int visuals_matched = 0; Trace((stderr, "default depth is %d: checking other visuals\n", depth)) /* 24-bit first */ visual_info.screen = screen; visual_info.depth = 24; visual_list = XGetVisualInfo(display, VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched); if (visuals_matched == 0) {/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */ fprintf(stderr, "default screen depth %d not supported, and no" " 24-bit visuals found\n", depth); return 2; } Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n", visuals_matched)) visual = visual_list[0].visual; depth = visual_list[0].depth;/* colormap_size = visual_list[0].colormap_size; visual_class = visual->class; visualID = XVisualIDFromVisual(visual); */ have_nondefault_visual = TRUE; need_colormap = TRUE; } else { XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info); visual = visual_info.visual; } RMask = visual->red_mask; GMask = visual->green_mask; BMask = visual->blue_mask;/* GRR: add/check 8-bit support */ if (depth == 8 || need_colormap) { colormap = XCreateColormap(display, root, visual, AllocNone); if (!colormap) { fprintf(stderr, "XCreateColormap() failed\n"); return 2; } have_colormap = TRUE; if (depth == 8) bg_image = FALSE; /* gradient just wastes palette entries */ } if (depth == 15 || depth == 16) { RShift = 15 - rpng2_x_msb(RMask); /* these are right-shifts */ GShift = 15 - rpng2_x_msb(GMask); BShift = 15 - rpng2_x_msb(BMask); } else if (depth > 16) { RShift = rpng2_x_msb(RMask) - 7; /* these are left-shifts */ GShift = rpng2_x_msb(GMask) - 7; BShift = rpng2_x_msb(BMask) - 7; } if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) { fprintf(stderr, "rpng2 internal logic error: negative X shift(s)!\n"); return 2; }/*--------------------------------------------------------------------------- Finally, create the window. ---------------------------------------------------------------------------*/ attr.backing_store = Always; attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -