00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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,
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
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;
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
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 };