int
rt_ebm_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    union record *rp;
    register struct rt_ebm_internal *eip;
    struct bu_vls str = BU_VLS_INIT_ZERO;
    int nbytes;
    mat_t tmat;
    struct bu_mapped_file *mp;

    BU_CK_EXTERNAL(ep);
    rp = (union record *)ep->ext_buf;
    if (rp->u_id != DBID_STRSOL) {
	bu_log("rt_ebm_import4: defective strsol record\n");
	return -1;
    }

    RT_CK_DB_INTERNAL(ip);
    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);

    eip = (struct rt_ebm_internal *)ip->idb_ptr;
    eip->magic = RT_EBM_INTERNAL_MAGIC;

    /* Provide default orientation info */
    MAT_IDN(eip->mat);

    bu_vls_strcpy(&str, rp->ss.ss_args);
    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);

    /* 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;
    }

    /* 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);

    /* 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;
    }

    nbytes = (eip->xdim+BIT_XWIDEN*2)*(eip->ydim+BIT_YWIDEN*2);

    /* If first use of this file, prepare in-memory buffer */
    if (!mp->apbuf) {
	size_t y;
	unsigned char *cp;

	/* 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;
	}
	mp->apbuf = (void *)bu_calloc(
	    1, nbytes, "rt_ebm_import4 bitmap");
	mp->apbuflen = nbytes;

	bu_semaphore_release(RT_SEM_MODEL);

	/* 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;
	}
    }
    return 0;
}