static gint gxsm_detect(const GwyFileDetectInfo *fileinfo, gboolean only_name) { NetCDF cdffile; const guchar *p; gint score; if (only_name) return g_str_has_suffix(fileinfo->name_lowercase, EXTENSION) ? 10 : 0; /* Weed out non-netCDF files quickly */ if (fileinfo->buffer_len < MAGIC_SIZE || (memcmp(fileinfo->head, MAGIC1, MAGIC_SIZE) != 0 && memcmp(fileinfo->head, MAGIC2, MAGIC_SIZE) != 0)) return 0; score = 0; gwy_clear(&cdffile, 1); p = fileinfo->head + MAGIC_SIZE; cdffile.nrecs = gwy_get_guint32_be(&p); if (cdffile_read_dim_array(&cdffile.dims, &cdffile.ndims, fileinfo->head, fileinfo->buffer_len-1, &p, NULL)) { if (cdffile_get_dim(&cdffile, "dimx") && cdffile_get_dim(&cdffile, "dimy")) score = 80; } cdffile_free(&cdffile); return score; }
static gboolean read_qt_string(const guchar **p, gsize *size, gchar **value) { const gunichar2 *utf16native; gunichar2 *must_free; guint len; *value = NULL; if (*size < sizeof(guint32)) return FALSE; len = gwy_get_guint32_be(p); *size -= sizeof(guint32); gwy_debug("QString length: %u", len); if (*size < len || len % sizeof(gunichar2)) return FALSE; if (!len) { *value = g_strdup(""); return TRUE; } if (G_BYTE_ORDER == G_BIG_ENDIAN) { utf16native = (const gunichar2*)(*p); must_free = NULL; } else if (G_BYTE_ORDER == G_LITTLE_ENDIAN) { utf16native = must_free = g_new(gunichar2, len/sizeof(gunichar2)); swab(*p, (gpointer)must_free, len); } *value = g_utf16_to_utf8(utf16native, len/sizeof(gunichar2), NULL, NULL, NULL); gwy_debug("QString data: <%s>", *value); g_free(must_free); *size -= len; *p += len; return TRUE; }
static gboolean mprofile_read_header(const guchar *buffer, gsize size, MProFile *mprofile, GError **error) { const guchar *p; guint i; p = buffer; if (size < HEADER_SIZE + 2) { err_TOO_SHORT(error); return FALSE; } get_CHARARRAY(mprofile->magic, &p); if (memcmp(mprofile->magic, MAGIC, MAGIC_SIZE) != 0) { err_FILE_TYPE(error, "MetroPro"); return FALSE; } mprofile->header_format = gwy_get_guint16_be(&p); if (mprofile->header_format != 1) { err_UNSUPPORTED(error, "FormatVersion"); return FALSE; } mprofile->header_size = gwy_get_guint32_be(&p); gwy_debug("header_format: %d, header_size: %d", mprofile->header_format, mprofile->header_size); if (mprofile->header_size < 570) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is too short.")); return FALSE; } if (mprofile->header_size > size) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is larger than file.")); return FALSE; } mprofile->software_type = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->software_date, &p); gwy_debug("software_type: %d, software_date: %s", mprofile->software_type, mprofile->software_date); mprofile->version_major = gwy_get_guint16_be(&p); mprofile->version_minor = gwy_get_guint16_be(&p); mprofile->version_micro = gwy_get_guint16_be(&p); gwy_debug("version: %d.%d.%d", mprofile->version_major, mprofile->version_minor, mprofile->version_micro); mprofile->intens_xoff = gwy_get_guint16_be(&p); mprofile->intens_yoff = gwy_get_guint16_be(&p); mprofile->intens_xres = gwy_get_guint16_be(&p); mprofile->intens_yres = gwy_get_guint16_be(&p); gwy_debug("INTENS xres: %d, yres: %d, xoff: %d, yoff: %d", mprofile->intens_xres, mprofile->intens_yres, mprofile->intens_xoff, mprofile->intens_yoff); mprofile->nbuckets = gwy_get_guint16_be(&p); mprofile->intens_range = gwy_get_guint16_be(&p); mprofile->intens_nbytes = gwy_get_guint32_be(&p); gwy_debug("intens_nbytes: %d, expecting: %d", mprofile->intens_nbytes, 2*mprofile->intens_xres*mprofile->intens_yres*mprofile->nbuckets); mprofile->phase_xoff = gwy_get_guint16_be(&p); mprofile->phase_yoff = gwy_get_guint16_be(&p); mprofile->phase_xres = gwy_get_guint16_be(&p); mprofile->phase_yres = gwy_get_guint16_be(&p); gwy_debug("PHASE xres: %d, yres: %d, xoff: %d, yoff: %d", mprofile->phase_xres, mprofile->phase_yres, mprofile->phase_xoff, mprofile->phase_yoff); mprofile->phase_nbytes = gwy_get_guint32_be(&p); gwy_debug("phase_nbytes: %d, expecting: %d", mprofile->phase_nbytes, 4*mprofile->phase_xres*mprofile->phase_yres); mprofile->timestamp = gwy_get_guint32_be(&p); get_CHARARRAY0(mprofile->comment, &p); gwy_debug("comment: %s", mprofile->comment); mprofile->source = gwy_get_guint16_be(&p); mprofile->scale_factor = gwy_get_gfloat_be(&p); mprofile->wavelength_in = gwy_get_gfloat_be(&p); mprofile->numeric_aperture = gwy_get_gfloat_be(&p); mprofile->obliquity_factor = gwy_get_gfloat_be(&p); mprofile->magnification = gwy_get_gfloat_be(&p); mprofile->camera_res = gwy_get_gfloat_be(&p); mprofile->acquire_mode = gwy_get_guint16_be(&p); gwy_debug("acquire_mode: %d", mprofile->acquire_mode); mprofile->intens_avgs = gwy_get_guint16_be(&p); if (!mprofile->intens_avgs) mprofile->intens_avgs = 1; mprofile->pzt_cal = gwy_get_guint16_be(&p); mprofile->pzt_gain_tolerance = gwy_get_guint16_be(&p); mprofile->pzt_gain = gwy_get_guint16_be(&p); mprofile->part_thickness = gwy_get_gfloat_be(&p); mprofile->agc = gwy_get_guint16_be(&p); mprofile->target_range = gwy_get_gfloat_be(&p); p += 2; mprofile->min_mod = gwy_get_guint32_be(&p); mprofile->min_mod_pts = gwy_get_guint32_be(&p); mprofile->phase_res = gwy_get_guint16_be(&p); mprofile->min_area_size = gwy_get_guint32_be(&p); mprofile->discont_action = gwy_get_guint16_be(&p); mprofile->discont_filter = gwy_get_gfloat_be(&p); mprofile->connection_order = gwy_get_guint16_be(&p); mprofile->data_inverted = gwy_get_guint16_be(&p); mprofile->camera_width = gwy_get_guint16_be(&p); mprofile->camera_height = gwy_get_guint16_be(&p); mprofile->system_type = gwy_get_guint16_be(&p); mprofile->system_board = gwy_get_guint16_be(&p); mprofile->system_serial = gwy_get_guint16_be(&p); mprofile->instrument_id = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->objective_name, &p); get_CHARARRAY0(mprofile->part_num, &p); gwy_debug("part_num: %s", mprofile->part_num); mprofile->code_vtype = gwy_get_guint16_be(&p); mprofile->phase_avgs = gwy_get_guint16_be(&p); mprofile->subtract_sys_err = gwy_get_guint16_be(&p); p += 16; get_CHARARRAY0(mprofile->part_ser_num, &p); mprofile->refactive_index = gwy_get_gfloat_be(&p); mprofile->remove_tilt_bias = gwy_get_guint16_be(&p); mprofile->remove_fringes = gwy_get_guint16_be(&p); mprofile->max_area_size = gwy_get_guint32_be(&p); mprofile->setup_type = gwy_get_guint16_be(&p); p += 2; mprofile->pre_connect_filter = gwy_get_gfloat_be(&p); mprofile->wavelength2 = gwy_get_gfloat_be(&p); mprofile->wavelength_fold = gwy_get_guint16_be(&p); mprofile->wavelength1 = gwy_get_gfloat_be(&p); mprofile->wavelength3 = gwy_get_gfloat_be(&p); mprofile->wavelength4 = gwy_get_gfloat_be(&p); get_CHARARRAY0(mprofile->wavelength_select, &p); mprofile->fda_res = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->scan_description, &p); gwy_debug("scan_description: %s", mprofile->scan_description); mprofile->nfiducials = gwy_get_guint16_be(&p); for (i = 0; i < G_N_ELEMENTS(mprofile->fiducials); i++) mprofile->fiducials[i] = gwy_get_gfloat_be(&p); mprofile->pixel_width = gwy_get_gfloat_be(&p); mprofile->pixel_height = gwy_get_gfloat_be(&p); mprofile->exit_pupil_diam = gwy_get_gfloat_be(&p); mprofile->light_level_pct = gwy_get_gfloat_be(&p); mprofile->coords_state = gwy_get_guint32_be(&p); mprofile->xpos = gwy_get_gfloat_be(&p); mprofile->ypos = gwy_get_gfloat_be(&p); mprofile->zpos = gwy_get_gfloat_be(&p); mprofile->xrot = gwy_get_gfloat_be(&p); mprofile->yrot = gwy_get_gfloat_be(&p); mprofile->zrot = gwy_get_gfloat_be(&p); mprofile->coherence_mode = gwy_get_guint16_be(&p); mprofile->surface_filter = gwy_get_guint16_be(&p); get_CHARARRAY0(mprofile->sys_err_file, &p); get_CHARARRAY0(mprofile->zoom_desc, &p); return TRUE; }
static gboolean read_parameters(const guchar *buffer, guint size, StmprgFile *stmprgfile, GError **error) { const guchar *p = buffer + MAGIC_SIZE; StmprgMainfield *mainfield; StmprgControl *control; StmprgOtherControl *other_control; gwy_debug("tp file size is %u, expecting %u", size, PARAM_SIZE); if (size < PARAM_SIZE) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("Parameter file is too short.")); return FALSE; } /* mainfield */ mainfield = &stmprgfile->mainfield; mainfield->start_x = gwy_get_gfloat_be(&p); mainfield->start_y = gwy_get_gfloat_be(&p); mainfield->field_x = gwy_get_gfloat_be(&p); mainfield->field_y = gwy_get_gfloat_be(&p); mainfield->inc_x = gwy_get_gfloat_be(&p); mainfield->inc_y = gwy_get_gfloat_be(&p); mainfield->points = gwy_get_gint32_be(&p); mainfield->lines = gwy_get_gint32_be(&p); mainfield->angle = gwy_get_gfloat_be(&p); mainfield->sol_x = gwy_get_gfloat_be(&p); mainfield->sol_y = gwy_get_gfloat_be(&p); mainfield->sol_z = gwy_get_gfloat_be(&p); mainfield->sol_ext1 = gwy_get_gfloat_be(&p); mainfield->sol_ext2 = gwy_get_gfloat_be(&p); mainfield->sol_h = gwy_get_gfloat_be(&p); g_assert(p - buffer == MAGIC_SIZE + MAINFIELD_SIZE); gwy_debug("start_x = %g", mainfield->start_x); gwy_debug("start_y = %g", mainfield->start_y); gwy_debug("field_x = %g", mainfield->field_x); gwy_debug("field_y = %g", mainfield->field_y); gwy_debug("inc_x = %g", mainfield->inc_x); gwy_debug("inc_y = %g", mainfield->inc_y); gwy_debug("points = %d", mainfield->points); gwy_debug("lines = %d", mainfield->lines); gwy_debug("angle = %g", mainfield->angle); gwy_debug("sol_x = %g", mainfield->sol_x); gwy_debug("sol_y = %g", mainfield->sol_y); gwy_debug("sol_z = %g", mainfield->sol_z); gwy_debug("sol_ext1 = %g", mainfield->sol_ext1); gwy_debug("sol_ext2 = %g", mainfield->sol_ext2); gwy_debug("sol_h = %g", mainfield->sol_h); if (err_DIMENSION(error, mainfield->points) || err_DIMENSION(error, mainfield->lines)) return FALSE; /* control */ control = &stmprgfile->control; control->mode = *(p++); control->channel1 = *(p++); control->channel2 = *(p++); control->channel3 = *(p++); control->spectr = *(p++); control->cfree = *(p++); control->type = gwy_get_gint16_be(&p); control->steps_x = gwy_get_gint32_be(&p); control->steps_y = gwy_get_gint32_be(&p); control->dac_speed = gwy_get_gint32_be(&p); control->poi_inc = gwy_get_gfloat_be(&p); control->lin_inc = gwy_get_gfloat_be(&p); control->ad1_reads = gwy_get_gint32_be(&p); control->ad2_reads = gwy_get_gint32_be(&p); control->ad3_reads = gwy_get_gint32_be(&p); control->analog_ave = gwy_get_gint32_be(&p); control->speed = gwy_get_gint32_be(&p); control->voltage = gwy_get_gfloat_be(&p); control->voltage_l = gwy_get_gfloat_be(&p); control->voltage_r = gwy_get_gfloat_be(&p); control->volt_flag = gwy_get_gint32_be(&p); control->volt_region = gwy_get_gint32_be(&p); control->current = gwy_get_gfloat_be(&p); control->current_l = gwy_get_gfloat_be(&p); control->current_r = gwy_get_gfloat_be(&p); control->curr_flag = gwy_get_gint32_be(&p); control->curr_region = gwy_get_gint32_be(&p); control->spec_lstart = gwy_get_gfloat_be(&p); control->spec_lend = gwy_get_gfloat_be(&p); control->spec_linc = gwy_get_gfloat_be(&p); control->spec_lsteps = gwy_get_guint32_be(&p); control->spec_rstart = gwy_get_gfloat_be(&p); control->spec_rend = gwy_get_gfloat_be(&p); control->spec_rinc = gwy_get_gfloat_be(&p); control->spec_rsteps = gwy_get_guint32_be(&p); control->version = gwy_get_gfloat_be(&p); control->free_lend = gwy_get_gfloat_be(&p); control->free_linc = gwy_get_gfloat_be(&p); control->free_lsteps = gwy_get_guint32_be(&p); control->free_rstart = gwy_get_gfloat_be(&p); control->free_rend = gwy_get_gfloat_be(&p); control->free_rinc = gwy_get_gfloat_be(&p); control->free_rsteps = gwy_get_guint32_be(&p); control->timer1 = gwy_get_guint32_be(&p); control->timer2 = gwy_get_guint32_be(&p); control->timer3 = gwy_get_guint32_be(&p); control->timer4 = gwy_get_guint32_be(&p); control->m_time = gwy_get_guint32_be(&p); control->u_divider = gwy_get_gfloat_be(&p); control->fb_control = gwy_get_gint32_be(&p); control->fb_delay = gwy_get_gint32_be(&p); control->point_time = gwy_get_gint32_be(&p); control->spec_time = gwy_get_gint32_be(&p); control->spec_delay = gwy_get_gint32_be(&p); control->fm = gwy_get_gint16_be(&p); control->fm_prgmode = gwy_get_gint16_be(&p); control->fm_channel1 = gwy_get_gint32_be(&p); control->fm_channel2 = gwy_get_gint32_be(&p); control->fm_wait = gwy_get_gint32_be(&p); control->fm_frames = gwy_get_gint32_be(&p); control->fm_delay = gwy_get_gint16_be(&p); control->spectr_edit = gwy_get_gint16_be(&p); control->fm_speed = gwy_get_gint16_be(&p); control->fm_reads = gwy_get_gint16_be(&p); g_assert(p - buffer == MAGIC_SIZE + MAINFIELD_SIZE + CONTROL_SIZE); gwy_debug("type = %d", control->type); gwy_debug("steps_x = %d", control->steps_x); gwy_debug("steps_y = %d", control->steps_y); gwy_debug("dac_speed = %d", control->dac_speed); gwy_debug("poi_inc = %g", control->poi_inc); gwy_debug("lin_inc = %g", control->lin_inc); gwy_debug("ad1_reads = %d", control->ad1_reads); gwy_debug("ad2_reads = %d", control->ad2_reads); gwy_debug("ad3_reads = %d", control->ad3_reads); gwy_debug("analog_ave = %d", control->analog_ave); gwy_debug("speed = %d", control->speed); gwy_debug("voltage = %g", control->voltage); gwy_debug("voltage_l = %g", control->voltage_l); gwy_debug("voltage_r = %g", control->voltage_r); gwy_debug("volt_flag = %d", control->volt_flag); gwy_debug("volt_region = %d", control->volt_region); gwy_debug("current = %g", control->current); gwy_debug("current_l = %g", control->current_l); gwy_debug("current_r = %g", control->current_r); gwy_debug("curr_flag = %d", control->curr_flag); gwy_debug("curr_region = %d", control->curr_region); gwy_debug("spec_lstart = %g", control->spec_lstart); gwy_debug("spec_lend = %g", control->spec_lend); gwy_debug("spec_linc = %g", control->spec_linc); gwy_debug("spec_lsteps = %u", control->spec_lsteps); gwy_debug("spec_rstart = %g", control->spec_rstart); gwy_debug("spec_rend = %g", control->spec_rend); gwy_debug("spec_rinc = %g", control->spec_rinc); gwy_debug("spec_rsteps = %u", control->spec_rsteps); gwy_debug("version = %g", control->version); gwy_debug("free_lend = %g", control->free_lend); gwy_debug("free_linc = %g", control->free_linc); gwy_debug("free_lsteps = %u", control->free_lsteps); gwy_debug("free_rstart = %g", control->free_rstart); gwy_debug("free_rend = %g", control->free_rend); gwy_debug("free_rinc = %g", control->free_rinc); gwy_debug("free_rsteps = %u", control->free_rsteps); gwy_debug("timer1 = %u", control->timer1); gwy_debug("timer2 = %u", control->timer2); gwy_debug("timer3 = %u", control->timer3); gwy_debug("timer4 = %u", control->timer4); gwy_debug("m_time = %u", control->m_time); gwy_debug("u_divider = %g", control->u_divider); gwy_debug("fb_control = %d", control->fb_control); gwy_debug("fb_delay = %d", control->fb_delay); gwy_debug("point_time = %d", control->point_time); gwy_debug("spec_time = %d", control->spec_time); gwy_debug("spec_delay = %d", control->spec_delay); gwy_debug("fm = %d", control->fm); gwy_debug("fm_prgmode = %d", control->fm_prgmode); gwy_debug("fm_channel1 = %d", control->fm_channel1); gwy_debug("fm_channel2 = %d", control->fm_channel2); gwy_debug("fm_wait = %d", control->fm_wait); gwy_debug("fm_frames = %d", control->fm_frames); gwy_debug("fm_delay = %d", control->fm_delay); gwy_debug("spectr_edit = %d", control->spectr_edit); gwy_debug("fm_speed = %d", control->fm_speed); gwy_debug("fm_reads = %d", control->fm_reads); /* other_control */ other_control = &stmprgfile->other_control; other_control->version = gwy_get_gfloat_be(&p); other_control->adc_data_l = gwy_get_gint32_be(&p); other_control->adc_data_r = gwy_get_gint32_be(&p); other_control->first_zp = gwy_get_gint16_be(&p); other_control->last_zp = gwy_get_gint16_be(&p); other_control->zdrift = gwy_get_gfloat_be(&p); other_control->savememory = gwy_get_gint32_be(&p); get_CHARARRAY0(other_control->date, &p); get_CHARARRAY0(other_control->comment, &p); get_CHARARRAY0(other_control->username, &p); get_CHARARRAY0(other_control->macro_file, &p); get_CHARARRAY0(other_control->cext_a, &p); get_CHARARRAY0(other_control->cext_b, &p); other_control->contscan = gwy_get_gint32_be(&p); other_control->spec_loop = gwy_get_gint32_be(&p); other_control->ext_c = gwy_get_gint32_be(&p); other_control->fm_zlift = gwy_get_gfloat_be(&p); other_control->ext_a = gwy_get_gint32_be(&p); other_control->vme_release = gwy_get_gfloat_be(&p); g_assert(p - buffer == PARAM_SIZE); gwy_debug("version = %g", other_control->version); gwy_debug("adc_data_l = %d", other_control->adc_data_l); gwy_debug("adc_data_r = %d", other_control->adc_data_r); gwy_debug("first_zp = %d", other_control->first_zp); gwy_debug("last_zp = %d", other_control->last_zp); gwy_debug("zdrift = %g", other_control->zdrift); gwy_debug("savememory = %d", other_control->savememory); gwy_debug("date = %s", other_control->date); gwy_debug("comment = %s", other_control->comment); gwy_debug("username = %s", other_control->username); gwy_debug("macro_file = %s", other_control->macro_file); gwy_debug("cext_a = %s", other_control->cext_a); gwy_debug("cext_b = %s", other_control->cext_b); gwy_debug("contscan = %d", other_control->contscan); gwy_debug("spec_loop = %d", other_control->spec_loop); gwy_debug("ext_c = %d", other_control->ext_c); gwy_debug("fm_zlift = %g", other_control->fm_zlift); gwy_debug("ext_a = %d", other_control->ext_a); gwy_debug("vme_release = %g", other_control->vme_release); return TRUE; }
static gboolean cdffile_read_var_array(NetCDFVar **pvars, gint *pnvars, NetCDFVersion version, const guchar *buf, gsize size, const guchar **p, GError **error) { NetCDFVar *vars; gint nvars, n, i, ts, offset_size; if (!cdffile_check_size(error, "var_array", buf, size, *p, 8)) return FALSE; n = gwy_get_guint32_be(p); gwy_debug("vars (%d)", n); if (n != 0 && n != NC_VARIABLE) { err_CDF_EXPECTED(error, "NC_VARIABLE"); return FALSE; } nvars = gwy_get_guint32_be(p); if (nvars && !n) { err_CDF_ZELEMENTS(error, "var_array"); return FALSE; } gwy_debug("nvars: %d", nvars); if (!nvars) return TRUE; switch (version) { case NETCDF_CLASSIC: offset_size = 4; break; case NETCDF_64BIT: offset_size = 8; break; default: g_return_val_if_reached(FALSE); break; } vars = g_new0(NetCDFVar, nvars); *pvars = vars; *pnvars = nvars; for (i = 0; i < nvars; i++) { if (!cdffile_check_size(error, "var_array", buf, size, *p, 4)) return FALSE; n = gwy_get_guint32_be(p); ALIGN4(n); if (!cdffile_check_size(error, "var_array", buf, size, *p, n + 4)) return FALSE; vars[i].name = g_strndup((const gchar*)*p, n); *p += n; vars[i].ndims = gwy_get_guint32_be(p); gwy_debug("var_array[%d]: <%s> %d", i, vars[i].name, vars[i].ndims); if (!cdffile_check_size(error, "var_array", buf, size, *p, 4*vars[i].ndims)) return FALSE; vars[i].dimids = g_new(gint, vars[i].ndims); for (n = 0; n < vars[i].ndims; n++) { vars[i].dimids[n] = gwy_get_guint32_be(p); gwy_debug("var_array[%d][%d]: %d", i, n, vars[i].dimids[n]); } if (!cdffile_read_attr_array(&vars[i].attrs, &vars[i].nattrs, buf, size, p, error)) return FALSE; if (!cdffile_check_size(error, "var_array", buf, size, *p, 8 + offset_size)) return FALSE; vars[i].type = gwy_get_guint32_be(p); ts = cdffile_type_size(vars[i].type); if (!ts) { err_DATA_TYPE(error, vars[i].type); return FALSE; } vars[i].vsize = gwy_get_guint32_be(p); switch (version) { case NETCDF_CLASSIC: vars[i].begin = gwy_get_guint32_be(p); break; case NETCDF_64BIT: vars[i].begin = gwy_get_guint64_be(p); break; } } return TRUE; }
static gboolean cdffile_read_attr_array(NetCDFAttr **pattrs, gint *pnattrs, const guchar *buf, gsize size, const guchar **p, GError **error) { NetCDFAttr *attrs; gint nattrs, n, ts, i; if (!cdffile_check_size(error, "attr_array", buf, size, *p, 8)) return FALSE; n = gwy_get_guint32_be(p); gwy_debug("attrs (%d)", n); if (n != 0 && n != NC_ATTRIBUTE) { err_CDF_EXPECTED(error, "NC_ATTRIBUTE"); return FALSE; } nattrs = gwy_get_guint32_be(p); if (nattrs && !n) { err_CDF_ZELEMENTS(error, "attr_array"); return FALSE; } gwy_debug("nattrs: %d", nattrs); if (!nattrs) return TRUE; attrs = g_new0(NetCDFAttr, nattrs); *pattrs = attrs; *pnattrs = nattrs; for (i = 0; i < nattrs; i++) { if (!cdffile_check_size(error, "attr_array", buf, size, *p, 4)) return FALSE; n = gwy_get_guint32_be(p); n += (4 - n % 4) % 4; if (!cdffile_check_size(error, "attr_array", buf, size, *p, n + 8)) return FALSE; attrs[i].name = g_strndup((const gchar*)*p, n); *p += n; attrs[i].type = gwy_get_guint32_be(p); attrs[i].nelems = gwy_get_guint32_be(p); gwy_debug("attr_array[%d]: <%s> %d of %d", i, attrs[i].name, attrs[i].nelems, attrs[i].type); ts = cdffile_type_size(attrs[i].type); if (!ts) { err_DATA_TYPE(error, attrs[i].type); return FALSE; } n = ts*attrs[i].nelems; ALIGN4(n); if (!cdffile_check_size(error, "attr_array", buf, size, *p, n)) return FALSE; attrs[i].values = *p; *p += n; } return TRUE; }
static gboolean cdffile_read_dim_array(NetCDFDim **pdims, gint *pndims, const guchar *buf, gsize size, const guchar **p, GError **error) { NetCDFDim *dims; gint ndims, n, i; if (!cdffile_check_size(error, "dim_array", buf, size, *p, 8)) return FALSE; n = gwy_get_guint32_be(p); gwy_debug("dims (%d)", n); if (n != 0 && n != NC_DIMENSION) { err_CDF_EXPECTED(error, "NC_DIMENSION"); return FALSE; } ndims = gwy_get_guint32_be(p); if (ndims && !n) { err_CDF_ZELEMENTS(error, "dim_array"); return FALSE; } gwy_debug("ndims: %d", ndims); if (!ndims) return TRUE; dims = g_new0(NetCDFDim, ndims); *pdims = dims; *pndims = ndims; for (i = 0; i < ndims; i++) { if (!cdffile_check_size(error, "dim_array", buf, size, *p, 4)) return FALSE; n = gwy_get_guint32_be(p); ALIGN4(n); if (!cdffile_check_size(error, "dim_array", buf, size, *p, n + 4)) return FALSE; dims[i].name = g_strndup((const gchar*)*p, n); *p += n; dims[i].length = gwy_get_guint32_be(p); gwy_debug("dim_array[%d]: <%s> %d%s", i, dims[i].name, dims[i].length, dims[i].length ? "" : "(record)"); } /* Check record dimensions */ n = -1; for (i = 0; i < ndims; i++) { if (!dims[i].length) { if (n > -1) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("More than one record dimension found.")); return FALSE; } n = i; } } return TRUE; }
static gboolean cdffile_load(NetCDF *cdffile, const gchar *filename, GError **error) { GError *err = NULL; const guchar *p; gwy_clear(cdffile, 1); if (!gwy_file_get_contents(filename, &cdffile->buffer, &cdffile->size, &err)) { err_GET_FILE_CONTENTS(error, &err); return FALSE; } if (cdffile->size < 32) { err_TOO_SHORT(error); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } p = cdffile->buffer; /* Header */ if (memcmp(p, MAGIC1, MAGIC_SIZE) == 0) cdffile->version = 1; else if (memcmp(p, MAGIC2, MAGIC_SIZE) == 0) cdffile->version = 2; else { err_FILE_TYPE(error, "NetCDF"); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } gwy_debug("Header: CDF v%d", (gint)cdffile->version); p += MAGIC_SIZE; /* N Records */ cdffile->nrecs = gwy_get_guint32_be(&p); gwy_debug("nrecs %d", cdffile->nrecs); /* Dimensions */ if (!cdffile_read_dim_array(&cdffile->dims, &cdffile->ndims, cdffile->buffer, cdffile->size, &p, error)) { cdffile_free(cdffile); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } /* Global attributes */ if (!cdffile_read_attr_array(&cdffile->attrs, &cdffile->nattrs, cdffile->buffer, cdffile->size, &p, error)) { cdffile_free(cdffile); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } /* Variables */ if (!cdffile_read_var_array(&cdffile->vars, &cdffile->nvars, cdffile->version, cdffile->buffer, cdffile->size, &p, error)) { cdffile_free(cdffile); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } cdffile->data_start = (gsize)(p - cdffile->buffer); /* Sanity check */ if (!cdffile_validate_vars(cdffile, error)) { cdffile_free(cdffile); gwy_file_abandon_contents(cdffile->buffer, cdffile->size, NULL); return FALSE; } return TRUE; }