Beispiel #1
0
/******************************************************************************
* Load RLE file into internal frame buffer.				      *
******************************************************************************/
static void LoadRle(char *FileName,
		    GifByteType **RedBuffer,
		    GifByteType **GreenBuffer,
		    GifByteType **BlueBuffer,
		    int *Width, int *Height)
{
    int i, j, k, Size;
    GifByteType *OutputPtr[3];
    rle_hdr in_hdr;
    rle_pixel **rows, *ptr;
    
    if (FileName != NULL) {
	if ((in_hdr.rle_file = fopen(FileName, "r")) == NULL)
	    GIF_EXIT("Can't open input file name.");
    }
    else
	in_hdr.rle_file = stdin;

    rle_get_setup_ok( &in_hdr, "rle2gif", FileName );

    *Width = in_hdr.xmax - in_hdr.xmin + 1;
    *Height = in_hdr.ymax - in_hdr.ymin + 1;

    if (in_hdr.ncolors != 3)
	GIF_EXIT("Input Rle file does not hold 3 (RGB) colors, aborted.");

    Size = *Width * *Height * sizeof(GifByteType);
    if (rle_row_alloc(&in_hdr, &rows) ||
	(*RedBuffer = (GifByteType *) malloc(Size)) == NULL ||
	(*GreenBuffer = (GifByteType *) malloc(Size)) == NULL ||
	(*BlueBuffer = (GifByteType *) malloc(Size)) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

    OutputPtr[0] = *RedBuffer;
    OutputPtr[1] = *GreenBuffer;
    OutputPtr[2] = *BlueBuffer;

    for (i = 0; i < *Height; i++) {
	rle_getrow(&in_hdr, rows);	    /* Get one scan line (3 colors). */

	for (j = 0; j < 3; j++) { /* Copy the 3 colors to the given buffers. */
	    ptr = &rows[j][in_hdr.xmin];

	    for (k = 0; k < *Width; k++)
		*OutputPtr[j]++ = *ptr++;
	}
    }
}
Beispiel #2
0
int
main(int argc, char **argv)
{
    FBIO *fbp;
    int i;
    int file_width;		/* unclipped width of rectangle */
    int file_skiplen;		/* # of pixels to skip on l.h.s. */
    int screen_xbase;		/* screen X of l.h.s. of rectangle */
    int screen_xlen;		/* clipped len of rectangle */
    int ncolors;

    infp = stdin;
    if (!get_args(argc, argv)) {
	(void)fputs(usage, stderr);
	bu_exit(1, NULL);
    }

    rle_dflt_hdr.rle_file = infp;
    if (rle_get_setup(&rle_dflt_hdr) < 0) {
	fprintf(stderr, "rle-fb: Error reading setup information\n");
	bu_exit(1, NULL);
    }

    if (r_debug) {
	fprintf(stderr, "Image bounds\n\tmin %d %d\n\tmax %d %d\n",
		rle_dflt_hdr.xmin, rle_dflt_hdr.ymin,
		rle_dflt_hdr.xmax, rle_dflt_hdr.ymax);
	fprintf(stderr, "%d color channels\n", rle_dflt_hdr.ncolors);
	fprintf(stderr, "%d color map channels\n", rle_dflt_hdr.ncmap);
	if (rle_dflt_hdr.alpha)
	    fprintf(stderr, "Alpha Channel present in input, ignored.\n");
	for (i=0; i < rle_dflt_hdr.ncolors; i++)
	    fprintf(stderr, "Background channel %d = %d\n",
		    i, rle_dflt_hdr.bg_color[i]);
	rle_debug(1);
    }

    if (rle_dflt_hdr.ncmap == 0)
	crunch = 0;

    /* Only interested in R, G, & B */
    RLE_CLR_BIT(rle_dflt_hdr, RLE_ALPHA);
    for (i = 3; i < rle_dflt_hdr.ncolors; i++)
	RLE_CLR_BIT(rle_dflt_hdr, i);
    ncolors = rle_dflt_hdr.ncolors > 3 ? 3 : rle_dflt_hdr.ncolors;

    /* Optional switch of library to overlay mode */
    if (overlay) {
	rle_dflt_hdr.background = 1;		/* overlay */
	override_background = 0;
    }

    /* Optional background color override */
    if (override_background) {
	for (i=0; i<ncolors; i++)
	    rle_dflt_hdr.bg_color[i] = background[i];
    }

    file_width = rle_dflt_hdr.xmax - rle_dflt_hdr.xmin + 1;

    /* If screen sizes not specified, try to display rectangle part > 0 */
    if (screen_width == 0) {
	screen_width = rle_dflt_hdr.xmax + 1;
	if (scr_xoff > 0)
	    screen_width += scr_xoff;
    }
    if (screen_height == 0) {
	screen_height = rle_dflt_hdr.ymax + 1;
	if (scr_yoff > 0)
	    screen_height += scr_yoff;
    }

    /* Incorporate command-line rectangle repositioning */
    rle_dflt_hdr.xmin += scr_xoff;
    rle_dflt_hdr.xmax += scr_xoff;
    rle_dflt_hdr.ymin += scr_yoff;

    /* Pretend saved image origin is at 0, clip & position in fb_write call */
    screen_xbase = rle_dflt_hdr.xmin;
    rle_dflt_hdr.xmax -= screen_xbase;
    rle_dflt_hdr.xmin = 0;

    if ((fbp = fb_open(framebuffer, screen_width, screen_height)) == FBIO_NULL)
	bu_exit(12, NULL);

    /* Honor original screen size desires, if set, unless they shrank */
    if (screen_width > 0 && fb_getwidth(fbp) < screen_width)
	screen_width = fb_getwidth(fbp);
    if (screen_height > 0 && fb_getheight(fbp) < screen_height)
	screen_height = fb_getheight(fbp);

    /* Discard any scanlines which exceed screen height */
    if (rle_dflt_hdr.ymax > screen_height-1)
	rle_dflt_hdr.ymax = screen_height-1;

    /* Clip left edge */
    screen_xlen = rle_dflt_hdr.xmax + 1;
    file_skiplen = 0;
    if (screen_xbase < 0) {
	file_skiplen = -screen_xbase;
	screen_xbase = 0;
	screen_xlen -= file_skiplen;
    }
    /* Clip right edge */
    if (screen_xbase + screen_xlen > screen_width)
	screen_xlen = screen_width - screen_xbase;
    if (screen_xlen <= 0 ||
	rle_dflt_hdr.ymin > screen_height ||
	rle_dflt_hdr.ymax < 0) {
	fprintf(stderr,
		"rle-fb:  Warning:  RLE image rectangle entirely off screen\n");
	goto done;
    }

    scan_buf = (unsigned char *)malloc(sizeof(RGBpixel) * screen_width);

    for (i=0; i < ncolors; i++)
	rows[i] = (unsigned char *)malloc((size_t)file_width);
    for (; i < 3; i++)
	rows[i] = rows[0];	/* handle monochrome images */

    /*
     * Import Utah color map, converting to libfb format.
     * Check for old format color maps, where high 8 bits
     * were zero, and correct them.
     * XXX need to handle < 3 channels of color map, by replication.
     */
    if (rle_dflt_hdr.ncmap > 0) {
	int maplen = (1 << rle_dflt_hdr.cmaplen);
	int all = 0;
	for (i=0; i<256; i++) {
	    cmap.cm_red[i] = rle_dflt_hdr.cmap[i];
	    cmap.cm_green[i] = rle_dflt_hdr.cmap[i+maplen];
	    cmap.cm_blue[i] = rle_dflt_hdr.cmap[i+2*maplen];
	    all |= cmap.cm_red[i] | cmap.cm_green[i] |
		cmap.cm_blue[i];
	}
	if ((all & 0xFF00) == 0 && (all & 0x00FF) != 0) {
	    /* This is an old (Edition 2) color map.
	     * Correct by shifting it left 8 bits.
	     */
	    for (i=0; i<256; i++) {
		cmap.cm_red[i] <<= 8;
		cmap.cm_green[i] <<= 8;
		cmap.cm_blue[i] <<= 8;
	    }
	    fprintf(stderr,
		    "rle-fb: correcting for old style colormap\n");
	}
    }
    if (rle_dflt_hdr.ncmap > 0 && !crunch)
	(void)fb_wmap(fbp, &cmap);
    else
	(void)fb_wmap(fbp, COLORMAP_NULL);

    /* Handle any lines below zero in y.  Decode and discard. */
    for (i = rle_dflt_hdr.ymin; i < 0; i++)
	rle_getrow(&rle_dflt_hdr, rows);

    for (; i <= rle_dflt_hdr.ymax; i++) {
	unsigned char *pp = (unsigned char *)scan_buf;
	rle_pixel *rp = &(rows[0][file_skiplen]);
	rle_pixel *gp = &(rows[1][file_skiplen]);
	rle_pixel *bp = &(rows[2][file_skiplen]);
	int j;

	if (overlay) {
	    fb_read(fbp, screen_xbase, i, scan_buf, screen_xlen);
	    for (j = 0; j < screen_xlen; j++) {
		*rp++ = *pp++;
		*gp++ = *pp++;
		*bp++ = *pp++;
	    }
	    pp = (unsigned char *)scan_buf;
	    rp = &(rows[0][file_skiplen]);
	    gp = &(rows[1][file_skiplen]);
	    bp = &(rows[2][file_skiplen]);
	}

	rle_getrow(&rle_dflt_hdr, rows);

	/* Grumble, convert from Utah layout */
	if (!crunch) {
	    for (j = 0; j < screen_xlen; j++) {
		*pp++ = *rp++;
		*pp++ = *gp++;
		*pp++ = *bp++;
	    }
	} else {
	    for (j = 0; j < screen_xlen; j++) {
		*pp++ = cmap.cm_red[*rp++]>>8;
		*pp++ = cmap.cm_green[*gp++]>>8;
		*pp++ = cmap.cm_blue[*bp++]>>8;
	    }
	}
	if (fb_write(fbp, screen_xbase, i, scan_buf, screen_xlen) != screen_xlen) break;
    }
done:
    fb_close(fbp);
    return 0;
}