This is rletorla.c in view mode; [Download] [Up]
/* * This software is copyrighted as noted below. It may be freely copied, * modified, and redistributed, provided that the copyright notice is * preserved on all copies. * * There is no warranty or other guarantee of fitness for this software, * it is provided solely "as is". Bug reports or fixes may be sent * to the author, who may or may not act on them as he desires. * * You may not include this software in a program or other software product * without supplying the source, or without informing the end-user that the * source is available for no extra charge. * * If you modify this software, you should include a notice giving the * name of the person performing the modification, the date of modification, * and the reason for such modification. */ /* * rletorla - A program which will convert Utah's "rle" images to * Wavefronts "rlb" image format. * * Author: Wesley C. Barris * AHPCRC * Minnesota Supercomputer Center, Inc. * Date: Thu June 21 1990 * Copyright (c) Wesley C. Barris */ /*----------------------------------------------------------------------------- * System includes. */ #include <stdio.h> #include "rlb_header.h" #include "rle.h" #ifdef USE_STDLIB_H #include <stdlib.h> #else #ifdef USE_STRING_H #include <string.h> #else #include <strings.h> #define strrchr rindex #define strchr index #endif #ifdef VOID_STAR extern void *malloc(); #else extern char *malloc(); #endif extern void free(); #endif /* USE_STDLIB_H */ #define VPRINTF if (verbose || header) fprintf #define GRAYSCALE 001 /* 8 bits, no colormap */ #define PSEUDOCOLOR 010 /* 8 bits, colormap */ #define TRUECOLOR 011 /* 24 bits, colormap */ #define DIRECTCOLOR 100 /* 24 bits, no colormap */ #define TRUE 1 #define FALSE 0 typedef unsigned char U_CHAR; /* * Wavefront type declarations. */ static RLB_HEADER rlb_head; /* * Utah type declarations. */ static rle_map *colormap; /* * Other declarations. */ static FILE *fpin, *fpout; static char rlaname[BUFSIZ], progname[30], *str; static int visual, isalpha, maplen; static int verbose = 0, header = 0; static int i; /*----------------------------------------------------------------------------- * Read the rle header. */ void read_rle_header(minx, maxx, miny, maxy) int *minx, *maxx, *miny, *maxy; { rle_dflt_hdr.rle_file = fpin; rle_get_setup(&rle_dflt_hdr); *minx = rle_dflt_hdr.xmin; *maxx = rle_dflt_hdr.xmax; *miny = rle_dflt_hdr.ymin; *maxy = rle_dflt_hdr.ymax; VPRINTF(stderr, "Image size: %dx%d\n", *maxx-*minx+1, *maxy-*miny+1); if (rle_dflt_hdr.ncolors == 1 && rle_dflt_hdr.ncmap == 3) { visual = PSEUDOCOLOR; colormap = rle_dflt_hdr.cmap; maplen = (1 << rle_dflt_hdr.cmaplen); VPRINTF(stderr, "Mapped color image with a map of length %d.\n", maplen); } else if (rle_dflt_hdr.ncolors == 3 && rle_dflt_hdr.ncmap == 0) { visual = DIRECTCOLOR; VPRINTF(stderr, "24 bit color image, no colormap.\n"); } else if (rle_dflt_hdr.ncolors == 3 && rle_dflt_hdr.ncmap == 3) { visual = TRUECOLOR; colormap = rle_dflt_hdr.cmap; maplen = (1 << rle_dflt_hdr.cmaplen); VPRINTF(stderr, "24 bit color image with color map of length %d\n" ,maplen); } else if (rle_dflt_hdr.ncolors == 1 && rle_dflt_hdr.ncmap == 0) { visual = GRAYSCALE; VPRINTF(stderr, "Grayscale image.\n"); } else { fprintf(stderr, "ncolors = %d, ncmap = %d, I don't know how to handle this!\n", rle_dflt_hdr.ncolors, rle_dflt_hdr.ncmap); exit(-1); } if (rle_dflt_hdr.alpha == 0) { isalpha = FALSE; VPRINTF(stderr, "No alpha channel.\n"); } else if (rle_dflt_hdr.alpha == 1) { isalpha = TRUE; VPRINTF(stderr, "Alpha channel exists!\n"); } else { fprintf(stderr, "alpha = %d, I don't know how to handle this!\n", rle_dflt_hdr.alpha); exit(-1); } switch (rle_dflt_hdr.background) { case 0: VPRINTF(stderr, "Use all pixels, ignore background color."); break; case 1: VPRINTF(stderr, "Use only non-background pixels, ignore background color."); break; case 2: VPRINTF(stderr, "Use only non-background pixels, clear to background color (default)."); break; default: VPRINTF(stderr, "Unknown background flag!\n"); break; } for (i = 0; i < rle_dflt_hdr.ncolors; i++) VPRINTF(stderr, " %d", rle_dflt_hdr.bg_color[i]); if (rle_dflt_hdr.ncolors == 1 && rle_dflt_hdr.ncmap == 3) { VPRINTF(stderr, " (%d %d %d)\n", rle_dflt_hdr.cmap[rle_dflt_hdr.bg_color[0]]>>8, rle_dflt_hdr.cmap[rle_dflt_hdr.bg_color[0]+256]>>8, rle_dflt_hdr.cmap[rle_dflt_hdr.bg_color[0]+512]>>8); } else if (rle_dflt_hdr.ncolors == 3 && rle_dflt_hdr.ncmap == 3) { VPRINTF(stderr, " (%d %d %d)\n", rle_dflt_hdr.cmap[rle_dflt_hdr.bg_color[0]]>>8, rle_dflt_hdr.cmap[rle_dflt_hdr.bg_color[1]+256]>>8, rle_dflt_hdr.cmap[rle_dflt_hdr.bg_color[2]+512]>>8); } else VPRINTF(stderr, "\n"); if (rle_dflt_hdr.comments) for (i = 0; rle_dflt_hdr.comments[i] != NULL; i++) VPRINTF(stderr, "%s\n", rle_dflt_hdr.comments[i]); } /*----------------------------------------------------------------------------- * Write the wavefront header. */ void write_rlb_header(minx, maxx, miny, maxy, frame_number) int minx, maxx, miny, maxy, frame_number; { char *ctime(); char *d_str; long second; long time(); bzero(&rlb_head, 740); rlb_head.window.left = minx; rlb_head.window.right = maxx; rlb_head.window.top = maxy; rlb_head.window.bottom = miny; rlb_head.active_window.left = rlb_head.window.left; rlb_head.active_window.right = rlb_head.window.right; rlb_head.active_window.top = rlb_head.window.top; rlb_head.active_window.bottom = rlb_head.window.bottom; rlb_head.frame = frame_number; rlb_head.num_chan = 3; rlb_head.num_matte = 1; strcpy(rlb_head.gamma, "2.2000"); strcpy(rlb_head.red_pri, "0.670 0.330"); strcpy(rlb_head.green_pri, "0.210 0.710"); strcpy(rlb_head.blue_pri, "0.140 0.080"); strcpy(rlb_head.white_pt, "0.310 0.316"); d_str = strrchr(rlaname, '/'); if ( d_str == NULL ) d_str = rlaname; strncpy(rlb_head.name, d_str, 29); rlb_head.name[29] = '\0'; strcpy(rlb_head.desc, "A Wavefront file converted from an rle file."); strcpy(rlb_head.program, progname); gethostname(rlb_head.machine, 32); strcpy(rlb_head.user, getenv("USER")); second = time((long *)NULL); d_str = ctime(&second); strncpy(rlb_head.date, &d_str[4], 12); strncpy(&rlb_head.date[12], &d_str[19], 5); rlb_head.date[17] = '\0'; strcpy(rlb_head.aspect, "user defined"); sprintf(rlb_head.aspect_ratio, "%3.2f", (float)(maxx-minx+1)/(maxy-miny+1)); strcpy(rlb_head.chan, "rgb"); /* * The following fields do not really need to be set because they should * all be zero and already are because bzero was used on the entire header. */ /* rlb_head.aux_mask = 0; rlb_head.encode_type = 0; rlb_head.field = 0; rlb_head.filter_type = 0; rlb_head.job_num = 0; rlb_head.lut_size = 0; rlb_head.lut_type = 0; rlb_head.magic_number = 0; rlb_head.mix_type = 0; rlb_head.num_aux = 0; rlb_head.padding = 0; rlb_head.storage_type = 0; rlb_head.user_space_size = 0; rlb_head.wf_space_size = 0; */ fwrite(&rlb_head, 740, 1, fpout); } /*----------------------------------------------------------------------------- * Encode the data before writing. */ int encode(c_in, c_out, width) U_CHAR *c_in; U_CHAR *c_out; int width; { int len; int ct; len = 0; while (width > 0) { if ((width > 1) && (c_in[0] == c_in[1])) { /* * Cruise until we find a different pixel value. */ for (ct = 2; ct < width; ct++) { if (c_in[ct] != c_in[ct-1]) break; if (ct >= 127) break; } /* * Write out the count. */ *c_out++ = ct - 1; len++; /* * Write out the value. */ *c_out++ = *c_in; len++; width -= ct; c_in += ct; } else { /* * Cruise until they can be encoded again. */ for (ct = 1; ct < width; ct++) { if ((width - ct > 1) && (c_in[ct] == c_in[ct+1])) break; if (ct >= 127) break; } /* * Write out the count. */ *c_out++ = 256 - ct; len++; /* * Copy string of pixels. */ for (; ct-- > 0; len++, width--) *c_out++ = *c_in++; } } return len; } /*----------------------------------------------------------------------------- * Write the data portion of the file. */ void write_rlb_data() { rle_pixel **scanline; U_CHAR *red, *green, *blue, *matte; U_CHAR *buf; int *offset; int width, height; int scan, x, y; short len; long offptr; /* * Create a scanline offset table then write it to reserve space in the file. */ width = rlb_head.window.right - rlb_head.window.left + 1; height = rlb_head.window.top - rlb_head.window.bottom + 1; if (!(offset = (int *)malloc(sizeof(int) * height))) { fprintf(stderr, "Offset malloc failed!\n"); exit(-3); } offptr = ftell(fpout); if (fwrite(offset, sizeof(int), height, fpout) != height) { fprintf(stderr, "Offset table write failed!\n"); exit(-4); } if (!(buf = (U_CHAR *)malloc(sizeof(U_CHAR) * width * 2))) { fprintf(stderr, "Buf malloc failed!\n"); exit(-7); } if (!(red = (U_CHAR *)malloc(sizeof(U_CHAR) * width * 4))) { fprintf(stderr, "Red scanline malloc failed!\n"); exit(-8); } green = &red[width]; blue = &green[width]; matte = &blue[width]; /* * Loop through those scan lines. */ if (!(rle_row_alloc(&rle_dflt_hdr, &scanline) == 0)) { fprintf(stderr, "rle row alloc failed!\n"); exit(-1); } for (scan = 0; scan < height; scan++) { y = rle_getrow(&rle_dflt_hdr, scanline); switch (visual) { case GRAYSCALE: /* 8 bits without colormap */ red = scanline[0]; green = scanline[0]; blue = scanline[0]; for (x = 0; x < width; x++) matte[x] = (red[x] || green[x] || blue ? 255 : 0); break; case TRUECOLOR: /* 24 bits with colormap */ if (isalpha) { matte = scanline[-1]; for (x = 0; x < width; x++) { red[x] = colormap[scanline[0][x]]>>8; green[x] = colormap[scanline[1][x]+256]>>8; blue[x] = colormap[scanline[2][x]+512]>>8; } } else for (x = 0; x < width; x++) { if (colormap[scanline[0][x]]>>8 != scanline[0][x] || colormap[scanline[1][x]+256]>>8 != scanline[1][x] || colormap[scanline[2][x]+512]>>8 != scanline[2][x]) fprintf(stderr,"A truecolor image with colormap whose resulting values don't match!\n"); red[x] = colormap[scanline[0][x]]>>8; green[x] = colormap[scanline[1][x]+256]>>8; blue[x] = colormap[scanline[2][x]+512]>>8; matte[x] = (red[x] || green[x] || blue ? 255 : 0); } break; case DIRECTCOLOR: /* 24 bits without colormap */ if (isalpha) { matte = scanline[-1]; red = scanline[0]; green = scanline[1]; blue = scanline[2]; } else { red = scanline[0]; green = scanline[1]; blue = scanline[2]; for (x = 0; x < width; x++) matte[x] = (red[x] || green[x] || blue ? 255 : 0); } break; case PSEUDOCOLOR: /* 8 bits with colormap */ for (x = 0; x < width; x++) { red[x] = colormap[scanline[0][x]]>>8; green[x] = colormap[scanline[0][x]+256]>>8; blue[x] = colormap[scanline[0][x]+512]>>8; matte[x] = (red[x] || green[x] || blue ? 255 : 0); } break; default: break; } /* * Record the location in the file. */ offset[scan] = ftell(fpout); /* * Write the red scan line. */ len = encode(red, buf, width); fwrite(&len, sizeof(short), 1, fpout); fwrite(buf, sizeof(U_CHAR), (int)len, fpout); /* * Write the green scan line. */ len = encode(green, buf, width); fwrite(&len, sizeof(short), 1, fpout); fwrite(buf, sizeof(U_CHAR), (int)len, fpout); /* * Write the blue scan line. */ len = encode(blue, buf, width); fwrite(&len, sizeof(short), 1, fpout); fwrite(buf, sizeof(U_CHAR), (int)len, fpout); /* * Write the matte scan line. */ len = encode(matte, buf, width); fwrite(&len, sizeof(short), 1, fpout); fwrite(buf, sizeof(U_CHAR), (int)len, fpout); } /* end of for scan = 0 to height */ /* * Write that offset table again with correct values. */ fseek(fpout, offptr, 0); fwrite(offset, sizeof(int), height, fpout); /* * Free up some stuff. */ free(offset); free(buf); free(red); } /*----------------------------------------------------------------------------- * Convert an rle file into an rla file. */ int main(argc, argv) int argc; char **argv; { char *lperiodP, *fname = NULL; int minx, maxx, miny, maxy, frame_number = 1; /* * Get those options. */ if (!scanargs(argc,argv, "% v%- h%- infile%s", &verbose, &header, &fname)) exit(-1); /* * Open the file. */ fpin = rle_open_f( cmd_name( argv ), fname, "r" ); if (!header) { strcpy(rlaname, fname); lperiodP = strrchr(rlaname, '.'); if (lperiodP) strcpy(lperiodP, ".rla"); else strcat(rlaname, ".rla"); if (!(fpout = fopen(rlaname, "w"))) { fprintf(stderr, "Cannot open %s for writing.\n", rlaname); exit(-1); } } strncpy(progname, cmd_name( argv ), 29); progname[29] = 0; /* * Read the rle file header. */ read_rle_header(&minx, &maxx, &miny, &maxy); if (header) exit(0); /* * Write the rlb file header. */ write_rlb_header(minx, maxx, miny, maxy, frame_number); /* * Write the rest of the Wavefront (rlb) file. */ write_rlb_data(); fclose(fpin); fclose(fpout); return 0; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.