This is rleflip.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.
*/
/*
* flip.c - Invert, reflect or 90-degree rotate an rle image.
*
* Author: John W. Peterson
* Computer Science Dept.
* University of Utah
* Date: Mon Jun 23 1986
* Copyright (c) 1986, University of Utah
*
* Usage is:
* flip [-v | -h | -l | -r] [ infile ] [ -o outfile ]
*
* Where the flags mean:
* -v : Vertical flip (top to bottom)
* -h : Horizontal flip (right to left)
* -r : Rotate image 90 degrees right (clockwise)
* -l : Rotate image 90 degrees left (counter-clockwise)
* -o : Specify an output file
*/
#include <stdio.h>
#include "rle.h"
#ifdef USE_STDLIB_H
#include <stdlib.h>
#else
#ifdef VOID_STAR
extern void *malloc();
#else
extern char *malloc();
#endif
extern void free();
#endif /* USE_STDLIB_H */
#define VERT_FLAG 0x01 /* Command line flags */
#define HORIZ_FLAG 0x02 /* must match appearance in scanargs */
#define LEFT_FLAG 0x04
#define RIGHT_FLAG 0x08
void
main(argc, argv)
int argc;
char *argv[];
{
int rle_cnt = 0;
int flags = 0, oflag = 0;
char *infilename = NULL, *out_fname = NULL;
FILE *outfile = stdout;
int xlen, ylen, i, j, chan;
int xlinewidth;
rle_hdr in_hdr, out_hdr;
rle_pixel *rastptr, *rasterbase;
rle_pixel **temp_line;
rle_pixel **rows;
#ifndef VOID_STAR
char *malloc();
#else
extern void *malloc();
#endif
int nchan; /* Number of channels actually used. */
int rle_err;
if (scanargs(argc, argv, "% rlhv!- o%-outfile!s infile%s",
&flags, &oflag, &out_fname, &infilename) == 0)
{
exit(-1);
}
in_hdr.rle_file = rle_open_f(cmd_name( argv ), infilename, "r");
while ( (rle_err = rle_get_setup( &in_hdr )) == RLE_SUCCESS )
{
rle_cnt++;
out_hdr = in_hdr;
if ( rle_cnt == 1 )
outfile = rle_open_f(cmd_name( argv ), out_fname, "w");
out_hdr.rle_file = outfile;
rle_addhist( argv, &in_hdr, &out_hdr );
nchan = out_hdr.alpha + out_hdr.ncolors;
/* Make row pointers for all seasons. */
rows = (rle_pixel **) malloc( nchan * sizeof( rle_pixel * ) );
if (! rows)
{
fprintf(stderr, "%s: malloc failed\n", cmd_name( argv ));
exit( -1 );
}
xlen = in_hdr.xmax - in_hdr.xmin + 1;
ylen = in_hdr.ymax - in_hdr.ymin + 1;
/* getrow and putrow assume the scanline starts at pixel 0 */
xlinewidth = in_hdr.xmax + 1;
/* Note:
* When you read in a row of pixels with rle_getrow, it places blank
* pixels between 0 and xmin of your buffer. However, when you
* use rle_putrow to write them out, the buffer must be pointing at
* where the data actually starts (i.e., at [xmin] of the getrow
* buffer. */
/* WARNING: Heavy-duty pointer munging ahead */
rasterbase = (rle_pixel *) malloc( xlinewidth * ylen * nchan );
if (rasterbase == NULL)
{
fprintf(stderr, "flip: No memory for raster\n");
exit(-1);
}
rastptr = rasterbase;
/****************************************************
* Read in all of the pixels
****************************************************/
for (i = in_hdr.ymin; i <= in_hdr.ymax; i++)
{
for (chan=0; chan < nchan; chan++)
{
rows[chan] = rastptr;
/* Increment pointer by xlinewidth */
rastptr = &(rastptr[xlinewidth]);
}
rle_getrow( &in_hdr, &rows[out_hdr.alpha] );
}
/****************************************************
* Invert along vertical axis
****************************************************/
if (flags == VERT_FLAG)
{
rle_put_setup( &out_hdr );
/* Find last row in raster */
rastptr = &(rasterbase[xlinewidth * (ylen - 1) * nchan]);
for (i = out_hdr.ymin; i <= out_hdr.ymax; i++)
{
for (chan=0; chan < nchan; chan++)
{
rows[chan] = &(rastptr[out_hdr.xmin]);
/* Increment pointer by xlinewidth */
rastptr = &(rastptr[xlinewidth]);
}
rle_putrow( &rows[out_hdr.alpha], xlen, &out_hdr );
rastptr = &(rastptr[ - 2 * nchan * xlinewidth ]);
}
}
else
/****************************************************
* Reflect across horizontal axis
****************************************************/
if (flags == HORIZ_FLAG)
{
register rle_pixel *inpxl, *outpxl;
rle_put_setup( &out_hdr );
if (rle_row_alloc( &out_hdr, &temp_line ))
fprintf(stderr, "%s: Ran out of malloc space\n",
cmd_name( argv ));
if (out_hdr.alpha)
temp_line--; /* Use zero based (vs. -1 based) addressing */
/* Temp row used to swap pixel order */
for (chan = 0; chan < nchan; chan++)
rows[chan] = &(temp_line[chan][out_hdr.xmin]);
for (i = 0; i < ylen; i++)
{
rastptr = &(rasterbase[i * xlinewidth * nchan]);
for (chan = 0; chan < nchan; chan++)
{
inpxl =
&(rastptr[chan * xlinewidth + xlinewidth - xlen]);
outpxl = &(temp_line[chan][xlinewidth-1]);
for (j = 0; j < xlen; j++)
*outpxl-- = *inpxl++;
}
rle_putrow( &rows[out_hdr.alpha], xlen, &out_hdr );
}
}
else
/****************************************************
* Rotation
****************************************************/
if ((flags == RIGHT_FLAG) || (flags == LEFT_FLAG))
{
int linebytes, chan_offset;
int lineoff;
int oxlen, oylen;
register rle_pixel *outptr;
/* Must first adjust size of output image... */
out_hdr.xmax = in_hdr.xmin + ylen - 1;
out_hdr.ymax = in_hdr.ymin + xlen - 1;
oxlen = out_hdr.xmax - out_hdr.xmin + 1;
oylen = out_hdr.ymax - out_hdr.ymin + 1;
rle_put_setup( &out_hdr );
if (rle_row_alloc( &out_hdr, &temp_line ))
fprintf(stderr, "%s: Ran out of malloc space\n",
cmd_name( argv ));
if (out_hdr.alpha)
temp_line--; /* Use zero based (vs. -1 based) */
/* addressing */
/* Temp row used to swap pixel order */
for (chan = 0; chan < nchan; chan++)
rows[chan] = temp_line[chan];
linebytes = nchan * xlinewidth; /* Bytes in entire */
/* input scanline */
if (flags == LEFT_FLAG)
{
/****************************************************
* Rotate left
****************************************************/
for (i = 0; i < oylen; i++)
{
lineoff = xlinewidth - xlen + i;
for (chan = 0; chan < nchan; chan++)
{
/* Bytes upto input chan */
chan_offset = lineoff + xlinewidth * chan;
outptr = temp_line[chan];
for (j = oxlen - 1; j >= 0; j--)
*outptr++ =
rasterbase[j * linebytes + chan_offset];
}
rle_putrow( &rows[out_hdr.alpha], oxlen, &out_hdr );
}
}
else
{
/****************************************************
* Rotate right
****************************************************/
for (i = 0; i < oylen; i++)
{
for (chan = 0; chan < nchan; chan++)
{
/* Bytes upto input chan */
chan_offset = xlinewidth * chan + (xlinewidth - 1 - i);
outptr = temp_line[chan];
for (j = 0; j < oxlen; j++)
{
*outptr++ = rasterbase[j * linebytes + chan_offset];
}
}
rle_putrow( &rows[out_hdr.alpha], oxlen, &out_hdr );
}
}
}
rle_puteof( &out_hdr );
free( rows );
free( rasterbase );
}
if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
rle_get_error( rle_err, argv[0], infilename );
exit( 0 );
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.