[gegl/soc-2013-n-point-deformation: 20/28] npd: preparation for transition to RGBA float color model
- From: Marek Dvoroznak <dvoromar src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/soc-2013-n-point-deformation: 20/28] npd: preparation for transition to RGBA float color model
- Date: Fri, 6 Dec 2013 05:02:47 +0000 (UTC)
commit 98cf609124840f6c8f71db539573df450b171667
Author: Marek Dvoroznak <dvoromar gmail com>
Date: Thu Aug 22 16:35:04 2013 +0200
npd: preparation for transition to RGBA float color model
libs/npd/graphics.c | 364 ++++++++++++++++++++++++++------------------
libs/npd/graphics.h | 46 ++++--
libs/npd/npd_common.h | 9 +-
operations/external/npd.c | 3 +-
4 files changed, 254 insertions(+), 168 deletions(-)
---
diff --git a/libs/npd/graphics.c b/libs/npd/graphics.c
index 57a580c..b590996 100644
--- a/libs/npd/graphics.c
+++ b/libs/npd/graphics.c
@@ -117,22 +117,23 @@ npd_create_mesh_from_image (NPDModel *model,
}
}
}
-
+
hidden_model->current_bones = g_new (NPDBone, current_bones->len);
hidden_model->reference_bones = g_new (NPDBone, reference_bones->len);
-
+
for (i = 0; i < current_bones->len; i++)
{
hidden_model->current_bones[i] = *(NPDBone*) g_ptr_array_index (current_bones, i);
hidden_model->reference_bones[i] = *(NPDBone*) g_ptr_array_index (reference_bones, i);
}
- g_ptr_array_free(current_bones, TRUE);
- g_ptr_array_free(reference_bones, TRUE);
+ g_ptr_array_free (current_bones, TRUE);
+ g_ptr_array_free (reference_bones, TRUE);
}
-void npd_draw_mesh (NPDModel *model,
- NPDDisplay *display)
+void
+npd_draw_mesh (NPDModel *model,
+ NPDDisplay *display)
{
NPDHiddenModel *hm = model->hidden_model;
gint i, j;
@@ -141,7 +142,7 @@ void npd_draw_mesh (NPDModel *model,
{
NPDBone *bone = &hm->current_bones[i];
NPDPoint *first = &bone->points[0];
- NPDPoint *p0, *p1;
+ NPDPoint *p0, *p1 = NULL;
for (j = 1; j < bone->num_of_points; j++)
{
@@ -153,41 +154,16 @@ void npd_draw_mesh (NPDModel *model,
}
}
-gboolean
-npd_compare_colors (NPDColor *c1,
- NPDColor *c2)
-{
- if (c1->r == c2->r &&
- c1->g == c2->g &&
- c1->b == c2->b &&
- c1->a == c2->a)
- return TRUE;
-
- return FALSE;
-}
-
-gboolean
-npd_is_color_transparent (NPDColor *color)
-{
- if (color->a == 0 &&
- color->b == 0 &&
- color->g == 0 &&
- color->r == 0)
- return TRUE;
-
- return FALSE;
-}
-
-gint
-npd_bilinear_interpolation (gint I0,
- gint I1,
- gint I2,
- gint I3,
+gfloat
+npd_bilinear_interpolation (gfloat I0,
+ gfloat I1,
+ gfloat I2,
+ gfloat I3,
gfloat dx,
gfloat dy)
{
- return floor ((I0 * (1 - dx) + I1 * dx) * (1 - dy)
- + (I2 * (1 - dx) + I3 * dx) * dy);
+ return (I0 * (1 - dx) + I1 * dx) * (1 - dy) +
+ (I2 * (1 - dx) + I3 * dx) * dy;
}
void
@@ -205,15 +181,15 @@ npd_bilinear_color_interpolation (NPDColor *I0,
out->a = npd_bilinear_interpolation (I0->a, I1->a, I2->a, I3->a, dx, dy);
}
-gint
-npd_blend_band (gint src,
- gint dst,
+gfloat
+npd_blend_band (gfloat src,
+ gfloat dst,
gfloat src_alpha,
gfloat dst_alpha,
gfloat out_alpha_recip)
{
- return floor ((src * src_alpha +
- dst * dst_alpha * (1 - src_alpha)) * out_alpha_recip);
+ return (src * src_alpha +
+ dst * dst_alpha * (1 - src_alpha)) * out_alpha_recip;
}
void
@@ -221,27 +197,37 @@ npd_blend_colors (NPDColor *src,
NPDColor *dst,
NPDColor *out_color)
{
+#ifdef NPD_RGBA_FLOAT
+ gfloat src_A = src->a,
+ dst_A = dst->a;
+#else
gfloat src_A = src->a / 255.0,
dst_A = dst->a / 255.0;
+#endif
gfloat out_alpha = src_A + dst_A * (1 - src_A);
gfloat out_alpha_recip = 1 / out_alpha;
out_color->r = npd_blend_band (src->r, dst->r, src_A, dst_A, out_alpha_recip);
out_color->g = npd_blend_band (src->g, dst->g, src_A, dst_A, out_alpha_recip);
out_color->b = npd_blend_band (src->b, dst->b, src_A, dst_A, out_alpha_recip);
+#ifdef NPD_RGBA_FLOAT
+ out_color->a = out_alpha;
+#else
out_color->a = out_alpha * 255;
+#endif
}
void
-npd_texture_fill_triangle (gint x1,
- gint y1,
- gint x2,
- gint y2,
- gint x3,
- gint y3,
+npd_texture_fill_triangle (gint x1,
+ gint y1,
+ gint x2,
+ gint y2,
+ gint x3,
+ gint y3,
NPDMatrix *A,
- NPDImage *input_image,
- NPDImage *output_image)
+ NPDImage *input_image,
+ NPDImage *output_image,
+ NPDSettings settings)
{
gint yA, yB, yC, xA, xB, xC;
gint tmp, y;
@@ -256,57 +242,74 @@ npd_texture_fill_triangle (gint x1,
gfloat k, l;
gfloat slope1, slope2, slope3, slope4;
- if (y1 == y2 && x1 > x2) {
- tmp = y1;y1 = y2;y2 = tmp;
- tmp = x1;x1 = x2;x2 = tmp;
- }
- if (y1 == y3 && x1 > x3) {
- tmp = y1;y1 = y3;y3 = tmp;
- tmp = x1;x1 = x3;x3 = tmp;
- }
- if (y2 == y3 && x2 > x3) {
- tmp = y2;y2 = y3;y3 = tmp;
- tmp = x2;x2 = x3;x3 = tmp;
- }
-
- if (y1 <= y2) {
- if (y2 <= y3) {
- // y1 <= y2 <= y3
- yA=y1;yB=y2;yC=y3;
- xA=x1;xB=x2;xC=x3;
- } else if (y1 <= y3) {
- // y1 <= y3 < y2
- yA=y1;yB=y3;yC=y2;
- xA=x1;xB=x3;xC=x2;
- } else {
- // y3 < y1 < y2
- yA=y3;yB=y1;yC=y2;
- xA=x3;xB=x1;xC=x2;
- }
- } else {
- if (y1 <= y3) {
- // y2 < y1 <= y3
- yA=y2;yB=y1;yC=y3;
- xA=x2;xB=x1;xC=x3;
- } else if (y2 <= y3) {
- // y2 <= y3 < y1
- yA=y2;yB=y3;yC=y1;
- xA=x2;xB=x3;xC=x1;
- } else {
- // y3 < y2 < y1
- yA=y3;yB=y2;yC=y1;
- xA=x3;xB=x2;xC=x1;
- }
- }
-
- deltaXAB = xB-xA, deltaYAB = yB-yA;
- deltaXBC = xC-xB, deltaYBC = yC-yB;
- deltaXAC = xC-xA, deltaYAC = yC-yA;
-
- slopeBC = (deltaYBC == 0 ? 0 : (gfloat) deltaXBC/deltaYBC);
- slopeAC = (deltaYAC == 0 ? 0 : (gfloat) deltaXAC/deltaYAC);
-
- if (deltaYAB == 0) {
+ if (y1 == y2 && x1 > x2)
+ {
+ tmp = y1; y1 = y2; y2 = tmp;
+ tmp = x1; x1 = x2; x2 = tmp;
+ }
+ if (y1 == y3 && x1 > x3)
+ {
+ tmp = y1; y1 = y3; y3 = tmp;
+ tmp = x1; x1 = x3; x3 = tmp;
+ }
+ if (y2 == y3 && x2 > x3)
+ {
+ tmp = y2; y2 = y3; y3 = tmp;
+ tmp = x2; x2 = x3; x3 = tmp;
+ }
+
+ if (y1 <= y2)
+ {
+ if (y2 <= y3)
+ {
+ /* y1 <= y2 <= y3 */
+ yA = y1; yB = y2; yC = y3;
+ xA = x1; xB = x2; xC = x3;
+ }
+ else if (y1 <= y3)
+ {
+ /* y1 <= y3 < y2 */
+ yA = y1; yB = y3; yC = y2;
+ xA = x1; xB = x3; xC = x2;
+ }
+ else
+ {
+ /* y3 < y1 < y2 */
+ yA = y3; yB = y1; yC = y2;
+ xA = x3; xB = x1; xC = x2;
+ }
+ }
+ else
+ {
+ if (y1 <= y3)
+ {
+ /* y2 < y1 <= y3 */
+ yA = y2; yB = y1; yC = y3;
+ xA = x2; xB = x1; xC = x3;
+ }
+ else if (y2 <= y3)
+ {
+ /* y2 <= y3 < y1 */
+ yA = y2; yB = y3; yC = y1;
+ xA = x2; xB = x3; xC = x1;
+ }
+ else
+ {
+ /* y3 < y2 < y1 */
+ yA = y3; yB = y2; yC = y1;
+ xA = x3; xB = x2; xC = x1;
+ }
+ }
+
+ deltaXAB = xB - xA, deltaYAB = yB - yA;
+ deltaXBC = xC - xB, deltaYBC = yC - yB;
+ deltaXAC = xC - xA, deltaYAC = yC - yA;
+
+ slopeBC = (deltaYBC == 0 ? 0 : (gfloat) deltaXBC / deltaYBC);
+ slopeAC = (deltaYAC == 0 ? 0 : (gfloat) deltaXAC / deltaYAC);
+
+ if (deltaYAB == 0)
+ {
slopeAB = 0;
k = xA;
l = xB;
@@ -315,57 +318,81 @@ npd_texture_fill_triangle (gint x1,
slope2 = slopeAC;
slope3 = slopeAC;
slope4 = slopeBC;
- } else {
- slopeAB = (gfloat) deltaXAB/deltaYAB;
+ }
+ else
+ {
+ slopeAB = (gfloat) deltaXAB / deltaYAB;
k = xA;
l = xA;
- if (slopeAB > slopeAC) {
+ if (slopeAB > slopeAC)
+ {
slope1 = slopeAC;
slope2 = slopeAB;
slope3 = slopeAC;
slope4 = slopeBC;
- } else {
+ }
+ else
+ {
slope1 = slopeAB;
slope2 = slopeAC;
slope3 = slopeBC;
slope4 = slopeAC;
- }
- }
-
- for (y=yA; y<yB; ++y) {
- npd_draw_texture_line((gint)round(k), (gint)round(l), y, A, input_image, output_image);
- k += slope1;
- l += slope2;
- }
-
- for (y=yB; y<=yC; ++y) {
- npd_draw_texture_line((gint)round(k), (gint)round(l), y, A, input_image, output_image);
- k += slope3;
- l += slope4;
- }
+ }
+ }
+
+ for (y = yA; y < yB; y++)
+ {
+ npd_draw_texture_line ((gint) round (k), (gint) round (l),
+ y, A,
+ input_image, output_image,
+ settings);
+ k += slope1;
+ l += slope2;
+ }
+
+ for (y = yB; y <= yC; y++)
+ {
+ npd_draw_texture_line ((gint) round (k), (gint) round (l),
+ y, A,
+ input_image, output_image,
+ settings);
+ k += slope3;
+ l += slope4;
+ }
}
void
-npd_texture_quadrilateral (NPDBone *reference_bone,
- NPDBone *current_bone,
- NPDImage *input_image,
- NPDImage *output_image)
+npd_texture_quadrilateral (NPDBone *reference_bone,
+ NPDBone *current_bone,
+ NPDImage *input_image,
+ NPDImage *output_image,
+ NPDSettings settings)
{
/* p1 are points of domain, p2 are points of codomain */
NPDPoint *p1 = current_bone->points;
NPDPoint *p2 = reference_bone->points;
NPDMatrix *A = NULL;
- npd_new_matrix(&A);
-
- npd_compute_affinity(&p1[0], &p1[1], &p1[2], &p2[0], &p2[1], &p2[2], A);
- npd_texture_fill_triangle((int)p1[0].x, (int)p1[0].y, (int)p1[1].x, (int)p1[1].y, (int)p1[2].x,
(int)p1[2].y, A, input_image, output_image);
-
- npd_compute_affinity(&p1[0], &p1[2], &p1[3], &p2[0], &p2[2], &p2[3], A);
- npd_texture_fill_triangle((int)p1[0].x, (int)p1[0].y, (int)p1[2].x, (int)p1[2].y, (int)p1[3].x,
(int)p1[3].y, A, input_image, output_image);
-
- npd_destroy_matrix(&A);
+ npd_new_matrix (&A);
+
+ npd_compute_affinity (&p1[0], &p1[1], &p1[2],
+ &p2[0], &p2[1], &p2[2], A);
+ npd_texture_fill_triangle ((gint) p1[0].x, (gint) p1[0].y,
+ (gint) p1[1].x, (gint) p1[1].y,
+ (gint) p1[2].x, (gint) p1[2].y,
+ A, input_image, output_image,
+ settings);
+
+ npd_compute_affinity (&p1[0], &p1[2], &p1[3],
+ &p2[0], &p2[2], &p2[3], A);
+ npd_texture_fill_triangle ((gint) p1[0].x, (gint) p1[0].y,
+ (gint) p1[2].x, (gint) p1[2].y,
+ (gint) p1[3].x, (gint) p1[3].y,
+ A, input_image, output_image,
+ settings);
+
+ npd_destroy_matrix (&A);
}
void
@@ -374,7 +401,8 @@ npd_draw_texture_line (gint x1,
gint y,
NPDMatrix *A,
NPDImage *input_image,
- NPDImage *output_image)
+ NPDImage *output_image,
+ NPDSettings settings)
{
gint x, fx, fy;
gfloat dx, dy;
@@ -382,27 +410,65 @@ npd_draw_texture_line (gint x1,
for (x = x1; x <= x2; x++)
{
NPDPoint p, q;
- NPDColor I0, I1, I2, I3, interpolated, dest;
+ NPDColor I0, interpolated, *final;
q.x = x; q.y = y;
- npd_apply_transformation(A, &q, &p);
+ npd_apply_transformation (A, &q, &p);
- fx = (gint) floor(p.x);
- fy = (gint) floor(p.y);
- dx = p.x - floor(p.x);
- dy = p.y - floor(p.y);
+ fx = floor (p.x);
+ fy = floor (p.y);
+
+ npd_get_pixel_color (input_image, fx, fy, &I0);
+ final = &I0;
/* bilinear interpolation */
- npd_get_pixel_color(input_image, fx, fy, &I0);
- npd_get_pixel_color(input_image, fx+1, fy, &I1);
- npd_get_pixel_color(input_image, fx, fy+1, &I2);
- npd_get_pixel_color(input_image, fx+1, fy+1, &I3);
- npd_bilinear_color_interpolation(&I0, &I1, &I2, &I3, dx, dy, &interpolated);
+ if (settings & NPD_BILINEAR_INTERPOLATION)
+ {
+ NPDColor I1, I2, I3;
+
+ dx = p.x - fx;
+ dy = p.y - fy;
+
+ npd_get_pixel_color (input_image, fx + 1, fy, &I1);
+ npd_get_pixel_color (input_image, fx, fy + 1, &I2);
+ npd_get_pixel_color (input_image, fx + 1, fy + 1, &I3);
+ npd_bilinear_color_interpolation (&I0, &I1, &I2, &I3, dx, dy, &interpolated);
+ final = &interpolated;
+ }
/* alpha blending */
- npd_get_pixel_color (output_image, x, y, &dest);
- npd_blend_colors (&interpolated, &dest, &interpolated);
+ if (settings & NPD_ALPHA_BLENDING)
+ {
+ NPDColor dest;
+ npd_get_pixel_color (output_image, x, y, &dest);
+ npd_blend_colors (final, &dest, final);
+ }
- npd_set_pixel_color (output_image, x, y, &interpolated);
+ npd_set_pixel_color (output_image, x, y, final);
}
}
+
+gboolean
+npd_compare_colors (NPDColor *c1,
+ NPDColor *c2)
+{
+ if (npd_equal_floats (c1->r, c2->r) &&
+ npd_equal_floats (c1->g, c2->g) &&
+ npd_equal_floats (c1->b, c2->b) &&
+ npd_equal_floats (c1->a, c2->a))
+ return TRUE;
+
+ return FALSE;
+}
+
+gboolean
+npd_is_color_transparent (NPDColor *color)
+{
+ if (npd_equal_floats (color->r, 0.0) &&
+ npd_equal_floats (color->g, 0.0) &&
+ npd_equal_floats (color->b, 0.0) &&
+ npd_equal_floats (color->a, 0.0))
+ return TRUE;
+
+ return FALSE;
+}
diff --git a/libs/npd/graphics.h b/libs/npd/graphics.h
index 02d2745..b180e1c 100644
--- a/libs/npd/graphics.h
+++ b/libs/npd/graphics.h
@@ -22,13 +22,28 @@
#include "npd_common.h"
+//#define NPD_RGBA_FLOAT
+
struct _NPDColor {
- unsigned char r;
- unsigned char g;
- unsigned char b;
- unsigned char a;
+#ifdef NPD_RGBA_FLOAT
+ gfloat r;
+ gfloat g;
+ gfloat b;
+ gfloat a;
+#else
+ guint8 r;
+ guint8 g;
+ guint8 b;
+ guint8 a;
+#endif
};
+typedef enum
+{
+ NPD_BILINEAR_INTERPOLATION = 1,
+ NPD_ALPHA_BLENDING = 1 << 1
+} NPDSettings;
+
void npd_create_model_from_image (NPDModel *model,
NPDImage *image,
gint square_size);
@@ -54,26 +69,29 @@ void npd_texture_fill_triangle (gint x1,
gint y3,
NPDMatrix *A,
NPDImage *input_image,
- NPDImage *output_image);
+ NPDImage *output_image,
+ NPDSettings settings);
void npd_texture_quadrilateral (NPDBone *reference_bone,
NPDBone *current_bone,
NPDImage *input_image,
- NPDImage *output_image);
+ NPDImage *output_image,
+ NPDSettings settings);
void npd_draw_texture_line (gint x1,
gint x2,
gint y,
NPDMatrix *A,
NPDImage *input_image,
- NPDImage *output_image);
+ NPDImage *output_image,
+ NPDSettings settings);
void (*npd_draw_line) (NPDDisplay *display,
gfloat x0,
gfloat y0,
gfloat x1,
gfloat y1);
-gint npd_bilinear_interpolation (gint I0,
- gint I1,
- gint I2,
- gint I3,
+gfloat npd_bilinear_interpolation (gfloat I0,
+ gfloat I1,
+ gfloat I2,
+ gfloat I3,
gfloat dx,
gfloat dy);
void npd_bilinear_color_interpolation (NPDColor *I0,
@@ -83,12 +101,12 @@ void npd_bilinear_color_interpolation (NPDColor *I0,
gfloat dx,
gfloat dy,
NPDColor *out);
-gint npd_blend_band (gint src,
- gint dst,
+gfloat npd_blend_band (gfloat src,
+ gfloat dst,
gfloat src_alpha,
gfloat dest_alpha,
gfloat out_alpha);
-void npd_blend_colors (NPDColor *src,
+void npd_blend_colors (NPDColor *src,
NPDColor *dst,
NPDColor *out_color);
void (*npd_get_pixel_color) (NPDImage *image,
diff --git a/libs/npd/npd_common.h b/libs/npd/npd_common.h
index bf1b20c..f4213a0 100644
--- a/libs/npd/npd_common.h
+++ b/libs/npd/npd_common.h
@@ -92,10 +92,11 @@ typedef struct
NPDDisplay *display;
} NPDModel;
-#define npd_init(set_pixel, get_pixel, draw_line)\
-npd_set_pixel_color = set_pixel;\
-npd_get_pixel_color = get_pixel;\
-npd_draw_line = draw_line
+#define npd_init(set_pixel, get_pixel, \
+ draw_line) \
+npd_set_pixel_color = set_pixel; \
+npd_get_pixel_color = get_pixel; \
+npd_draw_line = draw_line;
void npd_init_model (NPDModel *model);
void npd_destroy_hidden_model (NPDHiddenModel *model);
diff --git a/operations/external/npd.c b/operations/external/npd.c
index 1b700a8..c4bdec2 100644
--- a/operations/external/npd.c
+++ b/operations/external/npd.c
@@ -163,7 +163,8 @@ npd_draw_model (NPDModel *model,
npd_texture_quadrilateral(&hm->reference_bones[i],
&hm->current_bones[i],
image,
- &display->image);
+ &display->image,
+ NPD_BILINEAR_INTERPOLATION | NPD_ALPHA_BLENDING);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]