Esempio n. 1
0
static int _series_data(void)
{
	FILE *fp;
	bool hd = false;
	hid_t fid_job;
	hid_t jgid_root;
	hid_t jgid_step;
	int	nsteps;
	int stepx;
	char jgrp_step_name[MAX_GROUP_NAME + 1];

	fp = fopen(params.output, "w");
	if (fp == NULL) {
		error("Failed open file %s -- %m", params.output);
		return -1;
	}

	fid_job = H5Fopen(params.input, H5F_ACC_RDONLY, H5P_DEFAULT);
	if (fid_job < 0) {
		fclose(fp);
		error("Failed to open %s", params.input);
		return -1;
	}

	jgid_root = H5Gopen(fid_job, "/", H5P_DEFAULT);
	if (jgid_root < 0) {
		fclose(fp);
		H5Fclose(fid_job);
		error("Failed to open root");
		return -1;
	}

	nsteps = get_int_attribute(jgid_root, ATTR_NSTEPS);
	for (stepx = 0; stepx < nsteps; stepx++) {

		if ((params.step_id != -1) && (stepx != params.step_id))
			continue;

		sprintf(jgrp_step_name, "%s_%d", GRP_STEP, stepx);
		jgid_step = get_group(jgid_root, jgrp_step_name);
		if (jgid_step < 0) {
			error("Failed to open  group %s", jgrp_step_name);
			return -1;
		}

		if (strncmp(params.series,GRP_TASK,strlen(GRP_TASK)) == 0)
			_get_all_task_series(fp,hd,jgid_step, stepx);
		else
			_get_all_node_series(fp,hd,jgid_step, stepx);

		hd = true;
		H5Gclose(jgid_step);
	}

	H5Gclose(jgid_root);
	H5Fclose(fid_job);
	fclose(fp);

	return 0;
}
/* PUBLIC */
void adjust_weight_with_hints(Topform c,
			      BOOL degrade,
			      BOOL breadth_first_hints)
{
  Topform hint = find_matching_hint(c, Hints_idx);

  if (hint == NULL &&
      unit_clause(c->literals) &&
      eq_term(c->literals->atom) &&
      !oriented_eq(c->literals->atom)) {

    /* Try to find a hint that matches the flipped equality. */

    Term save_atom = c->literals->atom;
    c->literals->atom = top_flip(save_atom);
    hint = find_matching_hint(c, Hints_idx);
    zap_top_flip(c->literals->atom);
    c->literals->atom = save_atom;
    if (hint != NULL)
      c->attributes = set_string_attribute(c->attributes, label_att(),
					   "flip_matches_hint");
  }

  if (hint != NULL) {

    int bsub_wt = get_int_attribute(hint->attributes, Bsub_wt_attr, 1);

    if (bsub_wt != INT_MAX)
      c->weight = bsub_wt;
    else if (breadth_first_hints)
      c->weight = 0;

    /* If the hint has label attributes, copy them to the clause. */
    
    {
      int i = 0;
      char *s = get_string_attribute(hint->attributes, label_att(), ++i);
      while (s) {
	if (!string_attribute_member(c->attributes, label_att(), s))
	  c->attributes = set_string_attribute(c->attributes, label_att(), s);
	s = get_string_attribute(hint->attributes, label_att(), ++i);
      }
    }

    /* Veroff's hint degradation strategy. */

    if (degrade) {
      /* for now, add 1000 for each previous match */
      int i;
      for (i = 0; i < hint->weight; i++) 
	c->weight = c->weight + 1000;
    }
    c->matching_hint = hint;
    /* If/when c is eventually kept, the hint will have its weight
       field incremented in case hint degradation is being used. */
  }
}  /* adjust_weight_with_hints */
/**
 * init_thread_info
 * @brief Initialize thread data
 *
 * Initialize global thread or "logical cpu" data. The physical cpu data
 * initialization must have been completed before this is called.
 *
 * @returns pointer to thread_info on success, NULL otherwise
 */
static int
init_thread_info(struct dr_info *dr_info)
{
	struct thread *thread = NULL;
	struct thread *thread_list = NULL;
	struct thread *last = NULL;
	int rc, i = 0;
	struct stat s;
	char path[DR_PATH_MAX];
	int nr_threads, thread_cnt = 0;

	if (stat("/sys/devices/system/cpu", &s)) {
		say(ERROR, "Cannot gather CPU thread information,\n"
		    "stat(\"/sys/devices/system/cpu\"): %s\n",
		    strerror(errno));
		return -1;
	}

	nr_threads = s.st_nlink - 2;

	say(DEBUG, "Expecting %d threads...", nr_threads);

	sprintf(path, DR_THREAD_DIR_PATH, i);
	for (i = 0; 0 == stat(path, &s); i++) {
		thread = zalloc(sizeof(*thread));

		thread->id = i;
		snprintf(thread->path, DR_PATH_MAX, "%s", path);

		rc = get_int_attribute(thread->path, "physical_id",
				       &thread->phys_id,
				       sizeof(thread->phys_id));
		if (rc) {
			say(ERROR, "Could not get \"physical_id\" of thread "
			    "%s\n", thread->path);
			free(thread);
			return -1;
		}

		if (thread_list)
			last->next = thread;
		else
			thread_list = thread;

		last = thread;

		sprintf(path, DR_THREAD_DIR_PATH, i + 1);
		thread_cnt++;
	}

	say(DEBUG, "found %d.\n", thread_cnt);
	dr_info->all_threads = thread_list;
	return 0;
}
/**
 * get_thread_state
 * @brief Get the "online" status of the given thread.
 *
 * @param thread
 * @returns 0 = offline, 1 = online, -1 on error
 */
int
get_thread_state(struct thread *thread)
{
	char path[DR_PATH_MAX];
	int rc, status = -1;

	sprintf(path, DR_THREAD_ONLINE_PATH, thread->id);

	rc = get_int_attribute(path, NULL, &status, sizeof(status));

	return rc ? rc : status;
}
Esempio n. 5
0
/**
 * get_mem_scns
 * @brief Find the memory sections associated with the specified lmb
 *
 * @param lmb lmb to find memory sections of
 * @return 0 on success, !0 otherwise
 */
static int
get_mem_scns(struct dr_node *lmb)
{
	uint32_t lmb_sz = lmb->lmb_size;
	uint64_t phys_addr = lmb->lmb_address;
	uint32_t mem_scn;
	int rc = 0;

	mem_scn = phys_addr / block_sz_bytes;

	/* Assume the lmb is removable.  If we find a non-removable memory
	 * section then we flip the lmb back to not removable.
	 */
	lmb->is_removable = 1;

	lmb_sz = lmb->lmb_size;
	while (lmb_sz > 0) {
		char *sysfs_path = "/sys/devices/system/memory/memory%d";
		struct mem_scn *scn;
		struct stat sbuf;

		scn = zalloc(sizeof(*scn));
		if (scn == NULL)
			return -1;

		sprintf(scn->sysfs_path, sysfs_path, mem_scn);
		scn->phys_addr = phys_addr;

		if (!stat(scn->sysfs_path, &sbuf)) {
			get_int_attribute(scn->sysfs_path, "removable",
					  &scn->removable,
					  sizeof(scn->removable));
			if (!scn->removable)
				lmb->is_removable = 0;
		}

		scn->next = lmb->lmb_mem_scns;
		lmb->lmb_mem_scns = scn;

		lmb_sz -= block_sz_bytes;
		phys_addr += block_sz_bytes;
		mem_scn = phys_addr / block_sz_bytes;
	}

	/* If we do not find any associated memory sections, mark this
	 * as not removable.
	 */
	if ((lmb->lmb_mem_scns == NULL) || lmb->unusable)
		lmb->is_removable = 0;

	return rc;
}
Esempio n. 6
0
static void _extract_all_tasks(FILE *fp, hid_t gid_step, hid_t gid_nodes,
		int nnodes, int stepx)
{

	hid_t	gid_tasks, gid_task = 0, gid_node = -1, gid_level = -1;
	H5G_info_t group_info;
	int	ntasks, itx, len, task_id;
	char	task_name[MAX_GROUP_NAME+1];
	char*   node_name;
	char	buf[MAX_GROUP_NAME+1];
	bool hd = true;

	gid_tasks = get_group(gid_step, GRP_TASKS);
	if (gid_tasks < 0)
		fatal("No tasks in step %d", stepx);
	H5Gget_info(gid_tasks, &group_info);
	ntasks = (int) group_info.nlinks;
	if (ntasks <= 0)
		fatal("No tasks in step %d", stepx);

	for (itx = 0; itx<ntasks; itx++) {
		// Get the name of the group.
		len = H5Lget_name_by_idx(gid_tasks, ".", H5_INDEX_NAME,
		                         H5_ITER_INC, itx, buf, MAX_GROUP_NAME,
		                         H5P_DEFAULT);
		if ((len > 0) && (len < MAX_GROUP_NAME)) {
			gid_task = H5Gopen(gid_tasks, buf, H5P_DEFAULT);
			if (gid_task < 0)
				fatal("Failed to open %s", buf);
		} else
			fatal("Illegal task name %s",buf);
		task_id = get_int_attribute(gid_task, ATTR_TASKID);
		node_name = get_string_attribute(gid_task, ATTR_NODENAME);
		sprintf(task_name,"%s_%d", GRP_TASK, task_id);
		gid_node = H5Gopen(gid_nodes, node_name, H5P_DEFAULT);
		if (gid_node < 0)
			fatal("Failed to open %s for Task_%d",
					node_name, task_id);
		gid_level = get_group(gid_node, GRP_SAMPLES);
		if (gid_level < 0)
			fatal("Failed to open group %s for node=%s task=%d",
					GRP_SAMPLES,node_name, task_id);
		_extract_series(fp, stepx, hd, gid_level, node_name, task_name);

		hd = false;
		xfree(node_name);
		H5Gclose(gid_level);
		H5Gclose(gid_node);
		H5Gclose(gid_task);
	}
	H5Gclose(gid_tasks);
}
Esempio n. 7
0
static gboolean
on_connect_server_info_completed (LDAPMessage *result,
                                  gpointer user_data)
{
	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
	source_connect_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
	SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (g_async_result_get_source_object (user_data));
	LDAPServerInfo *sinfo;
	char *message;
	int code;
	int type;
	int rc;

	type = ldap_msgtype (result);
	g_return_val_if_fail (type == LDAP_RES_SEARCH_ENTRY || type == LDAP_RES_SEARCH_RESULT, FALSE);

	/* If we have results then fill in the server info */
	if (type == LDAP_RES_SEARCH_ENTRY) {

		g_debug ("Server Info Result");
#ifdef WITH_DEBUG
		dump_ldap_entry (closure->ldap, result);
#endif

		/* NOTE: When adding attributes here make sure to add them to kServerAttributes */
		sinfo = g_new0 (LDAPServerInfo, 1);
		sinfo->version = get_int_attribute (closure->ldap, result, "version");
		sinfo->base_dn = get_string_attribute (closure->ldap, result, "basekeyspacedn");
		if (!sinfo->base_dn)
			sinfo->base_dn = get_string_attribute (closure->ldap, result, "pgpbasekeyspacedn");
		sinfo->key_attr = g_strdup (sinfo->version > 1 ? "pgpkeyv2" : "pgpkey");
		set_ldap_server_info (self, sinfo);

		return TRUE; /* callback again */

	} else {
		rc = ldap_parse_result (closure->ldap, result, &code, NULL,
		                        &message, NULL, NULL, 0);
		g_return_val_if_fail (rc == LDAP_SUCCESS, FALSE);

		if (code != LDAP_SUCCESS)
			g_warning ("operation to get LDAP server info failed: %s", message);

		ldap_memfree (message);

		g_simple_async_result_complete_in_idle (res);
		seahorse_progress_end (closure->cancellable, res);
		return FALSE; /* don't callback again */
	}
}
Esempio n. 8
0
int do_migration(uint64_t stream_val)
{
    int rc, fd;
    int api_level = 0;
    char buf[64];

    /* If the kernel can also do the device tree update we should let the kernel do all the work.
       Check if sysfs migration api_version is readable and use api level to determine how to
       perform migration and post-mobility updates. */
    rc = get_int_attribute(SYSFS_MIGRATION_API_FILE, NULL, &api_level, sizeof(&api_level));
    if (rc)
        say(DEBUG,"get_int_attribute returned %d for path %s\n", rc, SYSFS_MIGRATION_API_FILE);

    if (api_level == MIGRATION_API_V0) {
        say(DEBUG, "about to issue ibm,suspend-me(%llx)\n", stream_val);
        rc = rtas_suspend_me(stream_val);
        say(DEBUG, "ibm,suspend-me() returned %d\n", rc);
    } else if (api_level == MIGRATION_API_V1) {
        sprintf(buf, "0x%" PRIx64 "\n", stream_val);

        fd = open(SYSFS_MIGRATION_FILE, O_WRONLY);
        if (fd == -1) {
            say(ERROR, "Could not open \"%s\" to initiate migration, "
                "%m\n", SYSFS_MIGRATION_FILE);
            return -1;
        }

        say(DEBUG, "Initiating migration via %s with %s\n",
            SYSFS_MIGRATION_FILE, buf);

        rc = write(fd, buf, strlen(buf));
        if (rc < 0) {
            say(DEBUG, "Write to migration file failed with rc: %d\n", rc);
            rc = errno;
        } else if (rc > 0)
            rc = 0;

        close(fd);
        say(DEBUG, "Kernel migration returned %d\n", rc);
    } else {
        say(ERROR, "Unknown kernel migration api version %d\n", api_level);
        rc = -1;
    }

    return rc;
}
Esempio n. 9
0
    // Search for TIFF tag 'tagid' having type 'tifftype', and if found,
    // add it in the obvious way to m_spec under the name 'oiioname'.
    void find_tag (int tifftag, TIFFDataType tifftype, const char *oiioname) {
#ifdef TIFF_VERSION_BIG
        const TIFFField *info = TIFFFindField (m_tif, tifftag, tifftype);
#else
        const TIFFFieldInfo *info = TIFFFindFieldInfo (m_tif, tifftag, tifftype);
#endif
        if (! info) {
            // Something has gone wrong, libtiff doesn't think the field type
            // is the same as we do.
            return;
        }
        if (tifftype == TIFF_ASCII)
            get_string_attribute (oiioname, tifftag);
        else if (tifftype == TIFF_SHORT)
            get_short_attribute (oiioname, tifftag);
        else if (tifftype == TIFF_LONG)
            get_int_attribute (oiioname, tifftag);
        else if (tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL ||
                 tifftype == TIFF_FLOAT || tifftype == TIFF_DOUBLE)
            get_float_attribute (oiioname, tifftag);
    }
Esempio n. 10
0
void post_mobility_update(int action)
{
    int rc;
    int do_update = 0;
    char *path;

    if (action == HIBERNATE)
        path = SYSFS_HIBERNATION_FILE;
    else
        path = SYSFS_MIGRATION_API_FILE;

    /* kernel will return 0 or sysfs attribute will be unreadable if drmgr
       needs to perform a device tree update */
    rc = get_int_attribute(path, NULL, &do_update, sizeof(do_update));
    if (rc)
        say(DEBUG, "get_int_attribute returned %d for path %s\n", rc, path);

    if (!do_update) {
        rc = rtas_activate_firmware();
        if (rc)
            say(DEBUG, "rtas_activate_firmware() returned %d\n", rc);
        devtree_update();
    }
}
Esempio n. 11
0
/**
 * get_hp_adapter_status
 * @brief check adapter status
 *
 * @param drc_name
 * @returns 0 if slot is empty
 * @returns 1 if adapter is configured
 * @returns 2 if adapter is not configured
 * @returns <0 on error
 */
int
get_hp_adapter_status(char *drc_name)
{
	int value, rc = 0;
	char path[DR_PATH_MAX], *bus_id;

	bus_id = get_bus_id(drc_name);
	if (bus_id)
		sprintf(path, PHP_SYSFS_ADAPTER_PATH, bus_id);
	else
		sprintf(path, PHP_SYSFS_ADAPTER_PATH, drc_name);

	rc = get_int_attribute(path, NULL, &value, sizeof(value));
	if (rc)
		return -1;

	say(DEBUG, "hp adapter status for %s is %d\n", drc_name, value);

	rc = value;
	if (rc != CONFIG && rc != NOT_CONFIG && rc != EMPTY)
	    rc = -1;

	return rc;
}
Esempio n. 12
0
static void _get_all_node_series(FILE *fp, bool hd, hid_t jgid_step, int stepx)
{
	char     **tod = NULL;  // Date time at each sample
	char     **node_name;	// Node Names
	double **all_series;	// Pointers to all sampled for each node
	double *et = NULL;	// Elapsed time at each sample
	uint64_t *series_smp;   // Number of samples in this series

	hid_t	jgid_nodes, jgid_node;
	int	nnodes, ndx, len, nsmp = 0, nitem = -1;
	char	jgrp_node_name[MAX_GROUP_NAME+1];
	void*   series_data = NULL;
	hdf5_api_ops_t* ops;

	nnodes = get_int_attribute(jgid_step, ATTR_NNODES);
	// allocate node arrays

	series_smp = xmalloc(nnodes * (sizeof(uint64_t)));
	if (series_smp == NULL) {
		fatal("Failed to get memory for node_samples");
		return;		/* fix for CLANG false positive */
	}

	node_name = xmalloc(nnodes * (sizeof(char*)));
	if (node_name == NULL) {
		fatal("Failed to get memory for node_name");
		return;		/* fix for CLANG false positive */
	}

	all_series = xmalloc(nnodes * (sizeof(double*)));
	if (all_series == NULL) {
		fatal("Failed to get memory for all_series");
		return;		/* fix for CLANG false positive */
	}

	jgid_nodes = get_group(jgid_step, GRP_NODES);
	if (jgid_nodes < 0)
		fatal("Failed to open  group %s", GRP_NODES);

	for (ndx=0; ndx<nnodes; ndx++) {
		len = H5Lget_name_by_idx(jgid_nodes, ".", H5_INDEX_NAME,
		                         H5_ITER_INC, ndx, jgrp_node_name,
		                         MAX_GROUP_NAME, H5P_DEFAULT);
		if ((len < 0) || (len > MAX_GROUP_NAME)) {
			debug("Invalid node name=%s", jgrp_node_name);
			continue;
		}
		node_name[ndx] = xstrdup(jgrp_node_name);
		jgid_node = get_group(jgid_nodes, jgrp_node_name);
		if (jgid_node < 0) {
			debug("Failed to open group %s", jgrp_node_name);
			continue;
		}
		ops = NULL;
		nitem = 0;
		series_data = _get_series_data(jgid_node, params.series,
		                               &ops, &nitem);
		if (series_data==NULL || nitem==0 || ops==NULL) {
			if (ops != NULL)
				xfree(ops);
			continue;
		}
		all_series[ndx] = ops->get_series_values(
			params.data_item, series_data, nitem);
		if (!all_series[ndx])
			fatal("No data item %s",params.data_item);
		series_smp[ndx] = nitem;
		if (ndx == 0) {
			nsmp = nitem;
			tod = ops->get_series_tod(series_data, nitem);
			et = ops->get_series_values("time",
			                            series_data, nitem);
		} else {
			if (nitem > nsmp) {
				// new largest number of samples
				_delete_string_list(tod, nsmp);
				xfree(et);
				nsmp = nitem;
				tod = ops->get_series_tod(series_data,
				                          nitem);
				et = ops->get_series_values("time",
				                            series_data, nitem);
			}
		}
		xfree(ops);
		xfree(series_data);
		H5Gclose(jgid_node);
	}
	if (nsmp == 0) {
		// May be bad series name
		info("No values %s for series %s found in step %d",
		     params.data_item,params.series,
		     stepx);
	} else {
		_series_analysis(fp, hd, stepx, nnodes, nsmp,
		                 node_name, tod, et, all_series, series_smp);
	}
	for (ndx=0; ndx<nnodes; ndx++) {
		xfree(node_name[ndx]);
		xfree(all_series[ndx]);
	}
	xfree(node_name);
	xfree(all_series);
	xfree(series_smp);
	_delete_string_list(tod, nsmp);
	xfree(et);

	H5Gclose(jgid_nodes);

}
Esempio n. 13
0
static void _merge_task_totals(hid_t jg_tasks, hid_t nsg_node, char* node_name)
{
	hid_t   jg_task, jg_totals, nsg_totals,
		g_total, nsg_tasks, nsg_task = -1;
	hsize_t nobj, ntasks = -1;
	int	i, len, taskx, taskid, taskcpus, size_data;
	void    *data;
	uint32_t type;
	char    buf[MAX_GROUP_NAME+1];
	char    group_name[MAX_GROUP_NAME+1];
	H5G_info_t group_info;

	if (jg_tasks < 0) {
		info("Job Tasks is not HDF5 object");
		return;
	}
	if (nsg_node < 0) {
		info("Node-Step is not HDF5 object");
		return;
	}

	nsg_tasks = get_group(nsg_node, GRP_TASKS);
	if (nsg_tasks < 0) {
		debug("No Tasks group in node-step file");
		return;
	}

	H5Gget_info(nsg_tasks, &group_info);
	ntasks = group_info.nlinks;
	for (taskx = 0; ((int)ntasks>0) && (taskx<((int)ntasks)); taskx++) {
		// Get the name of the group.
		len = H5Lget_name_by_idx(nsg_tasks, ".", H5_INDEX_NAME,
					 H5_ITER_INC, taskx, buf,
					 MAX_GROUP_NAME, H5P_DEFAULT);
		if (len<1 || len>MAX_GROUP_NAME) {
			info("Invalid group name %s", buf);
			continue;
		}
		nsg_task = H5Gopen(nsg_tasks, buf, H5P_DEFAULT);
		if (nsg_task < 0) {
			debug("Failed to open %s", buf);
			continue;
		}
		taskid = get_int_attribute(nsg_task, ATTR_TASKID);
		sprintf(group_name, "%s_%d", GRP_TASK, taskid);
		jg_task = H5Gcreate(jg_tasks, group_name,
				    H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
		if (jg_task < 0) {
			H5Gclose(nsg_task);
			info("Failed to create job task group");
			continue;
		}
		put_string_attribute(jg_task, ATTR_NODENAME, node_name);
		put_int_attribute(jg_task, ATTR_TASKID, taskid);
		taskcpus = get_int_attribute(nsg_task, ATTR_CPUPERTASK);
		put_int_attribute(jg_task, ATTR_CPUPERTASK, taskcpus);
		nsg_totals = get_group(nsg_task, GRP_TOTALS);
		if (nsg_totals < 0) {
			H5Gclose(jg_task);
			H5Gclose(nsg_task);
			continue;
		}
		jg_totals = H5Gcreate(jg_task, GRP_TOTALS,
				      H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
		if (jg_totals < 0) {
			H5Gclose(jg_task);
			H5Gclose(nsg_task);
			info("Failed to create job task totals");
			continue;
		}
		H5Gget_info(nsg_totals, &group_info);
		nobj = group_info.nlinks;
		for (i = 0; (nobj>0) && (i<nobj); i++) {
			// Get the name of the group.
			len = H5Lget_name_by_idx(nsg_totals, ".", H5_INDEX_NAME,
						 H5_ITER_INC, i, buf,
						 MAX_GROUP_NAME, H5P_DEFAULT);

			if (len<1 || len>MAX_GROUP_NAME) {
				info("Invalid group name %s", buf);
				continue;
			}
			g_total = H5Gopen(nsg_totals, buf, H5P_DEFAULT);
			if (g_total < 0) {
				info("Failed to open %s", buf);
				continue;
			}
			type = get_uint32_attribute(g_total, ATTR_DATATYPE);
			if (!type) {
				H5Gclose(g_total);
				info("No %s attribute", ATTR_DATATYPE);
				continue;
			}
			data = get_hdf5_data(g_total, type, buf, &size_data);
			if (data == NULL) {
				H5Gclose(g_total);
				info("Failed to get group %s type %s data", buf,
				     acct_gather_profile_type_to_string(type));
				continue;
			}
			put_hdf5_data(jg_totals, type, SUBDATA_DATA,
				      buf, data, 1);
			xfree(data);
			H5Gclose(g_total);
		}
		H5Gclose(nsg_totals);
		H5Gclose(nsg_task);
		H5Gclose(jg_totals);
		H5Gclose(jg_task);
	}
	H5Gclose(nsg_tasks);
}
Esempio n. 14
0
static void _extract_data()
{

	hid_t	fid_job, jgid_root, jgid_step, jgid_nodes,
		jgid_node, jgid_level;
	int	nsteps, nnodes, stepx, isx, len;
	char	jgrp_step_name[MAX_GROUP_NAME+1];
	char	jgrp_node_name[MAX_GROUP_NAME+1];
	bool    header;

	FILE* fp = fopen(params.output, "w");

	if (fp == NULL) {
		error("Failed to create output file %s -- %m",
		      params.output);
	}
	fid_job = H5Fopen(params.input, H5F_ACC_RDONLY, H5P_DEFAULT);
	if (fid_job < 0) {
		error("Failed to open %s", params.input);
		return;
	}
	jgid_root = H5Gopen(fid_job, "/", H5P_DEFAULT);
	if (jgid_root < 0) {
		H5Fclose(fid_job);
		error("Failed to open  root");
		return;
	}
	nsteps = get_int_attribute(jgid_root, ATTR_NSTEPS);
	for (stepx=0; stepx<nsteps; stepx++) {
		if ((params.step_id != -1) && (stepx != params.step_id))
			continue;
		sprintf(jgrp_step_name, "%s_%d", GRP_STEP, stepx);
		jgid_step = get_group(jgid_root, jgrp_step_name);
		if (jgid_step < 0) {
			error("Failed to open  group %s", jgrp_step_name);
			continue;
		}
		if (params.level && !strncasecmp(params.level, "Node:", 5)) {
			nnodes = get_int_attribute(jgid_step, ATTR_NNODES);
			jgid_nodes = get_group(jgid_step, GRP_NODES);
			if (jgid_nodes < 0) {
				H5Gclose(jgid_step);
				error("Failed to open  group %s", GRP_NODES);
				continue;
			}
			len = H5Lget_name_by_idx(jgid_nodes, ".", H5_INDEX_NAME,
						 H5_ITER_INC, 0, jgrp_node_name,
						 MAX_GROUP_NAME, H5P_DEFAULT);
			if ((len < 0) || (len > MAX_GROUP_NAME)) {
				H5Gclose(jgid_nodes);
				H5Gclose(jgid_step);
				error("Invalid node name %s", jgrp_node_name);
				continue;
			}
			jgid_node = get_group(jgid_nodes, jgrp_node_name);
			if (jgid_node < 0) {
				H5Gclose(jgid_nodes);
				H5Gclose(jgid_step);
				info("Failed to open group %s", jgrp_node_name);
				continue;
			}
			jgid_level = _get_series_parent(jgid_node);
			if (jgid_level == -1) {
				H5Gclose(jgid_node);
				H5Gclose(jgid_nodes);
				H5Gclose(jgid_step);
				continue;
			}
			_get_series_names(jgid_level);
			H5Gclose(jgid_level);
			H5Gclose(jgid_node);
			if (!params.series || !strcmp(params.series, "*")) {
				for (isx=0; isx<num_series; isx++) {
					_extract_node_level(
						fp, stepx, jgid_nodes,
						nnodes, true,
						series_names[isx]);
				}
			} else if (!strcmp(params.series, GRP_TASKS)) {
				header = true;
				for (isx=0; isx<num_series; isx++) {
					if (strstr(series_names[isx],
						   GRP_TASK)) {
						_extract_node_level(
							fp, stepx, jgid_nodes,
							nnodes, header,
							series_names[isx]);
						header = false;
					}
				}
			} else {
				_extract_node_level(fp, stepx, jgid_nodes,
						    nnodes, true,
						    params.series);
			}
			_delete_string_list(series_names, num_series);
			series_names = NULL;
			num_series = 0;
			H5Gclose(jgid_nodes);
		} else {
			error("%s is an illegal level", params.level);
		}
		H5Gclose(jgid_step);
	}
	H5Gclose(jgid_root);
	H5Fclose(fid_job);
	fclose(fp);

}
Esempio n. 15
0
void
TIFFInput::readspec ()
{
    uint32 width = 0, height = 0, depth = 0;
    unsigned short nchans = 1;
    TIFFGetField (m_tif, TIFFTAG_IMAGEWIDTH, &width);
    TIFFGetField (m_tif, TIFFTAG_IMAGELENGTH, &height);
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_IMAGEDEPTH, &depth);
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_SAMPLESPERPIXEL, &nchans);

    m_spec = ImageSpec ((int)width, (int)height, (int)nchans);

    float x = 0, y = 0;
    TIFFGetField (m_tif, TIFFTAG_XPOSITION, &x);
    TIFFGetField (m_tif, TIFFTAG_YPOSITION, &y);
    m_spec.x = (int)x;
    m_spec.y = (int)y;
    m_spec.z = 0;
    // FIXME? - TIFF spec describes the positions as in resolutionunit.
    // What happens if this is not unitless pixels?  Are we interpreting
    // it all wrong?

    if (TIFFGetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLWIDTH, &width) == 1
          && width > 0)
        m_spec.full_width = width;
    if (TIFFGetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLLENGTH, &height) == 1
          && height > 0)
        m_spec.full_height = height;

    if (TIFFIsTiled (m_tif)) {
        TIFFGetField (m_tif, TIFFTAG_TILEWIDTH, &m_spec.tile_width);
        TIFFGetField (m_tif, TIFFTAG_TILELENGTH, &m_spec.tile_height);
        TIFFGetFieldDefaulted (m_tif, TIFFTAG_TILEDEPTH, &m_spec.tile_depth);
    } else {
        m_spec.tile_width = 0;
        m_spec.tile_height = 0;
        m_spec.tile_depth = 0;
    }

    m_bitspersample = 8;
    TIFFGetField (m_tif, TIFFTAG_BITSPERSAMPLE, &m_bitspersample);
    m_spec.attribute ("oiio:BitsPerSample", (int)m_bitspersample);

    unsigned short sampleformat = SAMPLEFORMAT_UINT;
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_SAMPLEFORMAT, &sampleformat);
    switch (m_bitspersample) {
    case 1:
    case 2:
    case 4:
        // Make 1, 2, 4 bpp look like byte images
    case 8:
        if (sampleformat == SAMPLEFORMAT_UINT)
            m_spec.set_format (TypeDesc::UINT8);
        else if (sampleformat == SAMPLEFORMAT_INT)
            m_spec.set_format (TypeDesc::INT8);
        else m_spec.set_format (TypeDesc::UINT8);  // punt
        break;
    case 16:
        if (sampleformat == SAMPLEFORMAT_UINT)
            m_spec.set_format (TypeDesc::UINT16);
        else if (sampleformat == SAMPLEFORMAT_INT)
            m_spec.set_format (TypeDesc::INT16);
        break;
    case 32:
        if (sampleformat == SAMPLEFORMAT_IEEEFP)
            m_spec.set_format (TypeDesc::FLOAT);
        break;
    case 64:
        if (sampleformat == SAMPLEFORMAT_IEEEFP)
            m_spec.set_format (TypeDesc::DOUBLE);
        break;
    default:
        m_spec.set_format (TypeDesc::UNKNOWN);
        break;
    }

    // Use the table for all the obvious things that can be mindlessly
    // shoved into the image spec.
    for (int i = 0;  tiff_tag_table[i].name;  ++i)
        find_tag (tiff_tag_table[i].tifftag,
                  tiff_tag_table[i].tifftype, tiff_tag_table[i].name);

    // Now we need to get fields "by hand" for anything else that is less
    // straightforward...

    m_photometric = (m_spec.nchannels == 1 ? PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB);
    TIFFGetField (m_tif, TIFFTAG_PHOTOMETRIC, &m_photometric);
    m_spec.attribute ("tiff:PhotometricInterpretation", (int)m_photometric);
    if (m_photometric == PHOTOMETRIC_PALETTE) {
        // Read the color map
        unsigned short *r = NULL, *g = NULL, *b = NULL;
        TIFFGetField (m_tif, TIFFTAG_COLORMAP, &r, &g, &b);
        ASSERT (r != NULL && g != NULL && b != NULL);
        m_colormap.clear ();
        m_colormap.insert (m_colormap.end(), r, r + (1 << m_bitspersample));
        m_colormap.insert (m_colormap.end(), g, g + (1 << m_bitspersample));
        m_colormap.insert (m_colormap.end(), b, b + (1 << m_bitspersample));
        // Palette TIFF images are always 3 channels (to the client)
        m_spec.nchannels = 3;
        m_spec.default_channel_names ();
    }

    TIFFGetFieldDefaulted (m_tif, TIFFTAG_PLANARCONFIG, &m_planarconfig);
    m_spec.attribute ("tiff:PlanarConfiguration", (int)m_planarconfig);
    if (m_planarconfig == PLANARCONFIG_SEPARATE)
        m_spec.attribute ("planarconfig", "separate");
    else
        m_spec.attribute ("planarconfig", "contig");

    int compress = 0;
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_COMPRESSION, &compress);
    m_spec.attribute ("tiff:Compression", compress);
    switch (compress) {
    case COMPRESSION_NONE :
        m_spec.attribute ("compression", "none");
        break;
    case COMPRESSION_LZW :
        m_spec.attribute ("compression", "lzw");
        break;
    case COMPRESSION_CCITTRLE :
        m_spec.attribute ("compression", "ccittrle");
        break;
    case COMPRESSION_DEFLATE :
    case COMPRESSION_ADOBE_DEFLATE :
        m_spec.attribute ("compression", "zip");
        break;
    case COMPRESSION_PACKBITS :
        m_spec.attribute ("compression", "packbits");
        break;
    default:
        break;
    }

    int rowsperstrip = -1;
    if (! m_spec.tile_width) {
        TIFFGetField (m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
        if (rowsperstrip > 0)
            m_spec.attribute ("tiff:RowsPerStrip", rowsperstrip);
    }

    // The libtiff docs say that only uncompressed images, or those with
    // rowsperstrip==1, support random access to scanlines.
    m_no_random_access = (compress != COMPRESSION_NONE && rowsperstrip != 1);

    short resunit = -1;
    TIFFGetField (m_tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
    switch (resunit) {
    case RESUNIT_NONE : m_spec.attribute ("ResolutionUnit", "none"); break;
    case RESUNIT_INCH : m_spec.attribute ("ResolutionUnit", "in"); break;
    case RESUNIT_CENTIMETER : m_spec.attribute ("ResolutionUnit", "cm"); break;
    }

    get_matrix_attribute ("worldtocamera", TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA);
    get_matrix_attribute ("worldtoscreen", TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN);
    get_int_attribute ("tiff:subfiletype", TIFFTAG_SUBFILETYPE);
    // FIXME -- should subfiletype be "conventionized" and used for all
    // plugins uniformly? 

    // FIXME: do we care about fillorder for 1-bit and 4-bit images?

    // Special names for shadow maps
    char *s = NULL;
    TIFFGetField (m_tif, TIFFTAG_PIXAR_TEXTUREFORMAT, &s);
    if (s)
        m_emulate_mipmap = true;
    if (s && ! strcmp (s, "Shadow")) {
        for (int c = 0;  c < m_spec.nchannels;  ++c)
            m_spec.channelnames[c] = "z";
    }

    // N.B. we currently ignore the following TIFF fields:
    // ExtraSamples
    // GrayResponseCurve GrayResponseUnit
    // MaxSampleValue MinSampleValue
    // NewSubfileType SubfileType(deprecated)
    // Colorimetry fields

    // Search for an EXIF IFD in the TIFF file, and if found, rummage 
    // around for Exif fields.
#if TIFFLIB_VERSION > 20050912    /* compat with old TIFF libs - skip Exif */
    int exifoffset = 0;
    if (TIFFGetField (m_tif, TIFFTAG_EXIFIFD, &exifoffset) &&
            TIFFReadEXIFDirectory (m_tif, exifoffset)) {
        for (int i = 0;  exif_tag_table[i].name;  ++i)
            find_tag (exif_tag_table[i].tifftag, exif_tag_table[i].tifftype,
                      exif_tag_table[i].name);
        // I'm not sure what state TIFFReadEXIFDirectory leaves us.
        // So to be safe, close and re-seek.
        TIFFClose (m_tif);
        m_tif = TIFFOpen (m_filename.c_str(), "rm");
        TIFFSetDirectory (m_tif, m_subimage);

        // A few tidbits to look for
        ImageIOParameter *p;
        if ((p = m_spec.find_attribute ("Exif:ColorSpace", TypeDesc::INT))) {
            // Exif spec says that anything other than 0xffff==uncalibrated
            // should be interpreted to be sRGB.
            if (*(const int *)p->data() != 0xffff)
                m_spec.attribute ("oiio::ColorSpace", "sRGB");
        }
    }
#endif

#if TIFFLIB_VERSION >= 20051230
    // Search for IPTC metadata in IIM form -- but older versions of
    // libtiff botch the size, so ignore it for very old libtiff.
    int iptcsize = 0;
    const void *iptcdata = NULL;
    if (TIFFGetField (m_tif, TIFFTAG_RICHTIFFIPTC, &iptcsize, &iptcdata)) {
        std::vector<uint32> iptc ((uint32 *)iptcdata, (uint32 *)iptcdata+iptcsize);
        if (TIFFIsByteSwapped (m_tif))
            TIFFSwabArrayOfLong ((uint32*)&iptc[0], iptcsize);
        decode_iptc_iim (&iptc[0], iptcsize*4, m_spec);
    }
#endif

    // Search for an XML packet containing XMP (IPTC, Exif, etc.)
    int xmlsize = 0;
    const void *xmldata = NULL;
    if (TIFFGetField (m_tif, TIFFTAG_XMLPACKET, &xmlsize, &xmldata)) {
        // std::cerr << "Found XML data, size " << xmlsize << "\n";
        if (xmldata && xmlsize) {
            std::string xml ((const char *)xmldata, xmlsize);
            decode_xmp (xml, m_spec);
        }
    }

#if 0
    // Experimental -- look for photoshop data
    int photoshopsize = 0;
    const void *photoshopdata = NULL;
    if (TIFFGetField (m_tif, TIFFTAG_PHOTOSHOP, &photoshopsize, &photoshopdata)) {
        std::cerr << "Found PHOTOSHOP data, size " << photoshopsize << "\n";
        if (photoshopdata && photoshopsize) {
//            std::string photoshop ((const char *)photoshopdata, photoshopsize);
//            std::cerr << "PHOTOSHOP:\n" << photoshop << "\n---\n";
        }
    }
#endif
}
Esempio n. 16
0
static void _get_all_task_series(FILE *fp, bool hd, hid_t jgid_step, int stepx)
{

	hid_t	jgid_tasks, jgid_task = 0, jgid_nodes, jgid_node;
	H5G_info_t group_info;
	int	ntasks,itx, tid;
	uint64_t *task_id;
	char     **task_node_name;	/* Node Name for each task */
	char     **tod = NULL;  /* Date time at each sample */
	char     **series_name;	/* Node Names */
	double **all_series;	/* Pointers to all sampled for each node */
	double *et = NULL;	/* Elapsed time at each sample */
	uint64_t *series_smp;   /* Number of samples in this series */
	int	nnodes, ndx, len, nsmp = 0, nitem = -1;
	char	jgrp_node_name[MAX_GROUP_NAME+1];
	char	jgrp_task_name[MAX_GROUP_NAME+1];
	char	buf[MAX_GROUP_NAME+1];
	void*   series_data = NULL;
	hdf5_api_ops_t* ops;

	jgid_nodes = get_group(jgid_step, GRP_NODES);
	if (jgid_nodes < 0)
		fatal("Failed to open  group %s", GRP_NODES);
	jgid_tasks = get_group(jgid_step, GRP_TASKS);
	if (jgid_tasks < 0)
		fatal("No tasks in step %d", stepx);
	H5Gget_info(jgid_tasks, &group_info);
	ntasks = (int) group_info.nlinks;
	if (ntasks <= 0)
		fatal("No tasks in step %d", stepx);
	task_id = xmalloc(ntasks*sizeof(uint64_t));
	if (task_id == NULL)
		fatal("Failed to get memory for task_ids");
	task_node_name = xmalloc(ntasks*sizeof(char*));
	if (task_node_name == NULL)
		fatal("Failed to get memory for task_node_names");

	for (itx = 0; itx<ntasks; itx++) {
		// Get the name of the group.
		len = H5Lget_name_by_idx(jgid_tasks, ".", H5_INDEX_NAME,
		                         H5_ITER_INC, itx, buf, MAX_GROUP_NAME,
		                         H5P_DEFAULT);
		if ((len > 0) && (len < MAX_GROUP_NAME)) {
			jgid_task = H5Gopen(jgid_tasks, buf, H5P_DEFAULT);
			if (jgid_task < 0)
				fatal("Failed to open %s", buf);
		} else
			fatal("Illegal task name %s",buf);
		task_id[itx] = get_int_attribute(jgid_task, ATTR_TASKID);
		task_node_name[itx] = get_string_attribute(jgid_task,
		                                           ATTR_NODENAME);
		H5Gclose(jgid_task);
	}
	H5Gclose(jgid_tasks);

	nnodes = get_int_attribute(jgid_step, ATTR_NNODES);
	// allocate node arrays
	series_smp = (uint64_t*) xmalloc(ntasks*(sizeof(uint64_t)));
	if (series_smp == NULL) {
		fatal("Failed to get memory for node_samples");
		return; /* Fix for CLANG false positive */
	}
	series_name = (char**) xmalloc(ntasks*(sizeof(char*)));
	if (series_name == NULL) {
		fatal("Failed to get memory for series_name");
		return; /* Fix for CLANG false positive */
	}
	all_series = (double**) xmalloc(ntasks*(sizeof(double*)));
	if (all_series == NULL) {
		fatal("Failed to get memory for all_series");
		return; /* Fix for CLANG false positive */
	}

	for (ndx=0; ndx<nnodes; ndx++) {

		len = H5Lget_name_by_idx(jgid_nodes, ".", H5_INDEX_NAME,
		                         H5_ITER_INC, ndx, jgrp_node_name,
		                         MAX_GROUP_NAME, H5P_DEFAULT);
		if ((len < 0) || (len > MAX_GROUP_NAME))
			fatal("Invalid node name=%s", jgrp_node_name);
		jgid_node = get_group(jgid_nodes, jgrp_node_name);

		if (jgid_node < 0)
			fatal("Failed to open group %s", jgrp_node_name);
		for (itx = 0; itx<ntasks; itx++) {
			if (strcmp(jgrp_node_name, task_node_name[itx]) != 0)
				continue;
			tid = task_id[itx];
			series_name[itx] = xstrdup_printf("%s_%d %s",
			                                  GRP_TASK,tid,jgrp_node_name);
			sprintf(jgrp_task_name,"%s_%d",GRP_TASK, tid);

			ops = NULL;
			nitem = 0;
			series_data = _get_series_data(jgid_node,
			                               jgrp_task_name, &ops, &nitem);
			if (series_data==NULL || nitem==0 || ops==NULL) {
				if (ops != NULL)
					xfree(ops);
				continue;
			}
			all_series[itx] = ops->get_series_values(
				params.data_item, series_data, nitem);
			if (!all_series[ndx])
				fatal("No data item %s",params.data_item);
			series_smp[itx] = nitem;
			if (nsmp == 0) {
				nsmp = nitem;
				tod = ops->get_series_tod(series_data, nitem);
				et = ops->get_series_values("time",
				                            series_data, nitem);
			} else {
				if (nitem > nsmp) {
					// new largest number of samples
					_delete_string_list(tod, nsmp);
					xfree(et);
					nsmp = nitem;
					tod = ops->get_series_tod(series_data,
					                          nitem);
					et = ops->get_series_values("time",
					                            series_data, nitem);
				}
			}
			xfree(ops);
			xfree(series_data);
		}
		H5Gclose(jgid_node);
	}
	if (nsmp == 0) {
		// May be bad series name
		info("No values %s for series %s found in step %d",
		     params.data_item,params.series,
		     stepx);
	} else {
		_series_analysis(fp, hd, stepx, ntasks, nsmp,
		                 series_name, tod, et, all_series, series_smp);
	}
	for (itx=0; itx<ntasks; itx++) {
		xfree(all_series[itx]);
	}
	xfree(series_name);
	xfree(all_series);
	xfree(series_smp);
	_delete_string_list(tod, nsmp);
	xfree(et);
	_delete_string_list(task_node_name, ntasks);
	xfree(task_id);

	H5Gclose(jgid_nodes);
}
Esempio n. 17
0
/* Add a key to the key source from an LDAP entry */
static void
search_parse_key_from_ldap_entry (SeahorseLDAPSource *self,
                                  GcrSimpleCollection *results,
                                  LDAP *ldap,
                                  LDAPMessage *res)
{
	const gchar *algo;
	long int timestamp;
	long int expires;
	gchar *fpr, *fingerprint;
	gchar *uidstr;
	gboolean revoked;
	gboolean disabled;
	int length;

	g_return_if_fail (ldap_msgtype (res) == LDAP_RES_SEARCH_ENTRY);

	fpr = get_string_attribute (ldap, res, "pgpcertid");
	uidstr = get_string_attribute (ldap, res, "pgpuserid");
	revoked = get_boolean_attribute (ldap, res, "pgprevoked");
	disabled = get_boolean_attribute (ldap, res, "pgpdisabled");
	timestamp = get_date_attribute (ldap, res, "pgpkeycreatetime");
	expires = get_date_attribute (ldap, res, "pgpkeyexpiretime");
	algo = get_algo_attribute (ldap, res, "pgpkeytype");
	length = get_int_attribute (ldap, res, "pgpkeysize");

	if (fpr && uidstr) {
		SeahorsePgpSubkey *subkey;
		SeahorsePgpKey *key;
		SeahorsePgpUid *uid;
		GList *list;
		guint flags;

		/* Build up a subkey */
		subkey = seahorse_pgp_subkey_new ();
		seahorse_pgp_subkey_set_keyid (subkey, fpr);
		fingerprint = seahorse_pgp_subkey_calc_fingerprint (fpr);
		seahorse_pgp_subkey_set_fingerprint (subkey, fingerprint);
		g_free (fingerprint);
		seahorse_pgp_subkey_set_created (subkey, timestamp);
		seahorse_pgp_subkey_set_expires (subkey, expires);
		seahorse_pgp_subkey_set_algorithm (subkey, algo);
		seahorse_pgp_subkey_set_length (subkey, length);

		flags = SEAHORSE_FLAG_EXPORTABLE;
		if (revoked)
			flags |= SEAHORSE_FLAG_REVOKED;
		if (disabled)
			flags |= SEAHORSE_FLAG_DISABLED;
		seahorse_pgp_subkey_set_flags (subkey, flags);

		key = seahorse_pgp_key_new ();

		/* Build up a uid */
		uid = seahorse_pgp_uid_new (key, uidstr);
		if (revoked)
			seahorse_pgp_uid_set_validity (uid, SEAHORSE_VALIDITY_REVOKED);

		/* Now build them into a key */
		list = g_list_prepend (NULL, uid);
		seahorse_pgp_key_set_uids (key, list);
		seahorse_object_list_free (list);
		list = g_list_prepend (NULL, subkey);
		seahorse_pgp_key_set_subkeys (key, list);
		seahorse_object_list_free (list);
		g_object_set (key,
		              "object-flags", flags,
		              "place", self,
		              NULL);

		seahorse_pgp_key_realize (key);
		gcr_simple_collection_add (results, G_OBJECT (key));
		g_object_unref (key);
	}

	g_free (fpr);
	g_free (uidstr);
}
Esempio n. 18
0
void
TIFFInput::readspec (bool read_meta)
{
    uint32 width = 0, height = 0, depth = 0;
    unsigned short nchans = 1;
    TIFFGetField (m_tif, TIFFTAG_IMAGEWIDTH, &width);
    TIFFGetField (m_tif, TIFFTAG_IMAGELENGTH, &height);
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_IMAGEDEPTH, &depth);
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_SAMPLESPERPIXEL, &nchans);

    if (read_meta) {
        // clear the whole m_spec and start fresh
        m_spec = ImageSpec ((int)width, (int)height, (int)nchans);
    } else {
        // assume m_spec is valid, except for things that might differ
        // between MIP levels
        m_spec.width = (int)width;
        m_spec.height = (int)height;
        m_spec.depth = (int)depth;
        m_spec.full_x = 0;
        m_spec.full_y = 0;
        m_spec.full_z = 0;
        m_spec.full_width = (int)width;
        m_spec.full_height = (int)height;
        m_spec.full_depth = (int)depth;
        m_spec.nchannels = (int)nchans;
    }

    float x = 0, y = 0;
    TIFFGetField (m_tif, TIFFTAG_XPOSITION, &x);
    TIFFGetField (m_tif, TIFFTAG_YPOSITION, &y);
    m_spec.x = (int)x;
    m_spec.y = (int)y;
    m_spec.z = 0;
    // FIXME? - TIFF spec describes the positions as in resolutionunit.
    // What happens if this is not unitless pixels?  Are we interpreting
    // it all wrong?

    if (TIFFGetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLWIDTH, &width) == 1
          && width > 0)
        m_spec.full_width = width;
    if (TIFFGetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLLENGTH, &height) == 1
          && height > 0)
        m_spec.full_height = height;

    if (TIFFIsTiled (m_tif)) {
        TIFFGetField (m_tif, TIFFTAG_TILEWIDTH, &m_spec.tile_width);
        TIFFGetField (m_tif, TIFFTAG_TILELENGTH, &m_spec.tile_height);
        TIFFGetFieldDefaulted (m_tif, TIFFTAG_TILEDEPTH, &m_spec.tile_depth);
    } else {
        m_spec.tile_width = 0;
        m_spec.tile_height = 0;
        m_spec.tile_depth = 0;
    }

    m_bitspersample = 8;
    TIFFGetField (m_tif, TIFFTAG_BITSPERSAMPLE, &m_bitspersample);
    m_spec.attribute ("oiio:BitsPerSample", (int)m_bitspersample);

    unsigned short sampleformat = SAMPLEFORMAT_UINT;
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_SAMPLEFORMAT, &sampleformat);
    switch (m_bitspersample) {
    case 1:
    case 2:
    case 4:
    case 6:
        // Make 1, 2, 4, 6 bpp look like byte images
    case 8:
        if (sampleformat == SAMPLEFORMAT_UINT)
            m_spec.set_format (TypeDesc::UINT8);
        else if (sampleformat == SAMPLEFORMAT_INT)
            m_spec.set_format (TypeDesc::INT8);
        else m_spec.set_format (TypeDesc::UINT8);  // punt
        break;
    case 10:
    case 12:
    case 14:
        // Make 10, 12, 14 bpp look like 16 bit images
    case 16:
        if (sampleformat == SAMPLEFORMAT_UINT)
            m_spec.set_format (TypeDesc::UINT16);
        else if (sampleformat == SAMPLEFORMAT_INT)
            m_spec.set_format (TypeDesc::INT16);
        else if (sampleformat == SAMPLEFORMAT_IEEEFP)
            m_spec.set_format (TypeDesc::HALF); // not to spec, but why not?
        else
            m_spec.set_format (TypeDesc::UNKNOWN);
        break;
    case 32:
        if (sampleformat == SAMPLEFORMAT_IEEEFP)
            m_spec.set_format (TypeDesc::FLOAT);
        else if (sampleformat == SAMPLEFORMAT_UINT)
            m_spec.set_format (TypeDesc::UINT32);
        else if (sampleformat == SAMPLEFORMAT_INT)
            m_spec.set_format (TypeDesc::INT32);
        else
            m_spec.set_format (TypeDesc::UNKNOWN);
        break;
    case 64:
        if (sampleformat == SAMPLEFORMAT_IEEEFP)
            m_spec.set_format (TypeDesc::DOUBLE);
        else
            m_spec.set_format (TypeDesc::UNKNOWN);
        break;
    default:
        m_spec.set_format (TypeDesc::UNKNOWN);
        break;
    }

    // If we've been instructed to skip reading metadata, because it is
    // guaranteed to be identical to what we already have in m_spec,
    // skip everything following.
    if (! read_meta)
        return;

    // Use the table for all the obvious things that can be mindlessly
    // shoved into the image spec.
    for (int i = 0;  tiff_tag_table[i].name;  ++i)
        find_tag (tiff_tag_table[i].tifftag,
                  tiff_tag_table[i].tifftype, tiff_tag_table[i].name);

    // Now we need to get fields "by hand" for anything else that is less
    // straightforward...

    m_photometric = (m_spec.nchannels == 1 ? PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB);
    TIFFGetField (m_tif, TIFFTAG_PHOTOMETRIC, &m_photometric);
    m_spec.attribute ("tiff:PhotometricInterpretation", (int)m_photometric);
    if (m_photometric == PHOTOMETRIC_PALETTE) {
        // Read the color map
        unsigned short *r = NULL, *g = NULL, *b = NULL;
        TIFFGetField (m_tif, TIFFTAG_COLORMAP, &r, &g, &b);
        ASSERT (r != NULL && g != NULL && b != NULL);
        m_colormap.clear ();
        m_colormap.insert (m_colormap.end(), r, r + (1 << m_bitspersample));
        m_colormap.insert (m_colormap.end(), g, g + (1 << m_bitspersample));
        m_colormap.insert (m_colormap.end(), b, b + (1 << m_bitspersample));
        // Palette TIFF images are always 3 channels (to the client)
        m_spec.nchannels = 3;
        m_spec.default_channel_names ();
        // FIXME - what about palette + extra (alpha?) channels?  Is that
        // allowed?  And if so, ever encountered in the wild?
    }

    TIFFGetFieldDefaulted (m_tif, TIFFTAG_PLANARCONFIG, &m_planarconfig);
    m_separate = (m_planarconfig == PLANARCONFIG_SEPARATE &&
                  m_spec.nchannels > 1 &&
                  m_photometric != PHOTOMETRIC_PALETTE);
    m_spec.attribute ("tiff:PlanarConfiguration", (int)m_planarconfig);
    if (m_planarconfig == PLANARCONFIG_SEPARATE)
        m_spec.attribute ("planarconfig", "separate");
    else
        m_spec.attribute ("planarconfig", "contig");

    int compress = 0;
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_COMPRESSION, &compress);
    m_spec.attribute ("tiff:Compression", compress);
    switch (compress) {
    case COMPRESSION_NONE :
        m_spec.attribute ("compression", "none");
        break;
    case COMPRESSION_LZW :
        m_spec.attribute ("compression", "lzw");
        break;
    case COMPRESSION_CCITTRLE :
        m_spec.attribute ("compression", "ccittrle");
        break;
    case COMPRESSION_DEFLATE :
    case COMPRESSION_ADOBE_DEFLATE :
        m_spec.attribute ("compression", "zip");
        break;
    case COMPRESSION_PACKBITS :
        m_spec.attribute ("compression", "packbits");
        break;
    default:
        break;
    }

    int rowsperstrip = -1;
    if (! m_spec.tile_width) {
        TIFFGetField (m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
        if (rowsperstrip > 0)
            m_spec.attribute ("tiff:RowsPerStrip", rowsperstrip);
    }

    // The libtiff docs say that only uncompressed images, or those with
    // rowsperstrip==1, support random access to scanlines.
    m_no_random_access = (compress != COMPRESSION_NONE && rowsperstrip != 1);

    short resunit = -1;
    TIFFGetField (m_tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
    switch (resunit) {
    case RESUNIT_NONE : m_spec.attribute ("ResolutionUnit", "none"); break;
    case RESUNIT_INCH : m_spec.attribute ("ResolutionUnit", "in"); break;
    case RESUNIT_CENTIMETER : m_spec.attribute ("ResolutionUnit", "cm"); break;
    }

    get_matrix_attribute ("worldtocamera", TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA);
    get_matrix_attribute ("worldtoscreen", TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN);
    get_int_attribute ("tiff:subfiletype", TIFFTAG_SUBFILETYPE);
    // FIXME -- should subfiletype be "conventionized" and used for all
    // plugins uniformly? 

    // Do we care about fillorder?  No, the TIFF spec says, "We
    // recommend that FillOrder=2 (lsb-to-msb) be used only in
    // special-purpose applications".  So OIIO will assume msb-to-lsb
    // convention until somebody finds a TIFF file in the wild that
    // breaks this assumption.

    // Special names for shadow maps
    char *s = NULL;
    TIFFGetField (m_tif, TIFFTAG_PIXAR_TEXTUREFORMAT, &s);
    if (s)
        m_emulate_mipmap = true;
    if (s && ! strcmp (s, "Shadow")) {
        for (int c = 0;  c < m_spec.nchannels;  ++c)
            m_spec.channelnames[c] = "z";
    }

    unsigned short *sampleinfo = NULL;
    unsigned short extrasamples = 0;
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo);
    // std::cerr << "Extra samples = " << extrasamples << "\n";
    bool alpha_is_unassociated = false;  // basic assumption
    if (extrasamples) {
        // If the TIFF ExtraSamples tag was specified, use that to figure
        // out the meaning of alpha.
        int colorchannels = 3;
        if (m_photometric == PHOTOMETRIC_MINISWHITE ||
              m_photometric == PHOTOMETRIC_MINISBLACK ||
              m_photometric == PHOTOMETRIC_PALETTE ||
              m_photometric == PHOTOMETRIC_MASK)
            colorchannels = 1;
        for (int i = 0, c = colorchannels;
             i < extrasamples && c < m_spec.nchannels;  ++i, ++c) {
            // std::cerr << "   extra " << i << " " << sampleinfo[i] << "\n";
            if (sampleinfo[i] == EXTRASAMPLE_ASSOCALPHA) {
                // This is the alpha channel, associated as usual
                m_spec.alpha_channel = c;
            } else if (sampleinfo[i] == EXTRASAMPLE_UNASSALPHA) {
                // This is the alpha channel, but color is unassociated
                m_spec.alpha_channel = c;
                alpha_is_unassociated = true;
                m_spec.attribute ("oiio:UnassociatedAlpha", 1);
            } else {
                DASSERT (sampleinfo[i] == EXTRASAMPLE_UNSPECIFIED);
                // This extra channel is not alpha at all.  Undo any
                // assumptions we previously made about this channel.
                if (m_spec.alpha_channel == c) {
                    m_spec.channelnames[c] = Strutil::format("channel%d", c);
                    m_spec.alpha_channel = -1;
                }
            }
        }
        if (m_spec.alpha_channel >= 0)
            m_spec.channelnames[m_spec.alpha_channel] = "A";
    }
    // Will we need to do alpha conversions?
    m_convert_alpha = (m_spec.alpha_channel >= 0 && alpha_is_unassociated &&
                       ! m_keep_unassociated_alpha);

    // N.B. we currently ignore the following TIFF fields:
    // GrayResponseCurve GrayResponseUnit
    // MaxSampleValue MinSampleValue
    // NewSubfileType SubfileType(deprecated)
    // Colorimetry fields

    // Search for an EXIF IFD in the TIFF file, and if found, rummage 
    // around for Exif fields.
#if TIFFLIB_VERSION > 20050912    /* compat with old TIFF libs - skip Exif */
    int exifoffset = 0;
    if (TIFFGetField (m_tif, TIFFTAG_EXIFIFD, &exifoffset) &&
            TIFFReadEXIFDirectory (m_tif, exifoffset)) {
        for (int i = 0;  exif_tag_table[i].name;  ++i)
            find_tag (exif_tag_table[i].tifftag, exif_tag_table[i].tifftype,
                      exif_tag_table[i].name);
        // I'm not sure what state TIFFReadEXIFDirectory leaves us.
        // So to be safe, close and re-seek.
        TIFFClose (m_tif);
#ifdef _WIN32
        std::wstring wfilename = Filesystem::path_to_windows_native (m_filename);
        m_tif = TIFFOpenW (wfilename.c_str(), "rm");
#else
        m_tif = TIFFOpen (m_filename.c_str(), "rm");
#endif
        TIFFSetDirectory (m_tif, m_subimage);

        // A few tidbits to look for
        ImageIOParameter *p;
        if ((p = m_spec.find_attribute ("Exif:ColorSpace", TypeDesc::INT))) {
            // Exif spec says that anything other than 0xffff==uncalibrated
            // should be interpreted to be sRGB.
            if (*(const int *)p->data() != 0xffff)
                m_spec.attribute ("oiio::ColorSpace", "sRGB");
        }
    }
#endif

#if TIFFLIB_VERSION >= 20051230
    // Search for IPTC metadata in IIM form -- but older versions of
    // libtiff botch the size, so ignore it for very old libtiff.
    int iptcsize = 0;
    const void *iptcdata = NULL;
    if (TIFFGetField (m_tif, TIFFTAG_RICHTIFFIPTC, &iptcsize, &iptcdata)) {
        std::vector<uint32> iptc ((uint32 *)iptcdata, (uint32 *)iptcdata+iptcsize);
        if (TIFFIsByteSwapped (m_tif))
            TIFFSwabArrayOfLong ((uint32*)&iptc[0], iptcsize);
        decode_iptc_iim (&iptc[0], iptcsize*4, m_spec);
    }
#endif

    // Search for an XML packet containing XMP (IPTC, Exif, etc.)
    int xmlsize = 0;
    const void *xmldata = NULL;
    if (TIFFGetField (m_tif, TIFFTAG_XMLPACKET, &xmlsize, &xmldata)) {
        // std::cerr << "Found XML data, size " << xmlsize << "\n";
        if (xmldata && xmlsize) {
            std::string xml ((const char *)xmldata, xmlsize);
            decode_xmp (xml, m_spec);
        }
    }

#if 0
    // Experimental -- look for photoshop data
    int photoshopsize = 0;
    const void *photoshopdata = NULL;
    if (TIFFGetField (m_tif, TIFFTAG_PHOTOSHOP, &photoshopsize, &photoshopdata)) {
        std::cerr << "Found PHOTOSHOP data, size " << photoshopsize << "\n";
        if (photoshopdata && photoshopsize) {
//            std::string photoshop ((const char *)photoshopdata, photoshopsize);
//            std::cerr << "PHOTOSHOP:\n" << photoshop << "\n---\n";
        }
    }
#endif
}