- more information on gif library versions in README and Makefile.PL
[imager.git] / imgdouble.c
CommitLineData
2ce44e2a
TC
1/*
2=head1 NAME
3
4imgdouble.c - implements double per sample images
5
6=head1 SYNOPSIS
7
8 i_img *im = i_img_double_new(int x, int y, int channels);
9 # use like a normal image
10
11=head1 DESCRIPTION
12
13Implements double/sample images.
14
15This basic implementation is required so that we have some larger
16sample image type to work with.
17
18=over
19
20=cut
21*/
22
23#include "image.h"
24#include "imagei.h"
25
26static int i_ppix_ddoub(i_img *im, int x, int y, i_color *val);
27static int i_gpix_ddoub(i_img *im, int x, int y, i_color *val);
28static int i_glin_ddoub(i_img *im, int l, int r, int y, i_color *vals);
29static int i_plin_ddoub(i_img *im, int l, int r, int y, i_color *vals);
30static int i_ppixf_ddoub(i_img *im, int x, int y, i_fcolor *val);
31static int i_gpixf_ddoub(i_img *im, int x, int y, i_fcolor *val);
32static int i_glinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals);
33static int i_plinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals);
34static int i_gsamp_ddoub(i_img *im, int l, int r, int y, i_sample_t *samps,
18accb2a 35 int const *chans, int chan_count);
2ce44e2a 36static int i_gsampf_ddoub(i_img *im, int l, int r, int y, i_fsample_t *samps,
18accb2a 37 int const *chans, int chan_count);
2ce44e2a
TC
38
39/*
40=item IIM_base_16bit_direct
41
42Base structure used to initialize a 16-bit/sample image.
43
44Internal.
45
46=cut
47*/
48static i_img IIM_base_double_direct =
49{
50 0, /* channels set */
51 0, 0, 0, /* xsize, ysize, bytes */
9a88a5e6 52 ~0U, /* ch_mask */
2ce44e2a
TC
53 i_double_bits, /* bits */
54 i_direct_type, /* type */
55 0, /* virtual */
56 NULL, /* idata */
57 { 0, 0, NULL }, /* tags */
58 NULL, /* ext_data */
59
60 i_ppix_ddoub, /* i_f_ppix */
61 i_ppixf_ddoub, /* i_f_ppixf */
62 i_plin_ddoub, /* i_f_plin */
63 i_plinf_ddoub, /* i_f_plinf */
64 i_gpix_ddoub, /* i_f_gpix */
65 i_gpixf_ddoub, /* i_f_gpixf */
66 i_glin_ddoub, /* i_f_glin */
67 i_glinf_ddoub, /* i_f_glinf */
68 i_gsamp_ddoub, /* i_f_gsamp */
69 i_gsampf_ddoub, /* i_f_gsampf */
70
71 NULL, /* i_f_gpal */
72 NULL, /* i_f_ppal */
73 NULL, /* i_f_addcolor */
74 NULL, /* i_f_getcolor */
75 NULL, /* i_f_colorcount */
76 NULL, /* i_f_findcolor */
77
78 NULL, /* i_f_destroy */
79};
80
81/*
82=item i_img_double_new(int x, int y, int ch)
83
84Creates a new double per sample image.
85
86=cut
87*/
88i_img *i_img_double_new_low(i_img *im, int x, int y, int ch) {
89 mm_log((1,"i_img_double_new(x %d, y %d, ch %d)\n", x, y, ch));
1501d9b3
TC
90
91 if (x < 1 || y < 1) {
92 i_push_error(0, "Image sizes must be positive");
93 return NULL;
94 }
95 if (ch < 1 || ch > MAXCHANNELS) {
96 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
97 return NULL;
98 }
2ce44e2a
TC
99
100 *im = IIM_base_double_direct;
101 i_tags_new(&im->tags);
102 im->xsize = x;
103 im->ysize = y;
104 im->channels = ch;
105 im->bytes = x * y * ch * sizeof(double);
106 im->ext_data = NULL;
107 im->idata = mymalloc(im->bytes);
108 if (im->idata) {
109 memset(im->idata, 0, im->bytes);
110 }
111 else {
112 i_tags_destroy(&im->tags);
113 im = NULL;
114 }
115
116 return im;
117}
118
119i_img *i_img_double_new(int x, int y, int ch) {
120 i_img *im;
121
1501d9b3
TC
122 i_clear_error();
123
2ce44e2a
TC
124 im = mymalloc(sizeof(i_img));
125 if (im) {
126 if (!i_img_double_new_low(im, x, y, ch)) {
127 myfree(im);
128 im = NULL;
129 }
130 }
131
132 mm_log((1, "(%p) <- i_img_double_new\n", im));
133
134 return im;
135}
136
137static int i_ppix_ddoub(i_img *im, int x, int y, i_color *val) {
138 int off, ch;
139
140 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
141 return -1;
142
143 off = (x + y * im->xsize) * im->channels;
144 for (ch = 0; ch < im->channels; ++ch)
145 ((double*)im->idata)[off+ch] = Sample8ToF(val->channel[ch]);
146
147 return 0;
148}
149
150static int i_gpix_ddoub(i_img *im, int x, int y, i_color *val) {
151 int off, ch;
152
153 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
154 return -1;
155
156 off = (x + y * im->xsize) * im->channels;
157 for (ch = 0; ch < im->channels; ++ch)
158 val->channel[ch] = SampleFTo8(((double *)im->idata)[off+ch]);
159
160 return 0;
161}
162
163static int i_ppixf_ddoub(i_img *im, int x, int y, i_fcolor *val) {
164 int off, ch;
165
166 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
167 return -1;
168
169 off = (x + y * im->xsize) * im->channels;
170 for (ch = 0; ch < im->channels; ++ch)
171 ((double *)im->idata)[off+ch] = val->channel[ch];;
172
173 return 0;
174}
175
176static int i_gpixf_ddoub(i_img *im, int x, int y, i_fcolor *val) {
177 int off, ch;
178
179 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
180 return -1;
181
182 off = (x + y * im->xsize) * im->channels;
183 for (ch = 0; ch < im->channels; ++ch)
184 val->channel[ch] = ((double *)im->idata)[off+ch];
185
186 return 0;
187}
188
189static int i_glin_ddoub(i_img *im, int l, int r, int y, i_color *vals) {
190 int ch, count, i;
191 int off;
192 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
193 if (r > im->xsize)
194 r = im->xsize;
195 off = (l+y*im->xsize) * im->channels;
196 count = r - l;
197 for (i = 0; i < count; ++i) {
198 for (ch = 0; ch < im->channels; ++ch) {
199 vals[i].channel[ch] = SampleFTo8(((double *)im->idata)[off]);
200 ++off;
201 }
202 }
203 return count;
204 }
205 else {
206 return 0;
207 }
208}
209
210static int i_plin_ddoub(i_img *im, int l, int r, int y, i_color *vals) {
211 int ch, count, i;
212 int off;
213 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
214 if (r > im->xsize)
215 r = im->xsize;
216 off = (l+y*im->xsize) * im->channels;
217 count = r - l;
218 for (i = 0; i < count; ++i) {
219 for (ch = 0; ch < im->channels; ++ch) {
220 ((double *)im->idata)[off] = Sample8ToF(vals[i].channel[ch]);
221 ++off;
222 }
223 }
224 return count;
225 }
226 else {
227 return 0;
228 }
229}
230
231static int i_glinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) {
232 int ch, count, i;
233 int off;
234 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
235 if (r > im->xsize)
236 r = im->xsize;
237 off = (l+y*im->xsize) * im->channels;
238 count = r - l;
239 for (i = 0; i < count; ++i) {
240 for (ch = 0; ch < im->channels; ++ch) {
241 vals[i].channel[ch] = ((double *)im->idata)[off];
242 ++off;
243 }
244 }
245 return count;
246 }
247 else {
248 return 0;
249 }
250}
251
252static int i_plinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) {
253 int ch, count, i;
254 int off;
255 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
256 if (r > im->xsize)
257 r = im->xsize;
258 off = (l+y*im->xsize) * im->channels;
259 count = r - l;
260 for (i = 0; i < count; ++i) {
261 for (ch = 0; ch < im->channels; ++ch) {
262 ((double *)im->idata)[off] = vals[i].channel[ch];
263 ++off;
264 }
265 }
266 return count;
267 }
268 else {
269 return 0;
270 }
271}
272
273static int i_gsamp_ddoub(i_img *im, int l, int r, int y, i_sample_t *samps,
18accb2a 274 int const *chans, int chan_count) {
2ce44e2a
TC
275 int ch, count, i, w;
276 int off;
277
278 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
279 if (r > im->xsize)
280 r = im->xsize;
281 off = (l+y*im->xsize) * im->channels;
282 w = r - l;
283 count = 0;
284
285 if (chans) {
286 /* make sure we have good channel numbers */
287 for (ch = 0; ch < chan_count; ++ch) {
288 if (chans[ch] < 0 || chans[ch] >= im->channels) {
289 i_push_errorf(0, "No channel %d in this image", chans[ch]);
290 return 0;
291 }
292 }
293 for (i = 0; i < w; ++i) {
294 for (ch = 0; ch < chan_count; ++ch) {
295 *samps++ = SampleFTo8(((double *)im->idata)[off+chans[ch]]);
296 ++count;
297 }
298 off += im->channels;
299 }
300 }
301 else {
302 for (i = 0; i < w; ++i) {
303 for (ch = 0; ch < chan_count; ++ch) {
304 *samps++ = SampleFTo8(((double *)im->idata)[off+ch]);
305 ++count;
306 }
307 off += im->channels;
308 }
309 }
310
311 return count;
312 }
313 else {
314 return 0;
315 }
316}
317
318static int i_gsampf_ddoub(i_img *im, int l, int r, int y, i_fsample_t *samps,
18accb2a 319 int const *chans, int chan_count) {
2ce44e2a
TC
320 int ch, count, i, w;
321 int off;
322
323 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
324 if (r > im->xsize)
325 r = im->xsize;
326 off = (l+y*im->xsize) * im->channels;
327 w = r - l;
328 count = 0;
329
330 if (chans) {
331 /* make sure we have good channel numbers */
332 for (ch = 0; ch < chan_count; ++ch) {
333 if (chans[ch] < 0 || chans[ch] >= im->channels) {
334 i_push_errorf(0, "No channel %d in this image", chans[ch]);
335 return 0;
336 }
337 }
338 for (i = 0; i < w; ++i) {
339 for (ch = 0; ch < chan_count; ++ch) {
340 *samps++ = ((double *)im->idata)[off+chans[ch]];
341 ++count;
342 }
343 off += im->channels;
344 }
345 }
346 else {
347 for (i = 0; i < w; ++i) {
348 for (ch = 0; ch < chan_count; ++ch) {
349 *samps++ = ((double *)im->idata)[off+ch];
350 ++count;
351 }
352 off += im->channels;
353 }
354 }
355
356 return count;
357 }
358 else {
359 return 0;
360 }
361}
362
b8c2033e
AMH
363
364/*
365=back
366
367=head1 AUTHOR
368
369Tony Cook <tony@develop-help.com>
370
371=head1 SEE ALSO
372
373Imager(3)
374
375=cut
376*/