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.c,v 1.15 2004/06/12 17:57:10 rlk 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 }

Generated on Wed Aug 25 07:56:13 2004 for libgimpprint API Reference by doxygen 1.3.6