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) {
146 mm_log((1,"i_img_16_new(x %d, y %d, ch %d)\n", x, y, ch));
148 *im = IIM_base_16bit_direct;
149 i_tags_new(&im->tags);
153 im->bytes = x * y * ch * 2;
155 im->idata = mymalloc(im->bytes);
157 memset(im->idata, 0, im->bytes);
160 i_tags_destroy(&im->tags);
167 i_img *i_img_16_new(int x, int y, int ch) {
170 im = mymalloc(sizeof(i_img));
172 if (!i_img_16_new_low(im, x, y, ch)) {
178 mm_log((1, "(%p) <- i_img_16_new\n", im));
183 static int i_ppix_d16(i_img *im, int x, int y, i_color *val) {
186 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
189 off = (x + y * im->xsize) * im->channels;
190 for (ch = 0; ch < im->channels; ++ch)
191 STORE8as16(im->idata, off+ch, val->channel[ch]);
196 static int i_gpix_d16(i_img *im, int x, int y, i_color *val) {
199 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
202 off = (x + y * im->xsize) * im->channels;
203 for (ch = 0; ch < im->channels; ++ch)
204 val->channel[ch] = GET16as8(im->idata, off+ch);
209 static int i_ppixf_d16(i_img *im, int x, int y, i_fcolor *val) {
212 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
215 off = (x + y * im->xsize) * im->channels;
216 for (ch = 0; ch < im->channels; ++ch)
217 STORE16(im->idata, off+ch, SampleFTo16(val->channel[ch]));
222 static int i_gpixf_d16(i_img *im, int x, int y, i_fcolor *val) {
225 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
228 off = (x + y * im->xsize) * im->channels;
229 for (ch = 0; ch < im->channels; ++ch)
230 val->channel[ch] = Sample16ToF(GET16(im->idata, off+ch));
235 static int i_glin_d16(i_img *im, int l, int r, int y, i_color *vals) {
238 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
241 off = (l+y*im->xsize) * im->channels;
243 for (i = 0; i < count; ++i) {
244 for (ch = 0; ch < im->channels; ++ch) {
245 vals[i].channel[ch] = GET16as8(im->idata, off);
256 static int i_plin_d16(i_img *im, int l, int r, int y, i_color *vals) {
259 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
262 off = (l+y*im->xsize) * im->channels;
264 for (i = 0; i < count; ++i) {
265 for (ch = 0; ch < im->channels; ++ch) {
266 STORE8as16(im->idata, off, vals[i].channel[ch]);
277 static int i_glinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
280 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
283 off = (l+y*im->xsize) * im->channels;
285 for (i = 0; i < count; ++i) {
286 for (ch = 0; ch < im->channels; ++ch) {
287 vals[i].channel[ch] = Sample16ToF(GET16(im->idata, off));
298 static int i_plinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
301 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
304 off = (l+y*im->xsize) * im->channels;
306 for (i = 0; i < count; ++i) {
307 for (ch = 0; ch < im->channels; ++ch) {
308 STORE16(im->idata, off, SampleFTo16(vals[i].channel[ch]));
319 static int i_gsamp_d16(i_img *im, int l, int r, int y, i_sample_t *samps,
320 int const *chans, int chan_count) {
324 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
327 off = (l+y*im->xsize) * im->channels;
332 /* make sure we have good channel numbers */
333 for (ch = 0; ch < chan_count; ++ch) {
334 if (chans[ch] < 0 || chans[ch] >= im->channels) {
335 i_push_errorf(0, "No channel %d in this image", chans[ch]);
339 for (i = 0; i < w; ++i) {
340 for (ch = 0; ch < chan_count; ++ch) {
341 *samps++ = GET16as8(im->idata, off+chans[ch]);
348 for (i = 0; i < w; ++i) {
349 for (ch = 0; ch < chan_count; ++ch) {
350 *samps++ = GET16as8(im->idata, off+ch);
364 static int i_gsampf_d16(i_img *im, int l, int r, int y, i_fsample_t *samps,
365 int const *chans, int chan_count) {
369 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
372 off = (l+y*im->xsize) * im->channels;
377 /* make sure we have good channel numbers */
378 for (ch = 0; ch < chan_count; ++ch) {
379 if (chans[ch] < 0 || chans[ch] >= im->channels) {
380 i_push_errorf(0, "No channel %d in this image", chans[ch]);
384 for (i = 0; i < w; ++i) {
385 for (ch = 0; ch < chan_count; ++ch) {
386 *samps++ = Sample16ToF(GET16(im->idata, off+chans[ch]));
393 for (i = 0; i < w; ++i) {
394 for (ch = 0; ch < chan_count; ++ch) {
395 *samps++ = Sample16ToF(GET16(im->idata, off+ch));
414 Tony Cook <tony@develop-help.com>