📄 rpng2-x.c
字号:
} fprintf(stderr, "done.\n"); fflush(stderr); }/*--------------------------------------------------------------------------- Blast background image to display buffer before beginning PNG decode. ---------------------------------------------------------------------------*/ if (depth == 24 || depth == 32) { ulg red, green, blue; for (row = 0; row < rpng2_info.height; ++row) { src = bg_data + row*bg_rowbytes; dest = ximage->data + row*ximage_rowbytes; for (i = rpng2_info.width; i > 0; --i) { red = *src++; green = *src++; blue = *src++; pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ /* GRR BUG: this assumes bpp == 32, but may be 24: */ *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } } else if (depth == 16) { ush red, green, blue; for (row = 0; row < rpng2_info.height; ++row) { src = bg_data + row*bg_rowbytes; dest = ximage->data + row*ximage_rowbytes; for (i = rpng2_info.width; i > 0; --i) { red = ((ush)(*src) << 8); ++src; green = ((ush)(*src) << 8); ++src; blue = ((ush)(*src) << 8); ++src; pixel = ((red >> RShift) & RMask) | ((green >> GShift) & GMask) | ((blue >> BShift) & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } } else /* depth == 8 */ { /* GRR: add 8-bit support */ } XPutImage(display, window, gc, ximage, 0, 0, 0, 0, rpng2_info.width, rpng2_info.height); return 0;} /* end function rpng2_x_load_bg_image() */static void rpng2_x_display_row(ulg row){ uch bg_red = rpng2_info.bg_red; uch bg_green = rpng2_info.bg_green; uch bg_blue = rpng2_info.bg_blue; uch *src, *src2=NULL; char *dest; uch r, g, b, a; int ximage_rowbytes = ximage->bytes_per_line; ulg i, pixel; static int rows=0, prevpass=(-1); static ulg firstrow;/*--------------------------------------------------------------------------- rows and firstrow simply track how many rows (and which ones) have not yet been displayed; alternatively, we could call XPutImage() for every row and not bother with the records-keeping. ---------------------------------------------------------------------------*/ Trace((stderr, "beginning rpng2_x_display_row()\n")) if (rpng2_info.pass != prevpass) { if (pause_after_pass && rpng2_info.pass > 0) { XEvent e; KeySym k; fprintf(stderr, "%s: end of pass %d of 7; click in image window to continue\n", PROGNAME, prevpass + 1); do XNextEvent(display, &e); while (!(e.type == ButtonPress && e.xbutton.button == Button1) && !(e.type == KeyPress && ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) )) ; } fprintf(stderr, "%s: pass %d of 7\r", PROGNAME, rpng2_info.pass + 1); fflush(stderr); prevpass = rpng2_info.pass; } if (rows == 0) firstrow = row; /* first row that is not yet displayed */ ++rows; /* count of rows received but not yet displayed *//*--------------------------------------------------------------------------- Aside from the use of the rpng2_info struct, the lack of an outer loop (over rows) and moving the XPutImage() call outside the "if (depth)" tests, this routine is identical to rpng_x_display_image() in the non- progressive version of the program. ---------------------------------------------------------------------------*/ if (depth == 24 || depth == 32) { ulg red, green, blue; src = rpng2_info.image_data + row*rpng2_info.rowbytes; if (bg_image) src2 = bg_data + row*bg_rowbytes; dest = ximage->data + row*ximage_rowbytes; if (rpng2_info.channels == 3) { for (i = rpng2_info.width; i > 0; --i) { red = *src++; green = *src++; blue = *src++; pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ /* GRR BUG: this assumes bpp == 32, but may be 24: */ *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } else /* if (rpng2_info.channels == 4) */ { for (i = rpng2_info.width; i > 0; --i) { r = *src++; g = *src++; b = *src++; a = *src++; if (bg_image) { bg_red = *src2++; bg_green = *src2++; bg_blue = *src2++; } if (a == 255) { red = r; green = g; blue = b; } else if (a == 0) { red = bg_red; green = bg_green; blue = bg_blue; } else { /* this macro (from png.h) composites the foreground * and background values and puts the result into the * first argument */ alpha_composite(red, r, a, bg_red); alpha_composite(green, g, a, bg_green); alpha_composite(blue, b, a, bg_blue); } pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ /* GRR BUG: this assumes bpp == 32, but may be 24: */ *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } } else if (depth == 16) { ush red, green, blue; src = rpng2_info.row_pointers[row]; if (bg_image) src2 = bg_data + row*bg_rowbytes; dest = ximage->data + row*ximage_rowbytes; if (rpng2_info.channels == 3) { for (i = rpng2_info.width; i > 0; --i) { red = ((ush)(*src) << 8); ++src; green = ((ush)(*src) << 8); ++src; blue = ((ush)(*src) << 8); ++src; pixel = ((red >> RShift) & RMask) | ((green >> GShift) & GMask) | ((blue >> BShift) & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } else /* if (rpng2_info.channels == 4) */ { for (i = rpng2_info.width; i > 0; --i) { r = *src++; g = *src++; b = *src++; a = *src++; if (bg_image) { bg_red = *src2++; bg_green = *src2++; bg_blue = *src2++; } if (a == 255) { red = ((ush)r << 8); green = ((ush)g << 8); blue = ((ush)b << 8); } else if (a == 0) { red = ((ush)bg_red << 8); green = ((ush)bg_green << 8); blue = ((ush)bg_blue << 8); } else { /* this macro (from png.h) composites the foreground * and background values and puts the result back into * the first argument (== fg byte here: safe) */ alpha_composite(r, r, a, bg_red); alpha_composite(g, g, a, bg_green); alpha_composite(b, b, a, bg_blue); red = ((ush)r << 8); green = ((ush)g << 8); blue = ((ush)b << 8); } pixel = ((red >> RShift) & RMask) | ((green >> GShift) & GMask) | ((blue >> BShift) & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } } else /* depth == 8 */ { /* GRR: add 8-bit support */ }/*--------------------------------------------------------------------------- Display after every 16 rows or when on one of last two rows. (Region may include previously displayed lines due to interlacing--i.e., not contiguous. Also, second-to-last row is final one in interlaced images with odd number of rows.) For demos, flush (and delay) after every 16th row so "sparse" passes don't go twice as fast. ---------------------------------------------------------------------------*/ if (demo_timing && (row - firstrow >= 16 || row >= rpng2_info.height-2)) { XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0, (int)firstrow, rpng2_info.width, row - firstrow + 1); XFlush(display); rows = 0; usleep(usleep_duration); } else if (!demo_timing && ((rows & 0xf) == 0 || row >= rpng2_info.height-2)) { XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0, (int)firstrow, rpng2_info.width, row - firstrow + 1); XFlush(display); rows = 0; }}static void rpng2_x_finish_display(void){ Trace((stderr, "beginning rpng2_x_finish_display()\n")) /* last row has already been displayed by rpng2_x_display_row(), so we * have nothing to do here except set a flag and let the user know that * the image is done */ rpng2_info.done = TRUE; printf( "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"); fflush(stdout);}static void rpng2_x_cleanup(void){ if (bg_image && bg_data) { free(bg_data); bg_data = NULL; } if (rpng2_info.image_data) { free(rpng2_info.image_data); rpng2_info.image_data = NULL; } if (rpng2_info.row_pointers) { free(rpng2_info.row_pointers); rpng2_info.row_pointers = NULL; } if (ximage) { if (ximage->data) { free(ximage->data); /* we allocated it, so we free it */ ximage->data = (char *)NULL; /* instead of XDestroyImage() */ } XDestroyImage(ximage); ximage = NULL; } if (have_gc) XFreeGC(display, gc); if (have_window) XDestroyWindow(display, window); if (have_colormap) XFreeColormap(display, colormap); if (have_nondefault_visual) XFree(visual_list);}static int rpng2_x_msb(ulg u32val){ int i; for (i = 31; i >= 0; --i) { if (u32val & 0x80000000L) break; u32val <<= 1; } return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -