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

📄 rpng2-x.c

📁 教你如何简单显示一章TIFF位图,分析的很透彻,很适合出学者.希望能给你带来帮助!
💻 C
📖 第 1 页 / 共 3 页
字号:
        r1 = rgb[bg[pat].rgb1_max].r;
        g1 = rgb[bg[pat].rgb1_max].g;
        b1 = rgb[bg[pat].rgb1_max].b;
        r2 = rgb[bg[pat].rgb2_max].r;
        g2 = rgb[bg[pat].rgb2_max].g;
        b2 = rgb[bg[pat].rgb2_max].b;

        for (row = 0;  row < rpng2_info.height;  ++row) {
            yidx = row % bgscale;
            if (yidx > hmax)
                yidx = bgscale-1 - yidx;
            dest = bg_data + row*bg_rowbytes;
            for (i = 0;  i < rpng2_info.width;  ++i) {
                xidx = i % bgscale;
                if (xidx > hmax)
                    xidx = bgscale-1 - xidx;
                k = xidx + yidx;
                *dest++ = (k*r1 + (max-k)*r2) / max;
                *dest++ = (k*g1 + (max-k)*g2) / max;
                *dest++ = (k*b1 + (max-k)*b2) / max;
            }
        }

/*---------------------------------------------------------------------------
    Radial "starburst" with azimuthal sinusoids; [eventually number of sinu-
    soids will equal bgscale?].  This one is slow but very cool.  Code con-
    tributed by Pieter S. van der Meulen (originally in Smalltalk).
  ---------------------------------------------------------------------------*/

    } else if ((bg[pat].type & 0x07) == 2) {
        uch ch;
        int ii, x, y, hw, hh, grayspot;
        double freq, rotate, saturate, gray, intensity;
        double angle=0.0, aoffset=0.0, maxDist, dist;
        double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;

        fprintf(stderr, "%s:  computing radial background...",
          PROGNAME);
        fflush(stderr);

        hh = rpng2_info.height / 2;
        hw = rpng2_info.width / 2;

        /* variables for radial waves:
         *   aoffset:  number of degrees to rotate hue [CURRENTLY NOT USED]
         *   freq:  number of color beams originating from the center
         *   grayspot:  size of the graying center area (anti-alias)
         *   rotate:  rotation of the beams as a function of radius
         *   saturate:  saturation of beams' shape azimuthally
         */
        angle = CLIP(angle, 0.0, 360.0);
        grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));
        freq = MAX((double)bg[pat].bg_freq, 0.0);
        saturate = (double)bg[pat].bg_bsat * 0.1;
        rotate = (double)bg[pat].bg_brot * 0.1;
        gray = 0.0;
        intensity = 0.0;
        maxDist = (double)((hw*hw) + (hh*hh));

        for (row = 0;  row < rpng2_info.height;  ++row) {
            y = row - hh;
            dest = bg_data + row*bg_rowbytes;
            for (i = 0;  i < rpng2_info.width;  ++i) {
                x = i - hw;
                angle = (x == 0)? PI_2 : atan((double)y / (double)x);
                gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
                gray = MIN(1.0, gray);
                dist = (double)((x*x) + (y*y)) / maxDist;
                intensity = cos((angle+(rotate*dist*PI)) * freq) *
                  gray * saturate;
                intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;
                hue = (angle + PI) * INV_PI_360 + aoffset;
                s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));
                s = MIN(MAX(s,0.0), 1.0);
                v = MIN(MAX(intensity,0.0), 1.0);

                if (s == 0.0) {
                    ch = (uch)(v * 255.0);
                    *dest++ = ch;
                    *dest++ = ch;
                    *dest++ = ch;
                } else {
                    if ((hue < 0.0) || (hue >= 360.0))
                        hue -= (((int)(hue / 360.0)) * 360.0);
                    hue /= 60.0;
                    ii = (int)hue;
                    f = hue - (double)ii;
                    p = (1.0 - s) * v;
                    q = (1.0 - (s * f)) * v;
                    t = (1.0 - (s * (1.0 - f))) * v;
                    if      (ii == 0) { red = v; green = t; blue = p; }
                    else if (ii == 1) { red = q; green = v; blue = p; }
                    else if (ii == 2) { red = p; green = v; blue = t; }
                    else if (ii == 3) { red = p; green = q; blue = v; }
                    else if (ii == 4) { red = t; green = p; blue = v; }
                    else if (ii == 5) { red = v; green = p; blue = q; }
                    *dest++ = (uch)(red * 255.0);
                    *dest++ = (uch)(green * 255.0);
                    *dest++ = (uch)(blue * 255.0);
                }
            }
        }
        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   << RPixelShift) |
                        (green << GPixelShift) |
                        (blue  << BPixelShift);
                /* recall that we set ximage->byte_order = MSBFirst above */
                *dest++ = ((uch *)&pixel)[3];
                *dest++ = ((uch *)&pixel)[2];
                *dest++ = ((uch *)&pixel)[1];
                *dest++ = ((uch *)&pixel)[0];
            }
        }

    } 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   >> RPixelShift) & RedMask)   |
                        ((green >> GPixelShift) & GreenMask) |
                        ((blue  >> BPixelShift) & BlueMask);
                /* recall that we set ximage->byte_order = MSBFirst above */
                *dest++ = ((uch *)&pixel)[1];
                *dest++ = ((uch *)&pixel)[0];
            }
        }

    } 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, *dest;
    uch r, g, b, a;
    int ximage_rowbytes = ximage->bytes_per_line;
    ulg i, pixel;
    static int rows=0;
    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 (rows == 0)
        firstrow = row;   /* first row 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   << RPixelShift) |
                        (green << GPixelShift) |
                        (blue  << BPixelShift);
                /* recall that we set ximage->byte_order = MSBFirst */
                *dest++ = ((uch *)&pixel)[3];
                *dest++ = ((uch *)&pixel)[2];
                *dest++ = ((uch *)&pixel)[1];
                *dest++ = ((uch *)&pixel)[0];
            }
        } 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   << RPixelShift) |
                        (green << GPixelShift) |
                        (blue  << BPixelShift);
                /* recall that we set ximage->byte_order = MSBFirst */
                *dest++ = ((uch *)&pixel)[3];
                *dest++ = ((uch *)&pixel)[2];
                *dest++ = ((uch *)&pixel)[1];
                *dest++ = ((uch *)&pixel)[0];
            }
        }

    } 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   >> RPixelShift) & RedMask)   |
                        ((green >> GPixelShift) & GreenMask) |
                        ((blue  >> BPixelShift) & BlueMask);
                /* recall that we set ximage->byte_order = MSBFirst */
                *dest++ = ((uch *)&pixel)[1];
                *dest++ = ((uch *)&pixel)[0];
            }
        } 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   >> RPixelShift) & RedMask)   |
                        ((green >> GPixelShift) & GreenMask) |
                        ((blue  >> BPixelShift) & BlueMask);
                /* recall that we set ximage->byte_order = MSBFirst */
                *dest++ = ((uch *)&pixel)[1];
                *dest++ = ((uch *)&pixel)[0];
            }
        }

    } else /* depth == 8 */ {

        /* GRR:  add 8-bit support */

    }


/*---------------------------------------------------------------------------
    Display after every 16 rows or when on last row.  (Region may include
    previously displayed lines due to interlacing--i.e., not contiguous.)
  ---------------------------------------------------------------------------*/

    if ((rows & 0xf) == 0 || row == rpng2_info.height-1) {
        XPutImage(display, window, gc, ximage, 0, firstrow, 0, firstrow,
          rpng2_info.width, row - firstrow + 1);
        XFlush(display);
        rows = 0;
    }

}





static void rpng2_x_finish_display()
{
    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 to quit.\n");
}





static void rpng2_x_cleanup()
{
    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;
    }

    XFreeGC(display, gc);

    if (have_window)
        XDestroyWindow(display, window);

    if (have_colormap)
        XFreeColormap(display, colormap);
}





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 + -