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.