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; }
/** * 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; }
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); }
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 */ } }
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; }
// 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); }
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(); } }
/** * 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; }
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); }
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); }
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); }
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 }
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); }
/* 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); }
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 }