From: Thomas T. <tt...@bi...> - 2000-05-18 22:23:47
|
Thomas Tonino wrote: > > Thomas, could you play around with your new matrix some more? It's > > not in, because having only one matrix caused problems, but it does > > look promising. It really bloats the executable, though. > > I have a number of things I'm trying. It turns out the things that I'm trying don't work. While CMY dither works fine the transition to K just doesn't work out - even if I use rand() instead of a matrix. This led me to believe that the current K generation needs error diffusion to give a decent result. I changed the following piece: else if (kdarkness < ub) /* Probabilistic */ { /* * Calculate how much black we are going to shuffle away */ if ( kdarkness >= lb ) rk = (kdarkness - lb) * ( ok / rb); else rk = 0; if ( rk > ok ) rk = ok; /* * Pick a range point, depending upon which dither * method we're using */ if ((d->dither_type & ~D_ADAPTIVE_BASE) == D_FLOYD) ditherbit = ((xrand() & 0xffff000) >> 12); else ditherbit = (DITHERPOINT(d, x, row, 4)); ditherbit = ditherbit * rb / 65536; if (rb == 0 || (ditherbit < (kdarkness - lb))) bk = ok; else bk = 0; The calculation of rk is new. rk is the amount of black that will on average be moved to bk by the DITHERPOINT macro. This rk (the amount to be generated) is then subtracted from cmy, just as bk (the amount that was generated) was originally: if (rk > 0) { c -= (d->k_clevel * rk) >> 6; m -= (d->k_mlevel * rk) >> 6; y -= (d->k_ylevel * rk) >> 6; I have to set density a bit lower (to 0.9) and still the density of black seems too high. I tried first with dither_set_black_lower(dither, .1 / bits) in print-escp2.c because that shows problems rather clearly, but with the above changes, the 'green problem' is fixed. Black does build up rather quickly though: dark colors are too dark. But compared to older pictures, the absence of the green problem makes everything look much crisper on my lowly 4 color printer. Going back to .4 for dither_set_black_lower shows a problem: from light to dark, first CMY builds up. At higher density, K also starts to build p. Suddenly, CMY drops off to 0 while K is not up to maximum yet. So there definitely is a problem with the value of rk: maybe it's off by a factor of 65536? The result for photos still looks okay even if dark colors are a bit muted. But in theory, this change looks like an improvement to me. I do not have good insight currently in what kdarkness, ok, and others exactly do. I do know that what I see for dither_set_black_lower = 0.4 demonstrates my code is wrong. I'd like to achieve something along the following lines: /* if c + m + y is more than the paper can absorb, we determine which portion to take off*/ coverage = c + m + y; if ( coverage > maxcoverage ) overcover = maxcoverage - coverage else overcover = 0 /* find out the K component of the color to be printed */ if ( c < m ) kcomponent = c; else kcomponent = m; if ( kcomponent > y ) kcomponent = y; /* if kcomponent = max, we can make blacktoprint max and thus no CMY needs to be printed */ blacktoprint = blackcurve(kcomponent); if ( overcover/3 > blacktoprint ) blacktoprint = overcover/3; /* no CMY will be printed if eff_x_value(max) equals max */ ctoprint = c - eff_c_value(blacktoprint); mtoprint = m - eff_m_value(blacktoprint); ytoprint = y - eff_y_value(blacktoprint); where eff_x_value might be one function if we let the 'greenishness problem' be covered by using black more aggerssively or using color management. It may even be possible to make this work with the right combination of the current variables. It just seems that using the binary dither result to adjust analogue input values is not a good idea for ordered dither, and it may not be a good idea at all. It's late now. The new matrixc will be ready tomorrow morning, but I doubt it will make a significant difference if rand() causes the same problems as re-using the matrix. Maybe K doesn't register exactly with CMY or so - in any case, K buildup in the old code looks very clustery. Thomas |