Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "psputil.hxx"
21 :
22 : #include "generic/printergfx.hxx"
23 : #include "vcl/strhelper.hxx"
24 :
25 : namespace psp {
26 :
27 : const sal_uInt32 nLineLength = 80;
28 : const sal_uInt32 nBufferSize = 16384;
29 :
30 : /*
31 : *
32 : * Bitmap compression / Hex encoding / Ascii85 Encoding
33 : *
34 : */
35 :
36 0 : PrinterBmp::~PrinterBmp()
37 : {
38 0 : }
39 :
40 : /* virtual base class */
41 :
42 0 : class ByteEncoder
43 : {
44 : private:
45 :
46 : public:
47 :
48 : virtual void EncodeByte (sal_uInt8 nByte) = 0;
49 : virtual ~ByteEncoder () = 0;
50 : };
51 :
52 0 : ByteEncoder::~ByteEncoder()
53 : {
54 0 : }
55 :
56 : /* HexEncoder */
57 :
58 : class HexEncoder : public ByteEncoder
59 : {
60 : private:
61 :
62 : osl::File* mpFile;
63 : sal_uInt32 mnColumn;
64 : sal_uInt32 mnOffset;
65 : sal_Char mpFileBuffer[nBufferSize + 16];
66 :
67 : public:
68 :
69 : explicit HexEncoder (osl::File* pFile);
70 : virtual ~HexEncoder ();
71 : void WriteAscii (sal_uInt8 nByte);
72 : virtual void EncodeByte (sal_uInt8 nByte) SAL_OVERRIDE;
73 : void FlushLine ();
74 : };
75 :
76 0 : HexEncoder::HexEncoder (osl::File* pFile) :
77 : mpFile (pFile),
78 : mnColumn (0),
79 0 : mnOffset (0)
80 0 : {}
81 :
82 0 : HexEncoder::~HexEncoder ()
83 : {
84 0 : FlushLine ();
85 0 : if (mnColumn > 0)
86 0 : WritePS (mpFile, "\n");
87 0 : }
88 :
89 : void
90 0 : HexEncoder::WriteAscii (sal_uInt8 nByte)
91 : {
92 0 : sal_uInt32 nOff = psp::getHexValueOf (nByte, mpFileBuffer + mnOffset);
93 0 : mnColumn += nOff;
94 0 : mnOffset += nOff;
95 :
96 0 : if (mnColumn >= nLineLength)
97 : {
98 0 : mnOffset += psp::appendStr ("\n", mpFileBuffer + mnOffset);
99 0 : mnColumn = 0;
100 : }
101 0 : if (mnOffset >= nBufferSize)
102 0 : FlushLine ();
103 0 : }
104 :
105 : void
106 0 : HexEncoder::EncodeByte (sal_uInt8 nByte)
107 : {
108 0 : WriteAscii (nByte);
109 0 : }
110 :
111 : void
112 0 : HexEncoder::FlushLine ()
113 : {
114 0 : if (mnOffset > 0)
115 : {
116 0 : WritePS (mpFile, mpFileBuffer, mnOffset);
117 0 : mnOffset = 0;
118 : }
119 0 : }
120 :
121 : /* Ascii85 encoder, is abi compatible with HexEncoder but writes a ~> to
122 : indicate end of data EOD */
123 :
124 : class Ascii85Encoder : public ByteEncoder
125 : {
126 : private:
127 :
128 : osl::File* mpFile;
129 : sal_uInt32 mnByte;
130 : sal_uInt8 mpByteBuffer[4];
131 :
132 : sal_uInt32 mnColumn;
133 : sal_uInt32 mnOffset;
134 : sal_Char mpFileBuffer[nBufferSize + 16];
135 :
136 : inline void PutByte (sal_uInt8 nByte);
137 : inline void PutEOD ();
138 : void ConvertToAscii85 ();
139 : void FlushLine ();
140 :
141 : public:
142 :
143 : explicit Ascii85Encoder (osl::File* pFile);
144 : virtual ~Ascii85Encoder ();
145 : virtual void EncodeByte (sal_uInt8 nByte) SAL_OVERRIDE;
146 : void WriteAscii (sal_uInt8 nByte);
147 : };
148 :
149 0 : Ascii85Encoder::Ascii85Encoder (osl::File* pFile) :
150 : mpFile (pFile),
151 : mnByte (0),
152 : mnColumn (0),
153 0 : mnOffset (0)
154 0 : {}
155 :
156 : inline void
157 0 : Ascii85Encoder::PutByte (sal_uInt8 nByte)
158 : {
159 0 : mpByteBuffer [mnByte++] = nByte;
160 0 : }
161 :
162 : inline void
163 0 : Ascii85Encoder::PutEOD ()
164 : {
165 0 : WritePS (mpFile, "~>\n");
166 0 : }
167 :
168 : void
169 0 : Ascii85Encoder::ConvertToAscii85 ()
170 : {
171 0 : if (mnByte < 4)
172 0 : std::memset (mpByteBuffer + mnByte, 0, (4 - mnByte) * sizeof(sal_uInt8));
173 :
174 0 : sal_uInt32 nByteValue = mpByteBuffer[0] * 256 * 256 * 256
175 0 : + mpByteBuffer[1] * 256 * 256
176 0 : + mpByteBuffer[2] * 256
177 0 : + mpByteBuffer[3];
178 :
179 0 : if (nByteValue == 0 && mnByte == 4)
180 : {
181 : /* special case of 4 Bytes in row */
182 0 : mpFileBuffer [mnOffset] = 'z';
183 :
184 0 : mnOffset += 1;
185 0 : mnColumn += 1;
186 : }
187 : else
188 : {
189 : /* real ascii85 encoding */
190 0 : mpFileBuffer [mnOffset + 4] = (nByteValue % 85) + 33;
191 0 : nByteValue /= 85;
192 0 : mpFileBuffer [mnOffset + 3] = (nByteValue % 85) + 33;
193 0 : nByteValue /= 85;
194 0 : mpFileBuffer [mnOffset + 2] = (nByteValue % 85) + 33;
195 0 : nByteValue /= 85;
196 0 : mpFileBuffer [mnOffset + 1] = (nByteValue % 85) + 33;
197 0 : nByteValue /= 85;
198 0 : mpFileBuffer [mnOffset + 0] = (nByteValue % 85) + 33;
199 :
200 0 : mnColumn += (mnByte + 1);
201 0 : mnOffset += (mnByte + 1);
202 :
203 : /* insert a newline if necessary */
204 0 : if (mnColumn > nLineLength)
205 : {
206 0 : sal_uInt32 nEolOff = mnColumn - nLineLength;
207 0 : sal_uInt32 nBufOff = mnOffset - nEolOff;
208 :
209 0 : std::memmove (mpFileBuffer + nBufOff + 1, mpFileBuffer + nBufOff, nEolOff);
210 0 : mpFileBuffer[ nBufOff ] = '\n';
211 :
212 0 : mnOffset++;
213 0 : mnColumn = nEolOff;
214 : }
215 : }
216 :
217 0 : mnByte = 0;
218 0 : }
219 :
220 : void
221 0 : Ascii85Encoder::WriteAscii (sal_uInt8 nByte)
222 : {
223 0 : PutByte (nByte);
224 0 : if (mnByte == 4)
225 0 : ConvertToAscii85 ();
226 :
227 0 : if (mnColumn >= nLineLength)
228 : {
229 0 : mnOffset += psp::appendStr ("\n", mpFileBuffer + mnOffset);
230 0 : mnColumn = 0;
231 : }
232 0 : if (mnOffset >= nBufferSize)
233 0 : FlushLine ();
234 0 : }
235 :
236 : void
237 0 : Ascii85Encoder::EncodeByte (sal_uInt8 nByte)
238 : {
239 0 : WriteAscii (nByte);
240 0 : }
241 :
242 : void
243 0 : Ascii85Encoder::FlushLine ()
244 : {
245 0 : if (mnOffset > 0)
246 : {
247 0 : WritePS (mpFile, mpFileBuffer, mnOffset);
248 0 : mnOffset = 0;
249 : }
250 0 : }
251 :
252 0 : Ascii85Encoder::~Ascii85Encoder ()
253 : {
254 0 : if (mnByte > 0)
255 0 : ConvertToAscii85 ();
256 0 : if (mnOffset > 0)
257 0 : FlushLine ();
258 0 : PutEOD ();
259 0 : }
260 :
261 : /* LZW encoder */
262 :
263 : class LZWEncoder : public Ascii85Encoder
264 : {
265 : private:
266 :
267 : struct LZWCTreeNode
268 : {
269 : LZWCTreeNode* mpBrother; // next node with same parent
270 : LZWCTreeNode* mpFirstChild; // first son
271 : sal_uInt16 mnCode; // code for the string
272 : sal_uInt16 mnValue; // pixelvalue
273 : };
274 :
275 : LZWCTreeNode* mpTable; // LZW compression data
276 : LZWCTreeNode* mpPrefix; // the compression is as same as the TIFF compression
277 : sal_uInt16 mnDataSize;
278 : sal_uInt16 mnClearCode;
279 : sal_uInt16 mnEOICode;
280 : sal_uInt16 mnTableSize;
281 : sal_uInt16 mnCodeSize;
282 : sal_uInt32 mnOffset;
283 : sal_uInt32 mdwShift;
284 :
285 : void WriteBits (sal_uInt16 nCode, sal_uInt16 nCodeLen);
286 :
287 : public:
288 :
289 : explicit LZWEncoder (osl::File* pOutputFile);
290 : virtual ~LZWEncoder ();
291 :
292 : virtual void EncodeByte (sal_uInt8 nByte) SAL_OVERRIDE;
293 : };
294 :
295 0 : LZWEncoder::LZWEncoder(osl::File* pOutputFile) :
296 0 : Ascii85Encoder (pOutputFile)
297 : {
298 0 : mnDataSize = 8;
299 :
300 0 : mnClearCode = 1 << mnDataSize;
301 0 : mnEOICode = mnClearCode + 1;
302 0 : mnTableSize = mnEOICode + 1;
303 0 : mnCodeSize = mnDataSize + 1;
304 :
305 0 : mnOffset = 32; // free bits in dwShift
306 0 : mdwShift = 0;
307 :
308 0 : mpTable = new LZWCTreeNode[ 4096 ];
309 :
310 0 : for (sal_uInt32 i = 0; i < 4096; i++)
311 : {
312 0 : mpTable[i].mpBrother = NULL;
313 0 : mpTable[i].mpFirstChild = NULL;
314 0 : mpTable[i].mnCode = i;
315 0 : mpTable[i].mnValue = (sal_uInt8)mpTable[i].mnCode;
316 : }
317 :
318 0 : mpPrefix = NULL;
319 :
320 0 : WriteBits( mnClearCode, mnCodeSize );
321 0 : }
322 :
323 0 : LZWEncoder::~LZWEncoder()
324 : {
325 0 : if (mpPrefix)
326 0 : WriteBits (mpPrefix->mnCode, mnCodeSize);
327 :
328 0 : WriteBits (mnEOICode, mnCodeSize);
329 :
330 0 : delete[] mpTable;
331 0 : }
332 :
333 : void
334 0 : LZWEncoder::WriteBits (sal_uInt16 nCode, sal_uInt16 nCodeLen)
335 : {
336 0 : mdwShift |= (nCode << (mnOffset - nCodeLen));
337 0 : mnOffset -= nCodeLen;
338 0 : while (mnOffset < 24)
339 : {
340 0 : WriteAscii ((sal_uInt8)(mdwShift >> 24));
341 0 : mdwShift <<= 8;
342 0 : mnOffset += 8;
343 : }
344 0 : if (nCode == 257 && mnOffset != 32)
345 0 : WriteAscii ((sal_uInt8)(mdwShift >> 24));
346 0 : }
347 :
348 : void
349 0 : LZWEncoder::EncodeByte (sal_uInt8 nByte )
350 : {
351 : LZWCTreeNode* p;
352 : sal_uInt16 i;
353 : sal_uInt8 nV;
354 :
355 0 : if (!mpPrefix)
356 : {
357 0 : mpPrefix = mpTable + nByte;
358 : }
359 : else
360 : {
361 0 : nV = nByte;
362 0 : for (p = mpPrefix->mpFirstChild; p != NULL; p = p->mpBrother)
363 : {
364 0 : if (p->mnValue == nV)
365 0 : break;
366 : }
367 :
368 0 : if (p != NULL)
369 : {
370 0 : mpPrefix = p;
371 : }
372 : else
373 : {
374 0 : WriteBits (mpPrefix->mnCode, mnCodeSize);
375 :
376 0 : if (mnTableSize == 409)
377 : {
378 0 : WriteBits (mnClearCode, mnCodeSize);
379 :
380 0 : for (i = 0; i < mnClearCode; i++)
381 0 : mpTable[i].mpFirstChild = NULL;
382 :
383 0 : mnCodeSize = mnDataSize + 1;
384 0 : mnTableSize = mnEOICode + 1;
385 : }
386 : else
387 : {
388 0 : if(mnTableSize == (sal_uInt16)((1 << mnCodeSize) - 1))
389 0 : mnCodeSize++;
390 :
391 0 : p = mpTable + (mnTableSize++);
392 0 : p->mpBrother = mpPrefix->mpFirstChild;
393 0 : mpPrefix->mpFirstChild = p;
394 0 : p->mnValue = nV;
395 0 : p->mpFirstChild = NULL;
396 : }
397 :
398 0 : mpPrefix = mpTable + nV;
399 : }
400 : }
401 0 : }
402 :
403 : /*
404 : *
405 : * bitmap handling routines
406 : *
407 : */
408 :
409 : void
410 0 : PrinterGfx::DrawBitmap (const Rectangle& rDest, const Rectangle& rSrc,
411 : const PrinterBmp& rBitmap)
412 : {
413 0 : double fScaleX = (double)rDest.GetWidth();
414 0 : double fScaleY = (double)rDest.GetHeight();
415 0 : if(rSrc.GetWidth() > 0)
416 : {
417 0 : fScaleX = (double)rDest.GetWidth() / (double)rSrc.GetWidth();
418 : }
419 0 : if(rSrc.GetHeight() > 0)
420 : {
421 0 : fScaleY = (double)rDest.GetHeight() / (double)rSrc.GetHeight();
422 : }
423 0 : PSGSave ();
424 0 : PSTranslate (rDest.BottomLeft());
425 0 : PSScale (fScaleX, fScaleY);
426 :
427 0 : if (mnPSLevel >= 2)
428 : {
429 0 : if (rBitmap.GetDepth() == 1)
430 : {
431 0 : DrawPS2MonoImage (rBitmap, rSrc);
432 : }
433 : else
434 0 : if (rBitmap.GetDepth() == 8 && mbColor)
435 : {
436 : // if the palette is larger than the image itself print it as a truecolor
437 : // image to save diskspace. This is important for printing transparent
438 : // bitmaps that are disassembled into small pieces
439 0 : sal_Int32 nImageSz = rSrc.GetWidth() * rSrc.GetHeight();
440 0 : sal_Int32 nPaletteSz = rBitmap.GetPaletteEntryCount();
441 0 : if ((nImageSz < nPaletteSz) || (nImageSz < 24) )
442 0 : DrawPS2TrueColorImage (rBitmap, rSrc);
443 : else
444 0 : DrawPS2PaletteImage (rBitmap, rSrc);
445 : }
446 : else
447 0 : if (rBitmap.GetDepth() == 24 && mbColor)
448 : {
449 0 : DrawPS2TrueColorImage (rBitmap, rSrc);
450 : }
451 : else
452 : {
453 0 : DrawPS2GrayImage (rBitmap, rSrc);
454 : }
455 : }
456 : else
457 : {
458 0 : DrawPS1GrayImage (rBitmap, rSrc);
459 : }
460 :
461 0 : PSGRestore ();
462 0 : }
463 :
464 : /*
465 : *
466 : * Implementation: PS Level 1
467 : *
468 : */
469 :
470 : void
471 0 : PrinterGfx::DrawPS1GrayImage (const PrinterBmp& rBitmap, const Rectangle& rArea)
472 : {
473 0 : sal_uInt32 nWidth = rArea.GetWidth();
474 0 : sal_uInt32 nHeight = rArea.GetHeight();
475 :
476 : sal_Char pGrayImage [512];
477 0 : sal_Int32 nChar = 0;
478 :
479 : // image header
480 0 : nChar += psp::getValueOf (nWidth, pGrayImage + nChar);
481 0 : nChar += psp::appendStr (" ", pGrayImage + nChar);
482 0 : nChar += psp::getValueOf (nHeight, pGrayImage + nChar);
483 0 : nChar += psp::appendStr (" 8 ", pGrayImage + nChar);
484 0 : nChar += psp::appendStr ("[ 1 0 0 1 0 ", pGrayImage + nChar);
485 0 : nChar += psp::getValueOf (nHeight, pGrayImage + nChar);
486 0 : nChar += psp::appendStr ("]", pGrayImage + nChar);
487 0 : nChar += psp::appendStr (" {currentfile ", pGrayImage + nChar);
488 0 : nChar += psp::getValueOf (nWidth, pGrayImage + nChar);
489 0 : nChar += psp::appendStr (" string readhexstring pop}\n", pGrayImage + nChar);
490 0 : nChar += psp::appendStr ("image\n", pGrayImage + nChar);
491 :
492 0 : WritePS (mpPageBody, pGrayImage);
493 :
494 : // image body
495 0 : std::unique_ptr<HexEncoder> xEncoder(new HexEncoder (mpPageBody));
496 :
497 0 : for (long nRow = rArea.Top(); nRow <= rArea.Bottom(); nRow++)
498 : {
499 0 : for (long nColumn = rArea.Left(); nColumn <= rArea.Right(); nColumn++)
500 : {
501 0 : unsigned char nByte = rBitmap.GetPixelGray (nRow, nColumn);
502 0 : xEncoder->EncodeByte (nByte);
503 : }
504 : }
505 :
506 0 : xEncoder.reset();
507 :
508 0 : WritePS (mpPageBody, "\n");
509 0 : }
510 :
511 : /*
512 : *
513 : * Implementation: PS Level 2
514 : *
515 : */
516 :
517 : void
518 0 : PrinterGfx::writePS2ImageHeader (const Rectangle& rArea, psp::ImageType nType)
519 : {
520 0 : sal_Int32 nChar = 0;
521 : sal_Char pImage [512];
522 :
523 0 : sal_Int32 nDictType = 0;
524 0 : switch (nType)
525 : {
526 0 : case psp::TrueColorImage: nDictType = 0; break;
527 0 : case psp::PaletteImage: nDictType = 1; break;
528 0 : case psp::GrayScaleImage: nDictType = 2; break;
529 0 : case psp::MonochromeImage: nDictType = 3; break;
530 0 : default: break;
531 : }
532 0 : sal_Int32 nCompressType = mbCompressBmp ? 1 : 0;
533 :
534 0 : nChar += psp::getValueOf (rArea.GetWidth(), pImage + nChar);
535 0 : nChar += psp::appendStr (" ", pImage + nChar);
536 0 : nChar += psp::getValueOf (rArea.GetHeight(), pImage + nChar);
537 0 : nChar += psp::appendStr (" ", pImage + nChar);
538 0 : nChar += psp::getValueOf (nDictType, pImage + nChar);
539 0 : nChar += psp::appendStr (" ", pImage + nChar);
540 0 : nChar += psp::getValueOf (nCompressType, pImage + nChar);
541 0 : nChar += psp::appendStr (" psp_imagedict image\n", pImage + nChar);
542 :
543 0 : WritePS (mpPageBody, pImage);
544 0 : }
545 :
546 : void
547 0 : PrinterGfx::writePS2Colorspace(const PrinterBmp& rBitmap, psp::ImageType nType)
548 : {
549 0 : switch (nType)
550 : {
551 : case psp::GrayScaleImage:
552 :
553 0 : WritePS (mpPageBody, "/DeviceGray setcolorspace\n");
554 0 : break;
555 :
556 : case psp::TrueColorImage:
557 :
558 0 : WritePS (mpPageBody, "/DeviceRGB setcolorspace\n");
559 0 : break;
560 :
561 : case psp::MonochromeImage:
562 : case psp::PaletteImage:
563 : {
564 :
565 0 : sal_Int32 nChar = 0;
566 : sal_Char pImage [4096];
567 :
568 0 : const sal_uInt32 nSize = rBitmap.GetPaletteEntryCount();
569 :
570 0 : nChar += psp::appendStr ("[/Indexed /DeviceRGB ", pImage + nChar);
571 0 : nChar += psp::getValueOf (nSize - 1, pImage + nChar);
572 0 : if (mbCompressBmp)
573 0 : nChar += psp::appendStr ("\npsp_lzwstring\n", pImage + nChar);
574 : else
575 0 : nChar += psp::appendStr ("\npsp_ascii85string\n", pImage + nChar);
576 0 : WritePS (mpPageBody, pImage);
577 :
578 0 : std::unique_ptr<ByteEncoder> xEncoder(mbCompressBmp ? new LZWEncoder(mpPageBody)
579 0 : : new Ascii85Encoder(mpPageBody));
580 0 : for (sal_uInt32 i = 0; i < nSize; i++)
581 : {
582 0 : PrinterColor aColor = rBitmap.GetPaletteColor(i);
583 :
584 0 : xEncoder->EncodeByte (aColor.GetRed());
585 0 : xEncoder->EncodeByte (aColor.GetGreen());
586 0 : xEncoder->EncodeByte (aColor.GetBlue());
587 0 : }
588 0 : xEncoder.reset();
589 :
590 0 : WritePS (mpPageBody, "pop ] setcolorspace\n");
591 : }
592 0 : break;
593 0 : default: break;
594 : }
595 0 : }
596 :
597 : void
598 0 : PrinterGfx::DrawPS2GrayImage (const PrinterBmp& rBitmap, const Rectangle& rArea)
599 : {
600 0 : writePS2Colorspace(rBitmap, psp::GrayScaleImage);
601 0 : writePS2ImageHeader(rArea, psp::GrayScaleImage);
602 :
603 0 : std::unique_ptr<ByteEncoder> xEncoder(mbCompressBmp ? new LZWEncoder(mpPageBody)
604 0 : : new Ascii85Encoder(mpPageBody));
605 :
606 0 : for (long nRow = rArea.Top(); nRow <= rArea.Bottom(); nRow++)
607 : {
608 0 : for (long nColumn = rArea.Left(); nColumn <= rArea.Right(); nColumn++)
609 : {
610 0 : unsigned char nByte = rBitmap.GetPixelGray (nRow, nColumn);
611 0 : xEncoder->EncodeByte (nByte);
612 : }
613 0 : }
614 0 : }
615 :
616 : void
617 0 : PrinterGfx::DrawPS2MonoImage (const PrinterBmp& rBitmap, const Rectangle& rArea)
618 : {
619 0 : writePS2Colorspace(rBitmap, psp::MonochromeImage);
620 0 : writePS2ImageHeader(rArea, psp::MonochromeImage);
621 :
622 0 : std::unique_ptr<ByteEncoder> xEncoder(mbCompressBmp ? new LZWEncoder(mpPageBody)
623 0 : : new Ascii85Encoder(mpPageBody));
624 :
625 0 : for (long nRow = rArea.Top(); nRow <= rArea.Bottom(); nRow++)
626 : {
627 0 : long nBitPos = 0;
628 0 : unsigned char nByte = 0;
629 :
630 0 : for (long nColumn = rArea.Left(); nColumn <= rArea.Right(); nColumn++)
631 : {
632 0 : unsigned char nBit = rBitmap.GetPixelIdx (nRow, nColumn);
633 0 : nByte |= nBit << (7 - nBitPos);
634 :
635 0 : if (++nBitPos == 8)
636 : {
637 0 : xEncoder->EncodeByte (nByte);
638 0 : nBitPos = 0;
639 0 : nByte = 0;
640 : }
641 : }
642 : // keep the row byte aligned
643 0 : if (nBitPos != 0)
644 0 : xEncoder->EncodeByte (nByte);
645 0 : }
646 0 : }
647 :
648 : void
649 0 : PrinterGfx::DrawPS2PaletteImage (const PrinterBmp& rBitmap, const Rectangle& rArea)
650 : {
651 0 : writePS2Colorspace(rBitmap, psp::PaletteImage);
652 0 : writePS2ImageHeader(rArea, psp::PaletteImage);
653 :
654 0 : std::unique_ptr<ByteEncoder> xEncoder(mbCompressBmp ? new LZWEncoder(mpPageBody)
655 0 : : new Ascii85Encoder(mpPageBody));
656 :
657 0 : for (long nRow = rArea.Top(); nRow <= rArea.Bottom(); nRow++)
658 : {
659 0 : for (long nColumn = rArea.Left(); nColumn <= rArea.Right(); nColumn++)
660 : {
661 0 : unsigned char nByte = rBitmap.GetPixelIdx (nRow, nColumn);
662 0 : xEncoder->EncodeByte (nByte);
663 : }
664 0 : }
665 0 : }
666 :
667 : void
668 0 : PrinterGfx::DrawPS2TrueColorImage (const PrinterBmp& rBitmap, const Rectangle& rArea)
669 : {
670 0 : writePS2Colorspace(rBitmap, psp::TrueColorImage);
671 0 : writePS2ImageHeader(rArea, psp::TrueColorImage);
672 :
673 0 : std::unique_ptr<ByteEncoder> xEncoder(mbCompressBmp ? new LZWEncoder(mpPageBody)
674 0 : : new Ascii85Encoder(mpPageBody));
675 :
676 0 : for (long nRow = rArea.Top(); nRow <= rArea.Bottom(); nRow++)
677 : {
678 0 : for (long nColumn = rArea.Left(); nColumn <= rArea.Right(); nColumn++)
679 : {
680 0 : PrinterColor aColor = rBitmap.GetPixelRGB (nRow, nColumn);
681 0 : xEncoder->EncodeByte (aColor.GetRed());
682 0 : xEncoder->EncodeByte (aColor.GetGreen());
683 0 : xEncoder->EncodeByte (aColor.GetBlue());
684 0 : }
685 0 : }
686 0 : }
687 :
688 801 : } /* namespace psp */
689 :
690 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|