Fix illegal identifiers, names starting with _ and uppercase are reserved.
[libav.git] / vhook / imlib2.c
index 411d0c4..1626f58 100644 (file)
@@ -2,59 +2,6 @@
  * imlib2 based hook
  * Copyright (c) 2002 Philip Gladstone
  *
- * This module implements a text overlay for a video image. Currently it
- * supports a fixed overlay or reading the text from a file. The string
- * is passed through strftime so that it is easy to imprint the date and
- * time onto the image.
- *
- * You may also overlay an image (even semi-transparent) like TV stations do.
- * You may move either the text or the image around your video to create
- * scrolling credits, for example.
- *
- * Text fonts are being looked for in FONTPATH
- *
- * Options:
- *
- * -C <rgb.txt>         The filename to read RGB color names from
- *                      Defaults if none specified:
- *                      /usr/share/X11/rgb.txt
- *                      /usr/lib/X11/rgb.txt
- * -c <color>           The color of the text
- * -F <fontname>        The font face and size
- * -t <text>            The text
- * -f <filename>        The filename to read text from
- * -x <expression>      X coordinate of text or image
- * -y <expression>      Y coordinate of text or image
- * -i <filename>        The filename to read a image from
- * -R <expression>      Value for R color
- * -G <expression>      Value for G color
- * -B <expression>      Value for B color
- *
- * Expressions are functions of:
- *      N  // frame number (starting at zero)
- *      H  // frame height
- *      W  // frame width
- *      h  // image height
- *      w  // image width
- *      X  // previous x
- *      Y  // previous y
- *
-
-   Examples:
-
-   FONTPATH="/cygdrive/c/WINDOWS/Fonts/"
-   FONTPATH="$FONTPATH:/usr/share/imlib2/data/fonts/"
-   FONTPATH="$FONTPATH:/usr/X11R6/lib/X11/fonts/TTF/"
-   export FONTPATH
-
-   ffmpeg -i input.avi -vhook \
-     'vhook/imlib2.dll -x W*(0.5+0.25*sin(N/47*PI))-w/2 -y H*(0.5+0.50*cos(N/97*PI))-h/2 -i /usr/share/imlib2/data/images/bulb.png'
-      -acodec copy -sameq output.avi
-
-   ffmpeg -i input.avi -vhook \
-     'vhook/imlib2.dll -c red -F Vera.ttf/20 -x 150+0.5*N -y 70+0.25*N -t Hello'
-      -acodec copy -sameq output.avi
-
  * This module is very much intended as an example of what could be done.
  *
  * One caution is that this is an expensive process -- in particular the
@@ -133,13 +80,13 @@ typedef struct {
     Imlib_Font fn;
     char *text;
     char *file;
-    int r, g, b;
-    AVEvalExpr *eval_r, *eval_g, *eval_b;
-    char *expr_R, *expr_G, *expr_B;
+    int r, g, b, a;
+    AVEvalExpr *eval_r, *eval_g, *eval_b, *eval_a;
+    char *expr_R, *expr_G, *expr_B, *expr_A;
     int eval_colors;
     double x, y;
     char *fileImage;
-    struct _CachedImage *cache;
+    struct CachedImage *cache;
     Imlib_Image imageOverlaid;
     AVEvalExpr *eval_x, *eval_y;
     char *expr_x, *expr_y;
@@ -152,8 +99,8 @@ typedef struct {
     struct SwsContext *fromRGB_convert_ctx;
 } ContextInfo;
 
-typedef struct _CachedImage {
-    struct _CachedImage *next;
+typedef struct CachedImage {
+    struct CachedImage *next;
     Imlib_Image image;
     int width;
     int height;
@@ -174,11 +121,19 @@ void Release(void *ctx)
             imlib_context_set_image(ci->imageOverlaid);
             imlib_free_image();
         }
-        ff_eval_free(ci->expr_x);
-        ff_eval_free(ci->expr_y);
-        ff_eval_free(ci->expr_R);
-        ff_eval_free(ci->expr_G);
-        ff_eval_free(ci->expr_B);
+        ff_eval_free(ci->eval_x);
+        ff_eval_free(ci->eval_y);
+        ff_eval_free(ci->eval_r);
+        ff_eval_free(ci->eval_g);
+        ff_eval_free(ci->eval_b);
+        ff_eval_free(ci->eval_a);
+
+        av_free(ci->expr_x);
+        av_free(ci->expr_y);
+        av_free(ci->expr_R);
+        av_free(ci->expr_G);
+        av_free(ci->expr_B);
+        av_free(ci->expr_A);
         sws_freeContext(ci->toRGB_convert_ctx);
         sws_freeContext(ci->fromRGB_convert_ctx);
         av_free(ctx);
@@ -195,6 +150,7 @@ int Configure(void **ctxp, int argc, char *argv[])
     char *color = 0;
     FILE *f;
     char *p;
+    char *error;
 
     *ctxp = av_mallocz(sizeof(ContextInfo));
     ci = (ContextInfo *) *ctxp;
@@ -217,7 +173,7 @@ int Configure(void **ctxp, int argc, char *argv[])
         imlib_add_path_to_font_path(fp);
 
 
-    while ((c = getopt(argc, argv, "R:G:B:C:c:f:F:t:x:y:i:")) > 0) {
+    while ((c = getopt(argc, argv, "R:G:B:A:C:c:f:F:t:x:y:i:")) > 0) {
         switch (c) {
             case 'R':
                 ci->expr_R = av_strdup(optarg);
@@ -231,6 +187,9 @@ int Configure(void **ctxp, int argc, char *argv[])
                 ci->expr_B = av_strdup(optarg);
                 ci->eval_colors = 1;
                 break;
+            case 'A':
+                ci->expr_A = av_strdup(optarg);
+                break;
             case 'C':
                 rgbtxt = optarg;
                 break;
@@ -268,13 +227,13 @@ int Configure(void **ctxp, int argc, char *argv[])
     }
 
     if (ci->text || ci->file) {
-    ci->fn = imlib_load_font(font);
-    if (!ci->fn) {
-        fprintf(stderr, "Failed to load font '%s'\n", font);
-        return -1;
-    }
-    imlib_context_set_font(ci->fn);
-    imlib_context_set_direction(IMLIB_TEXT_TO_RIGHT);
+        ci->fn = imlib_load_font(font);
+        if (!ci->fn) {
+            fprintf(stderr, "Failed to load font '%s'\n", font);
+            return -1;
+        }
+        imlib_context_set_font(ci->fn);
+        imlib_context_set_direction(IMLIB_TEXT_TO_RIGHT);
     }
 
     if (color) {
@@ -319,22 +278,31 @@ int Configure(void **ctxp, int argc, char *argv[])
             return -1;
         }
     } else if (ci->eval_colors) {
-        if (!(ci->eval_r = ff_parse(ci->expr_R, const_names, NULL, NULL, NULL, NULL, NULL))){
-            av_log(NULL, AV_LOG_ERROR, "Couldn't parse R expression '%s'\n", ci->expr_R);
+        if (!(ci->eval_r = ff_parse(ci->expr_R, const_names, NULL, NULL, NULL, NULL, &error))){
+            av_log(NULL, AV_LOG_ERROR, "Couldn't parse R expression '%s': %s\n", ci->expr_R, error);
             return -1;
         }
-        if (!(ci->eval_g = ff_parse(ci->expr_G, const_names, NULL, NULL, NULL, NULL, NULL))){
-            av_log(NULL, AV_LOG_ERROR, "Couldn't parse G expression '%s'\n", ci->expr_G);
+        if (!(ci->eval_g = ff_parse(ci->expr_G, const_names, NULL, NULL, NULL, NULL, &error))){
+            av_log(NULL, AV_LOG_ERROR, "Couldn't parse G expression '%s': %s\n", ci->expr_G, error);
             return -1;
         }
-        if (!(ci->eval_b = ff_parse(ci->expr_B, const_names, NULL, NULL, NULL, NULL, NULL))){
-            av_log(NULL, AV_LOG_ERROR, "Couldn't parse B expression '%s'\n", ci->expr_B);
+        if (!(ci->eval_b = ff_parse(ci->expr_B, const_names, NULL, NULL, NULL, NULL, &error))){
+            av_log(NULL, AV_LOG_ERROR, "Couldn't parse B expression '%s': %s\n", ci->expr_B, error);
             return -1;
         }
     }
 
-    if (!ci->eval_colors)
-    imlib_context_set_color(ci->r, ci->g, ci->b, 255);
+    if (ci->expr_A) {
+        if (!(ci->eval_a = ff_parse(ci->expr_A, const_names, NULL, NULL, NULL, NULL, &error))){
+            av_log(NULL, AV_LOG_ERROR, "Couldn't parse A expression '%s': %s\n", ci->expr_A, error);
+            return -1;
+        }
+    } else {
+        ci->a = 255;
+    }
+
+    if (!(ci->eval_colors || ci->eval_a))
+        imlib_context_set_color(ci->r, ci->g, ci->b, ci->a);
 
     /* load the image (for example, credits for a movie) */
     if (ci->fileImage) {
@@ -348,13 +316,13 @@ int Configure(void **ctxp, int argc, char *argv[])
         ci->imageOverlaid_height = imlib_image_get_height();
     }
 
-    if (!(ci->eval_x = ff_parse(ci->expr_x, const_names, NULL, NULL, NULL, NULL, NULL))){
-        av_log(NULL, AV_LOG_ERROR, "Couldn't parse x expression '%s'\n", ci->expr_x);
+    if (!(ci->eval_x = ff_parse(ci->expr_x, const_names, NULL, NULL, NULL, NULL, &error))){
+        av_log(NULL, AV_LOG_ERROR, "Couldn't parse x expression '%s': %s\n", ci->expr_x, error);
         return -1;
     }
 
-    if (!(ci->eval_y = ff_parse(ci->expr_y, const_names, NULL, NULL, NULL, NULL, NULL))){
-        av_log(NULL, AV_LOG_ERROR, "Couldn't parse y expression '%s'\n", ci->expr_y);
+    if (!(ci->eval_y = ff_parse(ci->expr_y, const_names, NULL, NULL, NULL, NULL, &error))){
+        av_log(NULL, AV_LOG_ERROR, "Couldn't parse y expression '%s': %s\n", ci->expr_y, error);
         return -1;
     }
 
@@ -401,7 +369,7 @@ void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width,
     imlib_context_set_image(image);
     data = imlib_image_get_data();
 
-        avpicture_fill(&picture1, (uint8_t *) data, PIX_FMT_RGB32, width, height);
+    avpicture_fill(&picture1, (uint8_t *) data, PIX_FMT_RGB32, width, height);
 
     // if we already got a SWS context, let's realloc if is not re-useable
     ci->toRGB_convert_ctx = sws_getCachedContext(ci->toRGB_convert_ctx,
@@ -471,11 +439,18 @@ void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width,
         ci->y = ff_parse_eval(ci->eval_y, const_values, ci);
         y = ci->y;
 
+        if (ci->eval_a) {
+            ci->a = ff_parse_eval(ci->eval_a, const_values, ci);
+        }
+
         if (ci->eval_colors) {
             ci->r = ff_parse_eval(ci->eval_r, const_values, ci);
             ci->g = ff_parse_eval(ci->eval_g, const_values, ci);
             ci->b = ff_parse_eval(ci->eval_b, const_values, ci);
-            imlib_context_set_color(ci->r, ci->g, ci->b, 255);
+        }
+
+        if (ci->eval_colors || ci->eval_a) {
+            imlib_context_set_color(ci->r, ci->g, ci->b, ci->a);
         }
 
         if (!(ci->imageOverlaid))