1 /*
2 Gri - A language for scientific graphics programming
3 Copyright (C) 2008 Daniel Kelley
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 //#define DEBUG_IMAGE 1 // for debugging
21 #include <stdio.h>
22 #include <string.h>
23 #include "extern.hh"
24
25 /*
26 * Image things (shared by other files through image_ex.h)
27 */
28 double _image0 = 0.0, _image255 = 0.0; /* uservalue <-> [0,255]
29 * scale */
30 double _image_missing_color_red = 1.0; /* for missing data */
31 double _image_missing_color_green = 1.0; /* for missing data */
32 double _image_missing_color_blue = 1.0; /* for missing data */
33 double _image_llx, _image_lly, _image_urx, _image_ury; /* coords */
34 double *_imageHist;
35 int _image_color_model = 0; /* 0=bw 1=rgb */
36 bool _imageTransform_exists = false;
37 bool _imageHist_exists = false;
38 IMAGE _image, _imageMask;
39 unsigned char *_imageTransform;
40
41 static bool x_image_scale_defined = false;
42 static bool y_image_scale_defined = false;
43 void show_image_transform(void); /* for debugging */
44
45 void
show_image_transform()46 show_image_transform()
47 {
48 if (_imageTransform_exists) {
49 int i;
50 printf("_imageTransform[0-255] is:\n");
51 for (i = 0; i < 256; i++) {
52 printf("im_tr[%d] = %d\n", i, _imageTransform[i]);
53 }
54 } else {
55 printf("_imageTransform[] NOT DEFINED YET\n");
56 }
57 }
58
59 bool
define_image_scales(double llx,double lly,double urx,double ury)60 define_image_scales(double llx, double lly, double urx, double ury)
61 {
62 if (llx != urx) {
63 _image_llx = llx;
64 _image_urx = urx;
65 x_image_scale_defined = true;
66 }
67 if (lly != ury) {
68 _image_lly = lly;
69 _image_ury = ury;
70 y_image_scale_defined = true;
71 }
72 return true;
73 }
74
75 bool
image_scales_defined()76 image_scales_defined()
77 {
78 return ((x_image_scale_defined && y_image_scale_defined) ? true : false);
79 }
80
81 /*
82 * Blank out image; make it be bw, not color.
83 */
84 bool
blank_image()85 blank_image()
86 {
87 if (_image.storage_exists) {
88 if (_image.image != NULL)
89 free(_image.image);
90 _image.image = NULL;
91 _image.storage_exists = false;
92 }
93 _image.ras_width = _image.ras_height = _image.ras_length = 0;
94 _image_llx = _image_lly = 0.0;
95 _image_urx = _image_ury = 0.0;
96 _image0 = _image255 = 0.0; /* used by image_range_exists() */
97 _image_color_model = 0;
98 x_image_scale_defined = false;
99 y_image_scale_defined = false;
100 _imageHist_exists = false;
101 /*
102 * Make transform into an even ramp, for each or R, G, B. Note that val
103 * will wrap around at 255.
104 */
105 unsigned int i;
106 unsigned char val;
107 for (val = 0, i = 0; i < 768; i++, val++)
108 _imageTransform[i] = val;
109 _imageTransform_exists = true;
110 #ifdef DEBUG_IMAGE
111 printf("%s:%d blanked image with storage at %X\n",__FILE__,__LINE__,(int)(_image.image));
112 #endif
113 return true;
114 }
115
116 bool
blank_imageMask()117 blank_imageMask()
118 {
119 if (_imageMask.storage_exists) {
120 free(_imageMask.image);
121 _imageMask.image = NULL;
122 _imageMask.storage_exists = false;
123 }
124 _imageMask.ras_width = _imageMask.ras_height = _imageMask.ras_length = 0;
125 #ifdef DEBUG_IMAGE
126 printf("%s:%d blanked imageMask with storage at %X\n",__FILE__,__LINE__,(int)(_imageMask.image));
127 #endif
128 return true;
129 }
130 bool
initialize_image()131 initialize_image()
132 {
133 _image.image = NULL;
134 _image.storage_exists = false;
135 GET_STORAGE(_imageTransform, unsigned char, 3 * 256);
136 return blank_image();
137 }
138 bool
initialize_imageMask()139 initialize_imageMask()
140 {
141 _imageMask.image = NULL;
142 _imageMask.storage_exists = false;
143 return blank_imageMask();
144 }
145
146 // Tell if the image range exists (created by `set image range').
147 bool
image_range_exists()148 image_range_exists()
149 {
150 return ((_image0 != 0.0 || _image255 != 0.0) ? true : false);
151 }
152
153 #if 0
154 //bool
155 //image_exists()
156 //{
157 // return ((_image.ras_length > 0) ? true : false);
158 //}
159 //bool
160 //imageMask_exists()
161 //{
162 // return ((_imageMask.ras_length > 0) ? true : false);
163 //}
164 #endif
165
166 /*
167 * Calculate histogram of image, normalized to sum to 1 over all image
168 * values. Histogram is defined in _imageHist[]; for example, _imageHist[0]
169 * is the normalized fraction of pixels with value 0.
170 *
171 * NOTE this code assumes 8bit images; to change that, change the symbol NUM,
172 * and change the unsigned char references to whatever makes sense.
173 */
174 #define NUM 256 /* change if not 8 bit images */
175 bool
calculate_image_histogram()176 calculate_image_histogram()
177 {
178 long good = 0, mhis[NUM];
179 int i;
180 if (!_image.storage_exists) {
181 err("no image exists");
182 return false;
183 }
184 if (_imageHist_exists)
185 return true;
186 for (i = 0; i < NUM; i++)
187 mhis[i] = 0;
188 if (_imageMask.storage_exists) {
189 long max = _image.ras_width * _image.ras_height;
190 unsigned char *im = _image.image;
191 unsigned char *imMask = _imageMask.image;
192 for (i = 0; i < max; i++) {
193 if (!*(imMask)) {
194 mhis[*im]++;
195 good++;
196 }
197 im++;
198 imMask++;
199 }
200 } else {
201 long max = _image.ras_width * _image.ras_height;
202 unsigned char *im = _image.image;
203 for (i = 0; i < max; i++) {
204 mhis[*im]++;
205 good++;
206 im++;
207 }
208 }
209 for (i = 0; i < NUM; i++)
210 _imageHist[i] = (double) mhis[i] / (double) good;
211 _imageHist_exists = true;
212 return true;
213 }
214
215 #undef NUM
216
217 double
image_to_value(int c)218 image_to_value(int c)
219 {
220 return (double) (_image0 + c * (_image255 - _image0) / 255.0);
221 }
222
223 /* value_to_image() -- conv double to uchar image value */
224 /*
225 * XREF convert_grid_to_imageCmd()
226 */
227 unsigned char
value_to_image(double v)228 value_to_image(double v)
229 {
230 int I;
231 I = (int) floor(0.5 + (255.0 * (v - _image0) / (_image255 - _image0)));
232 if (I < 0)
233 return ((unsigned char) 0);
234 else if (I > 255)
235 return ((unsigned char) 255);
236 else
237 return ((unsigned char) I);
238 }
239