GNU Info

Info Node: (gimpprint.info)Oversampling

(gimpprint.info)Oversampling


Prev: What is perfect weaving? Up: Weaving algorithms
Enter node , (file) or (file)node

Oversampling
------------

   By oversampling, we mean printing on the same row more than once.
There are two reasons for oversampling: to increase the horizontal
resolution of the printout and to reduce banding.

   Oversampling to increase horizontal resolution is necessary because,
although the printer might be able to position an ink drop to, for
example, 1/1440" horizontally, it may not be able to lay down two such
drops 1/1440" apart.  If it can print two drops 1/720" apart, 2x
oversampling will be necessary to get a 1/1440" horizontal resolution.
If it can only print two drops 1/360" apart, 4x oversampling will be
necessary for a 1/1440" horizontal resolution.  The printer enforces
this "drop spacing" by only accepting raster passes with a horizontal
resolution matching the spacing with which it can print dots, so we
must print passes at different horizontal positions if we are to obtain
a higher horizontal resolution.  (Another reason it does this may be to
reduce the amount of memory needed in the printer.)

   Oversampling can also be done to decrease the banding apparent in an
image.  By splitting a row into two or more sets of dots ("lines") and
printing each line on the same row, but with a different nozzle for
each line, we can get a smoother print.

   To quantify these two kinds of oversampling, we'll introduce two new
constants: H shows how many different horizontal offsets we want to
print at (the "horizontal oversampling") while O shows how many times
we want to print each row, over and above the number of times necessary
for horizontal oversampling (the "extra oversampling").

   It is necessary for all the lines printed by a given pass to have the
same horizontal offset, but there need not be any relation between them
in terms of extra oversampling.  For the moment, however, we will treat
all oversampling as potentially requiring this alignment; all lines in
one pass must be derived from the original row data in the same way.
Thus, we'll assume O=1 for now.

   So, how do we do this oversampling?  In fact, it can be done easily:
advance the paper by a factor of H less between each pass.  We'll
define a new variable, A, to show how much we advance the paper between
passes.  Previously, we'd have defined A=J; we now let A=J/H.  This
also affects our pass blocks.  Printing one pass block used to involve
advancing the paper S*J rows; it now advances the paper S*J/H rows.  We
therefore name a group of H pass blocks a "band".  Printing one band
involves advancing the paper S*J rows, as a pass block did before.

   To keep our weave pattern working correctly, so that overprinting
does not occur within a pass block, we also have to redefine G as
GCD(S,A).  Here's an example of an oversampled weave pattern:

S=4, J=10, H=2, A=J/H=10/2=5, G=GCD(4,5)=1,
passesperblock=S=4,
passespersubblock=S/G=4/1=4:

     0 *---*---*---*---*---*---*---*---*---*
     1      *---*---*---*---*---*---*---*---*---*
     2           *---*---*---*---*---*---*---*---*---*
     3                *---*---*---*---*---*---*---*---*---*
     4                     *---*---*---*---*---*---*---*---*---*
     5                          *---*---*---*---*---*---*---*---*---*
     6                               *---*---*---*---*---*---*---*---*---*
     7                                    *---*---*---*---*---*---*---*---*---*
     8                                         *---*---*---*---*---*---*---*---*---*
     9                                              *---*---*---*---*---*---*---*---*
     10                                                  *---*---*---*---*---*---*---
     11                                                       *---*---*---*---*---*--
     12                                                            *---*---*---*---*-
     13                                                                 *---*---*---*
     14                                                                      *---*---
     15                                                                           *--

   Now we have to determine which line is printed by each jet on each
pass.  If we number each line generated as we split up a row, we can
use these numbers.  We'll number the lines in our diagram by replacing
the `*'s with integers in the range [0...H-1].

   Overprinting occurs once per pass block, so we can simply print pass
block 0 with line 0, pass block 1 with line 1, pass block 2 with line
2, etc, wrapping to 0 when we've run out of lines:

     0 0---0---0---0---0---0---0---0---0---0
     1      0---0---0---0---0---0---0---0---0---0
     2           0---0---0---0---0---0---0---0---0---0
     3                0---0---0---0---0---0---0---0---0---0
     4                     1---1---1---1---1---1---1---1---1---1
     5                          1---1---1---1---1---1---1---1---1---1
     6                               1---1---1---1---1---1---1---1---1---1
     7                                    1---1---1---1---1---1---1---1---1---1
     8                                         0---0---0---0---0---0---0---0---0---0
     9                                              0---0---0---0---0---0---0---0---0
     10                                                  0---0---0---0---0---0---0---
     11                                                       0---0---0---0---0---0--
     12                                                            1---1---1---1---1-
     13                                                                 1---1---1---1
     14                                                                      1---1---
     15                                                                           1--

S=4,  J=12,  H=2,  A=J/H=12/2=6,  G=GCD(4,6)=2,
passesperblock=S=4,
passespersubblock=S/G=4/2=2:

     0 0---0---0---0---0---0---0---0---0---0---0---0
     1       0---0---0---0---0---0---0---0---0---0---0---0
     2              0---0---0---0---0---0---0---0---0---0---0---0
     3                    0---0---0---0---0---0---0---0---0---0---0---0
     4                         1---1---1---1---1---1---1---1---1---1---1---1
     5                               1---1---1---1---1---1---1---1---1---1---1---1
     6                                      1---1---1---1---1---1---1---1---1---1---1
     7                                            1---1---1---1---1---1---1---1---1--
     8                                                 0---0---0---0---0---0---0---0-
     9                                                       0---0---0---0---0---0---
     10                                                             0---0---0---0---0
     11                                                                   0---0---0--
     12                                                                        1---1-

   But what do we do if J is not an exact multiple of H?  This is a
difficult problem, which I struggled with for quite a few days before
giving in and taking the easy (but less elegant) way out.  The easy
solution is to round J/H down, then add on the accumulated error at the
end of each band.

S=4,  J=11,  H=2  A=floor(J/H)=floor(11/2)=5,  G=GCD(4,5),
passesperblock=S=4,
passespersubblock=S/G=4/1=4

     Band 0:
     0 0---0---0---0---0---0---0---0---0---0---0
     1      0---0---0---0---0---0---0---0---0---0---0
     2           0---0---0---0---0---0---0---0---0---0---0
     3                0---0---0---0---0---0---0---0---0---0---0
     4                     1---1---1---1---1---1---1---1---1---1---1
     5                          1---1---1---1---1---1---1---1---1---1---1
     6                               1---1---1---1---1---1---1---1---1---1---1
     7                                    1---1---1---1---1---1---1---1---1---1---
     
     Band 1:
     8 |                                           0---0---0---0---0---0---0---0---0-
     9  \-----------------------------------------/     0---0---0---0---0---0---0---0
     10                   S*J rows                           0---0---0---0---0---0---
     11                                                           0---0---0---0---0--
     12                                                                1---1---1---1-
     13                                                                     1---1---1
     14                                                                          1---

   We can calculate the starting row and subpass number of a given pass
in this scheme as follows:

     A = floor(J / H)
     subblocksperblock = gcd(S, A)
     subpassblock = floor((p % S) * subblocksperblock / S)
     if subpassblock * 2 < subblocksperblock
         subblockoffset = 2*subpassblock
     else
         subblockoffset = 2*(subblocksperblock-subpassblock)-1
     band = floor(P / (S * H))
     passinband = P % (S * H)
     startingrow = band * S * J + passinband * A + subblockoffset
     subpass = passinband / S

   So the row number of jet j of pass p is

     A = floor(J / H)
     subblocksperblock = gcd(S, A)
     
     subblockoffset(p)
         = 2*subpassblock       , if subpassblock * 2 < subblocksperblock
         = 2*(subblocksperblock-subpassblock)-1      , otherwise
           where
           subpassblock = floor((p % S) * subblocksperblock / S)
     
     band(p) = floor(p / (S * H))
     passinband(p) = p % (S * H)
     
     row(j, p) = band(p) * S * J + passinband(p) * A + subblockoffset(p) + j * S
     row(j, p) = p * J + subblockoffset(p) + j * S

   To be continued....


automatically generated by info2www version 1.2.2.9