summaryrefslogtreecommitdiff
path: root/doc/manual-html/gimpprint_33.html
blob: edf46275388f4296dc8ffce109b903e8c2a6eb81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
<HTML>
<HEAD>
<!-- This HTML file has been created by texi2html 1.51
     from .././gimpprint.texi on 11 June 2004 -->

<TITLE>GIMP-Print - Oversampling</TITLE>
</HEAD>
<BODY>
Go to the <A HREF="gimpprint_1.html">first</A>, <A HREF="gimpprint_32.html">previous</A>, <A HREF="gimpprint_34.html">next</A>, <A HREF="gimpprint_47.html">last</A> section, <A HREF="gimpprint_toc.html">table of contents</A>.
<P><HR><P>


<H3><A NAME="SEC48" HREF="gimpprint_toc.html#TOC48">B.2.5  Oversampling</A></H3>
<P>
<A NAME="IDX189"></A>

</P>
<P>
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.

</P>
<P>
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.)

</P>
<P>
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.

</P>
<P>
To quantify these two kinds of oversampling, we'll introduce two new
constants: @math{H} shows how many different horizontal offsets we want
to print at (the "horizontal oversampling") while @math{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").

</P>
<P>
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 @math{O=1} for now.

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

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

</P>
<P>
@math{S=4}, @math{J=10}, @math{H=2}, @math{A=J/H=10/2=5},
@math{G=GCD(4,5)=1},
<BR>passesperblock=@math{S}=4,
<BR>passespersubblock=@math{S/G}=4/1=4:

</P>

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

<P>
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 <SAMP>`*'</SAMP>s with integers in the range [0...@math{H-1}].

</P>
<P>
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:

</P>

<PRE>
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--
</PRE>

<P>
@math{S=4},  @math{J=12},  @math{H=2},  @math{A=J/H=12/2=6},  @math{G=GCD(4,6)=2},
<BR>passesperblock=@math{S}=4,
<BR>passespersubblock=@math{S/G}=4/2=2:

</P>

<PRE>
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-
</PRE>

<P>
But what do we do if @math{J} is not an exact multiple of @math{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 @math{J/H} down, then add on the accumulated
error at the end of each band.

</P>
<P>
@math{S=4},  @math{J=11},  @math{H=2}  @math{A=floor(J/H)=floor(11/2)=5},  @math{G=GCD(4,5)},
<BR>passesperblock=@math{S}=4,
<BR>passespersubblock=@math{S/G}=4/1=4

</P>

<PRE>
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---
</PRE>

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

</P>

<PRE>
A = floor(J / H)
subblocksperblock = gcd(S, A)
subpassblock = floor((p % S) * subblocksperblock / S)
if subpassblock * 2 &#60; 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
</PRE>

<P>
So the row number of jet @math{j} of pass @math{p} is

</P>

<PRE>
A = floor(J / H)
subblocksperblock = gcd(S, A)

subblockoffset(p)
    = 2*subpassblock       , if subpassblock * 2 &#60; 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
</PRE>

<P>
To be continued@enddots{}
<P><HR><P>
Go to the <A HREF="gimpprint_1.html">first</A>, <A HREF="gimpprint_32.html">previous</A>, <A HREF="gimpprint_34.html">next</A>, <A HREF="gimpprint_47.html">last</A> section, <A HREF="gimpprint_toc.html">table of contents</A>.
</BODY>
</HTML>