10
10
#include < map>
11
11
#include < string.h>
12
12
13
+ void make_pwg_hdr (Bytestream& outBts, const PrintParameters& params, bool backside);
14
+ void make_urf_hdr (Bytestream& outBts, const PrintParameters& params);
15
+
16
+ void compress_lines (Bytestream& bmpBts, Bytestream& outBts, const PrintParameters& params, bool backside);
17
+ void compress_line (uint8_t * raw, size_t len, Bytestream& outBts, size_t oneChunk);
18
+
13
19
Bytestream make_pwg_file_hdr ()
14
20
{
15
21
Bytestream pwgFileHdr;
@@ -42,21 +48,27 @@ void bmp_to_pwg(Bytestream& bmpBts, Bytestream& outBts, size_t page, const Print
42
48
size_t yRes = params.getPaperSizeHInPixels ();
43
49
uint8_t * raw = bmpBts.raw ();
44
50
size_t bytesPerLine = params.getPaperSizeWInBytes ();
45
- int step = backside&& params.getBackVFlip () ? -bytesPerLine : bytesPerLine;
46
- uint8_t * row0 = backside&& params.getBackVFlip () ? raw+ (yRes- 1 )* bytesPerLine : raw;
51
+ int oneLine = backside && params.getBackVFlip () ? -bytesPerLine : bytesPerLine;
52
+ uint8_t * row0 = backside && params.getBackVFlip () ? raw + (yRes - 1 ) * bytesPerLine : raw;
47
53
Array<uint8_t > tmpLine (bytesPerLine);
48
54
49
- for (size_t y=0 ; y<yRes; y++)
55
+ size_t colors = params.getNumberOfColors ();
56
+ size_t bpc = params.getBitsPerColor ();
57
+ // A chunk is the unit used for compression.
58
+ // Usually this is the number of bytes per color times the number of colors,
59
+ // but for 1-bit, compression is applied in whole bytes.
60
+ size_t oneChunk = bpc == 1 ? colors : colors * bpc / 8 ;
61
+
62
+ for (size_t y = 0 ; y < yRes; y++)
50
63
{
51
- uint8_t * thisLine = row0+y*step ;
64
+ uint8_t * thisLine = row0 + y * oneLine ;
52
65
uint8_t lineRepeat = 0 ;
53
- size_t colors = params.getNumberOfColors ();
54
66
55
- uint8_t * next_line = thisLine + step ;
67
+ uint8_t * next_line = thisLine + oneLine ;
56
68
while ((y+1 )<yRes && memcmp (thisLine, next_line, bytesPerLine) == 0 )
57
69
{
58
70
y++;
59
- next_line += step ;
71
+ next_line += oneLine ;
60
72
lineRepeat++;
61
73
if (lineRepeat == 255 )
62
74
{
@@ -68,7 +80,7 @@ void bmp_to_pwg(Bytestream& bmpBts, Bytestream& outBts, size_t page, const Print
68
80
if (backside && params.getBackHFlip ())
69
81
{
70
82
// Flip line into tmp buffer
71
- if (params. getBitsPerColor () == 1 )
83
+ if (bpc == 1 )
72
84
{
73
85
for (size_t i = 0 ; i < bytesPerLine; i++)
74
86
{
@@ -78,46 +90,48 @@ void bmp_to_pwg(Bytestream& bmpBts, Bytestream& outBts, size_t page, const Print
78
90
}
79
91
else
80
92
{
81
- for (size_t i = 0 ; i < bytesPerLine; i += colors)
93
+ uint8_t * lastChunk = thisLine + bytesPerLine - oneChunk;
94
+ for (size_t i = 0 ; i < bytesPerLine; i += oneChunk)
82
95
{
83
- memcpy (tmpLine+i, thisLine+bytesPerLine-colors- i, colors );
96
+ memcpy (tmpLine+i, lastChunk- i, oneChunk );
84
97
}
85
98
}
86
- compress_line (tmpLine, bytesPerLine, outBts, colors );
99
+ compress_line (tmpLine, bytesPerLine, outBts, oneChunk );
87
100
}
88
101
else
89
102
{
90
- compress_line (thisLine, bytesPerLine, outBts, colors );
103
+ compress_line (thisLine, bytesPerLine, outBts, oneChunk );
91
104
}
92
105
}
93
106
}
94
107
95
- void compress_line (uint8_t * raw, size_t len, Bytestream& outBts, int colors )
108
+ void compress_line (uint8_t * raw, size_t len, Bytestream& outBts, size_t oneChunk )
96
109
{
97
110
uint8_t * current;
98
111
uint8_t * pos = raw;
99
- uint8_t * epos = raw+len;
112
+ uint8_t * epos = raw + len;
113
+
100
114
while (pos != epos)
101
115
{
102
116
uint8_t * currentStart = pos;
103
117
current = pos;
104
- pos += colors ;
118
+ pos += oneChunk ;
105
119
106
- if (pos == epos || memcmp (pos, current, colors ) == 0 )
120
+ if (pos == epos || memcmp (pos, current, oneChunk ) == 0 )
107
121
{
108
122
int8_t repeat = 0 ;
109
123
// Find number of repititions
110
- while (pos != epos && memcmp (pos, current, colors ) == 0 )
124
+ while (pos != epos && memcmp (pos, current, oneChunk ) == 0 )
111
125
{
112
- pos += colors ;
126
+ pos += oneChunk ;
113
127
repeat++;
114
128
if (repeat == 127 )
115
129
{
116
130
break ;
117
131
}
118
132
}
119
133
outBts << repeat;
120
- outBts.putBytes (current, colors );
134
+ outBts.putBytes (current, oneChunk );
121
135
}
122
136
else
123
137
{
@@ -127,14 +141,14 @@ void compress_line(uint8_t* raw, size_t len, Bytestream& outBts, int colors)
127
141
do
128
142
{
129
143
current = pos;
130
- pos += colors ;
144
+ pos += oneChunk ;
131
145
verbatim++;
132
146
if (verbatim == 127 )
133
147
{
134
148
break ;
135
149
}
136
150
}
137
- while (pos != epos && memcmp (pos, current, colors ) != 0 );
151
+ while (pos != epos && memcmp (pos, current, oneChunk ) != 0 );
138
152
139
153
// This and the next sequence are equal,
140
154
// assume it starts a repeating sequence.
@@ -148,15 +162,15 @@ void compress_line(uint8_t* raw, size_t len, Bytestream& outBts, int colors)
148
162
// But in order to not lean on that (uint8_t)(256)==0, we have this.
149
163
if (verbatim == 1 )
150
164
{ // We ended up with one sequence, encode it as such
151
- pos = currentStart + colors ;
165
+ pos = currentStart + oneChunk ;
152
166
outBts << (uint8_t )0 ;
153
- outBts.putBytes (currentStart, colors );
167
+ outBts.putBytes (currentStart, oneChunk );
154
168
}
155
169
else
156
170
{ // 2 or more non-repeating sequnces
157
- pos = currentStart + verbatim*colors ;
158
- outBts << (uint8_t )(257 - verbatim);
159
- outBts.putBytes (currentStart, verbatim*colors );
171
+ pos = currentStart + verbatim * oneChunk ;
172
+ outBts << (uint8_t )(257 - verbatim);
173
+ outBts.putBytes (currentStart, verbatim * oneChunk );
160
174
}
161
175
}
162
176
}
@@ -193,7 +207,9 @@ void make_pwg_hdr(Bytestream& outBts, const PrintParameters& params, bool backsi
193
207
{PrintParameters::Gray8, PwgPgHdr::sGray },
194
208
{PrintParameters::Black8, PwgPgHdr::Black},
195
209
{PrintParameters::Gray1, PwgPgHdr::sGray },
196
- {PrintParameters::Black1, PwgPgHdr::Black}};
210
+ {PrintParameters::Black1, PwgPgHdr::Black},
211
+ {PrintParameters::sRGB48 , PwgPgHdr::sRGB },
212
+ {PrintParameters::Gray16, PwgPgHdr::sGray }};
197
213
198
214
outHdr.MediaType = params.mediaType ;
199
215
outHdr.Duplex = params.isTwoSided ();
@@ -235,14 +251,16 @@ void make_urf_hdr(Bytestream& outBts, const PrintParameters& params)
235
251
static const std::map<PrintParameters::ColorMode, UrfPgHdr::ColorSpace_enum>
236
252
urfColorSpaceMappings {{PrintParameters::sRGB24 , UrfPgHdr::sRGB },
237
253
{PrintParameters::CMYK32, UrfPgHdr::CMYK},
238
- {PrintParameters::Gray8, UrfPgHdr::sGray }};
254
+ {PrintParameters::Gray8, UrfPgHdr::sGray },
255
+ {PrintParameters::sRGB48 , UrfPgHdr::sRGB },
256
+ {PrintParameters::Gray16, UrfPgHdr::sGray }};
239
257
240
258
static const std::map<PrintParameters::DuplexMode, UrfPgHdr::Duplex_enum>
241
259
urfDuplexMappings {{PrintParameters::OneSided, UrfPgHdr::OneSided},
242
260
{PrintParameters::TwoSidedLongEdge, UrfPgHdr::TwoSidedLongEdge},
243
261
{PrintParameters::TwoSidedShortEdge, UrfPgHdr::TwoSidedShortEdge}};
244
262
245
- outHdr.BitsPerPixel = 8 * params.getNumberOfColors ();
263
+ outHdr.BitsPerPixel = params.getNumberOfColors () * params. getBitsPerColor ();
246
264
outHdr.ColorSpace = urfColorSpaceMappings.at (params.colorMode );
247
265
outHdr.Duplex = urfDuplexMappings.at (params.duplexMode );
248
266
outHdr.setQuality (params.quality );
0 commit comments