Revision: 76013
          http://sourceforge.net/p/brlcad/code/76013
Author:   starseeker
Date:     2020-06-03 19:31:59 +0000 (Wed, 03 Jun 2020)
Log Message:
-----------
No need to duplicate dm info in libged header - libdm's public API now lets us 
find out what we need from the display manager pointer without cracking struct 
dm.  Teach screengrab to optionally fetch the framebuffer image instead of the 
scene.

Modified Paths:
--------------
    brlcad/branches/dm-fb-merge/include/ged/defines.h
    brlcad/branches/dm-fb-merge/src/libged/icvfb.c
    brlcad/branches/dm-fb-merge/src/libged/screengrab.c
    brlcad/branches/dm-fb-merge/src/libtclcad/tclcad_obj.c
    brlcad/branches/dm-fb-merge/src/mged/cmd.c

Modified: brlcad/branches/dm-fb-merge/include/ged/defines.h
===================================================================
--- brlcad/branches/dm-fb-merge/include/ged/defines.h   2020-06-03 18:34:40 UTC 
(rev 76012)
+++ brlcad/branches/dm-fb-merge/include/ged/defines.h   2020-06-03 19:31:59 UTC 
(rev 76013)
@@ -204,7 +204,6 @@
     struct bview               *ged_gvp;
     struct bu_hash_tbl         *ged_selections; /**< @brief object name -> 
struct rt_object_selections */
 
-    void                       *ged_dmp;
     void                       *ged_refresh_clientdata;        /**< @brief  
client data passed to refresh handler */
     void                       (*ged_refresh_handler)(void *); /**< @brief  
function for handling refresh requests */
     void                       (*ged_output_handler)(struct ged *, char *);    
/**< @brief  function for handling output */
@@ -233,11 +232,7 @@
     db_search_callback_t ged_interp_eval; /* FIXME: broke the rule written on 
the previous line */
 
     /* Interface to LIBDM */
-    int ged_dm_width;
-    int ged_dm_height;
-    int ged_dmp_is_null;
-    void (*ged_dm_get_display_image)(struct ged *, unsigned char **);
-
+    void *ged_dmp;
 };
 
 typedef int (*ged_func_ptr)(struct ged *, int, const char *[]);

Modified: brlcad/branches/dm-fb-merge/src/libged/icvfb.c
===================================================================
--- brlcad/branches/dm-fb-merge/src/libged/icvfb.c      2020-06-03 18:34:40 UTC 
(rev 76012)
+++ brlcad/branches/dm-fb-merge/src/libged/icvfb.c      2020-06-03 19:31:59 UTC 
(rev 76013)
@@ -335,10 +335,8 @@
     }
 
     icv_write(img, file_name, type);
+    icv_destroy(img);
 
-    bu_free(img->data, "icv img data");
-    bu_free(img, "icv img");
-
     return ret;
 }
 

Modified: brlcad/branches/dm-fb-merge/src/libged/screengrab.c
===================================================================
--- brlcad/branches/dm-fb-merge/src/libged/screengrab.c 2020-06-03 18:34:40 UTC 
(rev 76012)
+++ brlcad/branches/dm-fb-merge/src/libged/screengrab.c 2020-06-03 19:31:59 UTC 
(rev 76013)
@@ -28,66 +28,121 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
-
-
 #include "icv.h"
+#include "dm.h"
 
 #include "./ged_private.h"
 
+static int
+image_mime(struct bu_vls *msg, size_t argc, const char **argv, void *set_mime)
+{
+    int type_int;
+    bu_mime_image_t type = BU_MIME_IMAGE_UNKNOWN;
+    bu_mime_image_t *set_type = (bu_mime_image_t *)set_mime;
 
-/* !!! FIXME: this command should not be directly utilizing LIBDM or
- * LIBFB as this breaks library encapsulation.  Generic functionality
- * should be moved out of LIBDM into LIBICV, or be handled by the
- * application logic calling this routine.
- */
+    BU_OPT_CHECK_ARGV0(msg, argc, argv, "mime format");
+
+    type_int = bu_file_mime(argv[0], BU_MIME_IMAGE);
+    type = (type_int < 0) ? BU_MIME_IMAGE_UNKNOWN : (bu_mime_image_t)type_int;
+    if (type == BU_MIME_IMAGE_UNKNOWN) {
+        if (msg) bu_vls_sprintf(msg, "Error - unknown geometry file type: %s 
\n", argv[0]);
+        return -1;
+    }
+    if (set_type) (*set_type) = type;
+    return 1;
+}
+
 int
 ged_screen_grab(struct ged *gedp, int argc, const char *argv[])
 {
 
     int i;
+    int print_help = 0;
     int width = 0;
     int height = 0;
+    int scr_xoff = 0;
+    int scr_yoff = 0;
     int bytes_per_pixel = 0;
     int bytes_per_line = 0;
-    static const char *usage = "image_name.ext";
+    int grab_fb = 0;
     unsigned char **rows = NULL;
     unsigned char *idata = NULL;
     struct icv_image *bif = NULL;      /**< icv image container for saving 
images */
+    struct dm *dmp = NULL;
+    struct fb *fbp = NULL;
+    bu_mime_image_t type = BU_MIME_IMAGE_AUTO;
+    //static char usage[] = "Usage: screengrab [-h] [-F] [-X scr_xoff] [-Y 
scr_yoff] [-w width] [-n height] [--format fmt] [file.img]\n";
+    static char usage[] = "Usage: screengrab [-h] [-F] [--format fmt] 
file.img\n";
 
-    if (gedp->ged_dmp_is_null) {
-       bu_vls_printf(gedp->ged_result_str, "Bad display pointer.");
-       return GED_ERROR;
-    }
+    struct bu_opt_desc d[8];
+    BU_OPT(d[0], "h", "help",           "",            NULL,      &print_help, 
      "Print help and exit");
+    BU_OPT(d[1], "F", "fb",             "",     NULL,             &grab_fb,    
      "screengrab framebuffer instead of scene display");
+    BU_OPT(d[2], "",  "format",         "fmt",  &image_mime,      &type,       
      "output image file format");
+    BU_OPT_NULL(d[3]);
+    //BU_OPT(d[3], "X", "scr_xoff",       "#",    &bu_opt_int,      &scr_xoff, 
        "X offset");
+    //BU_OPT(d[4], "Y", "scr_yoff",       "#",    &bu_opt_int,      &scr_yoff, 
        "Y offset");
+    //BU_OPT(d[5], "w", "width",          "#",    &bu_opt_int,      &width,    
        "image width to grab");
+    //BU_OPT(d[6], "n", "height",         "#",    &bu_opt_int,      &height,   
        "image height to grab");
+    //BU_OPT_NULL(d[7]);
 
-    if (gedp->ged_dm_get_display_image == NULL) {
-       bu_vls_printf(gedp->ged_result_str, "Bad display function pointer.");
-       return GED_ERROR;
-    }
-
     GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
     GED_CHECK_VIEW(gedp, GED_ERROR);
     GED_CHECK_DRAWABLE(gedp, GED_ERROR);
     GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
 
+    if (!gedp->ged_dmp) {
+       bu_vls_printf(gedp->ged_result_str, ": no display manager currently 
active");
+       return GED_ERROR;
+    }
+
+    dmp = (struct dm *)gedp->ged_dmp;
+
     /* initialize result */
     bu_vls_trunc(gedp->ged_result_str, 0);
 
     /* must be wanting help */
     if (argc == 1) {
-       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       _ged_cmd_help(gedp, usage, d);
        return GED_HELP;
     }
 
-    if (argc != 2) {
+    argc-=(argc>0); argv+=(argc>0); /* done with command name argv[0] */
+
+    int opt_ret = bu_opt_parse(NULL, argc, argv, d);
+
+    if (print_help) {
+       _ged_cmd_help(gedp, usage, d);
+       return GED_HELP;
+    }
+
+    argc = opt_ret;
+
+    if (grab_fb) {
+       fbp = dm_get_fb(dmp);
+       if (!fbp) {
+           bu_vls_printf(gedp->ged_result_str, ": display manager does not 
have a framebuffer");
+           return GED_ERROR;
+       }
+    }
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (!argc) {
        bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
-       return GED_ERROR;
+       return GED_HELP;
     }
 
-    width = gedp->ged_dm_width;
-    height = gedp->ged_dm_height;
+    if (!width) {
+       width = (grab_fb) ? fb_getwidth(fbp) : dm_get_width(dmp);
+    }
+    if (!height) {
+       height = (grab_fb) ? fb_getheight(fbp) : dm_get_height(dmp);
+    }
 
     if (width <= 0 || height <= 0) {
-       bu_vls_printf(gedp->ged_result_str, "%s: invalid screen dimensions.", 
argv[1]);
+       bu_vls_printf(gedp->ged_result_str, ": invalid screen dimensions.");
        return GED_ERROR;
     }
 
@@ -95,38 +150,38 @@
     bytes_per_line = width * bytes_per_pixel;
 
     /* create image file */
+    if (!grab_fb) {
 
-    if ((bif = icv_create(width, height, ICV_COLOR_SPACE_RGB)) == NULL) {
-       bu_vls_printf(gedp->ged_result_str, "%s: could not create icv_image 
write structure.", argv[1]);
-       return GED_ERROR;
-    }
-
-    rows = (unsigned char **)bu_calloc(height, sizeof(unsigned char *), 
"rows");
-
-    gedp->ged_dm_get_display_image(gedp, &idata);
-
-    if (!idata) {
-       bu_vls_printf(gedp->ged_result_str, "%s: display manager did not return 
image data.", argv[1]);
-       if (bif != NULL) icv_destroy(bif);
+       dm_get_display_image(dmp, &idata);
+       if (!idata) {
+           bu_vls_printf(gedp->ged_result_str, "%s: display manager did not 
return image data.", argv[1]);
+           return GED_ERROR;
+       }
+       bif = icv_create(width, height, ICV_COLOR_SPACE_RGB);
+       if (bif == NULL) {
+           bu_vls_printf(gedp->ged_result_str, ": could not create icv_image 
write structure.");
+           return GED_ERROR;
+       }
+       rows = (unsigned char **)bu_calloc(height, sizeof(unsigned char *), 
"rows");
+       for (i = 0; i < height; ++i) {
+           rows[i] = (unsigned char *)(idata + ((height-i-1)*bytes_per_line));
+           /* TODO : Add double type data to maintain resolution */
+           icv_writeline(bif, i, rows[i], ICV_DATA_UCHAR);
+       }
        bu_free(rows, "rows");
-       return GED_ERROR;
-    }
+       bu_free(idata, "image data");
 
-    for (i = 0; i < height; ++i) {
-       rows[i] = (unsigned char *)(idata + ((height-i-1)*bytes_per_line));
-       /* TODO : Add double type data to maintain resolution */
-       icv_writeline(bif, i, rows[i], ICV_DATA_UCHAR);
+    } else {
+       bif = fb_write_icv(fbp, scr_xoff, scr_yoff, width, height);
+       if (bif == NULL) {
+           bu_vls_printf(gedp->ged_result_str, ": could not create icv_image 
from framebuffer.");
+           return GED_ERROR;
+       }
     }
 
-    if (bif != NULL) {
-       icv_write(bif, argv[1], BU_MIME_IMAGE_AUTO);
-       icv_destroy(bif);
-       bif = NULL;
-    }
+    icv_write(bif, argv[0], type);
+    icv_destroy(bif);
 
-    bu_free(rows, "rows");
-    bu_free(idata, "image data");
-
     return GED_OK;
 }
 

Modified: brlcad/branches/dm-fb-merge/src/libtclcad/tclcad_obj.c
===================================================================
--- brlcad/branches/dm-fb-merge/src/libtclcad/tclcad_obj.c      2020-06-03 
18:34:40 UTC (rev 76012)
+++ brlcad/branches/dm-fb-merge/src/libtclcad/tclcad_obj.c      2020-06-03 
19:31:59 UTC (rev 76013)
@@ -1020,7 +1020,6 @@
 
 /* Utility Functions */
 HIDDEN int to_close_fbs(struct ged_dm_view *gdvp);
-HIDDEN void to_dm_get_display_image(struct ged *gedp, unsigned char **idata);
 HIDDEN void to_fbs_callback();
 HIDDEN int to_open_fbs(struct ged_dm_view *gdvp, Tcl_Interp *interp);
 
@@ -14880,13 +14879,6 @@
     return to_view_func_common(gedp, argc, argv, func, usage, maxargs, 0, 1);
 }
 
-static void
-mged_dm_get_display_image(struct ged *gedp, unsigned char **idata)
-{
-    struct dm *dmp = (struct dm *)gedp->ged_dmp;
-    dm_get_display_image(dmp, idata);
-}
-
 HIDDEN int
 to_view_func_common(struct ged *gedp,
                    int argc,
@@ -14929,10 +14921,6 @@
     }
 
     gedp->ged_dmp = gdvp->gdv_dmp;
-    gedp->ged_dm_width = dm_get_width(gdvp->gdv_dmp);
-    gedp->ged_dm_height = dm_get_height(gdvp->gdv_dmp);
-    gedp->ged_dmp_is_null = (gedp->ged_dmp == NULL);
-    gedp->ged_dm_get_display_image = mged_dm_get_display_image;
 
     /* Copy argv into av while skipping argv[1] (i.e. the view name) */
     gedp->ged_gvp = gdvp->gdv_view;
@@ -15045,9 +15033,6 @@
     /* Copy argv into av while skipping argv[1] (i.e. the view name) */
     gedp->ged_gvp = gdvp->gdv_view;
     gedp->ged_dmp = (void *)gdvp->gdv_dmp;
-    gedp->ged_dm_width = dm_get_width(gdvp->gdv_dmp);
-    gedp->ged_dm_height = dm_get_height(gdvp->gdv_dmp);
-    gedp->ged_dm_get_display_image = to_dm_get_display_image;
     gedp->ged_refresh_clientdata = (void *)gdvp;
     av[0] = (char *)argv[0];
     ac = argc-1;
@@ -15091,14 +15076,6 @@
 }
 
 
-HIDDEN void to_dm_get_display_image(struct ged *gedp, unsigned char **idata)
-{
-    if (gedp->ged_dmp) {
-       (void)dm_get_display_image(((struct dm *)gedp->ged_dmp), idata);
-    }
-}
-
-
 /*
  * Open/activate the display managers framebuffer.
  */

Modified: brlcad/branches/dm-fb-merge/src/mged/cmd.c
===================================================================
--- brlcad/branches/dm-fb-merge/src/mged/cmd.c  2020-06-03 18:34:40 UTC (rev 
76012)
+++ brlcad/branches/dm-fb-merge/src/mged/cmd.c  2020-06-03 19:31:59 UTC (rev 
76013)
@@ -82,38 +82,7 @@
  */
 static struct bu_vls tcl_output_hook = BU_VLS_INIT_ZERO;
 
-static int
-mged_dm_width(struct ged *gedp)
-{
-    struct dm *dmp = (struct dm *)gedp->ged_dmp;
-    return dm_get_width(dmp);
-}
 
-
-static int
-mged_dm_height(struct ged *gedp)
-{
-    struct dm *dmp = (struct dm *)gedp->ged_dmp;
-    return dm_get_height(dmp);
-}
-
-
-static int
-mged_dmp_is_null(struct ged *gedp)
-{
-    struct dm *dmp = (struct dm *)gedp->ged_dmp;
-    return dmp == NULL;
-}
-
-
-static void
-mged_dm_get_display_image(struct ged *gedp, unsigned char **idata)
-{
-    struct dm *dmp = (struct dm *)gedp->ged_dmp;
-    dm_get_display_image(dmp, idata);
-}
-
-
 /**
  * Used as a hook for bu_log output.  Sends output to the Tcl
  * procedure whose name is contained in the vls "tcl_output_hook".
@@ -712,10 +681,6 @@
     if (!GEDP->ged_gvp)
        GEDP->ged_gvp = view_state->vs_gvp;
     GEDP->ged_dmp = (void *)curr_dm_list->dml_dmp;
-    GEDP->ged_dm_width = mged_dm_width(GEDP);
-    GEDP->ged_dm_height = mged_dm_height(GEDP);
-    GEDP->ged_dmp_is_null = mged_dmp_is_null(GEDP);
-    GEDP->ged_dm_get_display_image = mged_dm_get_display_image;
 
     ret = (*ctp->ged_func)(GEDP, argc, (const char **)argv);
     Tcl_AppendResult(interpreter, bu_vls_addr(GEDP->ged_result_str), NULL);

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to