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