X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/b8c2033e5aee9480ee5f2d219bde41ee1d365505..a10945af5bc182cd109317d19d84a1f04df1cccc:/imgdouble.c diff --git a/imgdouble.c b/imgdouble.c index 0afd3dc2..903912ba 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,37 @@ static i_img IIM_base_double_direct = /* =item i_img_double_new(int x, int y, int ch) +=category Image creation + 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 +128,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 +143,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) 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; } @@ -149,15 +176,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) 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; } @@ -196,7 +230,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 +238,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 +283,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 +291,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 +316,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; @@ -305,7 +361,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;