Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rleflip.c
Go to the documentation of this file.
1 /*
2  * This software is copyrighted as noted below. It may be freely copied,
3  * modified, and redistributed, provided that the copyright notice is
4  * preserved on all copies.
5  *
6  * There is no warranty or other guarantee of fitness for this software,
7  * it is provided solely "as is". Bug reports or fixes may be sent
8  * to the author, who may or may not act on them as he desires.
9  *
10  * You may not include this software in a program or other software product
11  * without supplying the source, or without informing the end-user that the
12  * source is available for no extra charge.
13  *
14  * If you modify this software, you should include a notice giving the
15  * name of the person performing the modification, the date of modification,
16  * and the reason for such modification.
17  */
18 /*
19  * flip.c - Invert, reflect or 90-degree rotate an rle image.
20  *
21  * Author: John W. Peterson
22  * Computer Science Dept.
23  * University of Utah
24  * Date: Mon Jun 23 1986
25  * Copyright (c) 1986, University of Utah
26  *
27  * Usage is:
28  * flip [-v | -h | -l | -r] [ infile ] [ -o outfile ]
29  *
30  * Where the flags mean:
31  * -v : Vertical flip (top to bottom)
32  * -h : Horizontal flip (right to left)
33  * -r : Rotate image 90 degrees right (clockwise)
34  * -l : Rotate image 90 degrees left (counter-clockwise)
35  * -o : Specify an output file
36  */
37 
38 
39 #include <stdio.h>
40 #include "rle.h"
41 
42 #define VERT_FLAG 0x01 /* Command line flags */
43 #define HORIZ_FLAG 0x02 /* must match appearance in scanargs */
44 #define LEFT_FLAG 0x04
45 #define RIGHT_FLAG 0x08
46 
47 void
49 int argc;
50 char *argv[];
51 {
52  int rle_cnt;
53  int flags = 0, oflag = 0;
54  char *infilename = NULL, *out_fname = NULL;
55  FILE *outfile = stdout;
56  int xlen, ylen, i, j, chan;
57  int xlinewidth;
58  rle_hdr in_hdr, out_hdr;
59  rle_pixel *rastptr, *rasterbase;
60  rle_pixel **temp_line;
61  rle_pixel **rows;
62  int nchan; /* Number of channels actually used. */
63  int rle_err;
64 
65  in_hdr = *rle_hdr_init( NULL );
66  out_hdr = *rle_hdr_init( NULL );
67 
68  if (scanargs(argc, argv, "% rlhv!- o%-outfile!s infile%s",
69  &flags, &oflag, &out_fname, &infilename) == 0)
70  {
71  exit(-1);
72  }
73 
74  in_hdr.rle_file = rle_open_f(cmd_name( argv ), infilename, "r");
75  rle_names( &in_hdr, cmd_name( argv ), infilename, 0 );
76  rle_names( &out_hdr, in_hdr.cmd, out_fname, 0 );
77 
78  for ( rle_cnt = 0;
79  (rle_err = rle_get_setup( &in_hdr )) == RLE_SUCCESS;
80  rle_cnt++ )
81  {
82  (void)rle_hdr_cp( &in_hdr, &out_hdr );
83  if ( rle_cnt == 0 )
84  outfile = rle_open_f(cmd_name( argv ), out_fname, "w");
85  out_hdr.rle_file = outfile;
86 
87  rle_addhist( argv, &in_hdr, &out_hdr );
88 
89  nchan = out_hdr.alpha + out_hdr.ncolors;
90 
91  /* Make row pointers for all seasons. */
92  rows = (rle_pixel **) malloc( nchan * sizeof( rle_pixel * ) );
93  RLE_CHECK_ALLOC( cmd_name( argv ), rows, "image data" );
94 
95  xlen = in_hdr.xmax - in_hdr.xmin + 1;
96  ylen = in_hdr.ymax - in_hdr.ymin + 1;
97 
98  /* getrow and putrow assume the scanline starts at pixel 0 */
99  xlinewidth = in_hdr.xmax + 1;
100 
101  /* Note:
102  * When you read in a row of pixels with rle_getrow, it places blank
103  * pixels between 0 and xmin of your buffer. However, when you
104  * use rle_putrow to write them out, the buffer must be pointing at
105  * where the data actually starts (i.e., at [xmin] of the getrow
106  * buffer. */
107 
108  /* WARNING: Heavy-duty pointer munging ahead */
109 
110  rasterbase = (rle_pixel *) malloc( xlinewidth * ylen * nchan );
111  RLE_CHECK_ALLOC( cmd_name( argv ), rasterbase, "raster" );
112  rastptr = rasterbase;
113 
114  /****************************************************
115  * Read in all of the pixels
116  ****************************************************/
117 
118  for (i = in_hdr.ymin; i <= in_hdr.ymax; i++)
119  {
120  for (chan=0; chan < nchan; chan++)
121  {
122  rows[chan] = rastptr;
123  /* Increment pointer by xlinewidth */
124  rastptr = &(rastptr[xlinewidth]);
125  }
126  rle_getrow( &in_hdr, &rows[out_hdr.alpha] );
127  }
128 
129  /****************************************************
130  * Invert along vertical axis
131  ****************************************************/
132 
133  if (flags == VERT_FLAG)
134  {
135  rle_put_setup( &out_hdr );
136 
137  /* Find last row in raster */
138  rastptr = &(rasterbase[xlinewidth * (ylen - 1) * nchan]);
139 
140  for (i = out_hdr.ymin; i <= out_hdr.ymax; i++)
141  {
142  for (chan=0; chan < nchan; chan++)
143  {
144  rows[chan] = &(rastptr[out_hdr.xmin]);
145  /* Increment pointer by xlinewidth */
146  rastptr = &(rastptr[xlinewidth]);
147  }
148  rle_putrow( &rows[out_hdr.alpha], xlen, &out_hdr );
149  rastptr = &(rastptr[ - 2 * nchan * xlinewidth ]);
150  }
151  }
152  else
153 
154  /****************************************************
155  * Reflect across horizontal axis
156  ****************************************************/
157 
158  if (flags == HORIZ_FLAG)
159  {
160  register rle_pixel *inpxl, *outpxl;
161 
162  rle_put_setup( &out_hdr );
163 
164  if (rle_row_alloc( &out_hdr, &temp_line ) < 0)
165  RLE_CHECK_ALLOC( cmd_name( argv ), 0, 0 );
166  if (out_hdr.alpha)
167  temp_line--; /* Use zero based (vs. -1 based) addressing */
168 
169  /* Temp row used to swap pixel order */
170  for (chan = 0; chan < nchan; chan++)
171  rows[chan] = &(temp_line[chan][out_hdr.xmin]);
172 
173  for (i = 0; i < ylen; i++)
174  {
175  rastptr = &(rasterbase[i * xlinewidth * nchan]);
176 
177  for (chan = 0; chan < nchan; chan++)
178  {
179  inpxl =
180  &(rastptr[chan * xlinewidth + xlinewidth - xlen]);
181  outpxl = &(temp_line[chan][xlinewidth-1]);
182 
183  for (j = 0; j < xlen; j++)
184  *outpxl-- = *inpxl++;
185  }
186  rle_putrow( &rows[out_hdr.alpha], xlen, &out_hdr );
187  }
188  }
189  else
190 
191  /****************************************************
192  * Rotation
193  ****************************************************/
194  if ((flags == RIGHT_FLAG) || (flags == LEFT_FLAG))
195  {
196  int linebytes, chan_offset;
197  int lineoff;
198  int oxlen, oylen;
199  register rle_pixel *outptr;
200 
201  /* Must first adjust size of output image... */
202  out_hdr.xmax = in_hdr.xmin + ylen - 1;
203  out_hdr.ymax = in_hdr.ymin + xlen - 1;
204 
205  oxlen = out_hdr.xmax - out_hdr.xmin + 1;
206  oylen = out_hdr.ymax - out_hdr.ymin + 1;
207 
208  rle_put_setup( &out_hdr );
209 
210  if (rle_row_alloc( &out_hdr, &temp_line ) < 0)
211  RLE_CHECK_ALLOC( cmd_name( argv ), 0, 0 );
212  if (out_hdr.alpha)
213  temp_line--; /* Use zero based (vs. -1 based) */
214  /* addressing */
215 
216  /* Temp row used to swap pixel order */
217  for (chan = 0; chan < nchan; chan++)
218  rows[chan] = temp_line[chan];
219 
220  linebytes = nchan * xlinewidth; /* Bytes in entire */
221  /* input scanline */
222 
223  if (flags == LEFT_FLAG)
224  {
225  /****************************************************
226  * Rotate left
227  ****************************************************/
228  for (i = 0; i < oylen; i++)
229  {
230  lineoff = xlinewidth - xlen + i;
231  for (chan = 0; chan < nchan; chan++)
232  {
233  /* Bytes upto input chan */
234  chan_offset = lineoff + xlinewidth * chan;
235  outptr = temp_line[chan];
236  for (j = oxlen - 1; j >= 0; j--)
237  *outptr++ =
238  rasterbase[j * linebytes + chan_offset];
239  }
240  rle_putrow( &rows[out_hdr.alpha], oxlen, &out_hdr );
241  }
242  }
243  else
244  {
245  /****************************************************
246  * Rotate right
247  ****************************************************/
248 
249  for (i = 0; i < oylen; i++)
250  {
251  for (chan = 0; chan < nchan; chan++)
252  {
253  /* Bytes upto input chan */
254  chan_offset = xlinewidth * chan + (xlinewidth - 1 - i);
255  outptr = temp_line[chan];
256  for (j = 0; j < oxlen; j++)
257  {
258  *outptr++ = rasterbase[j * linebytes + chan_offset];
259  }
260  }
261  rle_putrow( &rows[out_hdr.alpha], oxlen, &out_hdr );
262  }
263  }
264  }
265 
266  rle_puteof( &out_hdr );
267  free( rows );
268  free( rasterbase );
269  }
270 
271  if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
272  rle_get_error( rle_err, argv[0], infilename );
273 
274  exit( 0 );
275 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
int xmin
Definition: rle.h:100
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
Definition: rle_hdr.c:119
#define VERT_FLAG
Definition: rleflip.c:42
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
#define RLE_EMPTY
Definition: rle.h:73
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void main(int argc, char **argv)
Definition: aliastorle.c:121
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
Definition: rle_row_alc.c:56
#define LEFT_FLAG
Definition: rleflip.c:44
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
#define RLE_SUCCESS
Definition: rle.h:70
int ymin
Definition: rle.h:100
int rle_get_error(int code, const char *pgmname, const char *fname)
Definition: rle_error.c:76
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
#define RIGHT_FLAG
Definition: rleflip.c:45
const char * cmd
Definition: rle.h:133
void rle_puteof(rle_hdr *the_hdr)
Definition: rle_putrow.c:474
void rle_putrow(rows, int rowlen, rle_hdr *the_hdr)
Definition: rle_putrow.c:96
int xmax
Definition: rle.h:100
#define RLE_EOF
Definition: rle.h:74
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
int alpha
Definition: rle.h:100
#define HORIZ_FLAG
Definition: rleflip.c:43
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86