4 img16.c - implements 16-bit images
8 i_img *im = i_img_16_new(int x, int y, int channels);
9 # use like a normal image
13 Implements 16-bit/sample images.
15 This basic implementation is required so that we have some larger
16 sample image type to work with.
26 static int i_ppix_d16(i_img *im, int x, int y, const i_color *val);
27 static int i_gpix_d16(i_img *im, int x, int y, i_color *val);
28 static int i_glin_d16(i_img *im, int l, int r, int y, i_color *vals);
29 static int i_plin_d16(i_img *im, int l, int r, int y, const i_color *vals);
30 static int i_ppixf_d16(i_img *im, int x, int y, const i_fcolor *val);
31 static int i_gpixf_d16(i_img *im, int x, int y, i_fcolor *val);
32 static int i_glinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals);
33 static int i_plinf_d16(i_img *im, int l, int r, int y, const i_fcolor *vals);
34 static int i_gsamp_d16(i_img *im, int l, int r, int y, i_sample_t *samps,
35 int const *chans, int chan_count);
36 static int i_gsampf_d16(i_img *im, int l, int r, int y, i_fsample_t *samps,
37 int const *chans, int chan_count);
38 static int i_gsamp_bits_d16(i_img *im, int l, int r, int y, unsigned *samps,
39 int const *chans, int chan_count, int bits);
40 static int i_psamp_bits_d16(i_img *im, int l, int r, int y, unsigned const *samps,
41 int const *chans, int chan_count, int bits);
44 =item IIM_base_16bit_direct
46 Base structure used to initialize a 16-bit/sample image.
52 static i_img IIM_base_16bit_direct =
55 0, 0, 0, /* xsize, ysize, bytes */
58 i_direct_type, /* type */
61 { 0, 0, NULL }, /* tags */
64 i_ppix_d16, /* i_f_ppix */
65 i_ppixf_d16, /* i_f_ppixf */
66 i_plin_d16, /* i_f_plin */
67 i_plinf_d16, /* i_f_plinf */
68 i_gpix_d16, /* i_f_gpix */
69 i_gpixf_d16, /* i_f_gpixf */
70 i_glin_d16, /* i_f_glin */
71 i_glinf_d16, /* i_f_glinf */
72 i_gsamp_d16, /* i_f_gsamp */
73 i_gsampf_d16, /* i_f_gsampf */
77 NULL, /* i_f_addcolors */
78 NULL, /* i_f_getcolors */
79 NULL, /* i_f_colorcount */
80 NULL, /* i_f_maxcolors */
81 NULL, /* i_f_findcolor */
82 NULL, /* i_f_setcolors */
84 NULL, /* i_f_destroy */
90 /* it's possible some platforms won't have a 16-bit integer type,
91 so we check for one otherwise we work by bytes directly
93 We do assume 8-bit char
95 "Compaq C V6.4-009 on Compaq Tru64 UNIX V5.1A (Rev. 1885)" says it
96 supports C99, but doesn't supply stdint.h, which is required for
97 both hosted and freestanding implementations. So guard against it.
99 #if __STDC_VERSION__ >= 199901L && !defined(OS_dec_osf)
100 /* C99 should define something useful */
103 typedef uint16_t i_sample16_t;
108 /* check out unsigned short */
111 #if USHRT_MAX == 65535
112 typedef unsigned short i_sample16_t;
119 /* we have a real 16-bit unsigned integer */
120 #define STORE16(bytes, offset, word) \
121 (((i_sample16_t *)(bytes))[offset] = (word))
122 #define STORE8as16(bytes, offset, byte) \
123 (((i_sample16_t *)(bytes))[offset] = (byte) * 256 + (byte))
124 #define GET16(bytes, offset) \
125 (((i_sample16_t *)(bytes))[offset])
128 /* we have to do this the hard way */
129 #define STORE16(bytes, offset, word) \
130 ((((unsigned char *)(bytes))[(offset)*2] = (word) >> 8), \
131 (((unsigned char *)(bytes))[(offset)*2+1] = (word) & 0xFF))
132 #define STORE8as16(bytes, offset, byte) \
133 ((((unsigned char *)(bytes))[(offset)*2] = (byte)), \
134 (((unsigned char *)(bytes))[(offset)*2+1] = (byte)))
136 #define GET16(bytes, offset) \
137 (((unsigned char *)(bytes))[(offset)*2] * 256 \
138 + ((unsigned char *)(bytes))[(offset)*2+1])
142 #define GET16as8(bytes, offset) \
143 ((((i_sample16_t *)(bytes))[offset]+127) / 257)
146 =item i_img_16_new(x, y, ch)
148 =category Image creation/destruction
149 =synopsis i_img *img = i_img_16_new(width, height, channels);
151 Create a new 16-bit/sample image.
153 Returns the image on success, or NULL on failure.
158 i_img *i_img_16_new(int x, int y, int ch) {
160 int bytes, line_bytes;
162 mm_log((1,"i_img_16_new(x %d, y %d, ch %d)\n", x, y, ch));
164 if (x < 1 || y < 1) {
165 i_push_error(0, "Image sizes must be positive");
168 if (ch < 1 || ch > MAXCHANNELS) {
169 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
172 bytes = x * y * ch * 2;
173 if (bytes / y / ch / 2 != x) {
174 i_push_errorf(0, "integer overflow calculating image allocation");
178 /* basic assumption: we can always allocate a buffer representing a
179 line from the image, otherwise we're going to have trouble
180 working with the image */
181 line_bytes = sizeof(i_fcolor) * x;
182 if (line_bytes / x != sizeof(i_fcolor)) {
183 i_push_error(0, "integer overflow calculating scanline allocation");
188 *im = IIM_base_16bit_direct;
189 i_tags_new(&im->tags);
195 im->idata = mymalloc(im->bytes);
196 memset(im->idata, 0, im->bytes);
204 =item i_img_to_rgb16(im)
206 =category Image creation
208 Returns a 16-bit/sample version of the supplied image.
210 Returns the image on success, or NULL on failure.
216 i_img_to_rgb16(i_img *im) {
221 targ = i_img_16_new(im->xsize, im->ysize, im->channels);
224 line = mymalloc(sizeof(i_fcolor) * im->xsize);
225 for (y = 0; y < im->ysize; ++y) {
226 i_glinf(im, 0, im->xsize, y, line);
227 i_plinf(targ, 0, im->xsize, y, line);
235 static int i_ppix_d16(i_img *im, int x, int y, const i_color *val) {
238 if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
241 off = (x + y * im->xsize) * im->channels;
242 if (I_ALL_CHANNELS_WRITABLE(im)) {
243 for (ch = 0; ch < im->channels; ++ch)
244 STORE8as16(im->idata, off+ch, val->channel[ch]);
247 for (ch = 0; ch < im->channels; ++ch)
248 if (im->ch_mask & (1 << ch))
249 STORE8as16(im->idata, off+ch, val->channel[ch]);
255 static int i_gpix_d16(i_img *im, int x, int y, i_color *val) {
258 if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
261 off = (x + y * im->xsize) * im->channels;
262 for (ch = 0; ch < im->channels; ++ch)
263 val->channel[ch] = GET16as8(im->idata, off+ch);
268 static int i_ppixf_d16(i_img *im, int x, int y, const i_fcolor *val) {
271 if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
274 off = (x + y * im->xsize) * im->channels;
275 if (I_ALL_CHANNELS_WRITABLE(im)) {
276 for (ch = 0; ch < im->channels; ++ch)
277 STORE16(im->idata, off+ch, SampleFTo16(val->channel[ch]));
280 for (ch = 0; ch < im->channels; ++ch)
281 if (im->ch_mask & (1 << ch))
282 STORE16(im->idata, off+ch, SampleFTo16(val->channel[ch]));
288 static int i_gpixf_d16(i_img *im, int x, int y, i_fcolor *val) {
291 if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
294 off = (x + y * im->xsize) * im->channels;
295 for (ch = 0; ch < im->channels; ++ch)
296 val->channel[ch] = Sample16ToF(GET16(im->idata, off+ch));
301 static int i_glin_d16(i_img *im, int l, int r, int y, i_color *vals) {
304 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
307 off = (l+y*im->xsize) * im->channels;
309 for (i = 0; i < count; ++i) {
310 for (ch = 0; ch < im->channels; ++ch) {
311 vals[i].channel[ch] = GET16as8(im->idata, off);
322 static int i_plin_d16(i_img *im, int l, int r, int y, const i_color *vals) {
325 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
328 off = (l+y*im->xsize) * im->channels;
330 if (I_ALL_CHANNELS_WRITABLE(im)) {
331 for (i = 0; i < count; ++i) {
332 for (ch = 0; ch < im->channels; ++ch) {
333 STORE8as16(im->idata, off, vals[i].channel[ch]);
339 for (i = 0; i < count; ++i) {
340 for (ch = 0; ch < im->channels; ++ch) {
341 if (im->ch_mask & (1 << ch))
342 STORE8as16(im->idata, off, vals[i].channel[ch]);
354 static int i_glinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
357 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
360 off = (l+y*im->xsize) * im->channels;
362 for (i = 0; i < count; ++i) {
363 for (ch = 0; ch < im->channels; ++ch) {
364 vals[i].channel[ch] = Sample16ToF(GET16(im->idata, off));
375 static int i_plinf_d16(i_img *im, int l, int r, int y, const i_fcolor *vals) {
378 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
381 off = (l+y*im->xsize) * im->channels;
383 if (I_ALL_CHANNELS_WRITABLE(im)) {
384 for (i = 0; i < count; ++i) {
385 for (ch = 0; ch < im->channels; ++ch) {
386 STORE16(im->idata, off, SampleFTo16(vals[i].channel[ch]));
392 for (i = 0; i < count; ++i) {
393 for (ch = 0; ch < im->channels; ++ch) {
394 if (im->ch_mask & (1 << ch))
395 STORE16(im->idata, off, SampleFTo16(vals[i].channel[ch]));
407 static int i_gsamp_d16(i_img *im, int l, int r, int y, i_sample_t *samps,
408 int const *chans, int chan_count) {
412 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
415 off = (l+y*im->xsize) * im->channels;
420 /* make sure we have good channel numbers */
421 for (ch = 0; ch < chan_count; ++ch) {
422 if (chans[ch] < 0 || chans[ch] >= im->channels) {
423 i_push_errorf(0, "No channel %d in this image", chans[ch]);
427 for (i = 0; i < w; ++i) {
428 for (ch = 0; ch < chan_count; ++ch) {
429 *samps++ = GET16as8(im->idata, off+chans[ch]);
436 if (chan_count <= 0 || chan_count > im->channels) {
437 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
441 for (i = 0; i < w; ++i) {
442 for (ch = 0; ch < chan_count; ++ch) {
443 *samps++ = GET16as8(im->idata, off+ch);
457 static int i_gsampf_d16(i_img *im, int l, int r, int y, i_fsample_t *samps,
458 int const *chans, int chan_count) {
462 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
465 off = (l+y*im->xsize) * im->channels;
470 /* make sure we have good channel numbers */
471 for (ch = 0; ch < chan_count; ++ch) {
472 if (chans[ch] < 0 || chans[ch] >= im->channels) {
473 i_push_errorf(0, "No channel %d in this image", chans[ch]);
477 for (i = 0; i < w; ++i) {
478 for (ch = 0; ch < chan_count; ++ch) {
479 *samps++ = Sample16ToF(GET16(im->idata, off+chans[ch]));
486 if (chan_count <= 0 || chan_count > im->channels) {
487 i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels",
491 for (i = 0; i < w; ++i) {
492 for (ch = 0; ch < chan_count; ++ch) {
493 *samps++ = Sample16ToF(GET16(im->idata, off+ch));
508 i_gsamp_bits_d16(i_img *im, int l, int r, int y, unsigned *samps,
509 int const *chans, int chan_count, int bits) {
514 return i_gsamp_bits_fb(im, l, r, y, samps, chans, chan_count, bits);
517 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
520 off = (l+y*im->xsize) * im->channels;
525 /* make sure we have good channel numbers */
526 for (ch = 0; ch < chan_count; ++ch) {
527 if (chans[ch] < 0 || chans[ch] >= im->channels) {
528 i_push_errorf(0, "No channel %d in this image", chans[ch]);
532 for (i = 0; i < w; ++i) {
533 for (ch = 0; ch < chan_count; ++ch) {
534 *samps++ = GET16(im->idata, off+chans[ch]);
541 if (chan_count <= 0 || chan_count > im->channels) {
542 i_push_error(0, "Invalid channel count");
545 for (i = 0; i < w; ++i) {
546 for (ch = 0; ch < chan_count; ++ch) {
547 *samps++ = GET16(im->idata, off+ch);
557 i_push_error(0, "Image position outside of image");
563 i_psamp_bits_d16(i_img *im, int l, int r, int y, unsigned const *samps,
564 int const *chans, int chan_count, int bits) {
569 i_push_error(0, "Invalid bits for 16-bit image");
573 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
576 off = (l+y*im->xsize) * im->channels;
581 /* make sure we have good channel numbers */
582 for (ch = 0; ch < chan_count; ++ch) {
583 if (chans[ch] < 0 || chans[ch] >= im->channels) {
584 i_push_errorf(0, "No channel %d in this image", chans[ch]);
588 for (i = 0; i < w; ++i) {
589 for (ch = 0; ch < chan_count; ++ch) {
590 if (im->ch_mask & (1 << ch))
591 STORE16(im->idata, off+chans[ch], *samps);
599 if (chan_count <= 0 || chan_count > im->channels) {
600 i_push_error(0, "Invalid channel count");
603 for (i = 0; i < w; ++i) {
604 for (ch = 0; ch < chan_count; ++ch) {
605 if (im->ch_mask & (1 << ch))
606 STORE16(im->idata, off+ch, *samps);
617 i_push_error(0, "Image position outside of image");
627 Tony Cook <tony@develop-help.com>