static void array_dtor(stp_array_t *array) { if (array->data) stp_sequence_destroy(array->data); memset(array, 0, sizeof(stp_array_t)); }
static void curve_dtor(stp_curve_t *curve) { CHECK_CURVE(curve); clear_curve_data(curve); if (curve->seq) stp_sequence_destroy(curve->seq); memset(curve, 0, sizeof(stp_curve_t)); curve->curve_type = -1; }
void stp_array_set_size(stp_array_t *array, int x_size, int y_size) { check_array(array); if (array->data) /* Free old data */ stp_sequence_destroy(array->data); array->x_size = x_size; array->y_size = y_size; array->data = stp_sequence_create(); stp_sequence_set_size(array->data, array->x_size * array->y_size); }
void stp_array_copy(stp_array_t *dest, const stp_array_t *source) { check_array(dest); check_array(source); dest->x_size = source->x_size; dest->y_size = source->y_size; if (dest->data) stp_sequence_destroy(dest->data); dest->data = stp_sequence_create_copy(source->data); }
stp_mxml_node_t * stp_xmltree_create_from_curve(const stp_curve_t *curve) /* The curve */ { stp_curve_wrap_mode_t wrapmode; stp_curve_type_t interptype; double gammaval, low, high; stp_sequence_t *seq; char *cgamma; stp_mxml_node_t *curvenode = NULL; stp_mxml_node_t *child = NULL; stp_xml_init(); /* Get curve details */ wrapmode = stp_curve_get_wrap(curve); interptype = stp_curve_get_interpolation_type(curve); gammaval = stp_curve_get_gamma(curve); if (gammaval && wrapmode != STP_CURVE_WRAP_NONE) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_xmltree_create_from_curve: " "curve sets gamma and wrap_mode is not STP_CURVE_WRAP_NONE\n"); goto error; } /* Construct the allocated strings required */ stp_asprintf(&cgamma, "%g", gammaval); curvenode = stp_mxmlNewElement(NULL, "curve"); stp_mxmlElementSetAttr(curvenode, "wrap", stpi_wrap_mode_names[wrapmode]); stp_mxmlElementSetAttr(curvenode, "type", stpi_curve_type_names[interptype]); stp_mxmlElementSetAttr(curvenode, "gamma", cgamma); if (curve->piecewise) stp_mxmlElementSetAttr(curvenode, "piecewise", "true"); else stp_mxmlElementSetAttr(curvenode, "piecewise", "false"); stp_free(cgamma); seq = stp_sequence_create(); stp_curve_get_bounds(curve, &low, &high); stp_sequence_set_bounds(seq, low, high); if (gammaval != 0) /* A gamma curve does not require sequence data */ { stp_sequence_set_size(seq, 0); } else { const double *data; size_t count; data = stpi_curve_get_data_internal(curve, &count); stp_sequence_set_data(seq, count, data); } child = stp_xmltree_create_from_sequence(seq); if (seq) { stp_sequence_destroy(seq); seq = NULL; } if (child == NULL) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_xmltree_create_from_curve: sequence node is NULL\n"); goto error; } stp_mxmlAdd(curvenode, STP_MXML_ADD_AFTER, NULL, child); stp_xml_exit(); return curvenode; error: stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_xmltree_create_from_curve: error during xmltree creation\n"); if (curvenode) stp_mxmlDelete(curvenode); if (child) stp_mxmlDelete(child); stp_xml_exit(); return NULL; }
stp_curve_t * stp_curve_create_from_xmltree(stp_mxml_node_t *curve) /* The curve node */ { const char *stmp; /* Temporary string */ stp_mxml_node_t *child; /* Child sequence node */ stp_curve_t *ret = NULL; /* Curve to return */ stp_curve_type_t curve_type; /* Type of curve */ stp_curve_wrap_mode_t wrap_mode; /* Curve wrap mode */ double fgamma; /* Gamma value */ stp_sequence_t *seq = NULL; /* Sequence data */ double low, high; /* Sequence bounds */ int piecewise = 0; stp_xml_init(); /* Get curve type */ stmp = stp_mxmlElementGetAttr(curve, "type"); if (stmp) { if (!strcmp(stmp, "linear")) curve_type = STP_CURVE_TYPE_LINEAR; else if (!strcmp(stmp, "spline")) curve_type = STP_CURVE_TYPE_SPLINE; else { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: %s: \"type\" invalid\n", stmp); goto error; } } else { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: \"type\" missing\n"); goto error; } /* Get curve wrap mode */ stmp = stp_mxmlElementGetAttr(curve, "wrap"); if (stmp) { if (!strcmp(stmp, "nowrap")) wrap_mode = STP_CURVE_WRAP_NONE; else if (!strcmp(stmp, "wrap")) { wrap_mode = STP_CURVE_WRAP_AROUND; } else { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: %s: \"wrap\" invalid\n", stmp); goto error; } } else { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: \"wrap\" missing\n"); goto error; } /* Get curve gamma */ stmp = stp_mxmlElementGetAttr(curve, "gamma"); if (stmp) { fgamma = stp_xmlstrtod(stmp); } else { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: \"gamma\" missing\n"); goto error; } /* If gamma is set, wrap_mode must be STP_CURVE_WRAP_NONE */ if (fgamma && wrap_mode != STP_CURVE_WRAP_NONE) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: " "gamma set and \"wrap\" is not STP_CURVE_WRAP_NONE\n"); goto error; } stmp = stp_mxmlElementGetAttr(curve, "piecewise"); if (stmp && strcmp(stmp, "true") == 0) piecewise = 1; /* Set up the curve */ ret = stp_curve_create(wrap_mode); stp_curve_set_interpolation_type(ret, curve_type); child = stp_mxmlFindElement(curve, curve, "sequence", NULL, NULL, STP_MXML_DESCEND); if (child) seq = stp_sequence_create_from_xmltree(child); if (seq == NULL) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: sequence read failed\n"); goto error; } /* Set curve bounds */ stp_sequence_get_bounds(seq, &low, &high); stp_curve_set_bounds(ret, low, high); if (fgamma) stp_curve_set_gamma(ret, fgamma); else /* Not a gamma curve, so set points */ { size_t seq_count; const double* data; stp_sequence_get_data(seq, &seq_count, &data); if (piecewise) { if ((seq_count % 2) != 0) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: invalid data count %ld\n", (long)seq_count); goto error; } if (stp_curve_set_data_points(ret, seq_count / 2, (const stp_curve_point_t *) data) == 0) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: failed to set curve data points\n"); goto error; } } else { if (stp_curve_set_data(ret, seq_count, data) == 0) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: failed to set curve data\n"); goto error; } } } if (seq) { stp_sequence_destroy(seq); seq = NULL; } /* Validate curve */ if (stpi_curve_check_parameters(ret, stp_curve_count_points(ret)) == 0) { stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: parameter check failed\n"); goto error; } stp_xml_exit(); return ret; error: stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: error during curve read\n"); if (ret) stp_curve_destroy(ret); stp_xml_exit(); return NULL; }
stp_array_t * stp_array_create_from_xmltree(stp_mxml_node_t *array) /* The array node */ { const char *stmp; /* Temporary string */ stp_mxml_node_t *child; /* Child sequence node */ int x_size, y_size; size_t count; stp_sequence_t *seq = NULL; stp_array_t *ret = NULL; stmp = stp_mxmlElementGetAttr(array, "x-size"); if (stmp) { x_size = (int) strtoul(stmp, NULL, 0); } else { stp_erprintf("stp_array_create_from_xmltree: \"x-size\" missing\n"); goto error; } /* Get y-size */ stmp = stp_mxmlElementGetAttr(array, "y-size"); if (stmp) { y_size = (int) strtoul(stmp, NULL, 0); } else { stp_erprintf("stp_array_create_from_xmltree: \"y-size\" missing\n"); goto error; } /* Get the sequence data */ child = stp_mxmlFindElement(array, array, "sequence", NULL, NULL, STP_MXML_DESCEND); if (child) seq = stp_sequence_create_from_xmltree(child); if (seq == NULL) goto error; ret = stp_array_create(x_size, y_size); if (ret->data) stp_sequence_destroy(ret->data); ret->data = seq; count = stp_sequence_get_size(seq); if (count != (x_size * y_size)) { stp_erprintf("stp_array_create_from_xmltree: size mismatch between array and sequence\n"); goto error; } return ret; error: stp_erprintf("stp_array_create_from_xmltree: error during array read\n"); if (ret) stp_array_destroy(ret); return NULL; }