- extra concept index entries
[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) {
653ea321
TC
89 int bytes;
90
2ce44e2a 91 mm_log((1,"i_img_double_new(x %d, y %d, ch %d)\n", x, y, ch));
1501d9b3
TC
92
93 if (x < 1 || y < 1) {
94 i_push_error(0, "Image sizes must be positive");
95 return NULL;
96 }
97 if (ch < 1 || ch > MAXCHANNELS) {
98 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
99 return NULL;
100 }
653ea321
TC
101 bytes = x * y * ch * sizeof(double);
102 if (bytes / y / ch / sizeof(double) != x) {
103 i_push_errorf(0, "integer overflow calculating image allocation");
104 return NULL;
105 }
2ce44e2a
TC
106
107 *im = IIM_base_double_direct;
108 i_tags_new(&im->tags);
109 im->xsize = x;
110 im->ysize = y;
111 im->channels = ch;
653ea321 112 im->bytes = bytes;
2ce44e2a
TC
113 im->ext_data = NULL;
114 im->idata = mymalloc(im->bytes);
115 if (im->idata) {
116 memset(im->idata, 0, im->bytes);
117 }
118 else {
119 i_tags_destroy(&im->tags);
120 im = NULL;
121 }
122
123 return im;
124}
125
126i_img *i_img_double_new(int x, int y, int ch) {
127 i_img *im;
128
1501d9b3
TC
129 i_clear_error();
130
2ce44e2a
TC
131 im = mymalloc(sizeof(i_img));
132 if (im) {
133 if (!i_img_double_new_low(im, x, y, ch)) {
134 myfree(im);
135 im = NULL;
136 }
137 }
138
139 mm_log((1, "(%p) <- i_img_double_new\n", im));
140
141 return im;
142}
143
144static int i_ppix_ddoub(i_img *im, int x, int y, i_color *val) {
145 int off, ch;
146
147 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
148 return -1;
149
150 off = (x + y * im->xsize) * im->channels;
35f40526
TC
151 if (I_ALL_CHANNELS_WRITABLE(im)) {
152 for (ch = 0; ch < im->channels; ++ch)
153 ((double*)im->idata)[off+ch] = Sample8ToF(val->channel[ch]);
154 }
155 else {
156 for (ch = 0; ch < im->channels; ++ch)
157 if (im->ch_mask & (1<<ch))
158 ((double*)im->idata)[off+ch] = Sample8ToF(val->channel[ch]);
159 }
2ce44e2a
TC
160
161 return 0;
162}
163
164static int i_gpix_ddoub(i_img *im, int x, int y, i_color *val) {
165 int off, ch;
166
167 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
168 return -1;
169
170 off = (x + y * im->xsize) * im->channels;
171 for (ch = 0; ch < im->channels; ++ch)
172 val->channel[ch] = SampleFTo8(((double *)im->idata)[off+ch]);
173
174 return 0;
175}
176
177static int i_ppixf_ddoub(i_img *im, int x, int y, i_fcolor *val) {
178 int off, ch;
179
180 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
181 return -1;
182
183 off = (x + y * im->xsize) * im->channels;
35f40526
TC
184 if (I_ALL_CHANNELS_WRITABLE(im)) {
185 for (ch = 0; ch < im->channels; ++ch)
186 ((double *)im->idata)[off+ch] = val->channel[ch];
187 }
188 else {
189 for (ch = 0; ch < im->channels; ++ch)
190 if (im->ch_mask & (1 << ch))
191 ((double *)im->idata)[off+ch] = val->channel[ch];
192 }
2ce44e2a
TC
193
194 return 0;
195}
196
197static int i_gpixf_ddoub(i_img *im, int x, int y, i_fcolor *val) {
198 int off, ch;
199
200 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
201 return -1;
202
203 off = (x + y * im->xsize) * im->channels;
204 for (ch = 0; ch < im->channels; ++ch)
205 val->channel[ch] = ((double *)im->idata)[off+ch];
206
207 return 0;
208}
209
210static int i_glin_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 vals[i].channel[ch] = SampleFTo8(((double *)im->idata)[off]);
221 ++off;
222 }
223 }
224 return count;
225 }
226 else {
227 return 0;
228 }
229}
230
231static int i_plin_ddoub(i_img *im, int l, int r, int y, i_color *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;
35f40526
TC
239 if (I_ALL_CHANNELS_WRITABLE(im)) {
240 for (i = 0; i < count; ++i) {
241 for (ch = 0; ch < im->channels; ++ch) {
242 ((double *)im->idata)[off] = Sample8ToF(vals[i].channel[ch]);
243 ++off;
244 }
245 }
246 }
247 else {
248 for (i = 0; i < count; ++i) {
249 for (ch = 0; ch < im->channels; ++ch) {
250 if (im->ch_mask & (1 << ch))
251 ((double *)im->idata)[off] = Sample8ToF(vals[i].channel[ch]);
252 ++off;
253 }
2ce44e2a
TC
254 }
255 }
256 return count;
257 }
258 else {
259 return 0;
260 }
261}
262
263static int i_glinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) {
264 int ch, count, i;
265 int off;
266 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
267 if (r > im->xsize)
268 r = im->xsize;
269 off = (l+y*im->xsize) * im->channels;
270 count = r - l;
271 for (i = 0; i < count; ++i) {
272 for (ch = 0; ch < im->channels; ++ch) {
273 vals[i].channel[ch] = ((double *)im->idata)[off];
274 ++off;
275 }
276 }
277 return count;
278 }
279 else {
280 return 0;
281 }
282}
283
284static int i_plinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) {
285 int ch, count, i;
286 int off;
287 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
288 if (r > im->xsize)
289 r = im->xsize;
290 off = (l+y*im->xsize) * im->channels;
291 count = r - l;
35f40526
TC
292 if (I_ALL_CHANNELS_WRITABLE(im)) {
293 for (i = 0; i < count; ++i) {
294 for (ch = 0; ch < im->channels; ++ch) {
295 ((double *)im->idata)[off] = vals[i].channel[ch];
296 ++off;
297 }
298 }
299 }
300 else {
301 for (i = 0; i < count; ++i) {
302 for (ch = 0; ch < im->channels; ++ch) {
303 if (im->ch_mask & (1 << ch))
304 ((double *)im->idata)[off] = vals[i].channel[ch];
305 ++off;
306 }
2ce44e2a
TC
307 }
308 }
309 return count;
310 }
311 else {
312 return 0;
313 }
314}
315
316static int i_gsamp_ddoub(i_img *im, int l, int r, int y, i_sample_t *samps,
18accb2a 317 int const *chans, int chan_count) {
2ce44e2a
TC
318 int ch, count, i, w;
319 int off;
320
321 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
322 if (r > im->xsize)
323 r = im->xsize;
324 off = (l+y*im->xsize) * im->channels;
325 w = r - l;
326 count = 0;
327
328 if (chans) {
329 /* make sure we have good channel numbers */
330 for (ch = 0; ch < chan_count; ++ch) {
331 if (chans[ch] < 0 || chans[ch] >= im->channels) {
332 i_push_errorf(0, "No channel %d in this image", chans[ch]);
333 return 0;
334 }
335 }
336 for (i = 0; i < w; ++i) {
337 for (ch = 0; ch < chan_count; ++ch) {
338 *samps++ = SampleFTo8(((double *)im->idata)[off+chans[ch]]);
339 ++count;
340 }
341 off += im->channels;
342 }
343 }
344 else {
345 for (i = 0; i < w; ++i) {
346 for (ch = 0; ch < chan_count; ++ch) {
347 *samps++ = SampleFTo8(((double *)im->idata)[off+ch]);
348 ++count;
349 }
350 off += im->channels;
351 }
352 }
353
354 return count;
355 }
356 else {
357 return 0;
358 }
359}
360
361static int i_gsampf_ddoub(i_img *im, int l, int r, int y, i_fsample_t *samps,
18accb2a 362 int const *chans, int chan_count) {
2ce44e2a
TC
363 int ch, count, i, w;
364 int off;
365
366 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
367 if (r > im->xsize)
368 r = im->xsize;
369 off = (l+y*im->xsize) * im->channels;
370 w = r - l;
371 count = 0;
372
373 if (chans) {
374 /* make sure we have good channel numbers */
375 for (ch = 0; ch < chan_count; ++ch) {
376 if (chans[ch] < 0 || chans[ch] >= im->channels) {
377 i_push_errorf(0, "No channel %d in this image", chans[ch]);
378 return 0;
379 }
380 }
381 for (i = 0; i < w; ++i) {
382 for (ch = 0; ch < chan_count; ++ch) {
383 *samps++ = ((double *)im->idata)[off+chans[ch]];
384 ++count;
385 }
386 off += im->channels;
387 }
388 }
389 else {
390 for (i = 0; i < w; ++i) {
391 for (ch = 0; ch < chan_count; ++ch) {
392 *samps++ = ((double *)im->idata)[off+ch];
393 ++count;
394 }
395 off += im->channels;
396 }
397 }
398
399 return count;
400 }
401 else {
402 return 0;
403 }
404}
405
b8c2033e
AMH
406
407/*
408=back
409
410=head1 AUTHOR
411
412Tony Cook <tony@develop-help.com>
413
414=head1 SEE ALSO
415
416Imager(3)
417
418=cut
419*/