Пример #1
0
void
gegl_matrix3_invert (GeglMatrix3 *matrix)
{
  GeglMatrix3 copy;
  gdouble coeff;

  gegl_matrix3_copy_into (&copy, matrix);
  coeff = 1 / gegl_matrix3_determinant (matrix);

  matrix->coeff [0][0] = (copy.coeff [1][1] * copy.coeff [2][2] -
                   copy.coeff [1][2] * copy.coeff [2][1]) * coeff;
  matrix->coeff [1][0] = (copy.coeff [1][2] * copy.coeff [2][0] -
                   copy.coeff [1][0] * copy.coeff [2][2]) * coeff;
  matrix->coeff [2][0] = (copy.coeff [1][0] * copy.coeff [2][1] -
                   copy.coeff [1][1] * copy.coeff [2][0]) * coeff;

  matrix->coeff [0][1] = (copy.coeff [0][2] * copy.coeff [2][1] -
                   copy.coeff [0][1] * copy.coeff [2][2]) * coeff;
  matrix->coeff [1][1] = (copy.coeff [0][0] * copy.coeff [2][2] -
                   copy.coeff [0][2] * copy.coeff [2][0]) * coeff;
  matrix->coeff [2][1] = (copy.coeff [0][1] * copy.coeff [2][0] -
                   copy.coeff [0][0] * copy.coeff [2][1]) * coeff;

  matrix->coeff [0][2] = (copy.coeff [0][1] * copy.coeff [1][2] -
                   copy.coeff [0][2] * copy.coeff [1][1]) * coeff;
  matrix->coeff [1][2] = (copy.coeff [0][2] * copy.coeff [1][0] -
                   copy.coeff [0][0] * copy.coeff [1][2]) * coeff;
  matrix->coeff [2][2] = (copy.coeff [0][0] * copy.coeff [1][1] -
                   copy.coeff [0][1] * copy.coeff [1][0]) * coeff;
}
Пример #2
0
gboolean
gegl_matrix3_is_translate (GeglMatrix3 *matrix)
{
  GeglMatrix3 copy;
  gegl_matrix3_copy_into (&copy, matrix);
  copy.coeff [0][2] = copy.coeff [1][2] = 0.;
  return gegl_matrix3_is_identity (&copy);
}
Пример #3
0
static gboolean
gegl_affine_matrix3_allow_fast_reflect_y (GeglMatrix3 *matrix)
{
  GeglMatrix3 copy;

  if (! GEGL_FLOAT_EQUAL (matrix->coeff[0][0], -1.0))
    return FALSE;
  gegl_matrix3_copy_into (&copy, matrix);
  copy.coeff[0][0] = 1.;
  return gegl_affine_matrix3_allow_fast_translate (&copy);
}
Пример #4
0
void
gegl_matrix3_multiply (GeglMatrix3 *left,
                       GeglMatrix3 *right,
                       GeglMatrix3 *product)
{
  GeglMatrix3 temp;
  gint    i;

  for (i = 0; i < 3; i++)
    {
      temp.coeff [i][0] = left->coeff [i][0] * right->coeff [0][0]
                    + left->coeff [i][1] * right->coeff [1][0]
                    + left->coeff [i][2] * right->coeff [2][0];
      temp.coeff [i][1] = left->coeff [i][0] * right->coeff [0][1]
                    + left->coeff [i][1] * right->coeff [1][1]
                    + left->coeff [i][2] * right->coeff [2][1];
      temp.coeff [i][2] = left->coeff [i][0] * right->coeff [0][2]
                    + left->coeff [i][1] * right->coeff [1][2]
                    + left->coeff [i][2] * right->coeff [2][2];
    }

  gegl_matrix3_copy_into (product, &temp);
}
Пример #5
0
static void
affine_generic (GeglBuffer  *dest,
                GeglBuffer  *src,
                GeglMatrix3 *matrix,
                GeglSampler *sampler)
{
  GeglBufferIterator *i;
  const GeglRectangle *dest_extent;
  gint                  x, y;
  gfloat * restrict     dest_buf,
                       *dest_ptr;
  GeglMatrix3           inverse;
  GeglMatrix2           inverse_jacobian;
  gdouble               u_start,
                        v_start,
                        u_float,
                        v_float;

  Babl                 *format;

  gint                  dest_pixels;

  format = babl_format ("RaGaBaA float");

  /* XXX: fast paths as existing in files in the same dir as affine.c
   *      should probably be hooked in here, and bailing out before using
   *      the generic code.
   */
  g_object_get (dest, "pixels", &dest_pixels, NULL);
  dest_extent = gegl_buffer_get_extent (dest);


  i = gegl_buffer_iterator_new (dest, dest_extent, format, GEGL_BUFFER_WRITE);
  while (gegl_buffer_iterator_next (i))
    {
      GeglRectangle *roi = &i->roi[0];
      dest_buf           = (gfloat *)i->data[0];

      gegl_matrix3_copy_into (&inverse, matrix);
      gegl_matrix3_invert (&inverse);
      inverse_jacobian.coeff[0][0] = inverse.coeff[0][0];
      inverse_jacobian.coeff[0][1] = inverse.coeff[0][1];
      inverse_jacobian.coeff[1][0] = inverse.coeff[1][0];
      inverse_jacobian.coeff[1][1] = inverse.coeff[1][1];

     /* set inverse_jacobian for samplers that support it */
      u_start = inverse.coeff[0][0] * roi->x + inverse.coeff[0][1]
                    * roi->y + inverse.coeff[0][2];
      v_start = inverse.coeff[1][0] * roi->x + inverse.coeff[1][1]
                    * roi->y + inverse.coeff[1][2];

      /* correct rounding on e.g. negative scaling (is this sound?) */
      if (inverse.coeff [0][0] < 0.)  u_start -= .001;
      if (inverse.coeff [1][1] < 0.)  v_start -= .001;

      for (dest_ptr = dest_buf, y = roi->height; y--;)
        {
           u_float = u_start;
           v_float = v_start;

           for (x = roi->width; x--;)
             {
               gegl_sampler_get (sampler, u_float, v_float, &inverse_jacobian, dest_ptr);
               dest_ptr+=4;
               u_float += inverse.coeff [0][0];
               v_float += inverse.coeff [1][0];
             }
           u_start += inverse.coeff [0][1];
           v_start += inverse.coeff [1][1];
        }
    }
}