From e5c5f6be80792dbfc5db2906cc1564fb08d6aa41 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 13 Oct 2002 18:46:10 +0000 Subject: - reimplemented using organic masks, rendered with gouraud shaded triangles Original commit message from CVS: - reimplemented using organic masks, rendered with gouraud shaded triangles - implemented more masks - implemented adjustable border --- gst/smpte/barboxwipes.c | 529 +++++++++++++++++++++++++++++++++++++++--------- gst/smpte/gstmask.c | 35 ++-- gst/smpte/gstmask.h | 22 +- gst/smpte/gstsmpte.c | 168 ++++++++++----- gst/smpte/gstsmpte.h | 3 + gst/smpte/paint.c | 200 ++++++++++++++++-- gst/smpte/paint.h | 18 +- 7 files changed, 763 insertions(+), 212 deletions(-) (limited to 'gst/smpte') diff --git a/gst/smpte/barboxwipes.c b/gst/smpte/barboxwipes.c index 031c282a..8c858f9d 100644 --- a/gst/smpte/barboxwipes.c +++ b/gst/smpte/barboxwipes.c @@ -20,122 +20,455 @@ #include "paint.h" #include "gstmask.h" -static void -gst_bar_wipe_lr_update (GstMask *mask, - GstClockTime position, - GstClockTime duration) +enum { - gint width = mask->width; - gint height = mask->height; - gint split = (position * width) / duration; + BOX_VERTICAL = 1, + BOX_HORIZONTAL = 2, + TRIGANLE_LINEAR = 3, +}; - gst_smpte_paint_rect (mask->data, width, split, 0, width - split, height, 0); - gst_smpte_paint_rect (mask->data, width, 0, 0, split, height, 255); -} +static gint boxes_1b[][7] = +{ +#define WIPE_B1_1 0 + { BOX_VERTICAL, 0, 0, 0, 1, 1, 1 }, +#define WIPE_B1_2 1 + { BOX_HORIZONTAL, 0, 0, 0, 1, 1, 1 } +}; -static void -gst_bar_wipe_tb_update (GstMask *mask, - GstClockTime position, - GstClockTime duration) +static gint boxes_2b[][7*2] = { - gint width = mask->width; - gint height = mask->height; - gint split = (position * height) / duration; +#define WIPE_B2_21 0 + { BOX_VERTICAL, 0, 0, 1, 1, 2, 0, + BOX_VERTICAL, 1, 0, 0, 2, 2, 1 }, +#define WIPE_B2_22 1 + { BOX_HORIZONTAL, 0, 0, 1, 2, 1, 0, + BOX_HORIZONTAL, 0, 1, 0, 2, 2, 1 }, +}; - gst_smpte_paint_rect (mask->data, width, 0, 0, width, split, 255); - gst_smpte_paint_rect (mask->data, width, 0, split, width, height - split, 0); -} +static gint triangles_2t[][2*9] = +{ + /* 3 -> 6 */ +#define WIPE_T2_3 0 + { 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 0, 0, 1, 1, 1 }, +#define WIPE_T2_4 WIPE_T2_3+1 + { 0, 0, 1, 1, 0, 0, 0, 1, 1, + 1, 0, 0, 0, 1, 1, 1, 1, 1 }, +#define WIPE_T2_5 WIPE_T2_4+1 + { 0, 0, 1, 0, 1, 1, 1, 1, 0, + 1, 0, 1, 0, 0, 1, 1, 1, 0 }, +#define WIPE_T2_6 WIPE_T2_5+1 + { 0, 0, 1, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 1, 1 }, +#define WIPE_T2_41 WIPE_T2_6+1 + { 0, 0, 0, 1, 0, 1, 0, 1, 1, + 1, 0, 1, 0, 1, 1, 1, 1, 2 }, +#define WIPE_T2_42 WIPE_T2_41+1 + { 0, 0, 1, 1, 0, 0, 1, 1, 1, + 0, 0, 1, 0, 1, 2, 1, 1, 1 }, +#define WIPE_T2_45 WIPE_T2_42+1 + { 0, 0, 1, 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 1, 1, 1 }, +#define WIPE_T2_46 WIPE_T2_45+1 + { 0, 0, 0, 1, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 0 }, +}; + +static gint triangles_3t[][3*9] = +{ + /* 23 -> 26 */ +#define WIPE_T3_23 0 + { 0, 0, 1, 1, 0, 0, 0, 2, 1, + 1, 0, 0, 0, 2, 1, 2, 2, 1, + 1, 0, 0, 2, 0, 1, 2, 2, 1 }, +#define WIPE_T3_24 1 + { 0, 0, 1, 2, 0, 1, 2, 1, 0, + 0, 0, 1, 2, 1, 0, 0, 2, 1, + 2, 1, 0, 0, 2, 1, 2, 2, 1 }, +#define WIPE_T3_25 2 + { 0, 0, 1, 0, 2, 1, 1, 2, 0, + 0, 0, 1, 2, 0, 1, 1, 2, 0, + 2, 0, 1, 1, 2, 0, 2, 2, 1 }, +#define WIPE_T3_26 3 + { 0, 0, 1, 2, 0, 1, 0, 1, 0, + 2, 0, 1, 0, 1, 0, 2, 2, 1, + 0, 1, 0, 0, 2, 1, 2, 2, 1 } +}; + +static gint triangles_4t[][4*9] = +{ +#define WIPE_T4_61 0 + { 0, 0, 1, 1, 0, 0, 1, 2, 1, + 0, 0, 1, 0, 2, 2, 1, 2, 1, + 1, 0, 0, 2, 0, 1, 1, 2, 1, + 2, 0, 1, 1, 2, 1, 2, 2, 2 }, +#define WIPE_T4_62 1 + { 0, 0, 2, 2, 0, 1, 0, 1, 1, + 2, 0, 1, 0, 1, 1, 2, 1, 0, + 0, 1, 1, 2, 1, 0, 2, 2, 1, + 0, 1, 1, 0, 2, 2, 2, 2, 1 }, +#define WIPE_T4_63 2 + { 0, 0, 2, 1, 0, 1, 0, 2, 1, + 1, 0, 1, 0, 2, 1, 1, 2, 0, + 1, 0, 1, 1, 2, 0, 2, 2, 1, + 1, 0, 1, 2, 0, 2, 2, 2, 1 }, +#define WIPE_T4_64 3 + { 0, 0, 1, 2, 0, 2, 2, 1, 1, + 0, 0, 1, 0, 1, 0, 2, 1, 1, + 0, 1, 0, 2, 1, 1, 0, 2, 1, + 2, 1, 1, 0, 2, 1, 2, 2, 2 }, +#define WIPE_T4_65 4 + { 0, 0, 0, 1, 0, 1, 1, 2, 0, + 0, 0, 0, 0, 2, 1, 1, 2, 0, + 1, 0, 1, 2, 0, 0, 1, 2, 0, + 2, 0, 0, 1, 2, 0, 2, 2, 1 }, +#define WIPE_T4_66 5 + { 0, 0, 1, 2, 0, 0, 0, 1, 0, + 2, 0, 0, 0, 1, 0, 2, 1, 1, + 0, 1, 0, 2, 1, 1, 2, 2, 0, + 0, 1, 0, 0, 2, 1, 2, 2, 0 }, +#define WIPE_T4_67 6 + { 0, 0, 1, 1, 0, 0, 0, 2, 0, + 1, 0, 0, 0, 2, 0, 1, 2, 1, + 1, 0, 0, 1, 2, 1, 2, 2, 0, + 1, 0, 0, 2, 0, 1, 2, 2, 0 }, +#define WIPE_T4_68 7 + { 0, 0, 0, 2, 0, 1, 2, 1, 0, + 0, 0, 0, 0, 1, 1, 2, 1, 0, + 0, 1, 1, 2, 1, 0, 0, 2, 0, + 2, 1, 0, 0, 2, 0, 2, 2, 1 }, +#define WIPE_T4_101 8 + { 0, 0, 1, 2, 0, 1, 1, 1, 0, + 0, 0, 1, 1, 1, 0, 0, 2, 1, + 1, 1, 0, 0, 2, 1, 2, 2, 1, + 2, 0, 1, 1, 1, 0, 2, 2, 1 } +}; + +static gint triangles_8t[][8*9] = +{ + /* 7 */ +#define WIPE_T8_7 0 + { 0, 0, 0, 1, 0, 1, 1, 1, 1, + 1, 0, 1, 2, 0, 0, 1, 1, 1, + 2, 0, 0, 1, 1, 1, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 2, 2, 0, + 1, 1, 1, 1, 2, 1, 2, 2, 0, + 1, 1, 1, 0, 2, 0, 1, 2, 1, + 0, 1, 1, 1, 1, 1, 0, 2, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1 }, +#define WIPE_T8_43 1 + { 0, 0, 1, 1, 0, 0, 1, 1, 1, + 1, 0, 0, 2, 0, 1, 1, 1, 1, + 2, 0, 1, 1, 1, 1, 2, 1, 2, + 1, 1, 1, 2, 1, 2, 2, 2, 1, + 1, 1, 1, 1, 2, 0, 2, 2, 1, + 1, 1, 1, 0, 2, 1, 1, 2, 0, + 0, 1, 2, 1, 1, 1, 0, 2, 1, + 0, 0, 1, 0, 1, 2, 1, 1, 1 }, +#define WIPE_T8_44 2 + { 0, 0, 1, 1, 0, 2, 1, 1, 1, + 1, 0, 2, 2, 0, 1, 1, 1, 1, + 2, 0, 1, 1, 1, 1, 2, 1, 0, + 1, 1, 1, 2, 1, 0, 2, 2, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 1, + 1, 1, 1, 0, 2, 1, 1, 2, 2, + 0, 1, 0, 1, 1, 1, 0, 2, 1, + 0, 0, 1, 0, 1, 0, 1, 1, 1 }, +#define WIPE_T8_47 3 + { 0, 0, 0, 1, 0, 1, 1, 1, 0, + 1, 0, 1, 2, 0, 0, 1, 1, 0, + 2, 0, 0, 1, 1, 0, 2, 1, 1, + 1, 1, 0, 2, 1, 1, 2, 2, 0, + 1, 1, 0, 1, 2, 1, 2, 2, 0, + 1, 1, 0, 0, 2, 0, 1, 2, 1, + 0, 1, 1, 1, 1, 0, 0, 2, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 0 }, +#define WIPE_T8_48 4 + { 0, 0, 1, 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, 1, 1, 1, + 1, 0, 0, 2, 0, 1, 2, 1, 0, + 1, 0, 0, 1, 1, 1, 2, 1, 0, + 0, 1, 0, 1, 1, 1, 1, 2, 0, + 0, 1, 0, 0, 2, 1, 1, 2, 0, + 1, 1, 1, 2, 1, 0, 1, 2, 0, + 2, 1, 0, 1, 2, 0, 2, 2, 1 }, +}; + +static gint triangles_16t[][16*9] = +{ + /* 8 */ +#define WIPE_T16_8 0 + { 0, 0, 1, 2, 0, 1, 1, 1, 0, + 2, 0, 1, 1, 1, 0, 2, 2, 1, + 1, 1, 0, 0, 2, 1, 2, 2, 1, + 0, 0, 1, 1, 1, 0, 0, 2, 1, + 2, 0, 1, 4, 0, 1, 3, 1, 0, + 4, 0, 1, 3, 1, 0, 4, 2, 1, + 3, 1, 0, 2, 2, 1, 4, 2, 1, + 2, 0, 1, 3, 1, 0, 2, 2, 1, + 0, 2, 1, 2, 2, 1, 1, 3, 0, + 2, 2, 1, 1, 3, 0, 2, 4, 1, + 1, 3, 0, 0, 4, 1, 2, 4, 1, + 0, 2, 1, 1, 3, 0, 0, 4, 1, + 2, 2, 1, 4, 2, 1, 3, 3, 0, + 4, 2, 1, 3, 3, 0, 4, 4, 1, + 3, 3, 0, 2, 4, 1, 4, 4, 1, + 2, 2, 1, 3, 3, 0, 2, 4, 1 } +}; + +typedef struct _GstWipeConfig GstWipeConfig; + +struct _GstWipeConfig { + gint *objects; + gint nobjects; + gint xscale; + gint yscale; + gint cscale; +}; + +static GstWipeConfig wipe_config[] = +{ +#define WIPE_CONFIG_1 0 + { boxes_1b[WIPE_B1_1], 1, 0, 0, 0 }, /* 1 */ +#define WIPE_CONFIG_2 WIPE_CONFIG_1+1 + { boxes_1b[WIPE_B1_2], 1, 0, 0, 0 }, /* 2 */ +#define WIPE_CONFIG_3 WIPE_CONFIG_2+1 + { triangles_2t[WIPE_T2_3], 2, 0, 0, 0 }, /* 3 */ +#define WIPE_CONFIG_4 WIPE_CONFIG_3+1 + { triangles_2t[WIPE_T2_4], 2, 0, 0, 0 }, /* 4 */ +#define WIPE_CONFIG_5 WIPE_CONFIG_4+1 + { triangles_2t[WIPE_T2_5], 2, 0, 0, 0 }, /* 5 */ +#define WIPE_CONFIG_6 WIPE_CONFIG_5+1 + { triangles_2t[WIPE_T2_6], 2, 0, 0, 0 }, /* 6 */ +#define WIPE_CONFIG_7 WIPE_CONFIG_6+1 + { triangles_8t[WIPE_T8_7], 8, 1, 1, 0 }, /* 7 */ +#define WIPE_CONFIG_8 WIPE_CONFIG_7+1 + { triangles_16t[WIPE_T16_8], 16, 2, 2, 0 }, /* 8 */ + +#define WIPE_CONFIG_21 WIPE_CONFIG_8+1 + { boxes_2b[WIPE_B2_21], 2, 1, 1, 0 }, /* 21 */ +#define WIPE_CONFIG_22 WIPE_CONFIG_21+1 + { boxes_2b[WIPE_B2_22], 2, 1, 1, 0 }, /* 22 */ + +#define WIPE_CONFIG_23 WIPE_CONFIG_22+1 + { triangles_3t[WIPE_T3_23], 3, 1, 1, 0 }, /* 23 */ +#define WIPE_CONFIG_24 WIPE_CONFIG_23+1 + { triangles_3t[WIPE_T3_24], 3, 1, 1, 0 }, /* 24 */ +#define WIPE_CONFIG_25 WIPE_CONFIG_24+1 + { triangles_3t[WIPE_T3_23], 3, 1, 1, 0 }, /* 25 */ +#define WIPE_CONFIG_26 WIPE_CONFIG_25+1 + { triangles_3t[WIPE_T3_26], 3, 1, 1, 0 }, /* 26 */ +#define WIPE_CONFIG_41 WIPE_CONFIG_26+1 + { triangles_2t[WIPE_T2_41], 2, 0, 0, 1 }, /* 41 */ +#define WIPE_CONFIG_42 WIPE_CONFIG_41+1 + { triangles_2t[WIPE_T2_42], 2, 0, 0, 1 }, /* 42 */ +#define WIPE_CONFIG_43 WIPE_CONFIG_42+1 + { triangles_8t[WIPE_T8_43], 8, 1, 1, 1 }, /* 43 */ +#define WIPE_CONFIG_44 WIPE_CONFIG_43+1 + { triangles_8t[WIPE_T8_44], 8, 1, 1, 1 }, /* 44 */ +#define WIPE_CONFIG_45 WIPE_CONFIG_44+1 + { triangles_2t[WIPE_T2_45], 2, 0, 0, 0 }, /* 45 */ +#define WIPE_CONFIG_46 WIPE_CONFIG_45+1 + { triangles_2t[WIPE_T2_46], 2, 0, 0, 0 }, /* 46 */ +#define WIPE_CONFIG_47 WIPE_CONFIG_46+1 + { triangles_8t[WIPE_T8_47], 8, 1, 1, 0 }, /* 47 */ +#define WIPE_CONFIG_48 WIPE_CONFIG_47+1 + { triangles_8t[WIPE_T8_48], 8, 1, 1, 0 }, /* 48 */ +#define WIPE_CONFIG_61 WIPE_CONFIG_48+1 + { triangles_4t[WIPE_T4_61], 4, 1, 1, 1 }, /* 61 */ +#define WIPE_CONFIG_62 WIPE_CONFIG_61+1 + { triangles_4t[WIPE_T4_62], 4, 1, 1, 1 }, /* 62 */ +#define WIPE_CONFIG_63 WIPE_CONFIG_62+1 + { triangles_4t[WIPE_T4_63], 4, 1, 1, 1 }, /* 63 */ +#define WIPE_CONFIG_64 WIPE_CONFIG_63+1 + { triangles_4t[WIPE_T4_64], 4, 1, 1, 1 }, /* 64 */ +#define WIPE_CONFIG_65 WIPE_CONFIG_64+1 + { triangles_4t[WIPE_T4_65], 4, 1, 1, 0 }, /* 65 */ +#define WIPE_CONFIG_66 WIPE_CONFIG_65+1 + { triangles_4t[WIPE_T4_66], 4, 1, 1, 0 }, /* 66 */ +#define WIPE_CONFIG_67 WIPE_CONFIG_66+1 + { triangles_4t[WIPE_T4_67], 4, 1, 1, 0 }, /* 67 */ +#define WIPE_CONFIG_68 WIPE_CONFIG_67+1 + { triangles_4t[WIPE_T4_68], 4, 1, 1, 0 }, /* 68 */ +#define WIPE_CONFIG_101 WIPE_CONFIG_68+1 + { triangles_4t[WIPE_T4_101], 4, 1, 1, 0 }, /* 101 */ +}; static void -gst_box_wipe_update (GstMask *mask, - GstClockTime position, - GstClockTime duration) +gst_wipe_boxes_draw (GstMask *mask) { - static gint box_wipe_impacts[8][4] = - { - /* 3 -> 6 */ - { 0, 0, 0, 0 }, - { 2, 2, 0, 0 }, - { 2, 2, 2, 2 }, - { 0, 0, 2, 2 }, - /* 23 -> 26 */ - { 1, 1, 0, 0 }, - { 2, 2, 1, 1 }, - { 1, 1, 2, 2 }, - { 0, 0, 1, 1 }, - }; - gint *impacts = box_wipe_impacts[(mask->type & 0x0F) - 3]; - gint width = mask->width; - gint height = mask->height; - gint splitx = (position * width) / duration; - gint splity = (position * height) / duration; - - gst_smpte_paint_rect (mask->data, width, 0, 0, width, height, 0); - gst_smpte_paint_rect (mask->data, width, - (impacts[0] * width)/2 - (impacts[1] * splitx)/2, - (impacts[2] * height)/2 - (impacts[3] * splity)/2, - splitx, splity, 255); + GstWipeConfig *config = mask->user_data; + gint *impacts = config->objects; + gint width = (mask->width >> config->xscale) - 1; + gint height = (mask->height >> config->yscale) - 1; + gint depth = (1 << mask->bpp) >> config->cscale; + + gint i; + + for (i = 0; i < config->nobjects; i++) { + switch (impacts[0]) { + case BOX_VERTICAL: + gst_smpte_paint_vbox (mask->data, mask->width, + impacts[1] * width, impacts[2] * height, impacts[3] * depth, + impacts[4] * width, impacts[5] * height, impacts[6] * depth); + impacts += 7; + break; + case BOX_HORIZONTAL: + gst_smpte_paint_hbox (mask->data, mask->width, + impacts[1] * width, impacts[2] * height, impacts[3] * depth, + impacts[4] * width, impacts[5] * height, impacts[6] * depth); + impacts += 7; + default: + break; + } + } } static void -gst_fourc_box_wipe_update (GstMask *mask, - GstClockTime position, - GstClockTime duration) +gst_wipe_triangles_draw (GstMask *mask) { - static gint box_wipe_impacts[8][4] = - { - { 0, 0, 0, 0 }, - { 1, 1, 1, 1 }, - { 4, 2, 0, 0 }, - { 3, 1, 1, 1 }, - { 4, 2, 4, 2 }, - { 1, 1, 3, 1 }, - { 0, 0, 4, 2 }, - { 3, 1, 3, 1 }, - }; - gint *impacts; - gint width = mask->width; - gint height = mask->height; - gint splitx = (position * width/2) / duration; - gint splity = (position * height/2) / duration; - gint i; + GstWipeConfig *config = mask->user_data; + gint *impacts = config->objects; + gint width = (mask->width >> config->xscale) - 1; + gint height = (mask->height >> config->yscale) - 1; + gint depth = (1 << mask->bpp) >> config->cscale; - gst_smpte_paint_rect (mask->data, width, 0, 0, width, height, 0); + gint i; - for (i = 7; i > 0; i -= 2) { - impacts = box_wipe_impacts[mask->type - i]; - gst_smpte_paint_rect (mask->data, width, - (impacts[0] * width)/4 - (impacts[1] * splitx)/2, - (impacts[2] * height)/4 - (impacts[3] * splity)/2, - splitx, splity, 255); + for (i = 0; i < config->nobjects; i++) { + gst_smpte_paint_triangle_linear (mask->data, mask->width, + impacts[0] * width, impacts[1] * height, impacts[2] * depth, + impacts[3] * width, impacts[4] * height, impacts[5] * depth, + impacts[6] * width, impacts[7] * height, impacts[8] * depth); + impacts += 9; } } static GstMaskDefinition definitions[] = { - { 1, "bar_wipe_lr", "A bar moves from left to right", - _gst_mask_default_new, _gst_mask_default_destroy, gst_bar_wipe_lr_update }, - { 2, "bar_wipe_tb", "A bar moves from top to bottom", - _gst_mask_default_new, _gst_mask_default_destroy, gst_bar_wipe_tb_update }, - { 3, "box_wipe_tl", "A box expands from the upper-left corner to the lower-right corner", - _gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update }, - { 4, "box_wipe_tr", "A box expands from the upper-right corner to the lower-left corner", - _gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update }, - { 5, "box_wipe_br", "A box expands from the lower-right corner to the upper-left corner", - _gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update }, - { 6, "box_wipe_bl", "A box expands from the lower-left corner to the upper-right corner", - _gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update }, - { 23, "box_wipe_tc", "A box expands from the top edge's midpoint to the bottom corners", - _gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update }, - { 24, "box_wipe_rc", "A box expands from the right edge's midpoint to the left corners", - _gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update }, - { 25, "box_wipe_bc", "A box expands from the bottom edge's midpoint to the top corners", - _gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update }, - { 26, "box_wipe_lc", "A box expands from the left edge's midpoint to the right corners", - _gst_mask_default_new, _gst_mask_default_destroy, gst_box_wipe_update }, - { 7 , "four_box_wipe_ci", "A box shape expands from each of the four corners toward the center", - _gst_mask_default_new, _gst_mask_default_destroy, gst_fourc_box_wipe_update }, - { 8 , "four_box_wipe_co", "A box shape expands from the center of each quadrant toward the corners of each quadrant", - _gst_mask_default_new, _gst_mask_default_destroy, gst_fourc_box_wipe_update }, + { 1, "bar_wipe_lr", + "A bar moves from left to right", + gst_wipe_boxes_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_1] }, + { 2, "bar_wipe_tb", + "A bar moves from top to bottom", + gst_wipe_boxes_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_2] }, + { 3, "box_wipe_tl", + "A box expands from the upper-left corner to the lower-right corner", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_3] }, + { 4, "box_wipe_tr", + "A box expands from the upper-right corner to the lower-left corner", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_4] }, + { 5, "box_wipe_br", + "A box expands from the lower-right corner to the upper-left corner", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_5] }, + { 6, "box_wipe_bl", + "A box expands from the lower-left corner to the upper-right corner", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_6] }, + { 7 , "four_box_wipe_ci", + "A box shape expands from each of the four corners toward the center", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_7] }, + { 8 , "four_box_wipe_co", + "A box shape expands from the center of each quadrant toward the corners of each quadrant", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_8] }, + { 21, "barndoor_v", + "A central, vertical line splits and expands toward the left and right edges", + gst_wipe_boxes_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_21] }, + { 22, "barndoor_h", + "A central, horizontal line splits and expands toward the top and bottom edges", + gst_wipe_boxes_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_22] }, + { 23, "box_wipe_tc", + "A box expands from the top edge's midpoint to the bottom corners", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_23] }, + { 24, "box_wipe_rc", + "A box expands from the right edge's midpoint to the left corners", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_24] }, + { 25, "box_wipe_bc", + "A box expands from the bottom edge's midpoint to the top corners", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_25] }, + { 26, "box_wipe_lc", + "A box expands from the left edge's midpoint to the right corners", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_26] }, + { 41, "diagonal_tl", + "A diagonal line moves from the upper-left corner to the lower-right corner", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_41] }, + { 42, "diagonal_tr", + "A diagonal line moves from the upper right corner to the lower-left corner", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_42] }, + { 43, "bowtie_v", + "Two wedge shapes slide in from the top and bottom edges toward the center", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_43] }, + { 44, "bowtie_h", + "Two wedge shapes slide in from the left and right edges toward the center", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_44] }, + { 45, "barndoor_dbl", + "A diagonal line from the lower-left to upper-right corners splits and expands toward the opposite corners", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_45] }, + { 46, "barndoor_dtl", + "A diagonal line from upper-left to lower-right corners splits and expands toward the opposite corners", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_46] }, + { 47, "misc_diagonal_dbd", + "Four wedge shapes split from the center and retract toward the four edges", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_47] }, + { 48, "misc_diagonal_dd", + "A diamond connecting the four edge midpoints simultaneously contracts toward the center and expands toward the edges", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_48] }, + { 61, "vee_d", + "A wedge shape moves from top to bottom", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_61] }, + { 62, "vee_l", + "A wedge shape moves from right to left", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_62] }, + { 63, "vee_u", + "A wedge shape moves from bottom to top", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_63] }, + { 64, "vee_r", + "A wedge shape moves from left to right", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_64] }, + { 65, "barnvee_d", + "A 'V' shape extending from the bottom edge's midpoint to the opposite corners contracts toward the center and expands toward the edges", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_65] }, + { 66, "barnvee_l", + "A 'V' shape extending from the left edge's midpoint to the opposite corners contracts toward the center and expands toward the edges", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_66] }, + { 67, "barnvee_u", + "A 'V' shape extending from the top edge's midpoint to the opposite corners contracts toward the center and expands toward the edges", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_67] }, + { 68, "barnvee_r", + "A 'V' shape extending from the right edge's midpoint to the opposite corners contracts toward the center and expands toward the edges", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_68] }, + { 101, "iris_rect", + "A rectangle expands from the center.", + gst_wipe_triangles_draw, _gst_mask_default_destroy, + &wipe_config[WIPE_CONFIG_101] }, { 0, NULL, NULL, NULL } }; diff --git a/gst/smpte/gstmask.c b/gst/smpte/gstmask.c index a26d7190..14804524 100644 --- a/gst/smpte/gstmask.c +++ b/gst/smpte/gstmask.c @@ -19,6 +19,7 @@ #include "gstmask.h" +#include "paint.h" extern void _gst_barboxwipes_register (void); @@ -73,31 +74,23 @@ gst_mask_factory_new (gint type, gint bpp, gint width, gint height) definition = gst_mask_find_definition (type); if (definition) { - mask = definition->new_func (definition, bpp, width, height); + mask = g_new0 (GstMask, 1); + + mask->type = definition->type; + mask->bpp = bpp; + mask->width = width; + mask->height = height; + mask->destroy_func = definition->destroy_func; + mask->user_data = definition->user_data; + mask->data = g_malloc (width * height * sizeof (guint32)); + + if (definition->draw_func) + definition->draw_func (mask); } return mask; } -GstMask* -_gst_mask_default_new (GstMaskDefinition *definition, - gint bpp, gint width, gint height) -{ - GstMask *mask; - - mask = g_new0 (GstMask, 1); - - mask->type = definition->type; - mask->bpp = bpp; - mask->width = width; - mask->height = height; - mask->update_func = definition->update_func; - mask->destroy_func = definition->destroy_func; - mask->data = g_malloc (width * height * (bpp+7)>>3); - - return mask; -} - void _gst_mask_default_destroy (GstMask *mask) { @@ -119,6 +112,4 @@ gst_mask_update (GstMask *mask, { g_return_if_fail (mask != NULL); - if (mask->update_func) - mask->update_func (mask, position, duration); } diff --git a/gst/smpte/gstmask.h b/gst/smpte/gstmask.h index f53fb99f..6131c624 100644 --- a/gst/smpte/gstmask.h +++ b/gst/smpte/gstmask.h @@ -27,47 +27,37 @@ typedef struct _GstMask GstMask; typedef struct _GstMaskDefinition GstMaskDefinition; -typedef GstMask* (*GstMaskNewFunc) (GstMaskDefinition *definition, - gint bpp, gint width, gint height); +typedef void (*GstMaskDrawFunc) (GstMask *mask); typedef void (*GstMaskDestroyFunc) (GstMask *mask); -typedef void (*GstMaskUpdateFunc) (GstMask *mask, - GstClockTime position, - GstClockTime duration); + struct _GstMaskDefinition { gint type; gchar *short_name; gchar *long_name; - GstMaskNewFunc new_func; + GstMaskDrawFunc draw_func; GstMaskDestroyFunc destroy_func; - GstMaskUpdateFunc update_func; + gpointer user_data; }; struct _GstMask { gint type; - guint8 *data; + guint32 *data; + gpointer user_data; gint width; gint height; gint bpp; - GstMaskUpdateFunc update_func; GstMaskDestroyFunc destroy_func; }; void _gst_mask_init (void); void _gst_mask_register (GstMaskDefinition *definition); -GstMask* _gst_mask_default_new (GstMaskDefinition *definition, - gint bpp, gint width, gint height); void _gst_mask_default_destroy (GstMask *mask); const GList* gst_mask_get_definitions (void); GstMask* gst_mask_factory_new (gint type, gint bpp, gint width, gint height); void gst_mask_destroy (GstMask *mask); -void gst_mask_update (GstMask *mask, - GstClockTime position, - GstClockTime duration); - - #endif /* __GST_MASK_H__ */ diff --git a/gst/smpte/gstsmpte.c b/gst/smpte/gstsmpte.c index 536be8d4..47de304f 100644 --- a/gst/smpte/gstsmpte.c +++ b/gst/smpte/gstsmpte.c @@ -79,6 +79,9 @@ enum { enum { ARG_0, ARG_TYPE, + ARG_BORDER, + ARG_DEPTH, + ARG_FPS, }; #define GST_TYPE_SMPTE_TRANSITION_TYPE (gst_smpte_transition_type_get_type()) @@ -106,7 +109,8 @@ gst_smpte_transition_type_get_type (void) i++; } - smpte_transition_type = g_enum_register_static ("GstSMPTETransitionType", smpte_transitions); + smpte_transition_type = + g_enum_register_static ("GstSMPTETransitionType", smpte_transitions); } return smpte_transition_type; } @@ -166,7 +170,15 @@ gst_smpte_class_init (GstSMPTEClass *klass) g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TYPE, g_param_spec_enum ("type", "Type", "The type of transition to use", GST_TYPE_SMPTE_TRANSITION_TYPE, 1, G_PARAM_READWRITE)); - + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FPS, + g_param_spec_int ("fps", "FPS", "Frames per second if no input files are given", + 1, 255, 1, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BORDER, + g_param_spec_int ("border", "Border", "The border width of the transition", + 0, G_MAXINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DEPTH, + g_param_spec_int ("depth", "Depth", "Depth of the mask in bits", + 1, 24, 16, G_PARAM_READWRITE)); } /* wht yel cya grn mag red blu blk -I Q */ @@ -177,13 +189,35 @@ static int v_colors[] = { 128, 155, 0, 21, 235, 255, 107, 128, 128, 255 }; static void fill_i420 (guint8 *data, gint width, gint height, gint color) { + gint size = width * height, size4 = size >> 2; guint8 *yp = data; - guint8 *up = data + width * height; - guint8 *vp = data + width * height + (width * height) / 4; + guint8 *up = data + size; + guint8 *vp = data + size + size4; - gst_smpte_paint_rect (yp, width, 0, 0, width, height, y_colors[color]); - gst_smpte_paint_rect (up, width/2, 0, 0, width/2, height/2, u_colors[color]); - gst_smpte_paint_rect (vp, width/2, 0, 0, width/2, height/2, v_colors[color]); + memset (yp, y_colors[color], size); + memset (up, u_colors[color], size4); + memset (vp, v_colors[color], size4); +} + +static gboolean +gst_smpte_update_mask (GstSMPTE *smpte, gint type, gint depth, gint width, gint height) +{ + GstMask *newmask; + + newmask = gst_mask_factory_new (type, depth, width, height); + if (newmask) { + if (smpte->mask) { + gst_mask_destroy (smpte->mask); + } + smpte->mask = newmask; + smpte->type = type; + smpte->depth = depth; + smpte->width = width; + smpte->height = height; + + return TRUE; + } + return FALSE; } static gboolean @@ -199,7 +233,7 @@ gst_smpte_sinkconnect (GstPad *pad, GstCaps *caps) gst_caps_get_int (caps, "width", &smpte->width); gst_caps_get_int (caps, "height", &smpte->height); - smpte->mask = gst_mask_factory_new (smpte->type, 8, smpte->width, smpte->height); + gst_smpte_update_mask (smpte, smpte->type, smpte->depth, smpte->width, smpte->height); /* forward to the next plugin */ return gst_pad_try_set_caps(smpte->srcpad, gst_caps_copy_1(caps)); @@ -229,35 +263,43 @@ gst_smpte_init (GstSMPTE *smpte) smpte->duration = 64; smpte->position = 0; smpte->type = 1; - smpte->mask = gst_mask_factory_new (smpte->type, 8, smpte->width, smpte->height); + smpte->fps = 1; + smpte->border = 0; + smpte->depth = 16; + gst_smpte_update_mask (smpte, smpte->type, smpte->depth, smpte->width, smpte->height); } static void gst_smpte_blend_i420 (guint8 *in1, guint8 *in2, guint8 *out, GstMask *mask, - gint width, gint height) + gint width, gint height, gint border, gint pos) { - gint i, j; - guint8 *maskporig, *maskp; + guint32 *maskp; + gint value; + gint i; + gint min, max; guint8 *in1u, *in1v, *in2u, *in2v, *outu, *outv; - guint8 value; - gint chromsize = (width * height) >> 2; + gint lumsize = width * height; + gint chromsize = lumsize >> 2; + + if (border == 0) border++; - maskp = maskporig = mask->data; + min = pos - border; + max = pos; + + in1u = in1 + lumsize; in1v = in1 + chromsize; + in2u = in2 + lumsize; in2v = in2 + chromsize; + outu = out + lumsize; outv = out + chromsize; - for (i = width * height; i; i--) { + maskp = mask->data; + + for (i = lumsize; i; i--) { value = *maskp++; - *out++ = ((*in2++ * value) + (*in1++ * (255 - value))) >> 8; - } - in1u = in1; in1v = in1 + chromsize; - in2u = in2; in2v = in2 + chromsize; - outu = out; outv = out + chromsize; - - maskp = maskporig; - for (i = height/2; i; i--, maskp += width) { - for (j = width/2; j; j--, maskp += 2) { - value = *maskp; - *outu++ = ((*in2u++ * value) + (*in1u++ * (255 - value))) >> 8; - *outv++ = ((*in2v++ * value) + (*in1v++ * (255 - value))) >> 8; + value = ((CLAMP (value, min, max) - min) << 8) / border; + + *out++ = ((*in1++ * value) + (*in2++ * (255 - value))) >> 8; + if (i % 4) { + *outu++ = ((*in1u++ * value) + (*in2u++ * (255 - value))) >> 8; + *outv++ = ((*in1v++ * value) + (*in2v++ * (255 - value))) >> 8; } } } @@ -272,7 +314,7 @@ gst_smpte_loop (GstElement *element) smpte = GST_SMPTE (element); - ts = smpte->position * GST_SECOND; + ts = smpte->position * GST_SECOND / smpte->fps; if (GST_PAD_IS_USABLE (smpte->sinkpad1)) { in1 = gst_pad_pull (smpte->sinkpad1); @@ -297,23 +339,26 @@ gst_smpte_loop (GstElement *element) if (!GST_PAD_CAPS (smpte->srcpad)) { if (!gst_pad_try_set_caps (smpte->srcpad, - GST_CAPS_NEW ( - "smpte_srccaps", - "video/raw", - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')), - "width", GST_PROPS_INT (smpte->width), - "height", GST_PROPS_INT (smpte->height) - ))) + GST_CAPS_NEW ( + "smpte_srccaps", + "video/raw", + "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')), + "width", GST_PROPS_INT (smpte->width), + "height", GST_PROPS_INT (smpte->height) + ))) { gst_element_error (element, "cannot set caps"); return; } } - gst_mask_update (smpte->mask, smpte->position, smpte->duration); - - gst_smpte_blend_i420 (GST_BUFFER_DATA (in1), GST_BUFFER_DATA (in2), GST_BUFFER_DATA (outbuf), - smpte->mask, smpte->width, smpte->height); + gst_smpte_blend_i420 (GST_BUFFER_DATA (in1), + GST_BUFFER_DATA (in2), + GST_BUFFER_DATA (outbuf), + smpte->mask, smpte->width, smpte->height, + smpte->border, + ((1 << smpte->depth) + smpte->border) * + smpte->position / smpte->duration); } else { outbuf = in2; @@ -342,17 +387,24 @@ gst_smpte_set_property (GObject *object, guint prop_id, switch (prop_id) { case ARG_TYPE: { - GstMask *newmask; gint type = g_value_get_enum (value); - newmask = gst_mask_factory_new (type, 8, smpte->width, smpte->height); - if (newmask) { - if (smpte->mask) { - gst_mask_destroy (smpte->mask); - } - smpte->mask = newmask; - smpte->type = type; - } + gst_smpte_update_mask (smpte, type, smpte->depth, + smpte->width, smpte->height); + break; + } + case ARG_FPS: + smpte->fps = g_value_get_int (value); + break; + case ARG_BORDER: + smpte->border = g_value_get_int (value); + break; + case ARG_DEPTH: + { + gint depth = g_value_get_int (value); + + gst_smpte_update_mask (smpte, smpte->type, depth, + smpte->width, smpte->height); break; } default: @@ -375,6 +427,15 @@ gst_smpte_get_property (GObject *object, guint prop_id, g_value_set_enum (value, smpte->mask->type); } break; + case ARG_FPS: + g_value_set_int (value, smpte->fps); + break; + case ARG_BORDER: + g_value_set_int (value, smpte->border); + break; + case ARG_DEPTH: + g_value_set_int (value, smpte->depth); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -391,9 +452,12 @@ plugin_init (GModule *module, GstPlugin *plugin) &smpte_details); g_return_val_if_fail(factory != NULL, FALSE); - gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (smpte_sink1_factory)); - gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (smpte_sink2_factory)); - gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (smpte_src_factory)); + gst_element_factory_add_pad_template (factory, + GST_PAD_TEMPLATE_GET (smpte_sink1_factory)); + gst_element_factory_add_pad_template (factory, + GST_PAD_TEMPLATE_GET (smpte_sink2_factory)); + gst_element_factory_add_pad_template (factory, + GST_PAD_TEMPLATE_GET (smpte_src_factory)); gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); diff --git a/gst/smpte/gstsmpte.h b/gst/smpte/gstsmpte.h index 5ba6278a..5c863890 100644 --- a/gst/smpte/gstsmpte.h +++ b/gst/smpte/gstsmpte.h @@ -53,6 +53,9 @@ struct _GstSMPTE { *sinkpad2; gint type; + gint fps; + gint border; + gint depth; GstMask *mask; }; diff --git a/gst/smpte/paint.c b/gst/smpte/paint.c index 0fb96d77..3ccfc23f 100644 --- a/gst/smpte/paint.c +++ b/gst/smpte/paint.c @@ -20,32 +20,196 @@ #include "paint.h" void -gst_smpte_paint_rect (guint8 *dest, gint stride, gint x, gint y, gint w, gint h, guint8 color) -{ - guint8 *d = dest + stride * y + x; - gint i; - - for (i = 0; i < h; i++) { - memset (d, color, w); - d += stride; +gst_smpte_paint_vbox (guint32 *dest, gint stride, + gint x0, gint y0, gint c0, + gint x1, gint y1, gint c1) +{ + gint i, j; + gint width, height; + + width = x1 - x0; + height = y1 - y0; + + g_assert (width > 0); + g_assert (height > 0); + + dest = dest + y0 * stride + x0; + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + dest[j] = (c1 * j + c0 * (width - j)) / width; + } + dest += stride; + } +} + +void +gst_smpte_paint_hbox (guint32 *dest, gint stride, + gint x0, gint y0, gint c0, + gint x1, gint y1, gint c1) +{ + gint i, j; + gint width, height; + + width = x1 - x0; + height = y1 - y0; + + g_assert (width > 0); + g_assert (height > 0); + + g_print ("vbox: %d %d %d %d %d %d\n", x0, y0, c0, x1, y1, c1); + + dest = dest + y0 * stride + x0; + + for (i = 0; i < height; i++) { + guint32 value = (c1 * i + c0 * (height - i)) / height; + for (j = 0; j < width; j++) { + *dest++ = value; + } } } void -gst_smpte_paint_rect_s (guint8 *dest, gint stride, gint x, gint y, gint w, gint h, guint8 color) -{ - guint8 *d = dest + stride * y + x; +gst_smpte_paint_rect16 (guint16 * dest, gint depth, gint w, gint h) +{ gint i, j; - gint border = 100; for (i = 0; i < h; i++) { - if (w - border > 0) { - memset (d, color, w - border); + for (j = 0; j < w; j++) { + *dest++ = (guint16) ((double) (1 << depth) * j / w); } + } +} + +#define STEP_3D_LINE(dxabs,dyabs,dzabs,sdx,sdy,sdz,xr,yr,zr,px,py,pz) \ +G_STMT_START { \ + if (dxabs >= dyabs && dxabs >= dzabs) { \ + yr += dyabs; \ + zr += dzabs; \ + if (yr >= dxabs) { \ + py += sdy; \ + yr -= dxabs; \ + } \ + if (zr >= dzabs) { \ + pz += sdz; \ + zr -= dxabs; \ + } \ + px += sdx; \ + } else if (dyabs >= dxabs && dyabs >= dzabs) { \ + xr += dxabs; \ + zr += dzabs; \ + if (xr >= dyabs) { \ + px += sdx; \ + xr -= dyabs; \ + } \ + if (zr >= dzabs) { \ + pz += sdz; \ + zr -= dyabs; \ + } \ + py += sdy; \ + } else { \ + yr += dyabs; \ + xr += dxabs; \ + if (yr >= dyabs) { \ + py += sdy; \ + yr -= dzabs; \ + } \ + if (xr >= dyabs) { \ + px += sdx; \ + xr -= dzabs; \ + } \ + pz += sdz; \ + } \ +} G_STMT_END + +#define SWAP(a,b) \ +G_STMT_START { \ + typeof (a) tmp; \ + tmp = (a); \ + (a) = (b); \ + (b) = (tmp); \ +} G_STMT_END + +#define SIGN(a) ((a) < 0 ? -1 : 1) + +#define PREPARE_3D_LINE(x0,y0,z0,x1,y1,z1,dxabs,dyabs,dzabs,sdx,sdy,sdz,xr,yr,zr,px,py,pz)\ +G_STMT_START { \ + typeof (x0) dx, dy, dz; \ + dx = x1 - x0; \ + dy = y1 - y0; \ + dz = z1 - z0; \ + dxabs = abs (dx); \ + dyabs = abs (dy); \ + dzabs = abs (dz); \ + sdx = SIGN (dx); \ + sdy = SIGN (dy); \ + sdz = SIGN (dz); \ + xr = dxabs >> 1; \ + yr = dyabs >> 1; \ + zr = dzabs >> 1; \ + px = x0; \ + py = y0; \ + pz = z0; \ +} G_STMT_END + +void +gst_smpte_paint_triangle_linear (guint32 *dest, gint stride, + gint x0, gint y0, gint c0, + gint x1, gint y1, gint c1, gint x2, gint y2, gint c2) +{ + gint sdxl, sdyl, sdcl, dxlabs, dylabs, dclabs, xrl, yrl, crl, pxl, pyl, pcl; + gint sdxr, sdyr, sdcr, dxrabs, dyrabs, dcrabs, xrr, yrr, crr, pxr, pyr, pcr; + gint i, j, k, seg_start, seg_end; + + if (y0 > y1) { SWAP (x0, x1); SWAP (y0, y1); SWAP (c0, c1); } + if (y0 > y2) { SWAP (x0, x2); SWAP (y0, y2); SWAP (c0, c2); } + if (y1 > y2) { SWAP (x1, x2); SWAP (y1, y2); SWAP (c1, c2); } + + PREPARE_3D_LINE (x0,y0,c0,x2,y2,c2, + dxlabs,dylabs,dclabs, + sdxl, sdyl,sdcl, + xrl,yrl,crl, + pxl,pyl,pcl); + + PREPARE_3D_LINE (x0,y0,c0,x1,y1,c1, + dxrabs,dyrabs,dcrabs, + sdxr, sdyr,sdcr, + xrr,yrr,crr, + pxr,pyr,pcr); + + dest = dest + stride * y0; + seg_start = y0; + seg_end = y1; + + /* do two passes */ + for (k = 0; k < 2; k++) { + for (i = seg_start; i < seg_end; i++) { + gint s = pxl, e = pxr, sc = pcl, ec = pcr; + gint sign = SIGN (e - s); + + e += sign; + + for (j = s; j != e; j+=sign) { + dest[j] = (ec * (j - s) + sc * (e - j)) / (e - s); + } + while (pyr == i) { + STEP_3D_LINE (dxrabs, dyrabs, dcrabs, sdxr, sdyr, sdcr, + xrr, yrr, crr, pxr, pyr, pcr); + } + while (pyl == i) { + STEP_3D_LINE (dxlabs, dylabs, dclabs, sdxl, sdyl, sdcl, + xrl, yrl, crl, pxl, pyl, pcl); + } + dest += stride; + } + + PREPARE_3D_LINE (x1,y1,c1,x2,y2,c2, + dxrabs,dyrabs,dcrabs, + sdxr, sdyr,sdcr, + xrr,yrr,crr, + pxr,pyr,pcr); - for (j = 0; j < border - w; j++) { - *(d+w+j) = (color*(border-j)/border); - } - d += stride; + seg_start = y1; + seg_end = y2; } } diff --git a/gst/smpte/paint.h b/gst/smpte/paint.h index fc51a638..224ded7d 100644 --- a/gst/smpte/paint.h +++ b/gst/smpte/paint.h @@ -22,14 +22,20 @@ #include -void gst_smpte_paint_rect (guint8 *dest, gint stride, - gint x, gint y, gint w, gint h, - guint8 color); +void gst_smpte_paint_vbox (guint32 *dest, gint stride, + gint x0, gint y0, gint c0, + gint x1, gint y1, gint c1); +void gst_smpte_paint_hbox (guint32 *dest, gint stride, + gint x0, gint y0, gint c0, + gint x1, gint y1, gint c1); -void gst_smpte_paint_rect_s (guint8 *dest, gint stride, - gint x, gint y, gint w, gint h, - guint8 color); +void gst_smpte_paint_rect16 (guint16 *dest, gint depth, gint width, gint height); +void gst_smpte_paint_triangle_linear (guint32 *dest, gint stride, + gint x0, gint y0, gint c0, + gint x1, gint y1, gint c1, + gint x2, gint y2, gint c2); + #endif /* __GST_SMPTE_PAINT_H__ */ -- cgit v1.2.1