1 /*
2 * rlehisto.c - Create histogram image of an RLE file.
3 *
4 * Author: Gregg Townsend
5 * Department of Computer Science
6 * University of Arizona
7 * Date: June 23, 1990
8 *
9 * Original version:
10 * Author: Rod Bogart
11 * Computer Science Dept.
12 * University of Utah
13 * Date: Thu Nov 6 1986
14 * Copyright (c) 1986 Rod Bogart
15 *
16 * Flags:
17 * -b Don't count background color values for scaling.
18 * Ineffective when -c specified.
19 * -c Output cumulative values instead of discrete values.
20 * -t Print totals of each value in each channel.
21 * -h npix Set height of image.
22 * -o fname Direct output to file.
23 */
24 #ifndef lint
25 static char rcs_ident[] = "$Id: rlehisto.c,v 3.0.1.2 1992/02/11 21:36:13 spencer Exp $";
26 #endif
27
28 #include <stdio.h>
29 #include "rle.h"
30
31 #define MAXCHAN 10
32
33 int
main(argc,argv)34 main(argc, argv)
35 int argc;
36 char *argv[];
37 {
38 FILE *outfile = stdout;
39 int i, j, bflag=0, cflag=0, tflag=0, oflag=0;
40 int hist_height = 256;
41 rle_hdr in_hdr, out_hdr;
42 rle_pixel ** rows, ** rowsout;
43 rle_pixel *pixptr;
44 long *pixelcount[256];
45 long maxcount;
46 long n;
47 int chan, nchan;
48 int rle_cnt, rle_err;
49 char *infname = NULL, *outfname = NULL;
50
51 in_hdr = *rle_hdr_init( NULL );
52 out_hdr = *rle_hdr_init( NULL );
53
54 if ( scanargs( argc, argv,
55 "% b%- c%- t%- h%-height!d o%-outfile!s infile%s",
56 &bflag, &cflag, &tflag,
57 &i, &hist_height,
58 &oflag, &outfname, &infname ) == 0 )
59 exit( 1 );
60
61 in_hdr.rle_file = rle_open_f(cmd_name( argv ), infname, "r");
62 rle_names( &in_hdr, cmd_name( argv ), infname, 0 );
63 rle_names( &out_hdr, in_hdr.cmd, outfname, 0 );
64
65 for ( rle_cnt = 0;
66 (rle_err = rle_get_setup( &in_hdr )) == RLE_SUCCESS;
67 rle_cnt++ )
68 {
69 if ( rle_cnt == 0 )
70 outfile = rle_open_f(cmd_name( argv ), outfname, "w");
71
72 /* Only pay attention to bflag if background color is defined. */
73 bflag = (bflag && in_hdr.bg_color != NULL);
74
75 in_hdr.xmax -= in_hdr.xmin;
76 in_hdr.xmin = 0;
77
78 (void)rle_hdr_cp( &in_hdr, &out_hdr );
79 out_hdr.cmap = (rle_map *)NULL;
80 out_hdr.ncmap = 0;
81 out_hdr.cmaplen = 0;
82 out_hdr.background = 2;
83 out_hdr.bg_color = (int *)calloc( in_hdr.ncolors, sizeof(int) );
84 RLE_CHECK_ALLOC( cmd_name( argv ), out_hdr.bg_color,
85 "background" );
86 out_hdr.alpha = 0;
87 out_hdr.xmin = 0;
88 out_hdr.xmax = 255;
89 out_hdr.ymin = 0;
90 out_hdr.ymax = hist_height - 1;
91 out_hdr.rle_file = outfile;
92
93 nchan = in_hdr.ncolors;
94
95 if (!tflag)
96 {
97 rle_addhist( argv, &in_hdr, &out_hdr );
98 rle_put_setup( &out_hdr );
99 }
100
101 if ( rle_row_alloc( &out_hdr, &rowsout ) < 0 ||
102 rle_row_alloc( &in_hdr, &rows ) < 0 )
103 RLE_CHECK_ALLOC( cmd_name( argv ), 0, 0 );
104
105 for ( j = 0; j < 256; j++)
106 {
107 if ( rle_cnt == 0 )
108 {
109 pixelcount[j] = (long *) malloc(sizeof(long) * nchan);
110 RLE_CHECK_ALLOC( cmd_name( argv ), pixelcount[j], 0 );
111 }
112 for (chan=0; chan < nchan; chan++)
113 {
114 pixelcount[j][chan] = 0;
115 }
116 }
117 maxcount = 0;
118
119 for (j=in_hdr.ymin; j <= in_hdr.ymax; j++)
120 {
121 rle_getrow(&in_hdr, rows);
122 for (chan=0; chan < nchan; chan++)
123 {
124 pixptr = rows[chan];
125 for (i=0; i < in_hdr.xmax + 1; i++)
126 pixelcount[ *pixptr++ ][ chan ] += 1;
127 }
128 }
129
130 /* create cumulative figures if those are wanted. */
131 if (cflag)
132 {
133 for (chan = 0; chan < nchan; chan++)
134 {
135 for (j = 1; j < 256; j++)
136 pixelcount[j][chan] += pixelcount[j-1][chan];
137 if (pixelcount[255][chan] > maxcount)
138 maxcount = pixelcount[255][chan];
139 }
140 }
141 else
142 for ( chan = 0; chan < nchan; chan++ )
143 for ( j = 0; j < 256; j++ )
144 if ( bflag && j == in_hdr.bg_color[chan] )
145 continue;
146 else
147 if ( pixelcount[j][chan] > maxcount )
148 maxcount = pixelcount[j][chan];
149
150 /* after entire image has been read in, output the histogram */
151
152 if (tflag)
153 {
154 if ( rle_cnt > 0 )
155 fprintf( outfile, "\n\n" );
156 for (j = 0; j < 256; j++)
157 {
158 for (chan = 0; chan < nchan; chan++)
159 if (j > 0 && cflag) {
160 if (pixelcount[j][chan] != pixelcount[j-1][chan])
161 break;
162 } else {
163 if (pixelcount[j][chan] != 0)
164 break;
165 }
166 if (chan == nchan) /* if all entries zero, suppress line */
167 continue;
168 fprintf(outfile, "%3d.", j);
169 for (chan = 0; chan < nchan; chan++)
170 fprintf(outfile, "\t%ld", pixelcount[j][chan]);
171 fprintf(outfile, "\n");
172 }
173 }
174 else
175 {
176 for (i = 0; i < hist_height; i++)
177 {
178 n = (maxcount * i) / (hist_height - 2);
179 for (chan = 0; chan < nchan; chan++)
180 {
181 for (j = 0; j < 256; j++)
182 {
183 if (pixelcount[j][chan] > n)
184 rowsout[chan][j] = 255;
185 else
186 rowsout[chan][j] = 0;
187 }
188 }
189 rle_putrow( rowsout, 256, &out_hdr);
190 }
191 rle_puteof( &out_hdr );
192 }
193
194 /* Free memory. */
195 rle_row_free( &out_hdr, rowsout );
196 rle_row_free( &in_hdr, rows );
197 }
198 /* Check for an error. EOF or EMPTY is ok if at least one image
199 * has been read. Otherwise, print an error message.
200 */
201 if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
202 rle_get_error( rle_err, cmd_name( argv ), infname );
203
204 exit( 0 );
205 }
206