Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rleccube.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  * rleccube.c - Make an image of a "color cube".
20  *
21  * Author: Spencer W. Thomas
22  * EECS Dept.
23  * University of Michigan
24  * Date: Tue Jan 29 1991
25  * Copyright (c) 1991, University of Michigan
26  */
27 #ifndef lint
28 char rcsid[] = "$Header: /l/spencer/src/urt/tools/RCS/rleccube.c,v 3.0.1.1 1992/04/30 14:11:53 spencer Exp $";
29 #endif
30 /*
31 rleccube() Tag the file.
32 */
33 
34 #include <math.h>
35 #include "rle.h"
36 
37 /*****************************************************************
38  * TAG( main )
39  *
40  * Usage:
41  * rleccube [-p] [-w squares-wide] [-o outfile] [cube-side]
42  * Inputs:
43  * squares-wide: The number of squares per row in the output
44  * image. The output image will have
45  * ceiling(cube-side / squares-wide) rows, each
46  * with squares-wide blocks. For best results,
47  * should divide cube-side. Default is the
48  * smallest divisor of cube-side >=
49  * sqrt(cube-side).
50  * cube-side: The number of levels of red, green, and blue
51  * on each side of the color cube. The output
52  * image will have cube-side^3 pixels, arranged
53  * in squares as described above. Each square
54  * will have a constant value of red, with green
55  * and blue varying along the horizontal and
56  * vertical axes, respectively. Black will be in
57  * the lower left corner; red increases along
58  * each row from left to right. Must be <= 256.
59  * Default is 64.
60  * Outputs:
61  * outfile: If specified, the output image will be written
62  * to this file. Otherwise, it will be written
63  * to the standard output.
64  * Assumptions:
65  * [None]
66  * Algorithm:
67  * Pretty simple.
68  */
69 void
71 int argc;
72 char **argv;
73 {
74  int wflag = 0,
75  squares_wide = 8; /* Default squares/row. */
76  int cube_side = 64; /* Default size of cube is 64x64x64. */
77  double step = 255. / 63.; /* Corresponding step size. */
78  int oflag = 0;
79  int pflag = 0;
80  int nbits = 6; /* 64 = 2^6 */
81  char *ofname = NULL;
82  int r = 0, g, b;
83  int x, y;
84  rle_pixel **rows;
85 
86  if ( scanargs( argc, argv,
87  "% p%- w%-squares-wide!d o%-outfile!s cube-side%d",
88  &pflag, &wflag, &squares_wide,
89  &oflag, &ofname, &cube_side ) == 0 )
90  exit( 1 );
91 
92  if ( cube_side != 64 )
93  {
94  /* Error check. */
95  if ( cube_side < 2 || cube_side > 256 )
96  {
97  fprintf( stderr,
98  "%s: cube_side (%d given) must be >=2 and <= 256.\n",
99  cmd_name( argv ), cube_side );
100  exit( 1 );
101  }
102  /* Peano curve must have power of 2. */
103  if ( pflag )
104  {
105  register int i;
106 
107  if ( cube_side > 64 )
108  {
109  fprintf( stderr,
110  "%s: cube_side (%d given) must be <= 64 for Peano curve display.\n",
111  cmd_name( argv ), cube_side );
112  exit( 1 );
113  }
114  for ( nbits = 0, i = 1; i < cube_side; i <<= 1, nbits += 1 )
115  ;
116  if ( cube_side != i )
117  fprintf( stderr,
118  "%s: cube_side (%d given) adjusted to %d for Peano curve display.\n",
119  cmd_name( argv ), cube_side, i );
120  cube_side = i;
121  if ( wflag )
122  {
123  fprintf( stderr,
124  "%s: squares_wide (%d given) ignored for Peano curve display.\n",
125  cmd_name( argv ), squares_wide );
126  wflag = 0;
127  }
128  }
129  /* Recompute step and squares_wide. */
130  step = 255. / (cube_side - 1);
131  if ( !wflag )
132  {
133  squares_wide = (int)sqrt((double)cube_side);
134 
135  /* If cube_side isn't an exact square, search for a larger
136  * divisor of cube_side.
137  */
138  while ( cube_side % squares_wide != 0 )
139  squares_wide++;
140  }
141  }
142 
143  /* Error check. */
144  if ( wflag )
145  {
146  if ( squares_wide < 1 || squares_wide > cube_side )
147  {
148  fprintf( stderr,
149  "%s: squares_wide (%d given) must be >= 1 and <= %d.",
150  cmd_name( argv ), squares_wide, cube_side );
151  exit( 1 );
152  }
153  if ( pflag )
154  {
155  fprintf( stderr,
156  "%s: squares_wide (%d given) ignored for Peano curve display.\n",
157  cmd_name( argv ), squares_wide );
158  /* Note: only get here if cube_side was NOT given, so it's
159  * safe to reset squares_wide to its default.
160  */
161  squares_wide = 8;
162  }
163  }
164 
165  /* Set up the output. */
167  rle_dflt_hdr.xmax = cube_side * squares_wide - 1;
169  cube_side * ((cube_side + squares_wide - 1) / squares_wide) - 1;
170  rle_addhist( argv, NULL, &rle_dflt_hdr );
171  rle_dflt_hdr.rle_file = rle_open_f( cmd_name( argv ), ofname, "w" );
172  /* The other default values should be ok. */
173 
175 
176  /* Allocate scanline memory. */
177  if ( rle_row_alloc( &rle_dflt_hdr, &rows ) < 0 )
178  RLE_CHECK_ALLOC( cmd_name( argv ), 0, 0 );
179 
180  for ( y = 0; y <= rle_dflt_hdr.ymax; y++ )
181  {
182  if ( !pflag )
183  {
184  /* Green is constant per scanline. */
185  g = (int)(step * (y % cube_side));
186  for ( x = 0; x <= rle_dflt_hdr.xmax; x++ )
187  rows[1][x] = g;
188 
189  /* If first scanline of a new row, recompute red and blue. */
190  if ( g == 0 )
191  for ( x = 0; x <= rle_dflt_hdr.xmax; x++ )
192  {
193  b = (int)(step * (x % cube_side));
194  if ( b == 0 )
195  r = (int)(step * (x / cube_side +
196  squares_wide * y / cube_side));
197 
198  rows[0][x] = r;
199  rows[2][x] = b;
200  }
201  }
202  else
203  {
204  long int r;
205  int a[2], c[3];
206  int two_d_bits = (nbits * 3 / 2),
207  two_d_max = 1 << two_d_bits,
208  max_r = 1 << (3 * nbits);
209 
210  /* For each pixel on the scan-line, find its peano index
211  * and get the corresponding color.
212  */
213  a[1] = y;
214  for ( x = 0; x <= rle_dflt_hdr.xmax; x++ )
215  {
216  if ( x < two_d_max )
217  a[0] = x;
218  else
219  a[0] = 2 * two_d_max - x - 1;
220  hilbert_c2i( 2, nbits * 3 / 2, a, &r );
221  if ( x >= two_d_max )
222  r = max_r - r - 1;
223  hilbert_i2c( 3, nbits, r, c );
224  rows[0][x] = c[0] << (8 - nbits);
225  rows[1][x] = c[1] << (8 - nbits);
226  rows[2][x] = c[2] << (8 - nbits);
227  }
228  }
229 
230  rle_putrow( rows, squares_wide * cube_side, &rle_dflt_hdr );
231  }
232 
233  /* All done. */
235  exit( 0 );
236 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
char rcsid[]
Definition: rleswap.c:28
int xmin
Definition: rle.h:100
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void main(int argc, char **argv)
Definition: aliastorle.c:121
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
Definition: rle_row_alc.c:56
void hilbert_i2c(int n, int m, long int r, a)
Definition: hilbert.c:136
void hilbert_c2i(int n, int m, a, long int *r)
Definition: hilbert.c:245
int ymin
Definition: rle.h:100
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
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
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
rle_hdr rle_dflt_hdr
Definition: rle_global.c:66
FILE * rle_file
Definition: rle.h:114
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86