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

src/main/print-raw.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: print-raw.c,v 1.35 2004/05/07 19:20:33 rleigh Exp $"
00003  *
00004  *   Print plug-in RAW driver 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 <string.h>
00036 #include <stdio.h>
00037 
00038 #ifdef __GNUC__
00039 #define inline __inline__
00040 #endif
00041 
00042 typedef struct
00043 {
00044   const char *output_type;
00045   int output_channels;
00046   int rotate_channels;
00047   const char *name;
00048 } ink_t;
00049 
00050 typedef struct raw_printer
00051 {
00052   int output_bits;
00053 } raw_printer_t;
00054 
00055 static const raw_printer_t raw_model_capabilities[] =
00056 {
00057   {
00058     16
00059   },
00060   {
00061     8
00062   },
00063 };
00064 
00065 static const ink_t inks[] =
00066 {
00067   { "RGB", 3, 0, "RGB" },
00068   { "CMY", 3, 0, "CMY" },
00069   { "KCMY", 4, 1, "CMYK" },
00070   { "KCMY", 4, 0, "KCMY" },
00071   { "Whitescale", 1, 0, "RGBGray" },
00072   { "Grayscale", 1, 0, "CMYGray" },
00073 };
00074 
00075 static const int ink_count = sizeof(inks) / sizeof(ink_t);
00076 
00077 static const stp_parameter_t the_parameters[] =
00078 {
00079   {
00080     "InkType", N_("Ink Type"), N_("Advanced Printer Setup"),
00081     N_("Type of ink in the printer"),
00082     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00083     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00084   },
00085   {
00086     "PrintingMode", N_("Printing Mode"), N_("Core Parameter"),
00087     N_("Printing Output Mode"),
00088     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
00089     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00090   },
00091 };
00092 
00093 static const int the_parameter_count =
00094 sizeof(the_parameters) / sizeof(const stp_parameter_t);
00095 
00096 static stp_parameter_list_t
00097 raw_list_parameters(const stp_vars_t *v)
00098 {
00099   stp_parameter_list_t *ret = stp_parameter_list_create();
00100   int i;
00101   for (i = 0; i < the_parameter_count; i++)
00102     stp_parameter_list_add_param(ret, &(the_parameters[i]));
00103   return ret;
00104 }
00105 
00106 static void
00107 raw_parameters(const stp_vars_t *v, const char *name,
00108                stp_parameter_t *description)
00109 {
00110   int           i;
00111   description->p_type = STP_PARAMETER_TYPE_INVALID;
00112   if (name == NULL)
00113     return;
00114 
00115   description->deflt.str = NULL;
00116   for (i = 0; i < the_parameter_count; i++)
00117     if (strcmp(name, the_parameters[i].name) == 0)
00118       {
00119         stp_fill_parameter_settings(description, &(the_parameters[i]));
00120         break;
00121       }
00122   if (strcmp(name, "InkType") == 0)
00123     {
00124       description->bounds.str = stp_string_list_create();
00125       for (i = 0; i < ink_count; i++)
00126         stp_string_list_add_string(description->bounds.str,
00127                                   inks[i].name, inks[i].name);
00128       description->deflt.str =
00129         stp_string_list_param(description->bounds.str, 0)->name;
00130     }
00131   else if (strcmp(name, "PrintingMode") == 0)
00132     {
00133       description->bounds.str = stp_string_list_create();
00134       stp_string_list_add_string
00135         (description->bounds.str, "Color", _("Color"));
00136       stp_string_list_add_string
00137         (description->bounds.str, "BW", _("Black and White"));
00138       description->deflt.str =
00139         stp_string_list_param(description->bounds.str, 0)->name;
00140     }
00141   else
00142     description->is_active = 0;
00143 }
00144 
00145 /*
00146  * 'escp2_imageable_area()' - Return the imageable area of the page.
00147  */
00148 
00149 static void
00150 raw_imageable_area(const stp_vars_t *v,
00151                    int  *left,
00152                    int  *right,
00153                    int  *bottom,
00154                    int  *top)
00155 {
00156   *left = 0;
00157   *top = 0;
00158   *right = stp_get_page_width(v);
00159   *bottom = stp_get_page_height(v);
00160 }
00161 
00162 static void
00163 raw_limit(const stp_vars_t *v,                  /* I */
00164             int *width, int *height,
00165             int *min_width, int *min_height)
00166 {
00167   *width = 65535;
00168   *height = 65535;
00169   *min_width = 1;
00170   *min_height = 1;
00171 }
00172 
00173 static void
00174 raw_describe_resolution(const stp_vars_t *v, int *x, int *y)
00175 {
00176   *x = 72;
00177   *y = 72;
00178 }
00179 
00180 static const char *
00181 raw_describe_output(const stp_vars_t *v)
00182 {
00183   const char *ink_type = stp_get_string_parameter(v, "InkType");
00184   if (ink_type)
00185     {
00186       int i;
00187       for (i = 0; i < ink_count; i++)
00188         if (strcmp(ink_type, inks[i].name) == 0)
00189             return inks[i].output_type;
00190     }
00191   return "RGB";
00192 }
00193 
00194 /*
00195  * 'escp2_print()' - Print an image to an EPSON printer.
00196  */
00197 static int
00198 raw_print(const stp_vars_t *v, stp_image_t *image)
00199 {
00200   int           model = stp_get_model_id(v);
00201   int width = stp_get_page_width(v);
00202   int height = stp_get_page_height(v);
00203   int           i, j;
00204   int           y;              /* Looping vars */
00205   stp_vars_t    *nv = stp_vars_create_copy(v);
00206   int out_channels;
00207   unsigned short *final_out = NULL;
00208   int           status = 1;
00209   int bytes_per_channel = raw_model_capabilities[model].output_bits / 8;
00210   int ink_channels = 1;
00211   int rotate_output = 0;
00212   const char *ink_type = stp_get_string_parameter(nv, "InkType");
00213 
00214   stp_prune_inactive_options(nv);
00215   if (!stp_verify(nv))
00216     {
00217       stp_eprintf(nv, _("Print options not verified; cannot print.\n"));
00218       stp_vars_destroy(nv);
00219       return 0;
00220     }
00221   if (width != stp_image_width(image) || height != stp_image_height(image))
00222     {
00223       stp_eprintf(nv, _("Image dimensions must match paper dimensions"));
00224       stp_vars_destroy(nv);
00225       return 0;
00226     }
00227   if (ink_type)
00228     {
00229       for (i = 0; i < ink_count; i++)
00230         if (strcmp(ink_type, inks[i].name) == 0)
00231           {
00232             stp_set_string_parameter(nv, "STPIOutputType", inks[i].output_type);
00233             ink_channels = inks[i].output_channels;
00234             rotate_output = inks[i].rotate_channels;
00235             break;
00236           }
00237     }
00238 
00239   stp_set_float_parameter(nv, "Density", 1.0);
00240   stp_channel_reset(nv);
00241   for (i = 0; i < ink_channels; i++)
00242     stp_channel_add(nv, i, 0, 1.0);
00243 
00244   if (bytes_per_channel == 1)
00245     out_channels = stp_color_init(nv, image, 256);
00246   else
00247     out_channels = stp_color_init(nv, image, 65536);
00248 
00249   if (out_channels != ink_channels && out_channels != 1 && ink_channels != 1)
00250     {
00251       stp_eprintf(nv, "Internal error!  Output channels or input channels must be 1\n");
00252       stp_vars_destroy(nv);
00253       return 0;
00254     }
00255 
00256   if (out_channels != ink_channels)
00257     final_out = stp_malloc(width * ink_channels * 2);
00258 
00259   for (y = 0; y < height; y++)
00260     {
00261       unsigned short *out;
00262       unsigned short *real_out;
00263       unsigned zero_mask;
00264       if (stp_color_get_row(nv, image, y, &zero_mask))
00265         {
00266           status = 2;
00267           break;
00268         }
00269       out = stp_channel_get_input(nv);
00270       real_out = out;
00271       if (rotate_output)
00272         {
00273           unsigned short *tmp_out = real_out;
00274           for (i = 0; i < width; i++)
00275             {
00276               unsigned short tmp = tmp_out[0];
00277               for (j = 0; j < ink_channels - 1; j++)
00278                 tmp_out[j] = tmp_out[j + 1];
00279               tmp_out[ink_channels - 1] = tmp;
00280               tmp_out += ink_channels;
00281             }
00282         }
00283       if (out_channels != ink_channels)
00284         {
00285           real_out = final_out;
00286           if (out_channels < ink_channels)
00287             {
00288               for (i = 0; i < width; i++)
00289                 {
00290                   for (j = 0; j < ink_channels; j++)
00291                     final_out[i * ink_channels + j] = out[i];
00292                 }
00293             }
00294           else
00295             {
00296               for (i = 0; i < width; i++)
00297                 {
00298                   int avg = 0;
00299                   for (j = 0; j < out_channels; j++)
00300                     avg += out[i * out_channels + j];
00301                   final_out[i] = avg / out_channels;
00302                 }
00303             }
00304         }
00305       if (bytes_per_channel == 1)
00306         {
00307           unsigned char *char_out = (unsigned char *) real_out;
00308           for (i = 0; i < width * ink_channels; i++)
00309             char_out[i] = real_out[i] / 257;
00310         }
00311       stp_zfwrite((char *) real_out,
00312                   width * ink_channels * bytes_per_channel, 1, nv);
00313     }
00314   stp_image_conclude(image);
00315   if (final_out)
00316     stp_free(final_out);
00317   stp_vars_destroy(nv);
00318   return status;
00319 }
00320 
00321 static const stp_printfuncs_t print_raw_printfuncs =
00322 {
00323   raw_list_parameters,
00324   raw_parameters,
00325   stp_default_media_size,
00326   raw_imageable_area,
00327   raw_limit,
00328   raw_print,
00329   raw_describe_resolution,
00330   raw_describe_output,
00331   stp_verify_printer_params,
00332   NULL,
00333   NULL
00334 };
00335 
00336 
00337 
00338 
00339 static stp_family_t print_raw_module_data =
00340   {
00341     &print_raw_printfuncs,
00342     NULL
00343   };
00344 
00345 
00346 static int
00347 print_raw_module_init(void)
00348 {
00349   return stp_family_register(print_raw_module_data.printer_list);
00350 }
00351 
00352 
00353 static int
00354 print_raw_module_exit(void)
00355 {
00356   return stp_family_unregister(print_raw_module_data.printer_list);
00357 }
00358 
00359 
00360 /* Module header */
00361 #define stp_module_version print_raw_LTX_stp_module_version
00362 #define stp_module_data print_raw_LTX_stp_module_data
00363 
00364 stp_module_version_t stp_module_version = {0, 0};
00365 
00366 stp_module_t stp_module_data =
00367   {
00368     "raw",
00369     VERSION,
00370     "RAW family driver",
00371     STP_MODULE_CLASS_FAMILY,
00372     NULL,
00373     print_raw_module_init,
00374     print_raw_module_exit,
00375     (void *) &print_raw_module_data
00376   };

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