Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
crop.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  * crop.c - Crop an image to the given size.
20  *
21  * Author: Rod Bogart & 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  */
28 #ifndef lint
29 static char rcs_ident[] = "$Header: /l/spencer/src/urt/tools/RCS/crop.c,v 3.0.1.2 1992/04/30 14:09:40 spencer Exp $";
30 #endif
31 
32 #include <stdio.h>
33 #include "rle.h"
34 
35 extern void rle_box();
36 int pos_box_vals();
37 
38 void
40 int argc;
41 char *argv[];
42 {
43  rle_pixel **scanline, **rows, **outrows;
44  int xlen, i, j;
45  int xmin = -1, ymin = -1, xmax = -1, ymax = -1;
46  char *infilename = NULL, *out_fname = NULL;
47  FILE *outfile = stdout;
48  int oflag = 0, bflag = 0, bottom_row;
49  rle_hdr in_hdr, out_hdr;
50  int rle_cnt, rle_err;
51  long start;
52 
53  in_hdr = *rle_hdr_init( NULL );
54  out_hdr = *rle_hdr_init( NULL );
55 
56  if (scanargs( argc, argv,
57  "% b%- xmin%d ymin%d xmax%d ymax%d o%-outfile!s infile%s",
58  &bflag, &xmin, &ymin, &xmax, &ymax, &oflag, &out_fname,
59  &infilename ) == 0)
60  {
61  exit(-1);
62  }
63 
64  in_hdr.rle_file = rle_open_f( cmd_name( argv ), infilename, "r" );
65  rle_names( &in_hdr, cmd_name( argv ), infilename, 0 );
66  rle_names( &out_hdr, in_hdr.cmd, out_fname, 0 );
67  for ( rle_cnt = 0; ; rle_cnt++ )
68  {
69  start = ftell( in_hdr.rle_file );
70  if ( (rle_err = rle_get_setup( &in_hdr )) != RLE_SUCCESS )
71  break;
72 
73  (void)rle_hdr_cp( &in_hdr, &out_hdr );
74  rle_addhist( argv, &in_hdr, &out_hdr );
75 
76  if ( rle_cnt == 0 )
77  outfile = rle_open_f( cmd_name( argv ), out_fname, "w" );
78  out_hdr.rle_file = outfile;
79 
80  /* If bflag, then pre-scan file to get bounding box. */
81  if (bflag != 0)
82  {
83  if (xmin == -1 && start >= 0)
84  {
85  /* Common code with rlebox program. */
86  rle_box( &in_hdr, &xmin, &xmax, &ymin, &ymax );
87 
88  /* Rewind and start over. */
89  fseek( in_hdr.rle_file, start, 0 );
90  rle_get_setup( &in_hdr ); /* Should work fine this time. */
91  }
92  else
93  {
94  /* error message and exit: -b flag and box values or piped input */
95  if (xmin != -1)
96  fprintf( stderr,
97  "%s: You cannot specify the -b flag and box values together\n",
98  cmd_name( argv ) );
99  else
100  fprintf( stderr,
101  "%s: No piped input allowed with the -b flag\n",
102  cmd_name( argv ) );
103  exit(-1);
104  }
105  }
106  else if ( pos_box_vals( xmin, ymin, xmax, ymax ) != 0 )
107  {
108  fprintf( stderr,
109  "%s: You must specify either all the box coordinates or the -b flag\n",
110  cmd_name( argv ) );
111  exit(-1);
112  }
113 
114  xlen = xmax - xmin + 1;
115 
116  if ( (xmin > xmax) || (ymin > ymax) )
117  {
118  fprintf( stderr, "%s: Illegal size: %d, %d to %d, %d\n",
119  cmd_name( argv ), xmin, ymin, xmax, ymax );
120  exit(-1);
121  }
122 
123  /* should check for disjoint regions */
124 
125  out_hdr.xmin = xmin;
126  out_hdr.ymin = ymin;
127  out_hdr.xmax = xmax;
128  out_hdr.ymax = ymax;
129 
130  rle_put_setup( &out_hdr );
131 
132  if (out_hdr.xmax > in_hdr.xmax)
134  rle_row_alloc( &out_hdr, &scanline ) == 0,
135  "image data" );
136  else
138  rle_row_alloc( &in_hdr, &scanline ) == 0,
139  "image data" );
140 
141  rows = (rle_pixel **)
142  malloc((in_hdr.ncolors + in_hdr.alpha) * sizeof( rle_pixel * ));
143  RLE_CHECK_ALLOC( cmd_name( argv ), rows, "input image data" );
144 
145  outrows = (rle_pixel **)
146  malloc((in_hdr.ncolors + in_hdr.alpha) * sizeof( rle_pixel * ));
147  RLE_CHECK_ALLOC( cmd_name( argv ), outrows, "output image data" );
148 
149  if ( in_hdr.alpha )
150  {
151  rows++; /* So alpha is rows[-1] */
152  outrows++;
153  }
154 
155  for( i = -in_hdr.alpha; i < in_hdr.ncolors; i++ )
156  rows[i] = scanline[i];
157 
158  for( i = -in_hdr.alpha; i < in_hdr.ncolors; i++ )
159  outrows[i] = &scanline[i][xmin];
160 
161  /* Fill scanline with background color in case output is
162  * larger than input.
163  */
164  for ( j = -in_hdr.alpha; j < in_hdr.ncolors; j++ )
165  if ( in_hdr.bg_color && j >= 0 && in_hdr.bg_color[j] != 0 )
166  {
167  int c = in_hdr.bg_color[j];
168  register rle_pixel *pix;
169  for ( i = out_hdr.xmin, pix = &scanline[j][i];
170  i <= out_hdr.xmax;
171  i++, pix++ )
172  *pix = c;
173  }
174  else
175  bzero( (char *)&scanline[j][out_hdr.xmin],
176  out_hdr.xmax - out_hdr.xmin + 1 );
177 
178  bottom_row = in_hdr.ymin;
179  if (in_hdr.ymin > out_hdr.ymin)
180  {
181  /* Output blank scanlines if crop region is larger than data */
182  rle_skiprow(&out_hdr, in_hdr.ymin - out_hdr.ymin);
183  bottom_row = in_hdr.ymin;
184  }
185  else
186  if (in_hdr.ymin < out_hdr.ymin)
187  {
188  /* Read past extra lower scanlines */
189  for (i = in_hdr.ymin; i < out_hdr.ymin; i++)
190  rle_getrow(&in_hdr, rows );
191  bottom_row = out_hdr.ymin;
192  }
193 
194  /* Read in image */
195  for (j = bottom_row; j <= out_hdr.ymax; j++)
196  {
197  rle_getrow(&in_hdr, rows );
198 
199  rle_putrow( outrows, xlen, &out_hdr );
200  }
201  rle_puteof( &out_hdr );
202 
203  /* Skip extra upper scanlines. */
204  while ( rle_getskip( &in_hdr ) != 32768 )
205  ;
206 
207  /* Clean up for next time around. */
208  rle_row_free( (out_hdr.xmax > in_hdr.xmax) ? &out_hdr : &in_hdr,
209  scanline );
210  free( rows - in_hdr.alpha );
211  free( outrows - in_hdr.alpha );
212 
213  if ( bflag )
214  xmin = xmax = ymin = ymax = -1;
215  }
216 
217  /* Check for an error. EOF or EMPTY is ok if at least one image
218  * has been read. Otherwise, print an error message.
219  */
220  if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
221  rle_get_error( rle_err, cmd_name( argv ), infilename );
222 
223 
224  exit( 0 );
225 }
226 
227 /* Return 0 if all parameters >= 0, else -1. */
228 int
230 int x1, y1, x2, y2;
231 {
232  if ((x1 < 0) || (y1 < 0) || (x2 < 0) || (y2 < 0))
233  return -1;
234  else
235  return 0;
236 }
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
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
void rle_row_free(rle_hdr *the_hdr, rle_pixel **scanp)
Definition: rle_row_alc.c:114
#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
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
int * bg_color
Definition: rle.h:100
#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
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
unsigned int rle_getskip(rle_hdr *the_hdr)
Definition: rle_getskip.c:57
int pos_box_vals(int x1, int y1, int x2, int y2)
Definition: crop.c:229
static char rcs_ident[]
Definition: crop.c:29
void rle_skiprow(rle_hdr *the_hdr, int nrow)
Definition: rle_putrow.c:393
void rle_box(rle_hdr *the_hdr, int *xminp, int *xmaxp, int *yminp, int *ymaxp)
Definition: rle_box.c:16
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
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