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, 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, i_color *vals);
30 static int i_ppixf_d16(i_img *im, int x, int y, 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, 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);
40 =item IIM_base_16bit_direct
42 Base structure used to initialize a 16-bit/sample image.
48 static i_img IIM_base_16bit_direct =
51 0, 0, 0, /* xsize, ysize, bytes */
54 i_direct_type, /* type */
57 { 0, 0, NULL }, /* tags */
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 */
73 NULL, /* i_f_addcolor */
74 NULL, /* i_f_getcolor */
75 NULL, /* i_f_colorcount */
76 NULL, /* i_f_findcolor */
78 NULL, /* i_f_destroy */
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
84 We do assume 8-bit char
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.
90 #if __STDC_VERSION__ >= 199901L && !defined(OS_dec_osf)
91 /* C99 should define something useful */
94 typedef uint16_t i_sample16_t;
99 /* check out unsigned short */
102 #if USHRT_MAX == 65535
103 typedef unsigned short i_sample16_t;
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)
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))
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)
139 =item i_img_16_new(int x, int y, int ch)
141 Creates a new 16-bit per sample image.
145 i_img *i_img_16_new_low(i_img *im, int x, int y, int ch) {
147 mm_log((1,"i_img_16_new(x %d, y %d, ch %d)\n", x, y, ch));
149 if (x < 1 || y < 1) {
150 i_push_error(0, "Image sizes must be positive");
153 if (ch < 1 || ch > MAXCHANNELS) {
154 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
157 bytes = x * y * ch * 2;
158 if (bytes / y / ch / 2 != x) {
159 i_push_errorf(0, "integer overflow calculating image allocation");
163 *im = IIM_base_16bit_direct;
164 i_tags_new(&im->tags);
170 im->idata = mymalloc(im->bytes);
172 memset(im->idata, 0, im->bytes);
175 i_tags_destroy(&im->tags);
182 i_img *i_img_16_new(int x, int y, int ch) {
187 im = mymalloc(sizeof(i_img));
189 if (!i_img_16_new_low(im, x, y, ch)) {
195 mm_log((1, "(%p) <- i_img_16_new\n", im));
200 static int i_ppix_d16(i_img *im, int x, int y, i_color *val) {
203 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
206 off = (x + y * im->xsize) * im->channels;
207 if (I_ALL_CHANNELS_WRITABLE(im)) {
208 for (ch = 0; ch < im->channels; ++ch)
209 STORE8as16(im->idata, off+ch, val->channel[ch]);
212 for (ch = 0; ch < im->channels; ++ch)
213 if (im->ch_mask & (1 << ch))
214 STORE8as16(im->idata, off+ch, val->channel[ch]);
220 static int i_gpix_d16(i_img *im, int x, int y, i_color *val) {
223 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
226 off = (x + y * im->xsize) * im->channels;
227 for (ch = 0; ch < im->channels; ++ch)
228 val->channel[ch] = GET16as8(im->idata, off+ch);
233 static int i_ppixf_d16(i_img *im, int x, int y, i_fcolor *val) {
236 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
239 off = (x + y * im->xsize) * im->channels;
240 if (I_ALL_CHANNELS_WRITABLE(im)) {
241 for (ch = 0; ch < im->channels; ++ch)
242 STORE16(im->idata, off+ch, SampleFTo16(val->channel[ch]));
245 for (ch = 0; ch < im->channels; ++ch)
246 if (im->ch_mask & (1 << ch))
247 STORE16(im->idata, off+ch, SampleFTo16(val->channel[ch]));
253 static int i_gpixf_d16(i_img *im, int x, int y, i_fcolor *val) {
256 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
259 off = (x + y * im->xsize) * im->channels;
260 for (ch = 0; ch < im->channels; ++ch)
261 val->channel[ch] = Sample16ToF(GET16(im->idata, off+ch));
266 static int i_glin_d16(i_img *im, int l, int r, int y, i_color *vals) {
269 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
272 off = (l+y*im->xsize) * im->channels;
274 for (i = 0; i < count; ++i) {
275 for (ch = 0; ch < im->channels; ++ch) {
276 vals[i].channel[ch] = GET16as8(im->idata, off);
287 static int i_plin_d16(i_img *im, int l, int r, int y, i_color *vals) {
290 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
293 off = (l+y*im->xsize) * im->channels;
295 if (I_ALL_CHANNELS_WRITABLE(im)) {
296 for (i = 0; i < count; ++i) {
297 for (ch = 0; ch < im->channels; ++ch) {
298 STORE8as16(im->idata, off, vals[i].channel[ch]);
304 for (i = 0; i < count; ++i) {
305 for (ch = 0; ch < im->channels; ++ch) {
306 if (im->ch_mask & (1 << ch))
307 STORE8as16(im->idata, off, vals[i].channel[ch]);
319 static int i_glinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
322 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
325 off = (l+y*im->xsize) * im->channels;
327 for (i = 0; i < count; ++i) {
328 for (ch = 0; ch < im->channels; ++ch) {
329 vals[i].channel[ch] = Sample16ToF(GET16(im->idata, off));
340 static int i_plinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
343 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
346 off = (l+y*im->xsize) * im->channels;
348 if (I_ALL_CHANNELS_WRITABLE(im)) {
349 for (i = 0; i < count; ++i) {
350 for (ch = 0; ch < im->channels; ++ch) {
351 STORE16(im->idata, off, SampleFTo16(vals[i].channel[ch]));
357 for (i = 0; i < count; ++i) {
358 for (ch = 0; ch < im->channels; ++ch) {
359 if (im->ch_mask & (1 << ch))
360 STORE16(im->idata, off, SampleFTo16(vals[i].channel[ch]));
372 static int i_gsamp_d16(i_img *im, int l, int r, int y, i_sample_t *samps,
373 int const *chans, int chan_count) {
377 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
380 off = (l+y*im->xsize) * im->channels;
385 /* make sure we have good channel numbers */
386 for (ch = 0; ch < chan_count; ++ch) {
387 if (chans[ch] < 0 || chans[ch] >= im->channels) {
388 i_push_errorf(0, "No channel %d in this image", chans[ch]);
392 for (i = 0; i < w; ++i) {
393 for (ch = 0; ch < chan_count; ++ch) {
394 *samps++ = GET16as8(im->idata, off+chans[ch]);
401 for (i = 0; i < w; ++i) {
402 for (ch = 0; ch < chan_count; ++ch) {
403 *samps++ = GET16as8(im->idata, off+ch);
417 static int i_gsampf_d16(i_img *im, int l, int r, int y, i_fsample_t *samps,
418 int const *chans, int chan_count) {
422 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
425 off = (l+y*im->xsize) * im->channels;
430 /* make sure we have good channel numbers */
431 for (ch = 0; ch < chan_count; ++ch) {
432 if (chans[ch] < 0 || chans[ch] >= im->channels) {
433 i_push_errorf(0, "No channel %d in this image", chans[ch]);
437 for (i = 0; i < w; ++i) {
438 for (ch = 0; ch < chan_count; ++ch) {
439 *samps++ = Sample16ToF(GET16(im->idata, off+chans[ch]));
446 for (i = 0; i < w; ++i) {
447 for (ch = 0; ch < chan_count; ++ch) {
448 *samps++ = Sample16ToF(GET16(im->idata, off+ch));
467 Tony Cook <tony@develop-help.com>