+/*
+=item fill_image(fill, x, y, width, channels, data, work)
+
+=cut
+*/
+static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels,
+ i_fcolor *data) {
+ struct i_fill_image_t *f = (struct i_fill_image_t *)fill;
+ int i = 0;
+
+ if (f->has_matrix) {
+ /* the hard way */
+ while (i < width) {
+ double rx = f->matrix[0] * (x+i) + f->matrix[1] * y + f->matrix[2];
+ double ry = f->matrix[3] * (x+i) + f->matrix[4] * y + f->matrix[5];
+ double ix = floor(rx / f->src->xsize);
+ double iy = floor(ry / f->src->ysize);
+ i_fcolor c[2][2];
+ i_fcolor c2[2];
+ int dy;
+
+ if (f->xoff) {
+ rx += iy * f->xoff;
+ ix = floor(rx / f->src->xsize);
+ }
+ else if (f->yoff) {
+ ry += ix * f->yoff;
+ iy = floor(ry / f->src->ysize);
+ }
+ rx -= ix * f->src->xsize;
+ ry -= iy * f->src->ysize;
+
+ for (dy = 0; dy < 2; ++dy) {
+ if ((int)rx == f->src->xsize-1) {
+ i_gpixf(f->src, f->src->xsize-1, ((int)ry+dy) % f->src->ysize, &c[dy][0]);
+ i_gpixf(f->src, 0, ((int)ry+dy) % f->src->xsize, &c[dy][1]);
+ }
+ else {
+ i_glinf(f->src, (int)rx, (int)rx+2, ((int)ry+dy) % f->src->ysize,
+ c[dy]);
+ }
+ c2[dy] = interp_i_fcolor(c[dy][0], c[dy][1], rx, f->src->channels);
+ }
+ *data++ = interp_i_fcolor(c2[0], c2[1], ry, f->src->channels);
+ ++i;
+ }
+ }
+ else {
+ /* the easy way */
+ /* this should be possible to optimize to use i_glin() */
+ while (i < width) {
+ int rx = x+i;
+ int ry = y;
+ int ix = rx / f->src->xsize;
+ int iy = ry / f->src->ysize;
+
+ if (f->xoff) {
+ rx += iy * f->xoff;
+ ix = rx / f->src->xsize;
+ }
+ else if (f->yoff) {
+ ry += ix * f->yoff;
+ iy = ry / f->src->xsize;
+ }
+ rx -= ix * f->src->xsize;
+ ry -= iy * f->src->ysize;
+ i_gpixf(f->src, rx, ry, data);
+ ++data;
+ ++i;
+ }
+ }
+ if (f->src->channels == 3) {
+ /* just set the alpha */
+ for (i = 0; i < width; ++i) {
+ data->channel[3] = 1.0;
+ data++;
+ }
+ }
+ else if (f->src->channels == 2) {
+ /* copy the alpha to channel 3, duplicate the grey value */
+ for (i = 0; i < width; ++i) {
+ data->channel[3] = data->channel[1];
+ data->channel[1] = data->channel[2] = data->channel[0];
+ data++;
+ }
+ }
+ else if (f->src->channels == 1) {
+ /* set the alpha, duplicate grey */
+ for (i = 0; i < width; ++i) {
+ data->channel[3] = 1.0;
+ data->channel[1] = data->channel[2] = data->channel[0];
+ data++;