LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/ipcx - ipcx.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 178 0.0 %
Date: 2014-04-14 Functions: 0 8 0.0 %
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             : 
      21             : #include <vcl/graph.hxx>
      22             : #include <vcl/bmpacc.hxx>
      23             : 
      24             : class FilterConfigItem;
      25             : 
      26             : //============================ PCXReader ==================================
      27             : 
      28             : class PCXReader {
      29             : 
      30             : private:
      31             : 
      32             :     SvStream& m_rPCX;               // the PCX file to read
      33             : 
      34             :     Bitmap              aBmp;
      35             :     BitmapWriteAccess*  pAcc;
      36             :     sal_uInt8           nVersion;           // PCX-Version
      37             :     sal_uInt8           nEncoding;          // compression type
      38             :     sal_uLong           nBitsPerPlanePix;   // bits per plane per pixel
      39             :     sal_uLong           nPlanes;            // no of planes
      40             :     sal_uLong           nBytesPerPlaneLin;  // bytes per plane line
      41             :     sal_uInt16          nPaletteInfo;
      42             : 
      43             :     sal_uLong           nWidth, nHeight;    // dimension in pixel
      44             :     sal_uInt16          nResX, nResY;       // resolution in pixel per inch oder 0,0
      45             :     sal_uInt16          nDestBitsPerPixel;  // bits per pixel in destination bitmap 1,4,8 or 24
      46             :     sal_uInt8*          pPalette;
      47             :     sal_Bool            nStatus;            // from now on do not read status from stream ( SJ )
      48             : 
      49             : 
      50             :     sal_Bool            Callback( sal_uInt16 nPercent );
      51             :     void                ImplReadBody();
      52             :     void                ImplReadPalette( sal_uLong nCol );
      53             :     void                ImplReadHeader();
      54             : 
      55             : public:
      56             :                         PCXReader(SvStream &rStream);
      57             :                         ~PCXReader();
      58             :     sal_Bool                ReadPCX(Graphic & rGraphic );
      59             :                         // Reads a PCX file from the stream and fills the GDIMetaFile
      60             : };
      61             : 
      62             : //=================== methods of PCXReader ==============================
      63             : 
      64           0 : PCXReader::PCXReader(SvStream &rStream)
      65             :     : m_rPCX(rStream)
      66             :     , pAcc(NULL)
      67             :     , nVersion(0)
      68             :     , nEncoding(0)
      69             :     , nBitsPerPlanePix(0)
      70             :     , nPlanes(0)
      71             :     , nBytesPerPlaneLin(0)
      72             :     , nPaletteInfo(0)
      73             :     , nWidth(0)
      74             :     , nHeight(0)
      75             :     , nResX(0)
      76             :     , nResY(0)
      77             :     , nDestBitsPerPixel(0)
      78           0 :     , nStatus(false)
      79             : {
      80           0 :     pPalette = new sal_uInt8[ 768 ];
      81           0 : }
      82             : 
      83           0 : PCXReader::~PCXReader()
      84             : {
      85           0 :     delete[] pPalette;
      86           0 : }
      87             : 
      88           0 : sal_Bool PCXReader::Callback( sal_uInt16 /*nPercent*/ )
      89             : {
      90           0 :     return sal_False;
      91             : }
      92             : 
      93           0 : sal_Bool PCXReader::ReadPCX(Graphic & rGraphic)
      94             : {
      95           0 :     if ( m_rPCX.GetError() )
      96           0 :         return sal_False;
      97             : 
      98           0 :     sal_uLong*  pDummy = new sal_uLong; delete pDummy; // to achive that under OS/2
      99             :                                                // the right (Tools-) new is used
     100             :                                                // otherwise there are only Vector-news
     101             :                                                // in this DLL
     102             : 
     103           0 :     m_rPCX.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
     104             : 
     105             :     // read header:
     106             : 
     107           0 :     nStatus = sal_True;
     108             : 
     109           0 :     ImplReadHeader();
     110             : 
     111             :     // Write BMP header and conditionally (maybe invalid for now) color palette:
     112           0 :     if ( nStatus )
     113             :     {
     114           0 :         aBmp = Bitmap( Size( nWidth, nHeight ), nDestBitsPerPixel );
     115           0 :         if ( ( pAcc = aBmp.AcquireWriteAccess() ) == 0 )
     116           0 :             return sal_False;
     117             : 
     118           0 :         if ( nDestBitsPerPixel <= 8 )
     119             :         {
     120           0 :             sal_uInt16 nColors = 1 << nDestBitsPerPixel;
     121           0 :             sal_uInt8* pPal = pPalette;
     122           0 :             pAcc->SetPaletteEntryCount( nColors );
     123           0 :             for ( sal_uInt16 i = 0; i < nColors; i++, pPal += 3 )
     124             :             {
     125           0 :                 pAcc->SetPaletteColor( i, BitmapColor ( pPal[ 0 ], pPal[ 1 ], pPal[ 2 ] ) );
     126             :             }
     127             :         }
     128             :         // read bitmap data
     129           0 :         ImplReadBody();
     130             : 
     131             :         // If an extended color palette exists at the end of the file, then read it and
     132             :         // and write again in palette:
     133           0 :         if ( nDestBitsPerPixel == 8 && nStatus )
     134             :         {
     135           0 :             sal_uInt8* pPal = pPalette;
     136           0 :             m_rPCX.SeekRel(1);
     137           0 :             ImplReadPalette(256);
     138           0 :             pAcc->SetPaletteEntryCount( 256 );
     139           0 :             for ( sal_uInt16 i = 0; i < 256; i++, pPal += 3 )
     140             :             {
     141           0 :                 pAcc->SetPaletteColor( i, BitmapColor ( pPal[ 0 ], pPal[ 1 ], pPal[ 2 ] ) );
     142             :             }
     143             :         }
     144             :     /*
     145             :         // set resolution:
     146             :         if (nResX!=0 && nResY!=0) {
     147             :             MapMode aMapMode(MAP_INCH,Point(0,0),Fraction(1,nResX),Fraction(1,nResY));
     148             :             rBitmap.SetPrefMapMode(aMapMode);
     149             :             rBitmap.SetPrefSize(Size(nWidth,nHeight));
     150             :         }
     151           0 :     */  if ( nStatus && pAcc )
     152             :         {
     153           0 :             aBmp.ReleaseAccess( pAcc ), pAcc = NULL;
     154           0 :             rGraphic = aBmp;
     155           0 :             return sal_True;
     156             :         }
     157             :     }
     158           0 :     return sal_False;
     159             : }
     160             : 
     161           0 : void PCXReader::ImplReadHeader()
     162             : {
     163             :     sal_uInt8 nbyte;
     164             :     sal_uInt16 nushort;
     165             :     sal_uInt16 nMinX,nMinY,nMaxX,nMaxY;
     166             : 
     167           0 :     m_rPCX.ReadUChar( nbyte ).ReadUChar( nVersion ).ReadUChar( nEncoding );
     168           0 :     if ( nbyte!=0x0a || (nVersion != 0 && nVersion != 2 && nVersion != 3 && nVersion != 5) || nEncoding > 1 )
     169             :     {
     170           0 :         nStatus = sal_False;
     171           0 :         return;
     172             :     }
     173             : 
     174           0 :     m_rPCX.ReadUChar( nbyte ); nBitsPerPlanePix = (sal_uLong)nbyte;
     175           0 :     m_rPCX.ReadUInt16( nMinX ).ReadUInt16( nMinY ).ReadUInt16( nMaxX ).ReadUInt16( nMaxY );
     176             : 
     177           0 :     if ((nMinX > nMaxX) || (nMinY > nMaxY))
     178             :     {
     179           0 :         nStatus = sal_False;
     180           0 :         return;
     181             :     }
     182             : 
     183           0 :     nWidth = nMaxX-nMinX+1;
     184           0 :     nHeight = nMaxY-nMinY+1;
     185             : 
     186           0 :     m_rPCX.ReadUInt16( nResX );
     187           0 :     m_rPCX.ReadUInt16( nResY );
     188           0 :     if ( nResX >= nWidth || nResY >= nHeight || ( nResX != nResY ) )
     189           0 :         nResX = nResY = 0;
     190             : 
     191           0 :     ImplReadPalette( 16 );
     192             : 
     193           0 :     m_rPCX.SeekRel( 1 );
     194           0 :     m_rPCX.ReadUChar( nbyte );   nPlanes = (sal_uLong)nbyte;
     195           0 :     m_rPCX.ReadUInt16( nushort ); nBytesPerPlaneLin = (sal_uLong)nushort;
     196           0 :     m_rPCX.ReadUInt16( nPaletteInfo );
     197             : 
     198           0 :     m_rPCX.SeekRel( 58 );
     199             : 
     200           0 :     nDestBitsPerPixel = (sal_uInt16)( nBitsPerPlanePix * nPlanes );
     201           0 :     if (nDestBitsPerPixel == 2 || nDestBitsPerPixel == 3) nDestBitsPerPixel = 4;
     202             : 
     203           0 :     if ( ( nDestBitsPerPixel != 1 && nDestBitsPerPixel != 4 && nDestBitsPerPixel != 8 && nDestBitsPerPixel != 24 )
     204           0 :         || nPlanes > 4 || nBytesPerPlaneLin < ( ( nWidth * nBitsPerPlanePix+7 ) >> 3 ) )
     205             :     {
     206           0 :         nStatus = sal_False;
     207           0 :         return;
     208             :     }
     209             : 
     210             :     // If the bitmap has only 2 colors, the palatte is most often invalid and it is always(?)
     211             :     // a black and white image:
     212           0 :     if ( nPlanes == 1 && nBitsPerPlanePix == 1 )
     213             :     {
     214           0 :         pPalette[ 0 ] = pPalette[ 1 ] = pPalette[ 2 ] = 0x00;
     215           0 :         pPalette[ 3 ] = pPalette[ 4 ] = pPalette[ 5 ] = 0xff;
     216             :     }
     217             : }
     218             : 
     219           0 : void PCXReader::ImplReadBody()
     220             : {
     221             :     sal_uInt8   *pPlane[ 4 ], * pDest, * pSource1, * pSource2, * pSource3, *pSource4;
     222             :     sal_uLong   i, nx, ny, np, nCount, nPercent;
     223           0 :     sal_uLong   nLastPercent = 0;
     224           0 :     sal_uInt8   nDat = 0, nCol = 0;
     225             : 
     226           0 :     for( np = 0; np < nPlanes; np++ )
     227           0 :         pPlane[ np ] = new sal_uInt8[ nBytesPerPlaneLin ];
     228             : 
     229           0 :     nCount = 0;
     230           0 :     for ( ny = 0; ny < nHeight; ny++ )
     231             :     {
     232           0 :         if (m_rPCX.GetError() || m_rPCX.IsEof())
     233             :         {
     234           0 :             nStatus = sal_False;
     235           0 :             break;
     236             :         }
     237           0 :         nPercent = ny * 60 / nHeight + 10;
     238           0 :         if ( ny == 0 || nLastPercent + 4 <= nPercent )
     239             :         {
     240           0 :             nLastPercent = nPercent;
     241           0 :             if ( Callback( (sal_uInt16)nPercent ) == sal_True )
     242           0 :                 break;
     243             :         }
     244           0 :         for ( np = 0; np < nPlanes; np++)
     245             :         {
     246           0 :             if ( nEncoding == 0)
     247           0 :                 m_rPCX.Read( (void *)pPlane[ np ], nBytesPerPlaneLin );
     248             :             else
     249             :             {
     250           0 :                 pDest = pPlane[ np ];
     251           0 :                 nx = nBytesPerPlaneLin;
     252           0 :                 while ( nCount > 0 && nx > 0)
     253             :                 {
     254           0 :                     *(pDest++) = nDat;
     255           0 :                     nx--;
     256           0 :                     nCount--;
     257             :                 }
     258           0 :                 while ( nx > 0 )
     259             :                 {
     260           0 :                     m_rPCX.ReadUChar( nDat );
     261           0 :                     if ( ( nDat & 0xc0 ) == 0xc0 )
     262             :                     {
     263           0 :                         nCount =( (sal_uLong)nDat ) & 0x003f;
     264           0 :                         m_rPCX.ReadUChar( nDat );
     265           0 :                         if ( nCount < nx )
     266             :                         {
     267           0 :                             nx -= nCount;
     268           0 :                             while ( nCount > 0)
     269             :                             {
     270           0 :                                 *(pDest++) = nDat;
     271           0 :                                 nCount--;
     272             :                             }
     273             :                         }
     274             :                         else
     275             :                         {
     276           0 :                             nCount -= nx;
     277           0 :                             do
     278             :                             {
     279           0 :                                 *(pDest++) = nDat;
     280           0 :                                 nx--;
     281             :                             }
     282             :                             while ( nx > 0 );
     283           0 :                             break;
     284             :                         }
     285             :                     }
     286             :                     else
     287             :                     {
     288           0 :                         *(pDest++) = nDat;
     289           0 :                         nx--;
     290             :                     }
     291             :                 }
     292             :             }
     293             :         }
     294           0 :         pSource1 = pPlane[ 0 ];
     295           0 :         pSource2 = pPlane[ 1 ];
     296           0 :         pSource3 = pPlane[ 2 ];
     297           0 :         pSource4 = pPlane[ 3 ];
     298           0 :         switch ( nBitsPerPlanePix + ( nPlanes << 8 ) )
     299             :         {
     300             :             // 2 colors
     301             :             case 0x101 :
     302           0 :                 for ( i = 0; i < nWidth; i++ )
     303             :                 {
     304           0 :                     sal_uLong nShift = ( i & 7 ) ^ 7;
     305           0 :                     if ( nShift == 0 )
     306           0 :                         pAcc->SetPixelIndex( ny, i, *(pSource1++) & 1 );
     307             :                     else
     308           0 :                         pAcc->SetPixelIndex( ny, i, (*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->SetPixelIndex( 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->SetPixelIndex( 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->SetPixelIndex( ny, i, nCol );
     349             :                     }
     350             :                     else
     351             :                     {
     352             :                         nCol = sal::static_int_cast< sal_uInt8 >(
     353           0 :                             ( ( *pSource1 >> nShift ) & 1)  + ( ( ( *pSource2 >> nShift ) << 1 ) & 2 ) +
     354           0 :                             ( ( ( *pSource3 >> nShift ) << 2 ) & 4 ));
     355           0 :                         pAcc->SetPixelIndex( 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           0 :                         nCol = ( *pSource1++ & 1) + ( ( *pSource2++ << 1 ) & 2 ) + ( ( *pSource3++ << 2 ) & 4 ) +
     367           0 :                             ( ( *pSource4++ << 3 ) & 8 );
     368           0 :                         pAcc->SetPixelIndex( ny, i, nCol );
     369             :                     }
     370             :                     else
     371             :                     {
     372             :                         nCol = sal::static_int_cast< sal_uInt8 >(
     373           0 :                             ( ( *pSource1 >> nShift ) & 1)  + ( ( ( *pSource2 >> nShift ) << 1 ) & 2 ) +
     374           0 :                             ( ( ( *pSource3 >> nShift ) << 2 ) & 4 ) + ( ( ( *pSource4 >> nShift ) << 3 ) & 8 ));
     375           0 :                         pAcc->SetPixelIndex( 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.ReadUChar( r ).ReadUChar( g ).ReadUChar( b );
     403           0 :         *pPtr++ = r;
     404           0 :         *pPtr++ = g;
     405           0 :         *pPtr++ = b;
     406             :     }
     407           0 : }
     408             : 
     409             : //================== GraphicImport - the exported function ================
     410             : 
     411             : // this needs to be kept in sync with
     412             : // ImpFilterLibCacheEntry::GetImportFunction() from
     413             : // vcl/source/filter/graphicfilter.cxx
     414             : #if defined(DISABLE_DYNLOADING)
     415             : #define GraphicImport ipxGraphicImport
     416             : #endif
     417             : 
     418             : extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL
     419           0 : GraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
     420             : {
     421           0 :     PCXReader aPCXReader(rStream);
     422           0 :     sal_Bool nRetValue = aPCXReader.ReadPCX(rGraphic);
     423           0 :     if ( nRetValue == sal_False )
     424           0 :         rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
     425           0 :     return nRetValue;
     426             : }
     427             : 
     428             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10