static GwyDataField* read_data_field(const guchar *buffer, gint xres, gint yres, NetCDFType type) { GwyDataField *dfield; gdouble *data; gint i; dfield = gwy_data_field_new(xres, yres, 1.0, 1.0, FALSE); data = gwy_data_field_get_data(dfield); switch (type) { case NC_BYTE: case NC_CHAR: { const gint8 *d8 = (const gint8*)buffer; for (i = 0; i < xres*yres; i++) data[i] = d8[i]; } break; case NC_SHORT: { const gint16 *d16 = (const gint16*)buffer; for (i = 0; i < xres*yres; i++) data[i] = GINT16_FROM_BE(d16[i]); } break; case NC_INT: { const gint32 *d32 = (const gint32*)buffer; for (i = 0; i < xres*yres; i++) data[i] = GINT32_FROM_BE(d32[i]); } break; case NC_FLOAT: for (i = 0; i < xres*yres; i++) data[i] = gwy_get_gfloat_be(&buffer); break; case NC_DOUBLE: for (i = 0; i < xres*yres; i++) data[i] = gwy_get_gdouble_be(&buffer); break; default: g_return_val_if_reached(dfield); break; } return dfield; }
static GwySIUnit* read_real_size(const NetCDF *cdffile, const gchar *name, gdouble *real, gint *power10) { const NetCDFVar *var; const NetCDFAttr *attr; GwySIUnit *siunit; const guchar *p; gchar *s; *real = 1.0; *power10 = 0; if (!(var = cdffile_get_var(cdffile, name))) return NULL; /* * Warning: Madness ahead. * * Older GXSM files contain "AA" in "unit", that makes sense, as the units * are Angstroems. * * Newer GXSM files contain "nm" in "unit" though, in spite of the units * being still Angstroems. They seem to contain the real units in * "var_unit". The info field reads: * * This number is alwalys stored in Angstroem. Unit is used for user * display only. * * In addition they invented yet another Angstroem abbreviation: Ang. */ attr = cdffile_get_attr(var->attrs, var->nattrs, "var_unit"); if (!attr || attr->type != NC_CHAR) { attr = cdffile_get_attr(var->attrs, var->nattrs, "unit"); if (!attr || attr->type != NC_CHAR) return NULL; } if (!attr->nelems) s = NULL; else s = g_strndup(attr->values, attr->nelems); siunit = gwy_si_unit_new_parse(s, power10); g_free(s); p = (const guchar*)(cdffile->buffer + var->begin); if (var->type == NC_DOUBLE) *real = gwy_get_gdouble_be(&p); else if (var->type == NC_FLOAT) *real = gwy_get_gfloat_be(&p); else g_warning("Size is not a floating point number"); return siunit; }
static gboolean read_qt_double(const guchar **p, gsize *size, gdouble *value) { *value = 0; if (*size < sizeof(gdouble)) return FALSE; *value = gwy_get_gdouble_be(p); gwy_debug("QDouble data: %g", *value); *size -= sizeof(gdouble); return TRUE; }