libgimpprint API Reference: src/main/array.c Source File

Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

# src/main/array.c

Go to the documentation of this file.

    00001 /*
    00002  * "$Id: array_8c-source.html,v 1.1.1.2 2004/12/22 23:48:56 jlovell Exp $"
    00003  *
    00004  *   Array data type.  This type is designed to be derived from by
    00005  *   the curve and dither matrix types.
    00006  *
    00007  *   Copyright 2002-2003 Robert Krawitz (rlk@alum.mit.edu)
    00008  *   Copyright 2003      Roger Leigh (rleigh@debian.org)
    00009  *
    00010  *   This program is free software; you can redistribute it and/or modify it
    00011  *   under the terms of the GNU General Public License as published by the Free
    00012  *   Software Foundation; either version 2 of the License, or (at your option)
    00013  *   any later version.
    00014  *
    00015  *   This program is distributed in the hope that it will be useful, but
    00016  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    00017  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    00018  *   for more details.
    00019  *
    00020  *   You should have received a copy of the GNU General Public License
    00021  *   along with this program; if not, write to the Free Software
    00022  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    00023  */
    00024
    00025 #ifdef HAVE_CONFIG_H
    00026 #include <config.h>
    00027 #endif
    00028 #include <gimp-print/gimp-print.h>
    00029 #include "gimp-print-internal.h"
    00030 #include <gimp-print/gimp-print-intl-internal.h>
    00031 #include <math.h>
    00032 #include <string.h>
    00033 #include <stdlib.h>
    00034 #include <limits.h>
    00035
    00036
    00037 struct stp_array
    00038 {
    00039   stp_sequence_t *data; /* First member, to allow typecasting to sequence. */
    00040   int x_size;
    00041   int y_size;
    00042 };
    00043
    00044 /*
    00045  * We could do more sanity checks here if we want.
    00046  */
    00047 static inline void
    00048 check_array(const stp_array_t *array)
    00049 {
    00050   if (array == NULL)
    00051     {
    00052       stp_erprintf("Null stp_array_t! Please report this bug.\n");
    00053       stp_abort();
    00054     }
    00055 }
    00056
    00057
    00058 static void array_ctor(stp_array_t *array)
    00059 {
    00060   array->data = stp_sequence_create();
    00061   stp_sequence_set_size(array->data, array->x_size * array->y_size);
    00062 }
    00063
    00064 stp_array_t *
    00065 stp_array_create(int x_size, int y_size)
    00066 {
    00067   stp_array_t *ret;
    00068   ret = stp_zalloc(sizeof(stp_array_t));
    00069   ret->x_size = x_size;
    00070   ret->y_size = y_size;
    00071   ret->data = NULL;
    00072   array_ctor(ret);
    00073   return ret;
    00074 }
    00075
    00076
    00077 static void
    00078 array_dtor(stp_array_t *array)
    00079 {
    00080   if (array->data)
    00081     stp_sequence_destroy(array->data);
    00082   memset(array, 0, sizeof(stp_array_t));
    00083 }
    00084
    00085 void
    00086 stp_array_destroy(stp_array_t *array)
    00087 {
    00088   check_array(array);
    00089   array_dtor(array);
    00090   stp_free(array);
    00091 }
    00092
    00093 void
    00094 stp_array_copy(stp_array_t *dest, const stp_array_t *source)
    00095 {
    00096   check_array(dest);
    00097   check_array(source);
    00098
    00099   dest->x_size = source->x_size;
    00100   dest->y_size = source->y_size;
    00101   if (dest->data)
    00102     stp_sequence_destroy(dest->data);
    00103   dest->data = stp_sequence_create_copy(source->data);
    00104 }
    00105
    00106 stp_array_t *
    00107 stp_array_create_copy(const stp_array_t *array)
    00108 {
    00109   stp_array_t *ret;
    00110   check_array(array);
    00111   ret = stp_array_create(0, 0); /* gets freed next */
    00112   stp_array_copy(ret, array);
    00113   return ret;
    00114 }
    00115
    00116
    00117 void
    00118 stp_array_set_size(stp_array_t *array, int x_size, int y_size)
    00119 {
    00120   check_array(array);
    00121   if (array->data) /* Free old data */
    00122     stp_sequence_destroy(array->data);
    00123   array->x_size = x_size;
    00124   array->y_size = y_size;
    00125   array->data = stp_sequence_create();
    00126   stp_sequence_set_size(array->data, array->x_size * array->y_size);
    00127 }
    00128
    00129 void
    00130 stp_array_get_size(const stp_array_t *array, int *x_size, int *y_size)
    00131 {
    00132   check_array(array);
    00133   *x_size = array->x_size;
    00134   *y_size = array->y_size;
    00135   return;
    00136 }
    00137
    00138 void
    00139 stp_array_set_data(stp_array_t *array, const double *data)
    00140 {
    00141   check_array(array);
    00142   stp_sequence_set_data(array->data, array->x_size * array->y_size,
    00143                         data);
    00144 }
    00145
    00146 void
    00147 stp_array_get_data(const stp_array_t *array, size_t *size, const double **data)
    00148 {
    00149   check_array(array);
    00150   stp_sequence_get_data(array->data, size, data);
    00151 }
    00152
    00153 int
    00154 stp_array_set_point(stp_array_t *array, int x, int y, double data)
    00155 {
    00156   check_array(array);
    00157
    00158   if (((array->x_size * x) + y) >= (array->x_size * array->y_size))
    00159     return 0;
    00160
    00161   return stp_sequence_set_point(array->data, (array->x_size * x) + y, data);}
    00162
    00163 int
    00164 stp_array_get_point(const stp_array_t *array, int x, int y, double *data)
    00165 {
    00166   check_array(array);
    00167
    00168   if (((array->x_size * x) + y) >= array->x_size * array->y_size)
    00169     return 0;
    00170   return stp_sequence_get_point(array->data,
    00171                                 (array->x_size * x) + y, data);
    00172 }
    00173
    00174 const stp_sequence_t *
    00175 stp_array_get_sequence(const stp_array_t *array)
    00176 {
    00177   check_array(array);
    00178
    00179   return array->data;
    00180 }
    00181
    00182 stp_array_t *
    00183 stp_array_create_from_xmltree(stp_mxml_node_t *array)  /* The array node */
    00184 {
    00185   const char *stmp;                          /* Temporary string */
    00186   stp_mxml_node_t *child;                       /* Child sequence node */
    00187   int x_size, y_size;
    00188   size_t count;
    00189   stp_sequence_t *seq = NULL;
    00190   stp_array_t *ret = NULL;
    00191
    00192   stmp = stp_mxmlElementGetAttr(array, "x-size");
    00193   if (stmp)
    00194     {
    00195       x_size = (int) strtoul(stmp, NULL, 0);
    00196     }
    00197   else
    00198     {
    00199       stp_erprintf("stp_array_create_from_xmltree: \"x-size\" missing\n");
    00200       goto error;
    00201     }
    00202   /* Get y-size */
    00203   stmp = stp_mxmlElementGetAttr(array, "y-size");
    00204   if (stmp)
    00205     {
    00206       y_size = (int) strtoul(stmp, NULL, 0);
    00207     }
    00208   else
    00209     {
    00210       stp_erprintf("stp_array_create_from_xmltree: \"y-size\" missing\n");
    00211       goto error;
    00212     }
    00213
    00214   /* Get the sequence data */
    00215
    00216   child = stp_mxmlFindElement(array, array, "sequence", NULL, NULL, STP_MXML_DESCEND);
    00217   if (child)
    00218     seq = stp_sequence_create_from_xmltree(child);
    00219
    00220   if (seq == NULL)
    00221     goto error;
    00222
    00223   ret = stp_array_create(x_size, y_size);
    00224   if (ret->data)
    00225     stp_sequence_destroy(ret->data);
    00226   ret->data = seq;
    00227
    00228   count = stp_sequence_get_size(seq);
    00229   if (count != (x_size * y_size))
    00230     {
    00231       stp_erprintf("stp_array_create_from_xmltree: size mismatch between array and sequence\n");
    00232       goto error;
    00233     }
    00234
    00235   return ret;
    00236
    00237  error:
    00238   stp_erprintf("stp_array_create_from_xmltree: error during array read\n");
    00239   if (ret)
    00240     stp_array_destroy(ret);
    00241   return NULL;
    00242 }
    00243
    00244 stp_mxml_node_t *
    00245 stp_xmltree_create_from_array(const stp_array_t *array)  /* The array */
    00246 {
    00247   int x_size, y_size;
    00248   char *xs, *ys;
    00249
    00250   stp_mxml_node_t *arraynode = NULL;
    00251   stp_mxml_node_t *child = NULL;
    00252
    00253   stp_xml_init();
    00254
    00255   /* Get array details */
    00256   stp_array_get_size(array, &x_size, &y_size);
    00257
    00258   /* Construct the allocated strings required */
    00259   stp_asprintf(&xs, "%d", x_size);
    00260   stp_asprintf(&ys, "%d", y_size);
    00261
    00262   arraynode = stp_mxmlNewElement(NULL, "array");
    00263   stp_mxmlElementSetAttr(arraynode, "x-size", xs);
    00264   stp_mxmlElementSetAttr(arraynode, "y-size", ys);
    00265   stp_free(xs);
    00266   stp_free(ys);
    00267
    00268   child = stp_xmltree_create_from_sequence(stp_array_get_sequence(array));
    00269
    00270   if (child)
    00271     stp_mxmlAdd(arraynode, STP_MXML_ADD_AFTER, NULL, child);
    00272   else
    00273     {
    00274       stp_mxmlDelete(arraynode);
    00275       arraynode = NULL;
    00276     }
    00277
    00278   stp_xml_exit();
    00279
    00280   return arraynode;
    00281 }