- t1 library re-initialization modified to support T1Lib 5.1.0
[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;
151 for (ch = 0; ch < im->channels; ++ch)
152 ((double*)im->idata)[off+ch] = Sample8ToF(val->channel[ch]);
153
154 return 0;
155}
156
157static int i_gpix_ddoub(i_img *im, int x, int y, i_color *val) {
158 int off, ch;
159
160 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
161 return -1;
162
163 off = (x + y * im->xsize) * im->channels;
164 for (ch = 0; ch < im->channels; ++ch)
165 val->channel[ch] = SampleFTo8(((double *)im->idata)[off+ch]);
166
167 return 0;
168}
169
170static int i_ppixf_ddoub(i_img *im, int x, int y, i_fcolor *val) {
171 int off, ch;
172
173 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
174 return -1;
175
176 off = (x + y * im->xsize) * im->channels;
177 for (ch = 0; ch < im->channels; ++ch)
178 ((double *)im->idata)[off+ch] = val->channel[ch];;
179
180 return 0;
181}
182
183static int i_gpixf_ddoub(i_img *im, int x, int y, i_fcolor *val) {
184 int off, ch;
185
186 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
187 return -1;
188
189 off = (x + y * im->xsize) * im->channels;
190 for (ch = 0; ch < im->channels; ++ch)
191 val->channel[ch] = ((double *)im->idata)[off+ch];
192
193 return 0;
194}
195
196static int i_glin_ddoub(i_img *im, int l, int r, int y, i_color *vals) {
197 int ch, count, i;
198 int off;
199 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
200 if (r > im->xsize)
201 r = im->xsize;
202 off = (l+y*im->xsize) * im->channels;
203 count = r - l;
204 for (i = 0; i < count; ++i) {
205 for (ch = 0; ch < im->channels; ++ch) {
206 vals[i].channel[ch] = SampleFTo8(((double *)im->idata)[off]);
207 ++off;
208 }
209 }
210 return count;
211 }
212 else {
213 return 0;
214 }
215}
216
217static int i_plin_ddoub(i_img *im, int l, int r, int y, i_color *vals) {
218 int ch, count, i;
219 int off;
220 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
221 if (r > im->xsize)
222 r = im->xsize;
223 off = (l+y*im->xsize) * im->channels;
224 count = r - l;
225 for (i = 0; i < count; ++i) {
226 for (ch = 0; ch < im->channels; ++ch) {
227 ((double *)im->idata)[off] = Sample8ToF(vals[i].channel[ch]);
228 ++off;
229 }
230 }
231 return count;
232 }
233 else {
234 return 0;
235 }
236}
237
238static int i_glinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) {
239 int ch, count, i;
240 int off;
241 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
242 if (r > im->xsize)
243 r = im->xsize;
244 off = (l+y*im->xsize) * im->channels;
245 count = r - l;
246 for (i = 0; i < count; ++i) {
247 for (ch = 0; ch < im->channels; ++ch) {
248 vals[i].channel[ch] = ((double *)im->idata)[off];
249 ++off;
250 }
251 }
252 return count;
253 }
254 else {
255 return 0;
256 }
257}
258
259static int i_plinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) {
260 int ch, count, i;
261 int off;
262 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
263 if (r > im->xsize)
264 r = im->xsize;
265 off = (l+y*im->xsize) * im->channels;
266 count = r - l;
267 for (i = 0; i < count; ++i) {
268 for (ch = 0; ch < im->channels; ++ch) {
269 ((double *)im->idata)[off] = vals[i].channel[ch];
270 ++off;
271 }
272 }
273 return count;
274 }
275 else {
276 return 0;
277 }
278}
279
280static int i_gsamp_ddoub(i_img *im, int l, int r, int y, i_sample_t *samps,
18accb2a 281 int const *chans, int chan_count) {
2ce44e2a
TC
282 int ch, count, i, w;
283 int off;
284
285 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
286 if (r > im->xsize)
287 r = im->xsize;
288 off = (l+y*im->xsize) * im->channels;
289 w = r - l;
290 count = 0;
291
292 if (chans) {
293 /* make sure we have good channel numbers */
294 for (ch = 0; ch < chan_count; ++ch) {
295 if (chans[ch] < 0 || chans[ch] >= im->channels) {
296 i_push_errorf(0, "No channel %d in this image", chans[ch]);
297 return 0;
298 }
299 }
300 for (i = 0; i < w; ++i) {
301 for (ch = 0; ch < chan_count; ++ch) {
302 *samps++ = SampleFTo8(((double *)im->idata)[off+chans[ch]]);
303 ++count;
304 }
305 off += im->channels;
306 }
307 }
308 else {
309 for (i = 0; i < w; ++i) {
310 for (ch = 0; ch < chan_count; ++ch) {
311 *samps++ = SampleFTo8(((double *)im->idata)[off+ch]);
312 ++count;
313 }
314 off += im->channels;
315 }
316 }
317
318 return count;
319 }
320 else {
321 return 0;
322 }
323}
324
325static int i_gsampf_ddoub(i_img *im, int l, int r, int y, i_fsample_t *samps,
18accb2a 326 int const *chans, int chan_count) {
2ce44e2a
TC
327 int ch, count, i, w;
328 int off;
329
330 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
331 if (r > im->xsize)
332 r = im->xsize;
333 off = (l+y*im->xsize) * im->channels;
334 w = r - l;
335 count = 0;
336
337 if (chans) {
338 /* make sure we have good channel numbers */
339 for (ch = 0; ch < chan_count; ++ch) {
340 if (chans[ch] < 0 || chans[ch] >= im->channels) {
341 i_push_errorf(0, "No channel %d in this image", chans[ch]);
342 return 0;
343 }
344 }
345 for (i = 0; i < w; ++i) {
346 for (ch = 0; ch < chan_count; ++ch) {
347 *samps++ = ((double *)im->idata)[off+chans[ch]];
348 ++count;
349 }
350 off += im->channels;
351 }
352 }
353 else {
354 for (i = 0; i < w; ++i) {
355 for (ch = 0; ch < chan_count; ++ch) {
356 *samps++ = ((double *)im->idata)[off+ch];
357 ++count;
358 }
359 off += im->channels;
360 }
361 }
362
363 return count;
364 }
365 else {
366 return 0;
367 }
368}
369
b8c2033e
AMH
370
371/*
372=back
373
374=head1 AUTHOR
375
376Tony Cook <tony@develop-help.com>
377
378=head1 SEE ALSO
379
380Imager(3)
381
382=cut
383*/