LCOV - code coverage report
Current view: top level - vcl/generic/print - bitmap_gfx.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1 307 0.3 %
Date: 2015-06-13 12:38:46 Functions: 2 35 5.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11