⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpng2-x.c

📁 game engine, which is useful for everyone who is interested in it. I hope you can enjoy it.
💻 C
📖 第 1 页 / 共 4 页
字号:
        }
        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 + -