libgimpprint API Reference: src/main/print-util.c Source File

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

# src/main/print-util.c

Go to the documentation of this file.

    00001 /*
    00002  * "$Id: print-util_8c-source.html,v 1.1.1.2 2004/12/22 23:49:10 jlovell Exp $"
    00003  *
    00004  *   Print plug-in driver utility functions for the GIMP.
    00005  *
    00006  *   Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
    00007  *      Robert Krawitz (rlk@alum.mit.edu)
    00008  *
    00009  *   This program is free software; you can redistribute it and/or modify it
    00010  *   under the terms of the GNU General Public License as published by the Free
    00011  *   Software Foundation; either version 2 of the License, or (at your option)
    00012  *   any later version.
    00013  *
    00014  *   This program is distributed in the hope that it will be useful, but
    00015  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    00016  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    00017  *   for more details.
    00018  *
    00019  *   You should have received a copy of the GNU General Public License
    00020  *   along with this program; if not, write to the Free Software
    00021  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    00022  */
    00023
    00024 /*
    00025  * This file must include only standard C header files.  The core code must
    00026  * compile on generic platforms that don't support glib, gimp, gtk, etc.
    00027  */
    00028
    00029 #ifdef HAVE_CONFIG_H
    00030 #include <config.h>
    00031 #endif
    00032 #include <gimp-print/gimp-print.h>
    00033 #include "gimp-print-internal.h"
    00034 #include <gimp-print/gimp-print-intl-internal.h>
    00035 #include <math.h>
    00036 #include <limits.h>
    00037 #if defined(HAVE_VARARGS_H) && !defined(HAVE_STDARG_H)
    00038 #include <varargs.h>
    00039 #else
    00040 #include <stdarg.h>
    00041 #endif
    00042 #include <string.h>
    00043 #include <stdio.h>
    00044 #include <stdlib.h>
    00045 #include <sys/types.h>
    00046 #include <sys/stat.h>
    00047 #include <unistd.h>
    00048 #include "generic-options.h"
    00049
    00050 #define FMIN(a, b) ((a) < (b) ? (a) : (b))
    00051
    00052 typedef struct
    00053 {
    00054   stp_outfunc_t ofunc;
    00055   void *odata;
    00056   char *data;
    00057   size_t bytes;
    00058 } debug_msgbuf_t;
    00059
    00060 /*
    00061  * We cannot avoid use of the (non-ANSI) vsnprintf here; ANSI does
    00062  * not provide a safe, length-limited sprintf function.
    00063  */
    00064
    00065 #define STPI_VASPRINTF(result, bytes, format)                           \
    00066 {                                                                       \
    00067   int current_allocation = 64;                                          \
    00068   result = stp_malloc(current_allocation);                              \
    00069   while (1)                                                             \
    00070     {                                                                   \
    00071       va_list args;                                                     \
    00072       va_start(args, format);                                           \
    00073       bytes = vsnprintf(result, current_allocation, format, args);      \
    00074       va_end(args);                                                     \
    00075       if (bytes >= 0 && bytes < current_allocation)                     \
    00076         break;                                                          \
    00077       else                                                              \
    00078         {                                                               \
    00079           stp_free (result);                                            \
    00080           if (bytes < 0)                                                \
    00081             current_allocation *= 2;                                    \
    00082           else                                                          \
    00083             current_allocation = bytes + 1;                             \
    00084           result = stp_malloc(current_allocation);                      \
    00085         }                                                               \
    00086     }                                                                   \
    00087 }
    00088
    00089 void
    00090 stp_zprintf(const stp_vars_t *v, const char *format, ...)
    00091 {
    00092   char *result;
    00093   int bytes;
    00094   STPI_VASPRINTF(result, bytes, format);
    00095   (stp_get_outfunc(v))((void *)(stp_get_outdata(v)), result, bytes);
    00096   stp_free(result);
    00097 }
    00098
    00099 void
    00100 stp_asprintf(char **strp, const char *format, ...)
    00101 {
    00102   char *result;
    00103   int bytes;
    00104   STPI_VASPRINTF(result, bytes, format);
    00105   *strp = result;
    00106 }
    00107
    00108 void
    00109 stp_catprintf(char **strp, const char *format, ...)
    00110 {
    00111   char *result1;
    00112   char *result2;
    00113   int bytes;
    00114   STPI_VASPRINTF(result1, bytes, format);
    00115   stp_asprintf(&result2, "%s%s", *strp, result1);
    00116   stp_free(result1);
    00117   *strp = result2;
    00118 }
    00119
    00120
    00121 void
    00122 stp_zfwrite(const char *buf, size_t bytes, size_t nitems, const stp_vars_t *v)
    00123 {
    00124   (stp_get_outfunc(v))((void *)(stp_get_outdata(v)), buf, bytes * nitems);
    00125 }
    00126
    00127 void
    00128 stp_putc(int ch, const stp_vars_t *v)
    00129 {
    00130   unsigned char a = (unsigned char) ch;
    00131   (stp_get_outfunc(v))((void *)(stp_get_outdata(v)), (char *) &a, 1);
    00132 }
    00133
    00134 #define BYTE(expr, byteno) (((expr) >> (8 * byteno)) & 0xff)
    00135
    00136 void
    00137 stp_put16_le(unsigned short sh, const stp_vars_t *v)
    00138 {
    00139   stp_putc(BYTE(sh, 0), v);
    00140   stp_putc(BYTE(sh, 1), v);
    00141 }
    00142
    00143 void
    00144 stp_put16_be(unsigned short sh, const stp_vars_t *v)
    00145 {
    00146   stp_putc(BYTE(sh, 1), v);
    00147   stp_putc(BYTE(sh, 0), v);
    00148 }
    00149
    00150 void
    00151 stp_put32_le(unsigned int in, const stp_vars_t *v)
    00152 {
    00153   stp_putc(BYTE(in, 0), v);
    00154   stp_putc(BYTE(in, 1), v);
    00155   stp_putc(BYTE(in, 2), v);
    00156   stp_putc(BYTE(in, 3), v);
    00157 }
    00158
    00159 void
    00160 stp_put32_be(unsigned int in, const stp_vars_t *v)
    00161 {
    00162   stp_putc(BYTE(in, 3), v);
    00163   stp_putc(BYTE(in, 2), v);
    00164   stp_putc(BYTE(in, 1), v);
    00165   stp_putc(BYTE(in, 0), v);
    00166 }
    00167
    00168 void
    00169 stp_puts(const char *s, const stp_vars_t *v)
    00170 {
    00171   (stp_get_outfunc(v))((void *)(stp_get_outdata(v)), s, strlen(s));
    00172 }
    00173
    00174 void
    00175 stp_send_command(const stp_vars_t *v, const char *command,
    00176                  const char *format, ...)
    00177 {
    00178   int i = 0;
    00179   char fchar;
    00180   const char *out_str;
    00181   unsigned short byte_count = 0;
    00182   va_list args;
    00183
    00184   if (strlen(format) > 0)
    00185     {
    00186       va_start(args, format);
    00187       for (i = 0; i < strlen(format); i++)
    00188         {
    00189           switch (format[i])
    00190             {
    00191             case 'a':
    00192             case 'b':
    00193             case 'B':
    00194             case 'd':
    00195             case 'D':
    00196               break;
    00197             case 'c':
    00198               (void) va_arg(args, unsigned int);
    00199               byte_count += 1;
    00200               break;
    00201             case 'h':
    00202             case 'H':
    00203               (void) va_arg(args, unsigned int);
    00204               byte_count += 2;
    00205               break;
    00206             case 'l':
    00207             case 'L':
    00208               (void) va_arg(args, unsigned int);
    00209               byte_count += 4;
    00210               break;
    00211             case 's':
    00212               out_str = va_arg(args, const char *);
    00213               byte_count += strlen(out_str);
    00214               break;
    00215             }
    00216         }
    00217       va_end(args);
    00218     }
    00219
    00220   stp_puts(command, v);
    00221
    00222   va_start(args, format);
    00223   while ((fchar = format[0]) != '\0')
    00224     {
    00225       switch (fchar)
    00226         {
    00227         case 'a':
    00228           stp_putc(byte_count, v);
    00229           break;
    00230         case 'b':
    00231           stp_put16_le(byte_count, v);
    00232           break;
    00233         case 'B':
    00234           stp_put16_be(byte_count, v);
    00235           break;
    00236         case 'd':
    00237           stp_put32_le(byte_count, v);
    00238           break;
    00239         case 'D':
    00240           stp_put32_be(byte_count, v);
    00241           break;
    00242         case 'c':
    00243           stp_putc(va_arg(args, unsigned int), v);
    00244           break;
    00245         case 'h':
    00246           stp_put16_le(va_arg(args, unsigned int), v);
    00247           break;
    00248         case 'H':
    00249           stp_put16_be(va_arg(args, unsigned int), v);
    00250           break;
    00251         case 'l':
    00252           stp_put32_le(va_arg(args, unsigned int), v);
    00253           break;
    00254         case 'L':
    00255           stp_put32_be(va_arg(args, unsigned int), v);
    00256           break;
    00257         case 's':
    00258           stp_puts(va_arg(args, const char *), v);
    00259           break;
    00260         }
    00261       format++;
    00262     }
    00263   va_end(args);
    00264 }
    00265
    00266 void
    00267 stp_eprintf(const stp_vars_t *v, const char *format, ...)
    00268 {
    00269   int bytes;
    00270   if (stp_get_errfunc(v))
    00271     {
    00272       char *result;
    00273       STPI_VASPRINTF(result, bytes, format);
    00274       (stp_get_errfunc(v))((void *)(stp_get_errdata(v)), result, bytes);
    00275       stp_free(result);
    00276     }
    00277   else
    00278     {
    00279       va_list args;
    00280       va_start(args, format);
    00281       vfprintf(stderr, format, args);
    00282       va_end(args);
    00283     }
    00284 }
    00285
    00286 void
    00287 stp_erputc(int ch)
    00288 {
    00289   putc(ch, stderr);
    00290 }
    00291
    00292 void
    00293 stp_erprintf(const char *format, ...)
    00294 {
    00295   va_list args;
    00296   va_start(args, format);
    00297   vfprintf(stderr, format, args);
    00298   va_end(args);
    00299 }
    00300
    00301 static unsigned long stpi_debug_level = 0;
    00302
    00303 static void
    00304 stpi_init_debug(void)
    00305 {
    00306   static int debug_initialized = 0;
    00307   if (!debug_initialized)
    00308     {
    00309       const char *dval = getenv("STP_DEBUG");
    00310       debug_initialized = 1;
    00311       if (dval)
    00312         {
    00313           stpi_debug_level = strtoul(dval, 0, 0);
    00314           stp_erprintf("Gimp-Print %s %s\n", VERSION, RELEASE_DATE);
    00315         }
    00316     }
    00317 }
    00318
    00319 unsigned long
    00320 stp_get_debug_level(void)
    00321 {
    00322   stpi_init_debug();
    00323   return stpi_debug_level;
    00324 }
    00325
    00326 void
    00327 stp_dprintf(unsigned long level, const stp_vars_t *v, const char *format, ...)
    00328 {
    00329   int bytes;
    00330   stpi_init_debug();
    00331   if ((level & stpi_debug_level) && stp_get_errfunc(v))
    00332     {
    00333       char *result;
    00334       STPI_VASPRINTF(result, bytes, format);
    00335       (stp_get_errfunc(v))((void *)(stp_get_errdata(v)), result, bytes);
    00336       stp_free(result);
    00337     }
    00338 }
    00339
    00340 void
    00341 stp_deprintf(unsigned long level, const char *format, ...)
    00342 {
    00343   va_list args;
    00344   va_start(args, format);
    00345   stpi_init_debug();
    00346   if (level & stpi_debug_level)
    00347     vfprintf(stderr, format, args);
    00348   va_end(args);
    00349 }
    00350
    00351 static void
    00352 fill_buffer_writefunc(void *priv, const char *buffer, size_t bytes)
    00353 {
    00354   debug_msgbuf_t *msgbuf = (debug_msgbuf_t *) priv;
    00355   if (msgbuf->bytes == 0)
    00356     msgbuf->data = stp_malloc(bytes + 1);
    00357   else
    00358     msgbuf->data = stp_realloc(msgbuf->data, msgbuf->bytes + bytes + 1);
    00359   memcpy(msgbuf->data + msgbuf->bytes, buffer, bytes);
    00360   msgbuf->bytes += bytes;
    00361   msgbuf->data[msgbuf->bytes] = '\0';
    00362 }
    00363
    00364 void
    00365 stp_init_debug_messages(stp_vars_t *v)
    00366 {
    00367   int verified_flag = stp_get_verified(v);
    00368   debug_msgbuf_t *msgbuf = stp_malloc(sizeof(debug_msgbuf_t));
    00369   msgbuf->ofunc = stp_get_errfunc(v);
    00370   msgbuf->odata = stp_get_errdata(v);
    00371   msgbuf->data = NULL;
    00372   msgbuf->bytes = 0;
    00373   stp_set_errfunc((stp_vars_t *) v, fill_buffer_writefunc);
    00374   stp_set_errdata((stp_vars_t *) v, msgbuf);
    00375   stp_set_verified((stp_vars_t *) v, verified_flag);
    00376 }
    00377
    00378 void
    00379 stp_flush_debug_messages(stp_vars_t *v)
    00380 {
    00381   int verified_flag = stp_get_verified(v);
    00382   debug_msgbuf_t *msgbuf = (debug_msgbuf_t *)stp_get_errdata(v);
    00383   stp_set_errfunc((stp_vars_t *) v, msgbuf->ofunc);
    00384   stp_set_errdata((stp_vars_t *) v, msgbuf->odata);
    00385   stp_set_verified((stp_vars_t *) v, verified_flag);
    00386   if (msgbuf->bytes > 0)
    00387     {
    00388       stp_eprintf(v, "%s", msgbuf->data);
    00389       stp_free(msgbuf->data);
    00390     }
    00391   stp_free(msgbuf);
    00392 }
    00393
    00394 /* pointers to the allocation functions to use, which may be set by
    00395    client applications */
    00396 void *(*stp_malloc_func)(size_t size) = malloc;
    00397 void *(*stpi_realloc_func)(void *ptr, size_t size) = realloc;
    00398 void (*stpi_free_func)(void *ptr) = free;
    00399
    00400 void *
    00401 stp_malloc (size_t size)
    00402 {
    00403   register void *memptr = NULL;
    00404
    00405   if ((memptr = stp_malloc_func (size)) == NULL)
    00406     {
    00407       fputs("Virtual memory exhausted.\n", stderr);
    00408       stp_abort();
    00409     }
    00410   return (memptr);
    00411 }
    00412
    00413 void *
    00414 stp_zalloc (size_t size)
    00415 {
    00416   register void *memptr = stp_malloc(size);
    00417   (void) memset(memptr, 0, size);
    00418   return (memptr);
    00419 }
    00420
    00421 void *
    00422 stp_realloc (void *ptr, size_t size)
    00423 {
    00424   register void *memptr = NULL;
    00425
    00426   if (size > 0 && ((memptr = stpi_realloc_func (ptr, size)) == NULL))
    00427     {
    00428       fputs("Virtual memory exhausted.\n", stderr);
    00429       stp_abort();
    00430     }
    00431   return (memptr);
    00432 }
    00433
    00434 void
    00435 stp_free(void *ptr)
    00436 {
    00437   stpi_free_func(ptr);
    00438 }
    00439
    00440 int
    00441 stp_init(void)
    00442 {
    00443   static int stpi_is_initialised = 0;
    00444   if (!stpi_is_initialised)
    00445     {
    00446       /* Things that are only initialised once */
    00447       /* Set up gettext */
    00448 #ifdef ENABLE_NLS
    00449       setlocale (LC_ALL, "");
    00450       bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR);
    00451 #endif
    00452       stpi_init_debug();
    00453       stp_xml_preinit();
    00454       stpi_init_printer();
    00455       stpi_init_paper();
    00456       stpi_init_dither();
    00457       /* Load modules */
    00458       if (stp_module_load())
    00459         return 1;
    00460       /* Load XML data */
    00461       if (stp_xml_init_defaults())
    00462         return 1;
    00463       /* Initialise modules */
    00464       if (stp_module_init())
    00465         return 1;
    00466       /* Set up defaults for core parameters */
    00467       stp_initialize_printer_defaults();
    00468     }
    00469
    00470   stpi_is_initialised = 1;
    00471   return 0;
    00472 }
    00473
    00474 size_t
    00475 stp_strlen(const char *s)
    00476 {
    00477   return strlen(s);
    00478 }
    00479
    00480 char *
    00481 stp_strndup(const char *s, int n)
    00482 {
    00483   char *ret;
    00484   if (!s || n < 0)
    00485     {
    00486       ret = stp_malloc(1);
    00487       ret[0] = 0;
    00488       return ret;
    00489     }
    00490   else
    00491     {
    00492       ret = stp_malloc(n + 1);
    00493       memcpy(ret, s, n);
    00494       ret[n] = 0;
    00495       return ret;
    00496     }
    00497 }
    00498
    00499 char *
    00500 stp_strdup(const char *s)
    00501 {
    00502   char *ret;
    00503   if (!s)
    00504     {
    00505       ret = stp_malloc(1);
    00506       ret[0] = '\0';
    00507       return ret;
    00508     }
    00509   else
    00510     return stp_strndup(s, stp_strlen(s));
    00511 }
    00512
    00513 const char *
    00514 stp_set_output_codeset(const char *codeset)
    00515 {
    00516 #ifdef ENABLE_NLS
    00517   return (const char *)(bind_textdomain_codeset(PACKAGE, codeset));
    00518 #else
    00519   return "US-ASCII";
    00520 #endif
    00521 }
    00522
    00523 stp_curve_t *
    00524 stp_read_and_compose_curves(const char *s1, const char *s2,
    00525                             stp_curve_compose_t comp,
    00526                             size_t piecewise_point_count)
    00527 {
    00528   stp_curve_t *ret = NULL;
    00529   stp_curve_t *t1 = NULL;
    00530   stp_curve_t *t2 = NULL;
    00531   if (s1)
    00532     t1 = stp_curve_create_from_string(s1);
    00533   if (s2)
    00534     t2 = stp_curve_create_from_string(s2);
    00535   if (t1 && t2)
    00536     {
    00537       if (stp_curve_is_piecewise(t1) && stp_curve_is_piecewise(t2))
    00538         {
    00539           stp_curve_resample(t1, piecewise_point_count);
    00540           stp_curve_resample(t2, piecewise_point_count);
    00541         }
    00542       stp_curve_compose(&ret, t1, t2, comp, -1);
    00543     }
    00544   if (ret)
    00545     {
    00546       stp_curve_destroy(t1);
    00547       stp_curve_destroy(t2);
    00548       return ret;
    00549     }
    00550   else if (t1)
    00551     {
    00552       stp_curve_destroy(t2);
    00553       return t1;
    00554     }
    00555   else
    00556     return t2;
    00557 }
    00558
    00559 void
    00560 stp_merge_printvars(stp_vars_t *user, const stp_vars_t *print)
    00561 {
    00562   int i;
    00563   stp_parameter_list_t params = stp_get_parameter_list(print);
    00564   int count = stp_parameter_list_count(params);
    00565   for (i = 0; i < count; i++)
    00566     {
    00567       const stp_parameter_t *p = stp_parameter_list_param(params, i);
    00568       if (p->p_type == STP_PARAMETER_TYPE_DOUBLE &&
    00569           p->p_class == STP_PARAMETER_CLASS_OUTPUT &&
    00570           stp_check_float_parameter(print, p->name, STP_PARAMETER_DEFAULTED))
    00571         {
    00572           stp_parameter_t desc;
    00573           double prnval = stp_get_float_parameter(print, p->name);
    00574           double usrval;
    00575           stp_describe_parameter(print, p->name, &desc);
    00576           if (stp_check_float_parameter(user, p->name, STP_PARAMETER_ACTIVE))
    00577             usrval = stp_get_float_parameter(user, p->name);
    00578           else
    00579             usrval = desc.deflt.dbl;
    00580           if (strcmp(p->name, "Gamma") == 0)
    00581             usrval /= prnval;
    00582           else
    00583             usrval *= prnval;
    00584           if (usrval < desc.bounds.dbl.lower)
    00585             usrval = desc.bounds.dbl.lower;
    00586           else if (usrval > desc.bounds.dbl.upper)
    00587             usrval = desc.bounds.dbl.upper;
    00588           if (!stp_check_float_parameter(user, p->name, STP_PARAMETER_ACTIVE))
    00589             {
    00590               stp_clear_float_parameter(user, p->name);
    00591               stp_set_default_float_parameter(user, p->name, usrval);
    00592             }
    00593           else
    00594             stp_set_float_parameter(user, p->name, usrval);
    00595           stp_parameter_description_destroy(&desc);
    00596         }
    00597     }
    00598   stp_parameter_list_destroy(params);
    00599 }
    00600
    00601 stp_parameter_list_t
    00602 stp_get_parameter_list(const stp_vars_t *v)
    00603 {
    00604   stp_parameter_list_t ret = stp_parameter_list_create();
    00605   stp_parameter_list_t tmp_list;
    00606
    00607   tmp_list = stp_printer_list_parameters(v);
    00608   stp_parameter_list_append(ret, tmp_list);
    00609   stp_parameter_list_destroy(tmp_list);
    00610
    00611   tmp_list = stp_color_list_parameters(v);
    00612   stp_parameter_list_append(ret, tmp_list);
    00613   stp_parameter_list_destroy(tmp_list);
    00614
    00615   tmp_list = stp_dither_list_parameters(v);
    00616   stp_parameter_list_append(ret, tmp_list);
    00617   stp_parameter_list_destroy(tmp_list);
    00618
    00619   tmp_list = stp_list_generic_parameters(v);
    00620   stp_parameter_list_append(ret, tmp_list);
    00621   stp_parameter_list_destroy(tmp_list);
    00622
    00623   return ret;
    00624 }
    00625
    00626 void
    00627 stp_abort(void)
    00628 {
    00629   abort();
    00630 }