LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/ipcx - ipcx.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 171 0.0 %
Date: 2012-08-25 Functions: 0 8 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <vcl/graph.hxx>
      31                 :            : #include <vcl/bmpacc.hxx>
      32                 :            : #include <svtools/fltcall.hxx>
      33                 :            : 
      34                 :            : //============================ PCXReader ==================================
      35                 :            : 
      36                 :            : class PCXReader {
      37                 :            : 
      38                 :            : private:
      39                 :            : 
      40                 :            :     SvStream& m_rPCX;               // Die einzulesende PCX-Datei
      41                 :            : 
      42                 :            :     Bitmap              aBmp;
      43                 :            :     BitmapWriteAccess*  pAcc;
      44                 :            :     sal_uInt8               nVersion;           // PCX-Version
      45                 :            :     sal_uInt8               nEncoding;          // Art der Komprimierung
      46                 :            :     sal_uLong               nBitsPerPlanePix;   // Bits Pro Ebene pro Pixel
      47                 :            :     sal_uLong               nPlanes;            // Anzahl Ebenen
      48                 :            :     sal_uLong               nBytesPerPlaneLin;  // Bytes in einer Ebenen pro Zeile
      49                 :            :     sal_uInt16              nPaletteInfo;
      50                 :            : 
      51                 :            :     sal_uLong               nWidth, nHeight;    // Bildausmass in Pixeln
      52                 :            :     sal_uInt16              nResX, nResY;       // Aufloesung in Pixel pro Inch oder 0,0
      53                 :            :     sal_uInt16              nDestBitsPerPixel;  // Bits pro Pixel der Zielbitmap 1,4,8 oder 24
      54                 :            :     sal_uInt8*              pPalette;           //
      55                 :            :     sal_Bool                nStatus;            // status nun nicht mehr am stream abfragen ( SJ )
      56                 :            : 
      57                 :            : 
      58                 :            :     sal_Bool                Callback( sal_uInt16 nPercent );
      59                 :            :     void                ImplReadBody();
      60                 :            :     void                ImplReadPalette( sal_uLong nCol );
      61                 :            :     void                ImplReadHeader();
      62                 :            : 
      63                 :            : public:
      64                 :            :                         PCXReader(SvStream &rStream);
      65                 :            :                         ~PCXReader();
      66                 :            :     sal_Bool                ReadPCX(Graphic & rGraphic );
      67                 :            :                         // Liesst aus dem Stream eine PCX-Datei und fuellt das GDIMetaFile
      68                 :            : };
      69                 :            : 
      70                 :            : //=================== Methoden von PCXReader ==============================
      71                 :            : 
      72                 :          0 : PCXReader::PCXReader(SvStream &rStream)
      73                 :            :     : m_rPCX(rStream)
      74                 :          0 :     , pAcc(NULL)
      75                 :            : {
      76                 :          0 :     pPalette = new sal_uInt8[ 768 ];
      77                 :          0 : }
      78                 :            : 
      79                 :          0 : PCXReader::~PCXReader()
      80                 :            : {
      81                 :          0 :     delete[] pPalette;
      82                 :          0 : }
      83                 :            : 
      84                 :          0 : sal_Bool PCXReader::Callback( sal_uInt16 /*nPercent*/ )
      85                 :            : {
      86                 :          0 :     return sal_False;
      87                 :            : }
      88                 :            : 
      89                 :          0 : sal_Bool PCXReader::ReadPCX(Graphic & rGraphic)
      90                 :            : {
      91                 :          0 :     if ( m_rPCX.GetError() )
      92                 :          0 :         return sal_False;
      93                 :            : 
      94                 :          0 :     sal_uLong*  pDummy = new sal_uLong; delete pDummy; // damit unter OS/2
      95                 :            :                                                // das richtige (Tools-)new
      96                 :            :                                                // verwendet wird, da es sonst
      97                 :            :                                                // in dieser DLL nur Vector-news
      98                 :            :                                                // gibt;
      99                 :            : 
     100                 :          0 :     m_rPCX.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
     101                 :            : 
     102                 :            :     // Kopf einlesen:
     103                 :            : 
     104                 :          0 :     nStatus = sal_True;
     105                 :            : 
     106                 :          0 :     ImplReadHeader();
     107                 :            : 
     108                 :            :     // BMP-Header und ggf. (eventuell zunaechst ungueltige) Farbpalette schreiben:
     109                 :          0 :     if ( nStatus )
     110                 :            :     {
     111                 :          0 :         aBmp = Bitmap( Size( nWidth, nHeight ), nDestBitsPerPixel );
     112                 :          0 :         if ( ( pAcc = aBmp.AcquireWriteAccess() ) == sal_False )
     113                 :          0 :             return sal_False;
     114                 :            : 
     115                 :          0 :         if ( nDestBitsPerPixel <= 8 )
     116                 :            :         {
     117                 :          0 :             sal_uInt16 nColors = 1 << nDestBitsPerPixel;
     118                 :          0 :             sal_uInt8* pPal = pPalette;
     119                 :          0 :             pAcc->SetPaletteEntryCount( nColors );
     120                 :          0 :             for ( sal_uInt16 i = 0; i < nColors; i++, pPal += 3 )
     121                 :            :             {
     122                 :          0 :                 pAcc->SetPaletteColor( i, BitmapColor ( pPal[ 0 ], pPal[ 1 ], pPal[ 2 ] ) );
     123                 :            :             }
     124                 :            :         }
     125                 :            :         // Bitmap-Daten einlesen
     126                 :          0 :         ImplReadBody();
     127                 :            : 
     128                 :            :         // Wenn erweiterte Farbpalette am Ende von PCX, dann diese einlesen, und nochmals
     129                 :            :         // in Palette schreiben:
     130                 :          0 :         if ( nDestBitsPerPixel == 8 && nStatus )
     131                 :            :         {
     132                 :          0 :             sal_uInt8* pPal = pPalette;
     133                 :          0 :             m_rPCX.SeekRel(1);
     134                 :          0 :             ImplReadPalette(256);
     135                 :          0 :             pAcc->SetPaletteEntryCount( 256 );
     136                 :          0 :             for ( sal_uInt16 i = 0; i < 256; i++, pPal += 3 )
     137                 :            :             {
     138                 :          0 :                 pAcc->SetPaletteColor( i, BitmapColor ( pPal[ 0 ], pPal[ 1 ], pPal[ 2 ] ) );
     139                 :            :             }
     140                 :            :         }
     141                 :            :     /*
     142                 :            :         // Aufloesung einstellen:
     143                 :            :         if (nResX!=0 && nResY!=0) {
     144                 :            :             MapMode aMapMode(MAP_INCH,Point(0,0),Fraction(1,nResX),Fraction(1,nResY));
     145                 :            :             rBitmap.SetPrefMapMode(aMapMode);
     146                 :            :             rBitmap.SetPrefSize(Size(nWidth,nHeight));
     147                 :            :         }
     148                 :          0 :     */  if ( nStatus && pAcc )
     149                 :            :         {
     150                 :          0 :             aBmp.ReleaseAccess( pAcc ), pAcc = NULL;
     151                 :          0 :             rGraphic = aBmp;
     152                 :          0 :             return sal_True;
     153                 :            :         }
     154                 :            :     }
     155                 :          0 :     return sal_False;
     156                 :            : }
     157                 :            : 
     158                 :          0 : void PCXReader::ImplReadHeader()
     159                 :            : {
     160                 :            :     sal_uInt8 nbyte;
     161                 :            :     sal_uInt16 nushort;
     162                 :            :     sal_uInt16 nMinX,nMinY,nMaxX,nMaxY;
     163                 :            : 
     164                 :          0 :     m_rPCX >> nbyte >> nVersion >> nEncoding;
     165                 :          0 :     if ( nbyte!=0x0a || (nVersion != 0 && nVersion != 2 && nVersion != 3 && nVersion != 5) || nEncoding > 1 )
     166                 :            :     {
     167                 :          0 :         nStatus = sal_False;
     168                 :            :         return;
     169                 :            :     }
     170                 :            : 
     171                 :          0 :     m_rPCX >> nbyte; nBitsPerPlanePix = (sal_uLong)nbyte;
     172                 :          0 :     m_rPCX >> nMinX >> nMinY >> nMaxX >> nMaxY;
     173                 :            : 
     174                 :          0 :     if ((nMinX > nMaxX) || (nMinY > nMaxY))
     175                 :            :     {
     176                 :          0 :         nStatus = sal_False;
     177                 :            :         return;
     178                 :            :     }
     179                 :            : 
     180                 :          0 :     nWidth = nMaxX-nMinX+1;
     181                 :          0 :     nHeight = nMaxY-nMinY+1;
     182                 :            : 
     183                 :          0 :     m_rPCX >> nResX;
     184                 :          0 :     m_rPCX >> nResY;
     185                 :          0 :     if ( nResX >= nWidth || nResY >= nHeight || ( nResX != nResY ) )
     186                 :          0 :         nResX = nResY = 0;
     187                 :            : 
     188                 :          0 :     ImplReadPalette( 16 );
     189                 :            : 
     190                 :          0 :     m_rPCX.SeekRel( 1 );
     191                 :          0 :     m_rPCX >> nbyte;   nPlanes = (sal_uLong)nbyte;
     192                 :          0 :     m_rPCX >> nushort; nBytesPerPlaneLin = (sal_uLong)nushort;
     193                 :          0 :     m_rPCX >> nPaletteInfo;
     194                 :            : 
     195                 :          0 :     m_rPCX.SeekRel( 58 );
     196                 :            : 
     197                 :          0 :     nDestBitsPerPixel = (sal_uInt16)( nBitsPerPlanePix * nPlanes );
     198                 :          0 :     if (nDestBitsPerPixel == 2 || nDestBitsPerPixel == 3) nDestBitsPerPixel = 4;
     199                 :            : 
     200                 :          0 :     if ( ( nDestBitsPerPixel != 1 && nDestBitsPerPixel != 4 && nDestBitsPerPixel != 8 && nDestBitsPerPixel != 24 )
     201                 :            :         || nPlanes > 4 || nBytesPerPlaneLin < ( ( nWidth * nBitsPerPlanePix+7 ) >> 3 ) )
     202                 :            :     {
     203                 :          0 :         nStatus = sal_False;
     204                 :            :         return;
     205                 :            :     }
     206                 :            : 
     207                 :            :     // Wenn das Bild nur 2 Farben hat, ist die Palette zumeist ungueltig, und es handelt sich
     208                 :            :     // immer (?) um ein schwarz-weiss-Bild:
     209                 :          0 :     if ( nPlanes == 1 && nBitsPerPlanePix == 1 )
     210                 :            :     {
     211                 :          0 :         pPalette[ 0 ] = pPalette[ 1 ] = pPalette[ 2 ] = 0x00;
     212                 :          0 :         pPalette[ 3 ] = pPalette[ 4 ] = pPalette[ 5 ] = 0xff;
     213                 :            :     }
     214                 :            : }
     215                 :            : 
     216                 :          0 : void PCXReader::ImplReadBody()
     217                 :            : {
     218                 :            :     sal_uInt8   *pPlane[ 4 ], * pDest, * pSource1, * pSource2, * pSource3, *pSource4;
     219                 :            :     sal_uLong   i, nx, ny, np, nCount, nPercent;
     220                 :          0 :     sal_uLong   nLastPercent = 0;
     221                 :          0 :     sal_uInt8   nDat = 0, nCol = 0;
     222                 :            : 
     223                 :          0 :     for( np = 0; np < nPlanes; np++ )
     224                 :          0 :         pPlane[ np ] = new sal_uInt8[ nBytesPerPlaneLin ];
     225                 :            : 
     226                 :          0 :     nCount = 0;
     227                 :          0 :     for ( ny = 0; ny < nHeight; ny++ )
     228                 :            :     {
     229                 :          0 :         if (m_rPCX.GetError() || m_rPCX.IsEof())
     230                 :            :         {
     231                 :          0 :             nStatus = sal_False;
     232                 :          0 :             break;
     233                 :            :         }
     234                 :          0 :         nPercent = ny * 60 / nHeight + 10;
     235                 :          0 :         if ( ny == 0 || nLastPercent + 4 <= nPercent )
     236                 :            :         {
     237                 :          0 :             nLastPercent = nPercent;
     238                 :          0 :             if ( Callback( (sal_uInt16)nPercent ) == sal_True )
     239                 :          0 :                 break;
     240                 :            :         }
     241                 :          0 :         for ( np = 0; np < nPlanes; np++)
     242                 :            :         {
     243                 :          0 :             if ( nEncoding == 0)
     244                 :          0 :                 m_rPCX.Read( (void *)pPlane[ np ], nBytesPerPlaneLin );
     245                 :            :             else
     246                 :            :             {
     247                 :          0 :                 pDest = pPlane[ np ];
     248                 :          0 :                 nx = nBytesPerPlaneLin;
     249                 :          0 :                 while ( nCount > 0 && nx > 0)
     250                 :            :                 {
     251                 :          0 :                     *(pDest++) = nDat;
     252                 :          0 :                     nx--;
     253                 :          0 :                     nCount--;
     254                 :            :                 }
     255                 :          0 :                 while ( nx > 0 )
     256                 :            :                 {
     257                 :          0 :                     m_rPCX >> nDat;
     258                 :          0 :                     if ( ( nDat & 0xc0 ) == 0xc0 )
     259                 :            :                     {
     260                 :          0 :                         nCount =( (sal_uLong)nDat ) & 0x003f;
     261                 :          0 :                         m_rPCX >> nDat;
     262                 :          0 :                         if ( nCount < nx )
     263                 :            :                         {
     264                 :          0 :                             nx -= nCount;
     265                 :          0 :                             while ( nCount > 0)
     266                 :            :                             {
     267                 :          0 :                                 *(pDest++) = nDat;
     268                 :          0 :                                 nCount--;
     269                 :            :                             }
     270                 :            :                         }
     271                 :            :                         else
     272                 :            :                         {
     273                 :          0 :                             nCount -= nx;
     274                 :          0 :                             do
     275                 :            :                             {
     276                 :          0 :                                 *(pDest++) = nDat;
     277                 :          0 :                                 nx--;
     278                 :            :                             }
     279                 :            :                             while ( nx > 0 );
     280                 :          0 :                             break;
     281                 :            :                         }
     282                 :            :                     }
     283                 :            :                     else
     284                 :            :                     {
     285                 :          0 :                         *(pDest++) = nDat;
     286                 :          0 :                         nx--;
     287                 :            :                     }
     288                 :            :                 }
     289                 :            :             }
     290                 :            :         }
     291                 :          0 :         pSource1 = pPlane[ 0 ];
     292                 :          0 :         pSource2 = pPlane[ 1 ];
     293                 :          0 :         pSource3 = pPlane[ 2 ];
     294                 :          0 :         pSource4 = pPlane[ 3 ];
     295                 :          0 :         switch ( nBitsPerPlanePix + ( nPlanes << 8 ) )
     296                 :            :         {
     297                 :            :             // 2 colors
     298                 :            :             case 0x101 :
     299                 :          0 :                 for ( i = 0; i < nWidth; i++ )
     300                 :            :                 {
     301                 :          0 :                     sal_uLong nShift = ( i & 7 ) ^ 7;
     302                 :          0 :                     if ( nShift == 0 )
     303                 :          0 :                         pAcc->SetPixel( ny, i, ( *pSource1++ & 1 ) );
     304                 :            :                     else
     305                 :            :                         pAcc->SetPixel(
     306                 :            :                             ny, i,
     307                 :            :                             sal::static_int_cast< sal_uInt8 >(
     308                 :          0 :                                 ( *pSource1 >> nShift ) & 1) );
     309                 :            :                 }
     310                 :          0 :                 break;
     311                 :            :             // 4 colors
     312                 :            :             case 0x102 :
     313                 :          0 :                 for ( i = 0; i < nWidth; i++ )
     314                 :            :                 {
     315                 :          0 :                     switch( i & 3 )
     316                 :            :                     {
     317                 :            :                         case 0 :
     318                 :          0 :                             nCol = *pSource1 >> 6;
     319                 :          0 :                             break;
     320                 :            :                         case 1 :
     321                 :          0 :                             nCol = ( *pSource1 >> 4 ) & 0x03 ;
     322                 :          0 :                             break;
     323                 :            :                         case 2 :
     324                 :          0 :                             nCol = ( *pSource1 >> 2 ) & 0x03;
     325                 :          0 :                             break;
     326                 :            :                         case 3 :
     327                 :          0 :                             nCol = ( *pSource1++ ) & 0x03;
     328                 :          0 :                             break;
     329                 :            :                     }
     330                 :          0 :                     pAcc->SetPixel( ny, i, nCol );
     331                 :            :                 }
     332                 :          0 :                 break;
     333                 :            :             // 256 colors
     334                 :            :             case 0x108 :
     335                 :          0 :                 for ( i = 0; i < nWidth; i++ )
     336                 :            :                 {
     337                 :          0 :                     pAcc->SetPixel( ny, i, *pSource1++ );
     338                 :            :                 }
     339                 :          0 :                 break;
     340                 :            :             // 8 colors
     341                 :            :             case 0x301 :
     342                 :          0 :                 for ( i = 0; i < nWidth; i++ )
     343                 :            :                 {
     344                 :          0 :                     sal_uLong nShift = ( i & 7 ) ^ 7;
     345                 :          0 :                     if ( nShift == 0 )
     346                 :            :                     {
     347                 :          0 :                         nCol = ( *pSource1++ & 1) + ( ( *pSource2++ << 1 ) & 2 ) + ( ( *pSource3++ << 2 ) & 4 );
     348                 :          0 :                         pAcc->SetPixel( ny, i, nCol );
     349                 :            :                     }
     350                 :            :                     else
     351                 :            :                     {
     352                 :            :                         nCol = sal::static_int_cast< sal_uInt8 >(
     353                 :            :                             ( ( *pSource1 >> nShift ) & 1)  + ( ( ( *pSource2 >> nShift ) << 1 ) & 2 ) +
     354                 :          0 :                             ( ( ( *pSource3 >> nShift ) << 2 ) & 4 ));
     355                 :          0 :                         pAcc->SetPixel( ny, i, nCol );
     356                 :            :                     }
     357                 :            :                 }
     358                 :          0 :                 break;
     359                 :            :             // 16 colors
     360                 :            :             case 0x401 :
     361                 :          0 :                 for ( i = 0; i < nWidth; i++ )
     362                 :            :                 {
     363                 :          0 :                     sal_uLong nShift = ( i & 7 ) ^ 7;
     364                 :          0 :                     if ( nShift == 0 )
     365                 :            :                     {
     366                 :            :                         nCol = ( *pSource1++ & 1) + ( ( *pSource2++ << 1 ) & 2 ) + ( ( *pSource3++ << 2 ) & 4 ) +
     367                 :          0 :                             ( ( *pSource4++ << 3 ) & 8 );
     368                 :          0 :                         pAcc->SetPixel( ny, i, nCol );
     369                 :            :                     }
     370                 :            :                     else
     371                 :            :                     {
     372                 :            :                         nCol = sal::static_int_cast< sal_uInt8 >(
     373                 :            :                             ( ( *pSource1 >> nShift ) & 1)  + ( ( ( *pSource2 >> nShift ) << 1 ) & 2 ) +
     374                 :          0 :                             ( ( ( *pSource3 >> nShift ) << 2 ) & 4 ) + ( ( ( *pSource4 >> nShift ) << 3 ) & 8 ));
     375                 :          0 :                         pAcc->SetPixel( ny, i, nCol );
     376                 :            :                     }
     377                 :            :                 }
     378                 :          0 :                 break;
     379                 :            :             // 16m colors
     380                 :            :             case 0x308 :
     381                 :          0 :                 for ( i = 0; i < nWidth; i++ )
     382                 :            :                 {
     383                 :          0 :                     pAcc->SetPixel( ny, i, Color( *pSource1++, *pSource2++, *pSource3++ ) );
     384                 :            : 
     385                 :            :                 }
     386                 :          0 :                 break;
     387                 :            :             default :
     388                 :          0 :                 nStatus = sal_False;
     389                 :          0 :                 break;
     390                 :            :         }
     391                 :            :     }
     392                 :          0 :     for ( np = 0; np < nPlanes; np++ )
     393                 :          0 :         delete[] pPlane[ np ];
     394                 :          0 : }
     395                 :            : 
     396                 :          0 : void PCXReader::ImplReadPalette( sal_uLong nCol )
     397                 :            : {
     398                 :            :     sal_uInt8   r, g, b;
     399                 :          0 :     sal_uInt8*  pPtr = pPalette;
     400                 :          0 :     for ( sal_uLong i = 0; i < nCol; i++ )
     401                 :            :     {
     402                 :          0 :         m_rPCX >> r >> g >> b;
     403                 :          0 :         *pPtr++ = r;
     404                 :          0 :         *pPtr++ = g;
     405                 :          0 :         *pPtr++ = b;
     406                 :            :     }
     407                 :          0 : }
     408                 :            : 
     409                 :            : //================== GraphicImport - die exportierte Funktion ================
     410                 :            : 
     411                 :            : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool __LOADONCALLAPI
     412                 :          0 : GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool)
     413                 :            : {
     414                 :          0 :     PCXReader aPCXReader(rStream);
     415                 :          0 :     sal_Bool nRetValue = aPCXReader.ReadPCX(rGraphic);
     416                 :          0 :     if ( nRetValue == sal_False )
     417                 :          0 :         rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
     418                 :          0 :     return nRetValue;
     419                 :            : }
     420                 :            : 
     421                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10