LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/ipcx - ipcx.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 178 0.0 %
Date: 2014-04-11 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           0 :     , pAcc(NULL)
      67             : {
      68           0 :     pPalette = new sal_uInt8[ 768 ];
      69           0 : }
      70             : 
      71           0 : PCXReader::~PCXReader()
      72             : {
      73           0 :     delete[] pPalette;
      74           0 : }
      75             : 
      76           0 : sal_Bool PCXReader::Callback( sal_uInt16 /*nPercent*/ )
      77             : {
      78           0 :     return sal_False;
      79             : }
      80             : 
      81           0 : sal_Bool PCXReader::ReadPCX(Graphic & rGraphic)
      82             : {
      83           0 :     if ( m_rPCX.GetError() )
      84           0 :         return sal_False;
      85             : 
      86           0 :     sal_uLong*  pDummy = new sal_uLong; delete pDummy; // to achive that under OS/2
      87             :                                                // the right (Tools-) new is used
      88             :                                                // otherwise there are only Vector-news
      89             :                                                // in this DLL
      90             : 
      91           0 :     m_rPCX.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
      92             : 
      93             :     // read header:
      94             : 
      95           0 :     nStatus = sal_True;
      96             : 
      97           0 :     ImplReadHeader();
      98             : 
      99             :     // Write BMP header and conditionally (maybe invalid for now) color palette:
     100           0 :     if ( nStatus )
     101             :     {
     102           0 :         aBmp = Bitmap( Size( nWidth, nHeight ), nDestBitsPerPixel );
     103           0 :         if ( ( pAcc = aBmp.AcquireWriteAccess() ) == 0 )
     104           0 :             return sal_False;
     105             : 
     106           0 :         if ( nDestBitsPerPixel <= 8 )
     107             :         {
     108           0 :             sal_uInt16 nColors = 1 << nDestBitsPerPixel;
     109           0 :             sal_uInt8* pPal = pPalette;
     110           0 :             pAcc->SetPaletteEntryCount( nColors );
     111           0 :             for ( sal_uInt16 i = 0; i < nColors; i++, pPal += 3 )
     112             :             {
     113           0 :                 pAcc->SetPaletteColor( i, BitmapColor ( pPal[ 0 ], pPal[ 1 ], pPal[ 2 ] ) );
     114             :             }
     115             :         }
     116             :         // read bitmap data
     117           0 :         ImplReadBody();
     118             : 
     119             :         // If an extended color palette exists at the end of the file, then read it and
     120             :         // and write again in palette:
     121           0 :         if ( nDestBitsPerPixel == 8 && nStatus )
     122             :         {
     123           0 :             sal_uInt8* pPal = pPalette;
     124           0 :             m_rPCX.SeekRel(1);
     125           0 :             ImplReadPalette(256);
     126           0 :             pAcc->SetPaletteEntryCount( 256 );
     127           0 :             for ( sal_uInt16 i = 0; i < 256; i++, pPal += 3 )
     128             :             {
     129           0 :                 pAcc->SetPaletteColor( i, BitmapColor ( pPal[ 0 ], pPal[ 1 ], pPal[ 2 ] ) );
     130             :             }
     131             :         }
     132             :     /*
     133             :         // set resolution:
     134             :         if (nResX!=0 && nResY!=0) {
     135             :             MapMode aMapMode(MAP_INCH,Point(0,0),Fraction(1,nResX),Fraction(1,nResY));
     136             :             rBitmap.SetPrefMapMode(aMapMode);
     137             :             rBitmap.SetPrefSize(Size(nWidth,nHeight));
     138             :         }
     139           0 :     */  if ( nStatus && pAcc )
     140             :         {
     141           0 :             aBmp.ReleaseAccess( pAcc ), pAcc = NULL;
     142           0 :             rGraphic = aBmp;
     143           0 :             return sal_True;
     144             :         }
     145             :     }
     146           0 :     return sal_False;
     147             : }
     148             : 
     149           0 : void PCXReader::ImplReadHeader()
     150             : {
     151             :     sal_uInt8 nbyte;
     152             :     sal_uInt16 nushort;
     153             :     sal_uInt16 nMinX,nMinY,nMaxX,nMaxY;
     154             : 
     155           0 :     m_rPCX.ReadUChar( nbyte ).ReadUChar( nVersion ).ReadUChar( nEncoding );
     156           0 :     if ( nbyte!=0x0a || (nVersion != 0 && nVersion != 2 && nVersion != 3 && nVersion != 5) || nEncoding > 1 )
     157             :     {
     158           0 :         nStatus = sal_False;
     159           0 :         return;
     160             :     }
     161             : 
     162           0 :     m_rPCX.ReadUChar( nbyte ); nBitsPerPlanePix = (sal_uLong)nbyte;
     163           0 :     m_rPCX.ReadUInt16( nMinX ).ReadUInt16( nMinY ).ReadUInt16( nMaxX ).ReadUInt16( nMaxY );
     164             : 
     165           0 :     if ((nMinX > nMaxX) || (nMinY > nMaxY))
     166             :     {
     167           0 :         nStatus = sal_False;
     168           0 :         return;
     169             :     }
     170             : 
     171           0 :     nWidth = nMaxX-nMinX+1;
     172           0 :     nHeight = nMaxY-nMinY+1;
     173             : 
     174           0 :     m_rPCX.ReadUInt16( nResX );
     175           0 :     m_rPCX.ReadUInt16( nResY );
     176           0 :     if ( nResX >= nWidth || nResY >= nHeight || ( nResX != nResY ) )
     177           0 :         nResX = nResY = 0;
     178             : 
     179           0 :     ImplReadPalette( 16 );
     180             : 
     181           0 :     m_rPCX.SeekRel( 1 );
     182           0 :     m_rPCX.ReadUChar( nbyte );   nPlanes = (sal_uLong)nbyte;
     183           0 :     m_rPCX.ReadUInt16( nushort ); nBytesPerPlaneLin = (sal_uLong)nushort;
     184           0 :     m_rPCX.ReadUInt16( nPaletteInfo );
     185             : 
     186           0 :     m_rPCX.SeekRel( 58 );
     187             : 
     188           0 :     nDestBitsPerPixel = (sal_uInt16)( nBitsPerPlanePix * nPlanes );
     189           0 :     if (nDestBitsPerPixel == 2 || nDestBitsPerPixel == 3) nDestBitsPerPixel = 4;
     190             : 
     191           0 :     if ( ( nDestBitsPerPixel != 1 && nDestBitsPerPixel != 4 && nDestBitsPerPixel != 8 && nDestBitsPerPixel != 24 )
     192           0 :         || nPlanes > 4 || nBytesPerPlaneLin < ( ( nWidth * nBitsPerPlanePix+7 ) >> 3 ) )
     193             :     {
     194           0 :         nStatus = sal_False;
     195           0 :         return;
     196             :     }
     197             : 
     198             :     // If the bitmap has only 2 colors, the palatte is most often invalid and it is always(?)
     199             :     // a black and white image:
     200           0 :     if ( nPlanes == 1 && nBitsPerPlanePix == 1 )
     201             :     {
     202           0 :         pPalette[ 0 ] = pPalette[ 1 ] = pPalette[ 2 ] = 0x00;
     203           0 :         pPalette[ 3 ] = pPalette[ 4 ] = pPalette[ 5 ] = 0xff;
     204             :     }
     205             : }
     206             : 
     207           0 : void PCXReader::ImplReadBody()
     208             : {
     209             :     sal_uInt8   *pPlane[ 4 ], * pDest, * pSource1, * pSource2, * pSource3, *pSource4;
     210             :     sal_uLong   i, nx, ny, np, nCount, nPercent;
     211           0 :     sal_uLong   nLastPercent = 0;
     212           0 :     sal_uInt8   nDat = 0, nCol = 0;
     213             : 
     214           0 :     for( np = 0; np < nPlanes; np++ )
     215           0 :         pPlane[ np ] = new sal_uInt8[ nBytesPerPlaneLin ];
     216             : 
     217           0 :     nCount = 0;
     218           0 :     for ( ny = 0; ny < nHeight; ny++ )
     219             :     {
     220           0 :         if (m_rPCX.GetError() || m_rPCX.IsEof())
     221             :         {
     222           0 :             nStatus = sal_False;
     223           0 :             break;
     224             :         }
     225           0 :         nPercent = ny * 60 / nHeight + 10;
     226           0 :         if ( ny == 0 || nLastPercent + 4 <= nPercent )
     227             :         {
     228           0 :             nLastPercent = nPercent;
     229           0 :             if ( Callback( (sal_uInt16)nPercent ) == sal_True )
     230           0 :                 break;
     231             :         }
     232           0 :         for ( np = 0; np < nPlanes; np++)
     233             :         {
     234           0 :             if ( nEncoding == 0)
     235           0 :                 m_rPCX.Read( (void *)pPlane[ np ], nBytesPerPlaneLin );
     236             :             else
     237             :             {
     238           0 :                 pDest = pPlane[ np ];
     239           0 :                 nx = nBytesPerPlaneLin;
     240           0 :                 while ( nCount > 0 && nx > 0)
     241             :                 {
     242           0 :                     *(pDest++) = nDat;
     243           0 :                     nx--;
     244           0 :                     nCount--;
     245             :                 }
     246           0 :                 while ( nx > 0 )
     247             :                 {
     248           0 :                     m_rPCX.ReadUChar( nDat );
     249           0 :                     if ( ( nDat & 0xc0 ) == 0xc0 )
     250             :                     {
     251           0 :                         nCount =( (sal_uLong)nDat ) & 0x003f;
     252           0 :                         m_rPCX.ReadUChar( nDat );
     253           0 :                         if ( nCount < nx )
     254             :                         {
     255           0 :                             nx -= nCount;
     256           0 :                             while ( nCount > 0)
     257             :                             {
     258           0 :                                 *(pDest++) = nDat;
     259           0 :                                 nCount--;
     260             :                             }
     261             :                         }
     262             :                         else
     263             :                         {
     264           0 :                             nCount -= nx;
     265           0 :                             do
     266             :                             {
     267           0 :                                 *(pDest++) = nDat;
     268           0 :                                 nx--;
     269             :                             }
     270             :                             while ( nx > 0 );
     271           0 :                             break;
     272             :                         }
     273             :                     }
     274             :                     else
     275             :                     {
     276           0 :                         *(pDest++) = nDat;
     277           0 :                         nx--;
     278             :                     }
     279             :                 }
     280             :             }
     281             :         }
     282           0 :         pSource1 = pPlane[ 0 ];
     283           0 :         pSource2 = pPlane[ 1 ];
     284           0 :         pSource3 = pPlane[ 2 ];
     285           0 :         pSource4 = pPlane[ 3 ];
     286           0 :         switch ( nBitsPerPlanePix + ( nPlanes << 8 ) )
     287             :         {
     288             :             // 2 colors
     289             :             case 0x101 :
     290           0 :                 for ( i = 0; i < nWidth; i++ )
     291             :                 {
     292           0 :                     sal_uLong nShift = ( i & 7 ) ^ 7;
     293           0 :                     if ( nShift == 0 )
     294           0 :                         pAcc->SetPixelIndex( ny, i, *(pSource1++) & 1 );
     295             :                     else
     296           0 :                         pAcc->SetPixelIndex( ny, i, (*pSource1 >> nShift ) & 1 );
     297             :                 }
     298           0 :                 break;
     299             :             // 4 colors
     300             :             case 0x102 :
     301           0 :                 for ( i = 0; i < nWidth; i++ )
     302             :                 {
     303           0 :                     switch( i & 3 )
     304             :                     {
     305             :                         case 0 :
     306           0 :                             nCol = *pSource1 >> 6;
     307           0 :                             break;
     308             :                         case 1 :
     309           0 :                             nCol = ( *pSource1 >> 4 ) & 0x03 ;
     310           0 :                             break;
     311             :                         case 2 :
     312           0 :                             nCol = ( *pSource1 >> 2 ) & 0x03;
     313           0 :                             break;
     314             :                         case 3 :
     315           0 :                             nCol = ( *pSource1++ ) & 0x03;
     316           0 :                             break;
     317             :                     }
     318           0 :                     pAcc->SetPixelIndex( ny, i, nCol );
     319             :                 }
     320           0 :                 break;
     321             :             // 256 colors
     322             :             case 0x108 :
     323           0 :                 for ( i = 0; i < nWidth; i++ )
     324             :                 {
     325           0 :                     pAcc->SetPixelIndex( ny, i, *pSource1++ );
     326             :                 }
     327           0 :                 break;
     328             :             // 8 colors
     329             :             case 0x301 :
     330           0 :                 for ( i = 0; i < nWidth; i++ )
     331             :                 {
     332           0 :                     sal_uLong nShift = ( i & 7 ) ^ 7;
     333           0 :                     if ( nShift == 0 )
     334             :                     {
     335           0 :                         nCol = ( *pSource1++ & 1) + ( ( *pSource2++ << 1 ) & 2 ) + ( ( *pSource3++ << 2 ) & 4 );
     336           0 :                         pAcc->SetPixelIndex( ny, i, nCol );
     337             :                     }
     338             :                     else
     339             :                     {
     340             :                         nCol = sal::static_int_cast< sal_uInt8 >(
     341           0 :                             ( ( *pSource1 >> nShift ) & 1)  + ( ( ( *pSource2 >> nShift ) << 1 ) & 2 ) +
     342           0 :                             ( ( ( *pSource3 >> nShift ) << 2 ) & 4 ));
     343           0 :                         pAcc->SetPixelIndex( ny, i, nCol );
     344             :                     }
     345             :                 }
     346           0 :                 break;
     347             :             // 16 colors
     348             :             case 0x401 :
     349           0 :                 for ( i = 0; i < nWidth; i++ )
     350             :                 {
     351           0 :                     sal_uLong nShift = ( i & 7 ) ^ 7;
     352           0 :                     if ( nShift == 0 )
     353             :                     {
     354           0 :                         nCol = ( *pSource1++ & 1) + ( ( *pSource2++ << 1 ) & 2 ) + ( ( *pSource3++ << 2 ) & 4 ) +
     355           0 :                             ( ( *pSource4++ << 3 ) & 8 );
     356           0 :                         pAcc->SetPixelIndex( ny, i, nCol );
     357             :                     }
     358             :                     else
     359             :                     {
     360             :                         nCol = sal::static_int_cast< sal_uInt8 >(
     361           0 :                             ( ( *pSource1 >> nShift ) & 1)  + ( ( ( *pSource2 >> nShift ) << 1 ) & 2 ) +
     362           0 :                             ( ( ( *pSource3 >> nShift ) << 2 ) & 4 ) + ( ( ( *pSource4 >> nShift ) << 3 ) & 8 ));
     363           0 :                         pAcc->SetPixelIndex( ny, i, nCol );
     364             :                     }
     365             :                 }
     366           0 :                 break;
     367             :             // 16m colors
     368             :             case 0x308 :
     369           0 :                 for ( i = 0; i < nWidth; i++ )
     370             :                 {
     371           0 :                     pAcc->SetPixel( ny, i, Color( *pSource1++, *pSource2++, *pSource3++ ) );
     372             : 
     373             :                 }
     374           0 :                 break;
     375             :             default :
     376           0 :                 nStatus = sal_False;
     377           0 :                 break;
     378             :         }
     379             :     }
     380           0 :     for ( np = 0; np < nPlanes; np++ )
     381           0 :         delete[] pPlane[ np ];
     382           0 : }
     383             : 
     384           0 : void PCXReader::ImplReadPalette( sal_uLong nCol )
     385             : {
     386             :     sal_uInt8   r, g, b;
     387           0 :     sal_uInt8*  pPtr = pPalette;
     388           0 :     for ( sal_uLong i = 0; i < nCol; i++ )
     389             :     {
     390           0 :         m_rPCX.ReadUChar( r ).ReadUChar( g ).ReadUChar( b );
     391           0 :         *pPtr++ = r;
     392           0 :         *pPtr++ = g;
     393           0 :         *pPtr++ = b;
     394             :     }
     395           0 : }
     396             : 
     397             : //================== GraphicImport - the exported function ================
     398             : 
     399             : // this needs to be kept in sync with
     400             : // ImpFilterLibCacheEntry::GetImportFunction() from
     401             : // vcl/source/filter/graphicfilter.cxx
     402             : #if defined(DISABLE_DYNLOADING)
     403             : #define GraphicImport ipxGraphicImport
     404             : #endif
     405             : 
     406             : extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL
     407           0 : GraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
     408             : {
     409           0 :     PCXReader aPCXReader(rStream);
     410           0 :     sal_Bool nRetValue = aPCXReader.ReadPCX(rGraphic);
     411           0 :     if ( nRetValue == sal_False )
     412           0 :         rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
     413           0 :     return nRetValue;
     414             : }
     415             : 
     416             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10