/****************************************************************************** * 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++; } } }
and the .rle file is written to stdout\n"; int main(int argc, char **argv) { unsigned char *scan_buf; size_t y; infp = stdin; outrle.rle_file = stdout; if (!get_args(argc, argv, &outrle, &infp, &infile, (int **)&background, &file_width, &file_height)) { (void)fputs(usage, stderr); bu_exit (1, NULL); } scan_buf = (unsigned char *)malloc(sizeof(unsigned char) * file_width); outrle.ncolors = 1; RLE_SET_BIT(outrle, RLE_RED); outrle.background = 2; /* use background */ outrle.bg_color = background; outrle.alpha = 0; /* no alpha channel */ outrle.ncmap = 0; /* no color map */ outrle.cmaplen = 0; outrle.cmap = (rle_map *)0; outrle.xmin = outrle.ymin = 0; outrle.xmax = file_width-1; outrle.ymax = file_height-1; outrle.comments = (const char **)0; /* Add comments to the header file, since we have one */ snprintf(comment, 128, "converted_from=%s", infile); rle_putcom(strdup(comment), &outrle); now = time(0); sprintf(comment, "converted_date=%24.24s", ctime(&now)); rle_putcom(strdup(comment), &outrle); if ((who = getenv("USER")) != (char *)0) { snprintf(comment, 128, "converted_by=%s", who); rle_putcom(strdup(comment), &outrle); } else { if ((who = getenv("LOGNAME")) != (char *)0) { snprintf(comment, 128, "converted_by=%s", who); rle_putcom(strdup(comment), &outrle); } } #if HAVE_GETHOSTNAME gethostname(host, sizeof(host)); snprintf(comment, 128, "converted_host=%s", host); rle_putcom(strdup(comment), &outrle); #endif rle_put_setup(&outrle); rle_row_alloc(&outrle, &rows); /* Read image a scanline at a time, and encode it */ for (y = 0; y < file_height; y++) { if (fread((char *)scan_buf, sizeof(unsigned char), (size_t)file_width, infp) != file_width) { (void) fprintf(stderr, "bw-rle: read of %lu pixels on line %lu failed!\n", (unsigned long)file_width, (unsigned long)y); bu_exit (1, NULL); } /* Grumble, convert to Utah layout */ { unsigned char *pp = scan_buf; rle_pixel *rp = rows[0]; size_t i; for (i=0; i<file_width; i++) { *rp++ = *pp++; } } rle_putrow(rows, file_width, &outrle); } rle_puteof(&outrle); fclose(infp); fclose(outrle.rle_file); return 0; }
int main(int argc, char **argv) { FBIO *fbp; unsigned char *scan_buf; int y; int cm_save_needed; outrle.rle_file = stdout; if (!get_args(argc, argv)) { (void)fputs(usage, stderr); bu_exit(1, NULL); } /* If screen size = default & file size is given, track file size */ if (screen_width == 0 && file_width > 0) screen_width = file_width; if (screen_height == 0 && file_height > 0) screen_height = file_height; 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); /* If not specified, output file size tracks screen size */ if (file_width == 0) file_width = screen_width; if (file_height == 0) file_height = screen_height; /* Clip below and to left of (0, 0) */ if (screen_xoff < 0) { file_width += screen_xoff; screen_xoff = 0; } if (screen_yoff < 0) { file_height += screen_yoff; screen_yoff = 0; } /* Clip up and to the right */ if (screen_xoff + file_width > screen_width) file_width = screen_width - screen_xoff; if (screen_yoff + file_height > screen_height) file_height = screen_height - screen_yoff; if (file_width <= 0 || file_height <= 0) { fprintf(stderr, "fb-rle: Error: image rectangle entirely off screen\n"); bu_exit(1, NULL); } /* Read color map, see if it is linear */ cm_save_needed = 1; if (fb_rmap(fbp, &cmap) == -1) cm_save_needed = 0; if (cm_save_needed && fb_is_linear_cmap(&cmap)) cm_save_needed = 0; if (crunch && (cm_save_needed == 0)) crunch = 0; /* Convert to Utah format */ if (cm_save_needed) for (y=0; y<256; y++) { rlemap[y+0*256] = cmap.cm_red[y]; rlemap[y+1*256] = cmap.cm_green[y]; rlemap[y+2*256] = cmap.cm_blue[y]; } scan_buf = (unsigned char *)malloc(sizeof(RGBpixel) * screen_width); /* Build RLE header */ outrle.ncolors = 3; RLE_SET_BIT(outrle, RLE_RED); RLE_SET_BIT(outrle, RLE_GREEN); RLE_SET_BIT(outrle, RLE_BLUE); outrle.background = 2; /* use background */ outrle.bg_color = background; outrle.alpha = 0; /* no alpha channel */ if (cm_save_needed && !crunch) { outrle.ncmap = 3; outrle.cmaplen = 8; /* 1<<8 = 256 */ outrle.cmap = rlemap; } else { outrle.ncmap = 0; /* no color map */ outrle.cmaplen = 0; outrle.cmap = (rle_map *)0; } outrle.xmin = screen_xoff; outrle.ymin = screen_yoff; outrle.xmax = screen_xoff + file_width - 1; outrle.ymax = screen_yoff + file_height - 1; outrle.comments = (const char **)0; /* Add comments to the header file, since we have one */ if (framebuffer == (char *)0) framebuffer = fbp->if_name; snprintf(comment, COMMENT_SIZE, "encoded_from=%s", framebuffer); rle_putcom(bu_strdup(comment), &outrle); now = time(0); snprintf(comment, COMMENT_SIZE, "encoded_date=%24.24s", ctime(&now)); rle_putcom(bu_strdup(comment), &outrle); if ((who = getenv("USER")) != (char *)0) { snprintf(comment, COMMENT_SIZE, "encoded_by=%s", who); rle_putcom(bu_strdup(comment), &outrle); } # if HAVE_GETHOSTNAME gethostname(host, sizeof(host)); snprintf(comment, COMMENT_SIZE, "encoded_host=%s", host); rle_putcom(bu_strdup(comment), &outrle); # endif rle_put_setup(&outrle); rle_row_alloc(&outrle, &rows); /* Read the image a scanline at a time, and encode it */ for (y = 0; y < file_height; y++) { if (fb_read(fbp, screen_xoff, y+screen_yoff, scan_buf, file_width) == -1) { (void) fprintf(stderr, "fb-rle: read of %d pixels on line %d failed!\n", file_width, y+screen_yoff); bu_exit(1, NULL); } if (crunch) cmap_crunch((RGBpixel *)scan_buf, file_width, &cmap); /* Grumble, convert to Utah layout */ { unsigned char *pp = (unsigned char *)scan_buf; rle_pixel *rp = rows[0]; rle_pixel *gp = rows[1]; rle_pixel *bp = rows[2]; int i; for (i=0; i<file_width; i++) { *rp++ = *pp++; *gp++ = *pp++; *bp++ = *pp++; } } rle_putrow(rows, file_width, &outrle); } rle_puteof(&outrle); fb_close(fbp); fclose(outrle.rle_file); return 0; }
/*----------------------------------------------------------------------------- * Write the rle data portion of the file. */ static void write_rle_data() { register int x; register int scan; register xel *xelrow, *pP; rle_pixel ***scanlines, **scanline; /* * Allocate some memory. */ /*xelrow = pnm_allowcrow(width);*/ xelrow = (xel*) pm_allocrow( width, sizeof(xel) ); MALLOCARRAY(scanlines, height); RLE_CHECK_ALLOC( hdr.cmd, scanlines, "scanline pointers" ); for ( scan = 0; scan < height; scan++ ) RLE_CHECK_ALLOC( hdr.cmd, (rle_row_alloc(&hdr, &scanlines[scan]) >= 0), "pixel memory" ); /* * Loop through the pnm files image window, read data and flip vertically. */ switch (format) { case PBM_FORMAT: case RPBM_FORMAT: for (scan = 0; scan < height; scan++) { scanline = scanlines[height - scan - 1]; pnm_readpnmrow(fp, xelrow, width, maxval, format); for (x = 0, pP = xelrow; x < width; x++, pP++) { scanline[RLE_RED][x] = (PNM_GET1(*pP) ? 255 : 0); if (do_alpha) { scanline[RLE_ALPHA][x] = scanline[RLE_RED][x]; } } } break; case PGM_FORMAT: case RPGM_FORMAT: for (scan = 0; scan < height; scan++) { scanline = scanlines[height - scan - 1]; pnm_readpnmrow(fp, xelrow, width, maxval, format); for (x = 0, pP = xelrow; x < width; x++, pP++) { scanline[RLE_RED][x] = PNM_GET1(*pP); if (do_alpha) { scanline[RLE_ALPHA][x] = (scanline[RLE_RED][x] ? 255 : 0); } } } break; case PPM_FORMAT: case RPPM_FORMAT: for (scan = 0; scan < height; scan++) { scanline = scanlines[height - scan - 1]; pnm_readpnmrow(fp, xelrow, width, maxval, format); for (x = 0, pP = xelrow; x < width; x++, pP++) { scanline[RLE_RED][x] = PPM_GETR(*pP); scanline[RLE_GREEN][x] = PPM_GETG(*pP); scanline[RLE_BLUE][x] = PPM_GETB(*pP); if (do_alpha) { scanline[RLE_ALPHA][x] = (scanline[RLE_RED][x] || scanline[RLE_GREEN][x] || scanline[RLE_BLUE][x] ? 255 : 0); } } } break; } /* * Write out data in URT order (bottom to top). */ for ( scan = 0; scan < height; scan++ ) { rle_putrow(scanlines[scan], width, &hdr); rle_row_free( &hdr, scanlines[scan] ); } free( scanlines ); VPRINTF(stderr, "Done -- write eof to RLE data.\n"); rle_puteof(&hdr); }