?? rpng2-x.c
字號:
else {
pat = atoi(*argv) - 1;
if (pat < 0 || pat >= num_bgpat)
++error;
else {
bg_image = TRUE;
have_bg = FALSE;
}
}
} 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;
} 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", PROGNAME, VERSION, appname);
readpng2_version_info();
fprintf(stderr, "\n"
"Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n"
" %*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"
" 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, 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()) {
readpng2_cleanup(&rpng2_info);
return;
}
}
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;
attrmask = CWBackingStore | CWEventMask;
if (have_nondefault_visual) {
attr.colormap = colormap;
attr.background_pixel = 0;
attr.border_pixel = 1;
attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
}
window = XCreateWindow(display, root, 0, 0, rpng2_info.width,
rpng2_info.height, 0, depth, InputOutput, visual, attrmask, &attr);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -