Re: [Gegl-developer] Proposition : GeglInterpolator
What I tried to do with the gegl_interpolator was in fact what gimp is doing in gimpdrawable-transform, Gimp only downsamples in the scale-funcs not during the transformation . I'm not sure if it is possible to corectly downsample during transformation. So the resampler should use a transformation matrix, and take source coördinates. instead of : matrix3_copy (inverse, matrix); matrix3_invert (inverse); fu = du = inverse[0][0] * dest-x + inverse[0][1] * dest-y + inverse[0][2] - src-x; fv = dv = inverse[1][0] * dest-x + inverse[1][1] * dest-y + inverse[1][2] - src-y; for (dest_ptr = dest_buf, y = 0; y dest-height; y++) { for (x = 0; x dest-width; x++) { gegl_interpolator_get (interpolator, fu, fv, dest_buf); fu += inverse [0][0]; fv += inverse [1][0]; } du += inverse [0][1]; dv += inverse [1][1]; fu = du; fv = dv; ... } The transformed coordinates should be calculated within the resampler. gegl_resampler_set_matrix(resampler, matrix); for (y = 0; y dest-height; y++) { for (x = 0; x dest-width; x++) { gegl_resampler_get (resampler, x, y, dest_buf); } ... } The gegl_resampler_get should then calculate the number of transformed coordinates needed by the resampling method (lanczos/bicubic/bilinear/nearest) as in gimpdrawable-transform. ca= cos a sa = sin a . = don't touch gegl_resampler_set_matrix_identity() | 10 0 | | 01 0 | | 00 1 | gegl_resampler_set_scale(x, y) | *sy . 0 | | .*sy 0 | | .. 1 | gegl_resampler_set_translscale(tx, ty) | .. 0 | | .. 0 | | tx ty1 | gegl_resampler_set_rotate(a) | *ca *sa 0 | | *-sa *ca 0 | | .. 1 | gegl_resampler_set_matrix(a,b,c,d,e,f ) | ad0 | | be0 | | cf1 | Geert ___ Gegl-developer mailing list Gegl-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer
Re: [Gegl-developer] Proposition : GeglInterpolator
Nope, the point is that interpolation is wrong when scaling down you as will happen when scaling down using an affine transform or a perspective transform. By transforming the corners of a pixel, one would get an idea about the size needed for the resampling kernel. If you scale a image to 10% of the original size using cubic, you have a situation where the data for each destination pixel is taken from a region of 4x4pixel, whilst it should at least be taken from a region of 10x10pixels, 84% of the image data is thrown away. OK, the handling of scaling down is not yet in the proposition Could we not just add the scale factor to the API ? ___ Gegl-developer mailing list Gegl-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer
Re: [Gegl-developer] Proposition : GeglInterpolator
On 10/17/06, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: If you scale a image to 10% of the original size using cubic, you have a situation where the data for each destination pixel is taken from a region of 4x4pixel, whilst it should at least be taken from a region of 10x10pixels, 84% of the image data is thrown away. OK, the handling of scaling down is not yet in the proposition Could we not just add the scale factor to the API ? The scale factor is not enough, if we scale it to 10% horizontally and 70% vertically (or add some kind of rotation as well). A fixed scale factor would no longer be correct. Doing a reverse transform of the corners of the destination pixel would give us all the information we need, and work for perspective transforms as well, hence the method I suggested. /Øyvind K. -- «The future is already here. It's just not very evenly distributed» -- William Gibson http://pippin.gimp.org/http://ffii.org/ ___ Gegl-developer mailing list Gegl-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer
Re: [Gegl-developer] Proposition : GeglInterpolator
I've added the implementation to bug report : Bug 360888 – Interpolation for operations GeglInterpolator + GeglInterpolatorNearest | + GeglInterpolatorLinear | + GeglInterpolatorCubic | + GeglInterpolatorLanczos usage : void displacementmap(GeglBuffer *src, GeglBuffer *aux, GeglBuffer *dst, gdouble scale, gint cx, gint cy) { gint i, j, k; gint dst_pos; gdouble dx, dy, xc, yc; gfloat *buf = g_malloc0 (4 * 4 * 4); gfloat *aux_buf = g_malloc0 (aux-width * aux-height * 4 * 4); gfloat *dst_buf = g_malloc0 (dst-width * dst-height * 4 * 4); gegl_buffer_get_fmt (aux, aux_buf, babl_format (RGBA float)); gegl_buffer_get_fmt (dst, dst_buf, babl_format (RaGaBaA float)); * GeglInterpolatorCubic *interpolator = g_object_new (GEGL_TYPE_INTERPOLATOR_CUBIC, input, src, format, babl_format (RaGaBaA float), NULL); gegl_interpolator_prepare(GEGL_INTERPOLATOR(interpolator)) ; * for (i = 0; i src-height; i++) for (j = 0; j src-width; j++) { /* Calculate x/y - offset relative to origin */ dx = (gdouble) j / (src-width-1.0); dy = (gdouble) i / (src-height-1.0); xc = j + (gint) (displacement (aux, aux_buf, dx, dy, cx) * scale); yc = i + (gint) (displacement (aux, aux_buf, dx, dy, cy) * scale); * gegl_interpolator_get(GEGL_INTERPOLATOR(interpolator), xc, yc, buf); /* returns a interpolated pixel in dst */ * dst_pos = (i * dst-width + j )* 4; for (k = 0 ; k 4 ; k++) dst_buf[dst_pos+k]= buf[k]; } gegl_buffer_set_fmt (dst, dst_buf, babl_format (RaGaBaA float)); g_object_unref (interpolator); g_free (aux_buf); g_free (dst_buf); } ___ Gegl-developer mailing list Gegl-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer