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);
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_low(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 int bytes, line_bytes;
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 /* basic assumption: we can always allocate a buffer representing a
164 line from the image, otherwise we're going to have trouble
165 working with the image */
166 line_bytes = sizeof(i_fcolor) * x;
167 if (line_bytes / x != sizeof(i_fcolor)) {
168 i_push_error(0, "integer overflow calculating scanline allocation");
172 *im = IIM_base_16bit_direct;
173 i_tags_new(&im->tags);
179 im->idata = mymalloc(im->bytes);
181 memset(im->idata, 0, im->bytes);
184 i_tags_destroy(&im->tags);
192 =item i_img_16_new(x, y, ch)
194 =category Image creation
196 Create a new 16-bit/sample image.
198 Returns the image on success, or NULL on failure.
203 i_img *i_img_16_new(int x, int y, int ch) {
208 im = mymalloc(sizeof(i_img));
210 if (!i_img_16_new_low(im, x, y, ch)) {
216 mm_log((1, "(%p) <- i_img_16_new\n", im));
222 =item i_img_to_rgb16(im)
224 =category Image creation
226 Returns a 16-bit/sample version of the supplied image.
228 Returns the image on success, or NULL on failure.
234 i_img_to_rgb16(i_img *im) {
239 targ = i_img_16_new(im->xsize, im->ysize, im->channels);
242 line = mymalloc(sizeof(i_fcolor) * im->xsize);
243 for (y = 0; y < im->ysize; ++y) {
244 i_glinf(im, 0, im->xsize, y, line);
245 i_plinf(targ, 0, im->xsize, y, line);
253 static int i_ppix_d16(i_img *im, int x, int y, const i_color *val) {
256 if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
259 off = (x + y * im->xsize) * im->channels;
260 if (I_ALL_CHANNELS_WRITABLE(im)) {
261 for (ch = 0; ch < im->channels; ++ch)
262 STORE8as16(im->idata, off+ch, val->channel[ch]);
265 for (ch = 0; ch < im->channels; ++ch)
266 if (im->ch_mask & (1 << ch))
267 STORE8as16(im->idata, off+ch, val->channel[ch]);
273 static int i_gpix_d16(i_img *im, int x, int y, i_color *val) {
276 if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
279 off = (x + y * im->xsize) * im->channels;
280 for (ch = 0; ch < im->channels; ++ch)
281 val->channel[ch] = GET16as8(im->idata, off+ch);
286 static int i_ppixf_d16(i_img *im, int x, int y, const i_fcolor *val) {
289 if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
292 off = (x + y * im->xsize) * im->channels;
293 if (I_ALL_CHANNELS_WRITABLE(im)) {
294 for (ch = 0; ch < im->channels; ++ch)
295 STORE16(im->idata, off+ch, SampleFTo16(val->channel[ch]));
298 for (ch = 0; ch < im->channels; ++ch)
299 if (im->ch_mask & (1 << ch))
300 STORE16(im->idata, off+ch, SampleFTo16(val->channel[ch]));
306 static int i_gpixf_d16(i_img *im, int x, int y, i_fcolor *val) {
309 if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize)
312 off = (x + y * im->xsize) * im->channels;
313 for (ch = 0; ch < im->channels; ++ch)
314 val->channel[ch] = Sample16ToF(GET16(im->idata, off+ch));
319 static int i_glin_d16(i_img *im, int l, int r, int y, i_color *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] = GET16as8(im->idata, off);
340 static int i_plin_d16(i_img *im, int l, int r, int y, const i_color *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 STORE8as16(im->idata, off, 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 STORE8as16(im->idata, off, vals[i].channel[ch]);
372 static int i_glinf_d16(i_img *im, int l, int r, int y, i_fcolor *vals) {
375 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
378 off = (l+y*im->xsize) * im->channels;
380 for (i = 0; i < count; ++i) {
381 for (ch = 0; ch < im->channels; ++ch) {
382 vals[i].channel[ch] = Sample16ToF(GET16(im->idata, off));
393 static int i_plinf_d16(i_img *im, int l, int r, int y, const i_fcolor *vals) {
396 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
399 off = (l+y*im->xsize) * im->channels;
401 if (I_ALL_CHANNELS_WRITABLE(im)) {
402 for (i = 0; i < count; ++i) {
403 for (ch = 0; ch < im->channels; ++ch) {
404 STORE16(im->idata, off, SampleFTo16(vals[i].channel[ch]));
410 for (i = 0; i < count; ++i) {
411 for (ch = 0; ch < im->channels; ++ch) {
412 if (im->ch_mask & (1 << ch))
413 STORE16(im->idata, off, SampleFTo16(vals[i].channel[ch]));
425 static int i_gsamp_d16(i_img *im, int l, int r, int y, i_sample_t *samps,
426 int const *chans, int chan_count) {
430 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
433 off = (l+y*im->xsize) * im->channels;
438 /* make sure we have good channel numbers */
439 for (ch = 0; ch < chan_count; ++ch) {
440 if (chans[ch] < 0 || chans[ch] >= im->channels) {
441 i_push_errorf(0, "No channel %d in this image", chans[ch]);
445 for (i = 0; i < w; ++i) {
446 for (ch = 0; ch < chan_count; ++ch) {
447 *samps++ = GET16as8(im->idata, off+chans[ch]);
454 for (i = 0; i < w; ++i) {
455 for (ch = 0; ch < chan_count; ++ch) {
456 *samps++ = GET16as8(im->idata, off+ch);
470 static int i_gsampf_d16(i_img *im, int l, int r, int y, i_fsample_t *samps,
471 int const *chans, int chan_count) {
475 if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) {
478 off = (l+y*im->xsize) * im->channels;
483 /* make sure we have good channel numbers */
484 for (ch = 0; ch < chan_count; ++ch) {
485 if (chans[ch] < 0 || chans[ch] >= im->channels) {
486 i_push_errorf(0, "No channel %d in this image", chans[ch]);
490 for (i = 0; i < w; ++i) {
491 for (ch = 0; ch < chan_count; ++ch) {
492 *samps++ = Sample16ToF(GET16(im->idata, off+chans[ch]));
499 for (i = 0; i < w; ++i) {
500 for (ch = 0; ch < chan_count; ++ch) {
501 *samps++ = Sample16ToF(GET16(im->idata, off+ch));
520 Tony Cook <tony@develop-help.com>