#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gimp-print/gimp-print.h>
#include "gimp-print-internal.h"
#include <gimp-print/gimp-print-intl-internal.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
struct stp_array
{
stp_sequence_t *data;
int x_size;
int y_size;
};
static inline void
check_array(const stp_array_t *array)
{
if (array == NULL)
{
stp_erprintf("Null stp_array_t! Please report this bug.\n");
stp_abort();
}
}
static void array_ctor(stp_array_t *array)
{
array->data = stp_sequence_create();
stp_sequence_set_size(array->data, array->x_size * array->y_size);
}
stp_array_t *
stp_array_create(int x_size, int y_size)
{
stp_array_t *ret;
ret = stp_zalloc(sizeof(stp_array_t));
ret->x_size = x_size;
ret->y_size = y_size;
ret->data = NULL;
array_ctor(ret);
return ret;
}
static void
array_dtor(stp_array_t *array)
{
if (array->data)
stp_sequence_destroy(array->data);
memset(array, 0, sizeof(stp_array_t));
}
void
stp_array_destroy(stp_array_t *array)
{
check_array(array);
array_dtor(array);
stp_free(array);
}
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_array_t *
stp_array_create_copy(const stp_array_t *array)
{
stp_array_t *ret;
check_array(array);
ret = stp_array_create(0, 0);
stp_array_copy(ret, array);
return ret;
}
void
stp_array_set_size(stp_array_t *array, int x_size, int y_size)
{
check_array(array);
if (array->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_get_size(const stp_array_t *array, int *x_size, int *y_size)
{
check_array(array);
*x_size = array->x_size;
*y_size = array->y_size;
return;
}
void
stp_array_set_data(stp_array_t *array, const double *data)
{
check_array(array);
stp_sequence_set_data(array->data, array->x_size * array->y_size,
data);
}
void
stp_array_get_data(const stp_array_t *array, size_t *size, const double **data)
{
check_array(array);
stp_sequence_get_data(array->data, size, data);
}
int
stp_array_set_point(stp_array_t *array, int x, int y, double data)
{
check_array(array);
if (((array->x_size * x) + y) >= (array->x_size * array->y_size))
return 0;
return stp_sequence_set_point(array->data, (array->x_size * x) + y, data);}
int
stp_array_get_point(const stp_array_t *array, int x, int y, double *data)
{
check_array(array);
if (((array->x_size * x) + y) >= array->x_size * array->y_size)
return 0;
return stp_sequence_get_point(array->data,
(array->x_size * x) + y, data);
}
const stp_sequence_t *
stp_array_get_sequence(const stp_array_t *array)
{
check_array(array);
return array->data;
}
stp_array_t *
stp_array_create_from_xmltree(stp_mxml_node_t *array)
{
const char *stmp;
stp_mxml_node_t *child;
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;
}
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;
}
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;
}
stp_mxml_node_t *
stp_xmltree_create_from_array(const stp_array_t *array)
{
int x_size, y_size;
char *xs, *ys;
stp_mxml_node_t *arraynode = NULL;
stp_mxml_node_t *child = NULL;
stp_xml_init();
stp_array_get_size(array, &x_size, &y_size);
stp_asprintf(&xs, "%d", x_size);
stp_asprintf(&ys, "%d", y_size);
arraynode = stp_mxmlNewElement(NULL, "array");
stp_mxmlElementSetAttr(arraynode, "x-size", xs);
stp_mxmlElementSetAttr(arraynode, "y-size", ys);
stp_free(xs);
stp_free(ys);
child = stp_xmltree_create_from_sequence(stp_array_get_sequence(array));
if (child)
stp_mxmlAdd(arraynode, STP_MXML_ADD_AFTER, NULL, child);
else
{
stp_mxmlDelete(arraynode);
arraynode = NULL;
}
stp_xml_exit();
return arraynode;
}