]> git.imager.perl.org - imager.git/blame - img16.c
- eliminate unused variables and static functions
[imager.git] / img16.c
CommitLineData
faa9b3e7
TC
1/*
2=head1 NAME
3
4img16.c - implements 16-bit images
5
6=head1 SYNOPSIS
7
8 i_img *im = i_img_16_new(int x, int y, int channels);
9 # use like a normal image
10
11=head1 DESCRIPTION
12
13Implements 16-bit/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_d16(i_img *im, int x, int y, i_color *val);
27static int i_gpix_d16(i_img *im, int x, int y, i_color *val);
28static int i_glin_d16(i_img *im, int l, int r, int y, i_color *vals);
29static int i_plin_d16(i_img *im, int l, int r, int y, i_color *vals);
30static int i_ppixf_d16(i_img *im, int x, int y, i_fcolor *val);
31static int i_gpixf_d16(i_img *im, int x, int y, i_fcolor *val);
32static int i_glinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals);
33static int i_plinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals);
34static int i_gsamp_d16(i_img *im, int l, int r, int y, i_sample_t *samps,
18accb2a 35 int const *chans, int chan_count);
faa9b3e7 36static int i_gsampf_d16(i_img *im, int l, int r, int y, i_fsample_t *samps,
18accb2a 37 int const *chans, int chan_count);
faa9b3e7
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_16bit_direct =
49{
50 0, /* channels set */
51 0, 0, 0, /* xsize, ysize, bytes */
9a88a5e6 52 ~0U, /* ch_mask */
faa9b3e7
TC
53 i_16_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_d16, /* i_f_ppix */
61 i_ppixf_d16, /* i_f_ppixf */
62 i_plin_d16, /* i_f_plin */
63 i_plinf_d16, /* i_f_plinf */
64 i_gpix_d16, /* i_f_gpix */
65 i_gpixf_d16, /* i_f_gpixf */
66 i_glin_d16, /* i_f_glin */
67 i_glinf_d16, /* i_f_glinf */
68 i_gsamp_d16, /* i_f_gsamp */
69 i_gsampf_d16, /* 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/* it's possible some platforms won't have a 16-bit integer type,
82 so we check for one otherwise we work by bytes directly
83
84 We do assume 8-bit char
26fd367b
TC
85
86 "Compaq C V6.4-009 on Compaq Tru64 UNIX V5.1A (Rev. 1885)" says it
87 supports C99, but doesn't supply stdint.h, which is required for
88 both hosted and freestanding implementations. So guard against it.
faa9b3e7 89*/
26fd367b 90#if __STDC_VERSION__ >= 199901L && !defined(OS_dec_osf)
faa9b3e7
TC
91/* C99 should define something useful */
92#include <stdint.h>
93#ifdef UINT16_MAX
94typedef uint16_t i_sample16_t;
95#define GOT16
96#endif
97#endif
98
99/* check out unsigned short */
100#ifndef GOT16
101#include <limits.h>
102#if USHRT_MAX == 65535
103typedef unsigned short i_sample16_t;
104#define GOT16
105#endif
106#endif
107
108#ifdef GOT16
109
110/* we have a real 16-bit unsigned integer */
111#define STORE16(bytes, offset, word) \
112 (((i_sample16_t *)(bytes))[offset] = (word))
113#define STORE8as16(bytes, offset, byte) \
114 (((i_sample16_t *)(bytes))[offset] = (byte) * 256)
115#define GET16(bytes, offset) \
116 (((i_sample16_t *)(bytes))[offset])
117#define GET16as8(bytes, offset) \
118 (((i_sample16_t *)(bytes))[offset] / 256)
119
120#else
121
122/* we have to do this the hard way */
123#define STORE16(bytes, offset, word) \
124 ((((unsigned char *)(bytes))[(offset)*2] = (word) >> 8), \
125 (((unsigned char *)(bytes))[(offset)*2+1] = (word) & 0xFF))
126#define STORE8as16(bytes, offset, byte) \
127 ((((unsigned char *)(bytes))[(offset)*2] = (byte)), \
128 (((unsigned char *)(bytes))[(offset)*2+1] = 0))
129
130#define GET16(bytes, offset) \
131 (((unsigned char *)(bytes))[(offset)*2] * 256 \
132 + ((unsigned char *)(bytes))[(offset)*2+1])
133#define GET16as8(bytes, offset) \
134 (((unsigned char *)(bytes))[(offset)*2] << 8)
135
136#endif
137
138/*
139=item i_img_16_new(int x, int y, int ch)
140
141Creates a new 16-bit per sample image.
365ea842
TC
142
143=cut
faa9b3e7
TC
144*/
145i_img *i_img_16_new_low(i_img *im, int x, int y, int ch) {
653ea321 146 int bytes;
faa9b3e7 147 mm_log((1,"i_img_16_new(x %d, y %d, ch %d)\n", x, y, ch));
1501d9b3
TC
148
149 if (x < 1 || y < 1) {
150 i_push_error(0, "Image sizes must be positive");
151 return NULL;
152 }
153 if (ch < 1 || ch > MAXCHANNELS) {
154 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
155 return NULL;
156 }
653ea321
TC
157 bytes = x * y * ch * 2;
158 if (bytes / y / ch / 2 != x) {
159 i_push_errorf(0, "integer overflow calculating image allocation");
160 return NULL;
161 }
faa9b3e7
TC
162
163 *im = IIM_base_16bit_direct;
164 i_tags_new(&im->tags);
165 im->xsize = x;
166 im->ysize = y;
167 im->channels = ch;
653ea321 168 im->bytes = bytes;
faa9b3e7
TC
169 im->ext_data = NULL;
170 im->idata = mymalloc(im->bytes);
171 if (im->idata) {
172 memset(im->idata, 0, im->bytes);
173 }
174 else {
175 i_tags_destroy(&im->tags);
176 im = NULL;
177 }
178
179 return im;
180}
181
182i_img *i_img_16_new(int x, int y, int ch) {
183 i_img *im;
1501d9b3
TC
184
185 i_clear_error();
faa9b3e7
TC
186
187 im = mymalloc(sizeof(i_img));
188 if (im) {
189 if (!i_img_16_new_low(im, x, y, ch)) {
190 myfree(im);
191 im = NULL;
192 }
193 }
194
195 mm_log((1, "(%p) <- i_img_16_new\n", im));
196
197 return im;
198}
199
200static int i_ppix_d16(i_img *im, int x, int y, i_color *val) {
201 int off, ch;
202
203 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
204 return -1;
205
206 off = (x + y * im->xsize) * im->channels;
207 for (ch = 0; ch < im->channels; ++ch)
208 STORE8as16(im->idata, off+ch, val->channel[ch]);
209
210 return 0;
211}
212
213static int i_gpix_d16(i_img *im, int x, int y, i_color *val) {
214 int off, ch;
215
216 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
217 return -1;
218
219 off = (x + y * im->xsize) * im->channels;
220 for (ch = 0; ch < im->channels; ++ch)
221 val->channel[ch] = GET16as8(im->idata, off+ch);
222
223 return 0;
224}
225
226static int i_ppixf_d16(i_img *im, int x, int y, i_fcolor *val) {
227 int off, ch;
228
229 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
230 return -1;
231
232 off = (x + y * im->xsize) * im->channels;
233 for (ch = 0; ch < im->channels; ++ch)
234 STORE16(im->idata, off+ch, SampleFTo16(val->channel[ch]));
235
236 return 0;
237}
238
239static int i_gpixf_d16(i_img *im, int x, int y, i_fcolor *val) {
240 int off, ch;
241
242 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
243 return -1;
244
245 off = (x + y * im->xsize) * im->channels;
246 for (ch = 0; ch < im->channels; ++ch)
247 val->channel[ch] = Sample16ToF(GET16(im->idata, off+ch));
248
249 return 0;
250}
251
252static int i_glin_d16(i_img *im, int l, int r, int y, i_color *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 vals[i].channel[ch] = GET16as8(im->idata, off);
263 ++off;
264 }
265 }
266 return count;
267 }
268 else {
269 return 0;
270 }
271}
272
273static int i_plin_d16(i_img *im, int l, int r, int y, i_color *vals) {
274 int ch, count, i;
275 int off;
276 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
277 if (r > im->xsize)
278 r = im->xsize;
279 off = (l+y*im->xsize) * im->channels;
280 count = r - l;
281 for (i = 0; i < count; ++i) {
282 for (ch = 0; ch < im->channels; ++ch) {
283 STORE8as16(im->idata, off, vals[i].channel[ch]);
284 ++off;
285 }
286 }
287 return count;
288 }
289 else {
290 return 0;
291 }
292}
293
294static int i_glinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
295 int ch, count, i;
296 int off;
297 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
298 if (r > im->xsize)
299 r = im->xsize;
300 off = (l+y*im->xsize) * im->channels;
301 count = r - l;
302 for (i = 0; i < count; ++i) {
303 for (ch = 0; ch < im->channels; ++ch) {
304 vals[i].channel[ch] = Sample16ToF(GET16(im->idata, off));
305 ++off;
306 }
307 }
308 return count;
309 }
310 else {
311 return 0;
312 }
313}
314
315static int i_plinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
316 int ch, count, i;
317 int off;
318 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
319 if (r > im->xsize)
320 r = im->xsize;
321 off = (l+y*im->xsize) * im->channels;
322 count = r - l;
323 for (i = 0; i < count; ++i) {
324 for (ch = 0; ch < im->channels; ++ch) {
325 STORE16(im->idata, off, SampleFTo16(vals[i].channel[ch]));
326 ++off;
327 }
328 }
329 return count;
330 }
331 else {
332 return 0;
333 }
334}
335
336static int i_gsamp_d16(i_img *im, int l, int r, int y, i_sample_t *samps,
18accb2a 337 int const *chans, int chan_count) {
faa9b3e7
TC
338 int ch, count, i, w;
339 int off;
340
341 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
342 if (r > im->xsize)
343 r = im->xsize;
344 off = (l+y*im->xsize) * im->channels;
345 w = r - l;
346 count = 0;
347
348 if (chans) {
349 /* make sure we have good channel numbers */
350 for (ch = 0; ch < chan_count; ++ch) {
351 if (chans[ch] < 0 || chans[ch] >= im->channels) {
352 i_push_errorf(0, "No channel %d in this image", chans[ch]);
353 return 0;
354 }
355 }
356 for (i = 0; i < w; ++i) {
357 for (ch = 0; ch < chan_count; ++ch) {
358 *samps++ = GET16as8(im->idata, off+chans[ch]);
359 ++count;
360 }
361 off += im->channels;
362 }
363 }
364 else {
365 for (i = 0; i < w; ++i) {
366 for (ch = 0; ch < chan_count; ++ch) {
367 *samps++ = GET16as8(im->idata, off+ch);
368 ++count;
369 }
370 off += im->channels;
371 }
372 }
373
374 return count;
375 }
376 else {
377 return 0;
378 }
379}
380
381static int i_gsampf_d16(i_img *im, int l, int r, int y, i_fsample_t *samps,
18accb2a 382 int const *chans, int chan_count) {
faa9b3e7
TC
383 int ch, count, i, w;
384 int off;
385
386 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
387 if (r > im->xsize)
388 r = im->xsize;
389 off = (l+y*im->xsize) * im->channels;
390 w = r - l;
391 count = 0;
392
393 if (chans) {
394 /* make sure we have good channel numbers */
395 for (ch = 0; ch < chan_count; ++ch) {
396 if (chans[ch] < 0 || chans[ch] >= im->channels) {
397 i_push_errorf(0, "No channel %d in this image", chans[ch]);
398 return 0;
399 }
400 }
401 for (i = 0; i < w; ++i) {
402 for (ch = 0; ch < chan_count; ++ch) {
403 *samps++ = Sample16ToF(GET16(im->idata, off+chans[ch]));
404 ++count;
405 }
406 off += im->channels;
407 }
408 }
409 else {
410 for (i = 0; i < w; ++i) {
411 for (ch = 0; ch < chan_count; ++ch) {
412 *samps++ = Sample16ToF(GET16(im->idata, off+ch));
413 ++count;
414 }
415 off += im->channels;
416 }
417 }
418
419 return count;
420 }
421 else {
422 return 0;
423 }
424}
425
b8c2033e
AMH
426/*
427=back
428
429=head1 AUTHOR
430
431Tony Cook <tony@develop-help.com>
432
433=head1 SEE ALSO
434
435Imager(3)
436
437=cut
438*/