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 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 #include <gimp-print/gimp-print.h>
00032 #include "gimp-print-internal.h"
00033 #include <gimp-print/gimp-print-intl-internal.h>
00034 #ifdef HAVE_LIMITS_H
00035 #include <limits.h>
00036 #endif
00037 #include <math.h>
00038 #include <assert.h>
00039 #include <string.h>
00040 #include "dither-impl.h"
00041
00042 int
00043 stpi_dither_translate_channel(stp_vars_t *v, unsigned channel,
00044 unsigned subchannel)
00045 {
00046 stpi_dither_t *d = (stpi_dither_t *) stp_get_component_data(v, "Dither");
00047 unsigned chan_idx;
00048 if (!d)
00049 return -1;
00050 if (channel >= d->channel_count)
00051 return -1;
00052 if (subchannel >= d->subchannel_count[channel])
00053 return -1;
00054 chan_idx = d->channel_index[channel];
00055 return chan_idx + subchannel;
00056 }
00057
00058 unsigned char *
00059 stp_dither_get_channel(stp_vars_t *v, unsigned channel, unsigned subchannel)
00060 {
00061 stpi_dither_t *d = (stpi_dither_t *) stp_get_component_data(v, "Dither");
00062 int place = stpi_dither_translate_channel(v, channel, subchannel);
00063 if (place >= 0)
00064 return d->channel[place].ptr;
00065 else
00066 return NULL;
00067 }
00068
00069 static void
00070 insert_channel(stp_vars_t *v, stpi_dither_t *d, int channel)
00071 {
00072 unsigned oc = d->channel_count;
00073 int i;
00074 d->channel_index =
00075 stp_realloc (d->channel_index, sizeof(unsigned) * (channel + 1));
00076 d->subchannel_count =
00077 stp_realloc (d->subchannel_count, sizeof(unsigned) * (channel + 1));
00078 for (i = oc; i < channel + 1; i++)
00079 {
00080 if (oc == 0)
00081 d->channel_index[i] = 0;
00082 else
00083 d->channel_index[i] =
00084 d->channel_index[oc - 1] + d->subchannel_count[oc - 1];
00085 d->subchannel_count[i] = 0;
00086 }
00087 d->channel_count = channel + 1;
00088 }
00089
00090 void
00091 stpi_dither_channel_destroy(stpi_dither_channel_t *channel)
00092 {
00093 int i;
00094 STP_SAFE_FREE(channel->ink_list);
00095 if (channel->errs)
00096 {
00097 for (i = 0; i < channel->error_rows; i++)
00098 STP_SAFE_FREE(channel->errs[i]);
00099 STP_SAFE_FREE(channel->errs);
00100 }
00101 STP_SAFE_FREE(channel->ranges);
00102 stp_dither_matrix_destroy(&(channel->pick));
00103 stp_dither_matrix_destroy(&(channel->dithermat));
00104 }
00105
00106 static void
00107 initialize_channel(stp_vars_t *v, int channel, int subchannel)
00108 {
00109 stpi_dither_t *d = (stpi_dither_t *) stp_get_component_data(v, "Dither");
00110 int idx = stpi_dither_translate_channel(v, channel, subchannel);
00111 stpi_dither_channel_t *dc = &(CHANNEL(d, idx));
00112 stp_shade_t shade;
00113 stp_dotsize_t dot;
00114 assert(idx >= 0);
00115 memset(dc, 0, sizeof(stpi_dither_channel_t));
00116 stp_dither_matrix_clone(&(d->dither_matrix), &(dc->dithermat), 0, 0);
00117 stp_dither_matrix_clone(&(d->transition_matrix), &(dc->pick), 0, 0);
00118 shade.dot_sizes = ˙
00119 shade.value = 1.0;
00120 shade.numsizes = 1;
00121 dot.bit_pattern = 1;
00122 dot.value = 1.0;
00123 stp_dither_set_inks_full(v, channel, 1, &shade, 1.0, 1.0);
00124 }
00125
00126 static void
00127 insert_subchannel(stp_vars_t *v, stpi_dither_t *d, int channel, int subchannel)
00128 {
00129 int i;
00130 unsigned oc = d->subchannel_count[channel];
00131 unsigned increment = subchannel - oc + 1;
00132 unsigned old_place = d->channel_index[channel] + oc;
00133 stpi_dither_channel_t *nc =
00134 stp_malloc(sizeof(stpi_dither_channel_t) *
00135 (d->total_channel_count + increment));
00136
00137 if (d->channel)
00138 {
00139
00140
00141
00142
00143 memcpy(nc, d->channel, sizeof(stpi_dither_channel_t) * old_place);
00144 if (old_place < d->total_channel_count)
00145
00146
00147
00148
00149 memcpy(nc + old_place + increment, d->channel + old_place,
00150 (sizeof(stpi_dither_channel_t) *
00151 (d->total_channel_count - old_place)));
00152 stp_free(d->channel);
00153 }
00154 d->channel = nc;
00155 if (channel < d->channel_count - 1)
00156
00157 for (i = channel + 1; i < d->channel_count; i++)
00158 d->channel_index[i] += increment;
00159 d->subchannel_count[channel] = subchannel + 1;
00160 d->total_channel_count += increment;
00161 for (i = oc; i < oc + increment; i++)
00162 initialize_channel(v, channel, i);
00163 }
00164
00165 void
00166 stpi_dither_finalize(stp_vars_t *v)
00167 {
00168 stpi_dither_t *d = (stpi_dither_t *) stp_get_component_data(v, "Dither");
00169 if (!d->finalized)
00170 {
00171 int i;
00172 unsigned rc = 1 + (unsigned) ceil(sqrt(CHANNEL_COUNT(d)));
00173 unsigned x_n = d->dither_matrix.x_size / rc;
00174 unsigned y_n = d->dither_matrix.y_size / rc;
00175 for (i = 0; i < CHANNEL_COUNT(d); i++)
00176 {
00177 stpi_dither_channel_t *dc = &(CHANNEL(d, i));
00178 stp_dither_matrix_clone(&(d->dither_matrix), &(dc->dithermat),
00179 x_n * (i % rc), y_n * (i / rc));
00180 stp_dither_matrix_clone(&(d->dither_matrix), &(dc->pick),
00181 x_n * (i % rc), y_n * (i / rc));
00182 }
00183 d->finalized = 1;
00184 }
00185 }
00186
00187 void
00188 stp_dither_add_channel(stp_vars_t *v, unsigned char *data,
00189 unsigned channel, unsigned subchannel)
00190 {
00191 stpi_dither_t *d = (stpi_dither_t *) stp_get_component_data(v, "Dither");
00192 int idx;
00193 if (channel >= d->channel_count)
00194 insert_channel(v, d, channel);
00195 if (subchannel >= d->subchannel_count[channel])
00196 insert_subchannel(v, d, channel, subchannel);
00197 idx = stpi_dither_translate_channel(v, channel, subchannel);
00198 assert(idx >= 0);
00199 d->channel[idx].ptr = data;
00200 }
00201
00202 static void
00203 stpi_dither_finalize_ranges(stp_vars_t *v, stpi_dither_channel_t *dc)
00204 {
00205 stpi_dither_t *d = (stpi_dither_t *) stp_get_component_data(v, "Dither");
00206 int i;
00207 unsigned lbit = dc->bit_max;
00208 dc->signif_bits = 0;
00209 while (lbit > 0)
00210 {
00211 dc->signif_bits++;
00212 lbit >>= 1;
00213 }
00214
00215 for (i = 0; i < dc->nlevels; i++)
00216 {
00217 if (dc->ranges[i].lower->bits == dc->ranges[i].upper->bits)
00218 dc->ranges[i].is_same_ink = 1;
00219 else
00220 dc->ranges[i].is_same_ink = 0;
00221 if (dc->ranges[i].range_span > 0 && dc->ranges[i].value_span > 0)
00222 dc->ranges[i].is_equal = 0;
00223 else
00224 dc->ranges[i].is_equal = 1;
00225
00226 stp_dprintf(STP_DBG_INK, v,
00227 " level %d value[0] %d value[1] %d range[0] %d range[1] %d\n",
00228 i, dc->ranges[i].lower->value, dc->ranges[i].upper->value,
00229 dc->ranges[i].lower->range, dc->ranges[i].upper->range);
00230 stp_dprintf(STP_DBG_INK, v,
00231 " bits[0] %d bits[1] %d\n",
00232 dc->ranges[i].lower->bits, dc->ranges[i].upper->bits);
00233 stp_dprintf(STP_DBG_INK, v,
00234 " rangespan %d valuespan %d same_ink %d equal %d\n",
00235 dc->ranges[i].range_span, dc->ranges[i].value_span,
00236 dc->ranges[i].is_same_ink, dc->ranges[i].is_equal);
00237 if (i > 0 && dc->ranges[i].lower->range >= d->adaptive_limit)
00238 {
00239 d->adaptive_limit = dc->ranges[i].lower->range + 1;
00240 if (d->adaptive_limit > 65535)
00241 d->adaptive_limit = 65535;
00242 stp_dprintf(STP_DBG_INK, v, "Setting adaptive limit to %d\n",
00243 d->adaptive_limit);
00244 }
00245 }
00246 for (i = 0; i <= dc->nlevels; i++)
00247 stp_dprintf(STP_DBG_INK, v,
00248 " ink_list[%d] range %d value %d bits %d\n",
00249 i, dc->ink_list[i].range,
00250 dc->ink_list[i].value, dc->ink_list[i].bits);
00251 if (dc->nlevels == 1 && dc->ranges[0].upper->bits == 1)
00252 dc->very_fast = 1;
00253 else
00254 dc->very_fast = 0;
00255
00256 stp_dprintf(STP_DBG_INK, v,
00257 " bit_max %d signif_bits %d\n", dc->bit_max, dc->signif_bits);
00258 }
00259
00260 static void
00261 stpi_dither_set_ranges(stp_vars_t *v, int color, const stp_shade_t *shade,
00262 double density, double darkness)
00263 {
00264 stpi_dither_t *d = (stpi_dither_t *) stp_get_component_data(v, "Dither");
00265 stpi_dither_channel_t *dc = &(CHANNEL(d, color));
00266 const stp_dotsize_t *ranges = shade->dot_sizes;
00267 int nlevels = shade->numsizes;
00268 int i;
00269
00270 STP_SAFE_FREE(dc->ranges);
00271 STP_SAFE_FREE(dc->ink_list);
00272
00273 dc->nlevels = nlevels > 1 ? nlevels + 1 : nlevels;
00274 dc->ranges = (stpi_dither_segment_t *)
00275 stp_zalloc(dc->nlevels * sizeof(stpi_dither_segment_t));
00276 dc->ink_list = (stpi_ink_defn_t *)
00277 stp_zalloc((dc->nlevels + 1) * sizeof(stpi_ink_defn_t));
00278 dc->bit_max = 0;
00279 dc->density = density * 65535;
00280 dc->darkness = darkness;
00281 stp_init_debug_messages(v);
00282 stp_dprintf(STP_DBG_INK, v,
00283 "stpi_dither_set_ranges channel %d nlevels %d density %f darkness %f\n",
00284 color, nlevels, density, darkness);
00285 for (i = 0; i < nlevels; i++)
00286 stp_dprintf(STP_DBG_INK, v,
00287 " level %d value %f pattern %x\n", i,
00288 ranges[i].value, ranges[i].bit_pattern);
00289 dc->ranges[0].lower = &dc->ink_list[0];
00290 dc->ranges[0].upper = &dc->ink_list[1];
00291 dc->ink_list[0].range = 0;
00292 dc->ink_list[0].value = 0;
00293 dc->ink_list[0].bits = 0;
00294 if (nlevels == 1)
00295 dc->ink_list[1].range = 65535;
00296 else
00297 dc->ink_list[1].range = ranges[0].value * 65535.0 * density;
00298 if (dc->ink_list[1].range > 65535)
00299 dc->ink_list[1].range = 65535;
00300 dc->ink_list[1].value = ranges[0].value * 65535.0;
00301 if (dc->ink_list[1].value > 65535)
00302 dc->ink_list[1].value = 65535;
00303 dc->ink_list[1].bits = ranges[0].bit_pattern;
00304 if (ranges[0].bit_pattern > dc->bit_max)
00305 dc->bit_max = ranges[0].bit_pattern;
00306 dc->ranges[0].range_span = dc->ranges[0].upper->range;
00307 dc->ranges[0].value_span = dc->ranges[0].upper->value;
00308 if (dc->nlevels > 1)
00309 {
00310 for (i = 1; i < nlevels; i++)
00311 {
00312 int l = i + 1;
00313 dc->ranges[i].lower = &dc->ink_list[i];
00314 dc->ranges[i].upper = &dc->ink_list[l];
00315
00316 dc->ink_list[l].range =
00317 (ranges[i].value + ranges[i].value) * 32768.0 * density;
00318 if (dc->ink_list[l].range > 65535)
00319 dc->ink_list[l].range = 65535;
00320 dc->ink_list[l].value = ranges[i].value * 65535.0;
00321 if (dc->ink_list[l].value > 65535)
00322 dc->ink_list[l].value = 65535;
00323 dc->ink_list[l].bits = ranges[i].bit_pattern;
00324 if (ranges[i].bit_pattern > dc->bit_max)
00325 dc->bit_max = ranges[i].bit_pattern;
00326 dc->ranges[i].range_span =
00327 dc->ink_list[l].range - dc->ink_list[i].range;
00328 dc->ranges[i].value_span =
00329 dc->ink_list[l].value - dc->ink_list[i].value;
00330 }
00331 dc->ranges[i].lower = &dc->ink_list[i];
00332 dc->ranges[i].upper = &dc->ink_list[i+1];
00333 dc->ink_list[i+1] = dc->ink_list[i];
00334 dc->ink_list[i+1].range = 65535;
00335 dc->ranges[i].range_span =
00336 dc->ink_list[i+1].range - dc->ink_list[i].range;
00337 dc->ranges[i].value_span =
00338 dc->ink_list[i+1].value - dc->ink_list[i].value;
00339 }
00340 stpi_dither_finalize_ranges(v, dc);
00341 stp_flush_debug_messages(v);
00342 }
00343
00344 void
00345 stp_dither_set_inks_simple(stp_vars_t *v, int color, int nlevels,
00346 const double *levels, double density,
00347 double darkness)
00348 {
00349 stp_shade_t s;
00350 stp_dotsize_t *d = stp_malloc(nlevels * sizeof(stp_dotsize_t));
00351 int i;
00352 s.dot_sizes = d;
00353 s.value = 65535.0;
00354 s.numsizes = nlevels;
00355
00356 for (i = 0; i < nlevels; i++)
00357 {
00358 d[i].bit_pattern = i + 1;
00359 d[i].value = levels[i];
00360 }
00361 stp_dither_set_inks_full(v, color, 1, &s, density, darkness);
00362 stp_free(d);
00363 }
00364
00365 void
00366 stp_dither_set_inks_full(stp_vars_t *v, int color, int nshades,
00367 const stp_shade_t *shades, double density,
00368 double darkness)
00369 {
00370 int i;
00371 int idx;
00372 stpi_dither_channel_t *dc;
00373
00374 stpi_dither_t *d = (stpi_dither_t *) stp_get_component_data(v, "Dither");
00375
00376 stp_channel_reset_channel(v, color);
00377
00378 for (i = nshades - 1; i >= 0; i--)
00379 {
00380 int subchannel = nshades - i - 1;
00381 idx = stpi_dither_translate_channel(v, color, subchannel);
00382 assert(idx >= 0);
00383 dc = &(CHANNEL(d, idx));
00384
00385 stp_channel_add(v, color, subchannel, shades[i].value);
00386 if (idx >= 0)
00387 stpi_dither_set_ranges(v, idx, &shades[i], density,
00388 shades[i].value * darkness);
00389 stp_dprintf(STP_DBG_INK, v,
00390 " shade %d value %f\n",
00391 i, shades[i].value);
00392 }
00393 }
00394
00395 void
00396 stp_dither_set_inks(stp_vars_t *v, int color, double density, double darkness,
00397 int nshades, const double *svalues,
00398 int ndotsizes, const double *dvalues)
00399 {
00400 int i, j;
00401 stp_shade_t *shades = stp_malloc(sizeof(stp_shade_t) * nshades);
00402 stp_dotsize_t *dotsizes = stp_malloc(sizeof(stp_dotsize_t) * ndotsizes);
00403 j = 0;
00404 for (i = 0; i < ndotsizes; i++)
00405 {
00406
00407 if (dvalues[i] > 0)
00408 {
00409 dotsizes[j].value = dvalues[i];
00410 dotsizes[j].bit_pattern = i + 1;
00411 j++;
00412 }
00413 }
00414 for (i = 0; i < nshades; i++)
00415 {
00416 shades[i].value = svalues[i];
00417 shades[i].numsizes = j;
00418 shades[i].dot_sizes = dotsizes;
00419 }
00420 stp_dither_set_inks_full(v, color, nshades, shades, density, darkness);
00421 stp_free(dotsizes);
00422 stp_free(shades);
00423 }