X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/9a88a5e6b7a2a685d04c1c18d402a3735e5a3e37..333d74854bf4b789a43a77c53d620913bd922db0:/imgdouble.c diff --git a/imgdouble.c b/imgdouble.c index 7770f7a9..b9df1e30 100644 --- a/imgdouble.c +++ b/imgdouble.c @@ -20,21 +20,21 @@ sample image type to work with. =cut */ -#include "image.h" -#include "imagei.h" +#include "imager.h" +#include "imageri.h" -static int i_ppix_ddoub(i_img *im, int x, int y, i_color *val); +static int i_ppix_ddoub(i_img *im, int x, int y, const i_color *val); static int i_gpix_ddoub(i_img *im, int x, int y, i_color *val); static int i_glin_ddoub(i_img *im, int l, int r, int y, i_color *vals); -static int i_plin_ddoub(i_img *im, int l, int r, int y, i_color *vals); -static int i_ppixf_ddoub(i_img *im, int x, int y, i_fcolor *val); +static int i_plin_ddoub(i_img *im, int l, int r, int y, const i_color *vals); +static int i_ppixf_ddoub(i_img *im, int x, int y, const i_fcolor *val); static int i_gpixf_ddoub(i_img *im, int x, int y, i_fcolor *val); static int i_glinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals); -static int i_plinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals); +static int i_plinf_ddoub(i_img *im, int l, int r, int y, const i_fcolor *vals); static int i_gsamp_ddoub(i_img *im, int l, int r, int y, i_sample_t *samps, - int *chans, int chan_count); + int const *chans, int chan_count); static int i_gsampf_ddoub(i_img *im, int l, int r, int y, i_fsample_t *samps, - int *chans, int chan_count); + int const *chans, int chan_count); /* =item IIM_base_16bit_direct @@ -81,19 +81,38 @@ static i_img IIM_base_double_direct = /* =item i_img_double_new(int x, int y, int ch) +=category Image creation/destruction +=synopsis i_img *img = i_img_double_new(width, height, channels); + Creates a new double per sample image. =cut */ i_img *i_img_double_new_low(i_img *im, int x, int y, int ch) { + int bytes; + mm_log((1,"i_img_double_new(x %d, y %d, ch %d)\n", x, y, ch)); + + if (x < 1 || y < 1) { + i_push_error(0, "Image sizes must be positive"); + return NULL; + } + if (ch < 1 || ch > MAXCHANNELS) { + i_push_errorf(0, "channels must be between 1 and %d", MAXCHANNELS); + return NULL; + } + bytes = x * y * ch * sizeof(double); + if (bytes / y / ch / sizeof(double) != x) { + i_push_errorf(0, "integer overflow calculating image allocation"); + return NULL; + } *im = IIM_base_double_direct; i_tags_new(&im->tags); im->xsize = x; im->ysize = y; im->channels = ch; - im->bytes = x * y * ch * sizeof(double); + im->bytes = bytes; im->ext_data = NULL; im->idata = mymalloc(im->bytes); if (im->idata) { @@ -110,6 +129,8 @@ i_img *i_img_double_new_low(i_img *im, int x, int y, int ch) { i_img *i_img_double_new(int x, int y, int ch) { i_img *im; + i_clear_error(); + im = mymalloc(sizeof(i_img)); if (im) { if (!i_img_double_new_low(im, x, y, ch)) { @@ -123,15 +144,22 @@ i_img *i_img_double_new(int x, int y, int ch) { return im; } -static int i_ppix_ddoub(i_img *im, int x, int y, i_color *val) { +static int i_ppix_ddoub(i_img *im, int x, int y, const i_color *val) { int off, ch; - if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize) + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) return -1; off = (x + y * im->xsize) * im->channels; - for (ch = 0; ch < im->channels; ++ch) - ((double*)im->idata)[off+ch] = Sample8ToF(val->channel[ch]); + if (I_ALL_CHANNELS_WRITABLE(im)) { + for (ch = 0; ch < im->channels; ++ch) + ((double*)im->idata)[off+ch] = Sample8ToF(val->channel[ch]); + } + else { + for (ch = 0; ch < im->channels; ++ch) + if (im->ch_mask & (1<idata)[off+ch] = Sample8ToF(val->channel[ch]); + } return 0; } @@ -139,7 +167,7 @@ static int i_ppix_ddoub(i_img *im, int x, int y, i_color *val) { static int i_gpix_ddoub(i_img *im, int x, int y, i_color *val) { int off, ch; - if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize) + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) return -1; off = (x + y * im->xsize) * im->channels; @@ -149,15 +177,22 @@ static int i_gpix_ddoub(i_img *im, int x, int y, i_color *val) { return 0; } -static int i_ppixf_ddoub(i_img *im, int x, int y, i_fcolor *val) { +static int i_ppixf_ddoub(i_img *im, int x, int y, const i_fcolor *val) { int off, ch; - if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize) + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) return -1; off = (x + y * im->xsize) * im->channels; - for (ch = 0; ch < im->channels; ++ch) - ((double *)im->idata)[off+ch] = val->channel[ch];; + if (I_ALL_CHANNELS_WRITABLE(im)) { + for (ch = 0; ch < im->channels; ++ch) + ((double *)im->idata)[off+ch] = val->channel[ch]; + } + else { + for (ch = 0; ch < im->channels; ++ch) + if (im->ch_mask & (1 << ch)) + ((double *)im->idata)[off+ch] = val->channel[ch]; + } return 0; } @@ -165,7 +200,7 @@ static int i_ppixf_ddoub(i_img *im, int x, int y, i_fcolor *val) { static int i_gpixf_ddoub(i_img *im, int x, int y, i_fcolor *val) { int off, ch; - if (x < 0 || x >= im->xsize || y < 0 || y > im->ysize) + if (x < 0 || x >= im->xsize || y < 0 || y >= im->ysize) return -1; off = (x + y * im->xsize) * im->channels; @@ -196,7 +231,7 @@ static int i_glin_ddoub(i_img *im, int l, int r, int y, i_color *vals) { } } -static int i_plin_ddoub(i_img *im, int l, int r, int y, i_color *vals) { +static int i_plin_ddoub(i_img *im, int l, int r, int y, const i_color *vals) { int ch, count, i; int off; if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) { @@ -204,10 +239,21 @@ static int i_plin_ddoub(i_img *im, int l, int r, int y, i_color *vals) { r = im->xsize; off = (l+y*im->xsize) * im->channels; count = r - l; - for (i = 0; i < count; ++i) { - for (ch = 0; ch < im->channels; ++ch) { - ((double *)im->idata)[off] = Sample8ToF(vals[i].channel[ch]); - ++off; + if (I_ALL_CHANNELS_WRITABLE(im)) { + for (i = 0; i < count; ++i) { + for (ch = 0; ch < im->channels; ++ch) { + ((double *)im->idata)[off] = Sample8ToF(vals[i].channel[ch]); + ++off; + } + } + } + else { + for (i = 0; i < count; ++i) { + for (ch = 0; ch < im->channels; ++ch) { + if (im->ch_mask & (1 << ch)) + ((double *)im->idata)[off] = Sample8ToF(vals[i].channel[ch]); + ++off; + } } } return count; @@ -238,7 +284,7 @@ static int i_glinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) { } } -static int i_plinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) { +static int i_plinf_ddoub(i_img *im, int l, int r, int y, const i_fcolor *vals) { int ch, count, i; int off; if (y >=0 && y < im->ysize && l < im->xsize && l >= 0) { @@ -246,10 +292,21 @@ static int i_plinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) { r = im->xsize; off = (l+y*im->xsize) * im->channels; count = r - l; - for (i = 0; i < count; ++i) { - for (ch = 0; ch < im->channels; ++ch) { - ((double *)im->idata)[off] = vals[i].channel[ch]; - ++off; + if (I_ALL_CHANNELS_WRITABLE(im)) { + for (i = 0; i < count; ++i) { + for (ch = 0; ch < im->channels; ++ch) { + ((double *)im->idata)[off] = vals[i].channel[ch]; + ++off; + } + } + } + else { + for (i = 0; i < count; ++i) { + for (ch = 0; ch < im->channels; ++ch) { + if (im->ch_mask & (1 << ch)) + ((double *)im->idata)[off] = vals[i].channel[ch]; + ++off; + } } } return count; @@ -260,7 +317,7 @@ static int i_plinf_ddoub(i_img *im, int l, int r, int y, i_fcolor *vals) { } static int i_gsamp_ddoub(i_img *im, int l, int r, int y, i_sample_t *samps, - int *chans, int chan_count) { + int const *chans, int chan_count) { int ch, count, i, w; int off; @@ -288,6 +345,11 @@ static int i_gsamp_ddoub(i_img *im, int l, int r, int y, i_sample_t *samps, } } else { + if (chan_count <= 0 || chan_count > im->channels) { + i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels", + chan_count); + return 0; + } for (i = 0; i < w; ++i) { for (ch = 0; ch < chan_count; ++ch) { *samps++ = SampleFTo8(((double *)im->idata)[off+ch]); @@ -305,7 +367,7 @@ static int i_gsamp_ddoub(i_img *im, int l, int r, int y, i_sample_t *samps, } static int i_gsampf_ddoub(i_img *im, int l, int r, int y, i_fsample_t *samps, - int *chans, int chan_count) { + int const *chans, int chan_count) { int ch, count, i, w; int off; @@ -333,6 +395,11 @@ static int i_gsampf_ddoub(i_img *im, int l, int r, int y, i_fsample_t *samps, } } else { + if (chan_count <= 0 || chan_count > im->channels) { + i_push_errorf(0, "chan_count %d out of range, must be >0, <= channels", + chan_count); + return 0; + } for (i = 0; i < w; ++i) { for (ch = 0; ch < chan_count; ++ch) { *samps++ = ((double *)im->idata)[off+ch]; @@ -349,3 +416,17 @@ static int i_gsampf_ddoub(i_img *im, int l, int r, int y, i_fsample_t *samps, } } + +/* +=back + +=head1 AUTHOR + +Tony Cook + +=head1 SEE ALSO + +Imager(3) + +=cut +*/