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