DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 

(gimpprint.info.gz) Oversampling

Info Catalog (gimpprint.info.gz) What is perfect weaving? (gimpprint.info.gz) Weaving algorithms
 
 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....
 
Info Catalog (gimpprint.info.gz) What is perfect weaving? (gimpprint.info.gz) Weaving algorithms
automatically generated byinfo2html