Index: include/rt/geom.h
===================================================================
--- include/rt/geom.h	(revision 74518)
+++ include/rt/geom.h	(working copy)
@@ -330,8 +330,13 @@
     uint32_t ydim;	/**< @brief Y dimension (n cells) */
     fastf_t tallness;	/**< @brief Z dimension (mm) */
     mat_t mat;		/**< @brief convert local coords to model space */
-    /* REMAINING ELEMENTS PROVIDED BY IMPORT, UNUSED BY EXPORT */
-    struct bu_mapped_file *mp;	/**< @brief actual data */
+	unsigned short *buf; /**< @brief actual data */
+    struct bu_mapped_file *mp;	/**< @brief mapped file for data */
+	struct rt_db_internal *bip; /**< @brief db object for data */
+#define RT_EBM_SRC_V4_FILE '4'
+#define RT_EBM_SRC_FILE 'f'
+#define RT_EBM_SRC_OBJ 'o'
+	char datasrc; /**< @brief which type of data source */
 };
 #define RT_EBM_CK_MAGIC(_p) BU_CKMAG(_p, RT_EBM_INTERNAL_MAGIC, "rt_ebm_internal")
 /** @} */
Index: src/librt/primitives/ebm/ebm.c
===================================================================
--- src/librt/primitives/ebm/ebm.c	(revision 74518)
+++ src/librt/primitives/ebm/ebm.c	(working copy)
@@ -724,101 +724,85 @@
  * the associated internal variables.
  */
 int
-rt_ebm_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
+rt_ebm_import5(struct rt_db_internal* ip, const struct bu_external* ep, const fastf_t* mat, const struct db_i* dbip)
 {
-    register struct rt_ebm_internal *eip;
-    struct bu_vls str = BU_VLS_INIT_ZERO;
-    int nbytes;
-    mat_t tmat;
-    struct bu_mapped_file *mp;
+	register struct rt_ebm_internal* eip;
+	unsigned char* cp;
 
-    BU_CK_EXTERNAL(ep);
-    RT_CK_DB_INTERNAL(ip);
+	/* must be double for import and export */
+	double scanmat[16];
 
-    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
-    ip->idb_type = ID_EBM;
-    ip->idb_meth = &OBJ[ID_EBM];
-    BU_ALLOC(ip->idb_ptr, struct rt_ebm_internal);
+	if (RT_G_DEBUG & RT_DEBUG_HF)
+		bu_log("rt_dsp_import4__v5()\n");
 
-    eip = (struct rt_ebm_internal *)ip->idb_ptr;
-    eip->magic = RT_EBM_INTERNAL_MAGIC;
+	BU_CK_EXTERNAL(ep);
 
-    /* Provide default orientation info */
-    MAT_IDN(eip->mat);
+	BU_ASSERT(ep->ext_nbytes > 141);
 
-    bu_vls_strcpy(&str, (const char *)ep->ext_buf);
-    if (bu_struct_parse(&str, rt_ebm_parse, (char *)eip, NULL) < 0) {
-	bu_vls_free(&str);
-	bu_free((char *)eip, "rt_ebm_import4: eip");
-	ip->idb_type = ID_NULL;
-	ip->idb_ptr = (void *)NULL;
-	return -2;
-    }
-    bu_vls_free(&str);
+	RT_CK_DB_INTERNAL(ip);
 
-    /* Check for reasonable values */
-    if (eip->file[0] == '\0' || eip->xdim < 1 ||
-	eip->ydim < 1 || eip->mat[15] <= 0.0 ||
-	eip->tallness <= 0.0) {
-	bu_struct_print("Unreasonable EBM parameters", rt_ebm_parse,
-			(char *)eip);
-	bu_free((char *)eip, "rt_ebm_import4: eip");
-	ip->idb_type = ID_NULL;
-	ip->idb_ptr = (void *)NULL;
-	return -1;
-    }
+	ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
+	ip->idb_type = ID_EBM;
+	ip->idb_meth = &OBJ[ID_EBM];
+	BU_ALLOC(ip->idb_ptr, struct rt_ebm_internal);
 
-    /* Apply any modeling transforms to get final matrix */
-    if (mat == NULL) mat = bn_mat_identity;
-    bn_mat_mul(tmat, mat, eip->mat);
-    MAT_COPY(eip->mat, tmat);
+	eip = (struct rt_ebm_internal*)ip->idb_ptr;
+	eip->magic = RT_EBM_INTERNAL_MAGIC;
 
-    /* Get bit map from .bw(5) file */
-    mp = bu_open_mapped_file_with_path(dbip->dbi_filepath, eip->file, "ebm");
-    if (!mp) {
-	bu_log("rt_ebm_import4() unable to open '%s'\n", eip->file);
-	bu_free((char *)eip, "rt_ebm_import4: eip");
-    fail:
-	ip->idb_type = ID_NULL;
-	ip->idb_ptr = (void *)NULL;
-	return -1;
-    }
-    eip->mp = mp;
-    if (mp->buflen < (size_t)(eip->xdim*eip->ydim)) {
-	bu_log("rt_ebm_import4() file '%s' is too short %zu < %u\n",
-	       eip->file, mp->buflen, eip->xdim*eip->ydim);
-	goto fail;
-    }
+	/* get x, y dimensions */
+	cp = (unsigned char*)ep->ext_buf;
 
-    nbytes = (eip->xdim+BIT_XWIDEN*2)*(eip->ydim+BIT_YWIDEN*2);
+	eip->xdim = ntohl(*(uint32_t*)cp);
+	cp += SIZEOF_NETWORK_LONG;
+	if (eip->xdim < 1) {
+		bu_log("%s:%d EBM X dimension (%u) < 1 \n",
+			__FILE__, __LINE__,
+			eip->xdim);
+	}
 
-    /* If first use of this file, prepare in-memory buffer */
-    if (!mp->apbuf) {
-	size_t y;
-	unsigned char *cp;
+	eip->ydim = ntohl(*(uint32_t*)cp);
+	cp += SIZEOF_NETWORK_LONG;
+	if (eip->ydim < 1) {
+		bu_log("%s:%d EBM Y dimension (%u) < 1 \n",
+			__FILE__, __LINE__,
+			eip->ydim);
+	}
 
-	/* Prevent a multi-processor race */
-	bu_semaphore_acquire(RT_SEM_MODEL);
-	if (mp->apbuf) {
-	    /* someone else beat us, nothing more to do */
-	    bu_semaphore_release(RT_SEM_MODEL);
-	    return 0;
+	/* validate size */
+	if (eip->xdim == 0 || eip->ydim == 0) {
+	IMPORT_FAIL("zero dimension on map");
 	}
-	mp->apbuf = (void *)bu_calloc(
-	    1, nbytes, "rt_ebm_import4 bitmap");
-	mp->apbuflen = nbytes;
 
-	bu_semaphore_release(RT_SEM_MODEL);
+    /* convert matrix */
+	bu_cv_ntohd((unsigned char*)scanmat, cp, ELEMENTS_PER_MAT);
+	MAT_COPY(eip->mat, scanmat); /* double to fastf_t */
+	cp += SIZEOF_NETWORK_DOUBLE * ELEMENTS_PER_MAT; 
 
-	/* Because of in-memory padding, read each scanline separately */
-	cp = (unsigned char *)mp->buf;
-	for (y = 0; y < eip->ydim; y++) {
-	    /* BIT() addresses into mp->apbuf */
-	    memcpy(&BIT(eip, 0, y), cp, eip->xdim);
-	    cp += eip->xdim;
+	eip->datasrc = *cp;
+	cp++;
+	switch (eip->datasrc) {
+	case RT_EBM_SRC_V4_FILE:
+	case RT_DSP_SRC_FILE:
+	case RT_DSP_SRC_OBJ:
+		break;
+	default:
+		bu_log("%s:%d bogus EBM datasrc '%c' (%d)\n",
+			__FILE__, __LINE__,
+			eip->datasrc, eip->datasrc);
+		break;
 	}
-    }
-    return 0;
+
+    /* conert name of data location */
+	bu_vls_int(&eip->file);
+	bu_vls_strncpy(&eip->file, (char*)cp,
+			ep->ext_nbytes - (cp - (unsigned char*)ep->ext_buf));
+
+	if (mat == NULL) mat = bn_mat_identity;
+	if (ebm_get_data(eip, mat, dbip) != 0) {
+	IMPORT_FAIL("unable to load extruded bitmap data");
+	}
+
+    return 0; /* OK */
 }
 
 
@@ -829,9 +813,13 @@
 rt_ebm_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
 {
     struct rt_ebm_internal *eip;
-    struct rt_ebm_internal ebm;	/* scaled version */
-    struct bu_vls str = BU_VLS_INIT_ZERO;
+	unsigned long name_len;
+	unsigned char* cp;
+	size_t rem;
 
+	/* must be double for import and export */
+	double scanmat[16];
+
     if (dbip) RT_CK_DBI(dbip);
 
     RT_CK_DB_INTERNAL(ip);
@@ -838,22 +826,62 @@
     if (ip->idb_type != ID_EBM) return -1;
     eip = (struct rt_ebm_internal *)ip->idb_ptr;
     RT_EBM_CK_MAGIC(eip);
-    ebm = *eip;			/* struct copy */
 
-    /* Apply scale factor */
-    ebm.mat[15] /= local2mm;
+	if (RT_G_DEBUG * RT_DEBUG_HF)
+	bu_log("rt_ebm_export4_v5()\n");
 
+	name_len = bu_vls_strlen(&eip->file) + 1;
+
     BU_CK_EXTERNAL(ep);
 
-    bu_vls_struct_print(&str, rt_ebm_parse, (char *)&ebm);
+	ep->ext_nbytes =
+	SIZEOF_NETWORK_LONG * 2 +
+	SIZEOF_NETWORK_DOUBLE * ELEMENTS_PER_MAT +
+	2 + name_len;
 
-    ep->ext_nbytes = bu_vls_strlen(&str) + 1;
     ep->ext_buf = (uint8_t *)bu_calloc(1, ep->ext_nbytes, "ebm external");
+	cp = (unsigned char *)ep->ext_buf;
+	rem = ep->ext_nbytes;
 
-    bu_strlcpy((char *)ep->ext_buf, bu_vls_addr(&str), ep->ext_nbytes);
-    bu_vls_free(&str);
+	memset(ep->ext_buf, 0, ep->ext_nbytes);
 
-    return 0;
+	/* Now we fill the buffer with the data, making sure everything is
+	 * converted to Big-Endian IEEE
+	 */
+
+	*(uint32_t *)cp = htonl((uint32_t)eip->xdim);
+	cp += SIZEOF_NETWORK_LONG;
+	rem -= SIZEOF_NETWORK_LONG;
+
+	*(uint32_t *)cp = htonl((uint32_t)eip->ydim);
+	cp += SIZEOF_NETWORK_LONG;
+	rem -= SIZEOF_NETWORK_LONG;
+
+	/* Since libwdb users may want to operate in units other than mm,
+	 * we offer the opportunity to scale the solid (to get it into mm)
+	 * on the way out.
+	 */
+	eip->mat[15] *= local2mm;
+
+	MAT_COPY(scanmat, eip->mat); /* convert fastf_t to double */
+	bu_cv_htond(cp, (unsigned char *)scanmat, ELEMENTS_PER_MAT);
+
+	switch (eip->datasrc) {
+	case RT_EBM_SRC_V4_FILE:
+	case RT_EBM_SRC_FILE:
+	case RT_EBM_SRC_OBJ:
+		*cp = eip->datasrc;
+		break;
+	default:
+		*cp = RT_DSP_SRC_FILE;
+		break;
+	}
+	cp++;
+	rem--;
+
+	bu_srtlcpy((char *)cp, bu_vls_addr(&eip->file), rem);
+
+    return 0; /* OK */
 }
 
 
