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 if (x < 1 || y < 1) {
149 i_push_error(0, "Image sizes must be positive");
152 if (ch < 1 || ch > MAXCHANNELS) {
153 i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS);
157 *im = IIM_base_16bit_direct;
158 i_tags_new(&im->tags);
162 im->bytes = x * y * ch * 2;
164 im->idata = mymalloc(im->bytes);
166 memset(im->idata, 0, im->bytes);
169 i_tags_destroy(&im->tags);
176 i_img *i_img_16_new(int x, int y, int ch) {
181 im = mymalloc(sizeof(i_img));
183 if (!i_img_16_new_low(im, x, y, ch)) {
189 mm_log((1, "(%p) <- i_img_16_new\n", im));
194 static int i_ppix_d16(i_img *im, int x, int y, i_color *val) {
197 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
200 off = (x + y * im->xsize) * im->channels;
201 for (ch = 0; ch < im->channels; ++ch)
202 STORE8as16(im->idata, off+ch, val->channel[ch]);
207 static int i_gpix_d16(i_img *im, int x, int y, i_color *val) {
210 if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize)
213 off = (x + y * im->xsize) * im->channels;
214 for (ch = 0; ch < im->channels; ++ch)
215 val->channel[ch] = GET16as8(im->idata, off+ch);
220 static int i_ppixf_d16(i_img *im, int x, int y, i_fcolor *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 STORE16(im->idata, off+ch, SampleFTo16(val->channel[ch]));
233 static int i_gpixf_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 for (ch = 0; ch < im->channels; ++ch)
241 val->channel[ch] = Sample16ToF(GET16(im->idata, off+ch));
246 static int i_glin_d16(i_img *im, int l, int r, int y, i_color *vals) {
249 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
252 off = (l+y*im->xsize) * im->channels;
254 for (i = 0; i < count; ++i) {
255 for (ch = 0; ch < im->channels; ++ch) {
256 vals[i].channel[ch] = GET16as8(im->idata, off);
267 static int i_plin_d16(i_img *im, int l, int r, int y, i_color *vals) {
270 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
273 off = (l+y*im->xsize) * im->channels;
275 for (i = 0; i < count; ++i) {
276 for (ch = 0; ch < im->channels; ++ch) {
277 STORE8as16(im->idata, off, vals[i].channel[ch]);
288 static int i_glinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
291 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
294 off = (l+y*im->xsize) * im->channels;
296 for (i = 0; i < count; ++i) {
297 for (ch = 0; ch < im->channels; ++ch) {
298 vals[i].channel[ch] = Sample16ToF(GET16(im->idata, off));
309 static int i_plinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
312 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
315 off = (l+y*im->xsize) * im->channels;
317 for (i = 0; i < count; ++i) {
318 for (ch = 0; ch < im->channels; ++ch) {
319 STORE16(im->idata, off, SampleFTo16(vals[i].channel[ch]));
330 static int i_gsamp_d16(i_img *im, int l, int r, int y, i_sample_t *samps,
331 int const *chans, int chan_count) {
335 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
338 off = (l+y*im->xsize) * im->channels;
343 /* make sure we have good channel numbers */
344 for (ch = 0; ch < chan_count; ++ch) {
345 if (chans[ch] < 0 || chans[ch] >= im->channels) {
346 i_push_errorf(0, "No channel %d in this image", chans[ch]);
350 for (i = 0; i < w; ++i) {
351 for (ch = 0; ch < chan_count; ++ch) {
352 *samps++ = GET16as8(im->idata, off+chans[ch]);
359 for (i = 0; i < w; ++i) {
360 for (ch = 0; ch < chan_count; ++ch) {
361 *samps++ = GET16as8(im->idata, off+ch);
375 static int i_gsampf_d16(i_img *im, int l, int r, int y, i_fsample_t *samps,
376 int const *chans, int chan_count) {
380 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
383 off = (l+y*im->xsize) * im->channels;
388 /* make sure we have good channel numbers */
389 for (ch = 0; ch < chan_count; ++ch) {
390 if (chans[ch] < 0 || chans[ch] >= im->channels) {
391 i_push_errorf(0, "No channel %d in this image", chans[ch]);
395 for (i = 0; i < w; ++i) {
396 for (ch = 0; ch < chan_count; ++ch) {
397 *samps++ = Sample16ToF(GET16(im->idata, off+chans[ch]));
404 for (i = 0; i < w; ++i) {
405 for (ch = 0; ch < chan_count; ++ch) {
406 *samps++ = Sample16ToF(GET16(im->idata, off+ch));
425 Tony Cook <tony@develop-help.com>