LCOV - code coverage report
Current view: top level - libreoffice/filter/source/graphicfilter/ipcx - ipcx.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 171 0.0 %
Date: 2012-12-17 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;               // Die einzulesende PCX-Datei
      33             : 
      34             :     Bitmap              aBmp;
      35             :     BitmapWriteAccess*  pAcc;
      36             :     sal_uInt8               nVersion;           // PCX-Version
      37             :     sal_uInt8               nEncoding;          // Art der Komprimierung
      38             :     sal_uLong               nBitsPerPlanePix;   // Bits Pro Ebene pro Pixel
      39             :     sal_uLong               nPlanes;            // Anzahl Ebenen
      40             :     sal_uLong               nBytesPerPlaneLin;  // Bytes in einer Ebenen pro Zeile
      41             :     sal_uInt16              nPaletteInfo;
      42             : 
      43             :     sal_uLong               nWidth, nHeight;    // Bildausmass in Pixeln
      44             :     sal_uInt16              nResX, nResY;       // Aufloesung in Pixel pro Inch oder 0,0
      45             :     sal_uInt16              nDestBitsPerPixel;  // Bits pro Pixel der Zielbitmap 1,4,8 oder 24
      46             :     sal_uInt8*              pPalette;           //
      47             :     sal_Bool                nStatus;            // status nun nicht mehr am stream abfragen ( 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             :                         // Liesst aus dem Stream eine PCX-Datei und fuellt das GDIMetaFile
      60             : };
      61             : 
      62             : //=================== Methoden von 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; // damit unter OS/2
      87             :                                                // das richtige (Tools-)new
      88             :                                                // verwendet wird, da es sonst
      89             :                                                // in dieser DLL nur Vector-news
      90             :                                                // gibt;
      91             : 
      92           0 :     m_rPCX.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
      93             : 
      94             :     // Kopf einlesen:
      95             : 
      96           0 :     nStatus = sal_True;
      97             : 
      98           0 :     ImplReadHeader();
      99             : 
     100             :     // BMP-Header und ggf. (eventuell zunaechst ungueltige) Farbpalette schreiben:
     101           0 :     if ( nStatus )
     102             :     {
     103           0 :         aBmp = Bitmap( Size( nWidth, nHeight ), nDestBitsPerPixel );
     104           0 :         if ( ( pAcc = aBmp.AcquireWriteAccess() ) == sal_False )
     105           0 :             return sal_False;
     106             : 
     107           0 :         if ( nDestBitsPerPixel <= 8 )
     108             :         {
     109           0 :             sal_uInt16 nColors = 1 << nDestBitsPerPixel;
     110           0 :             sal_uInt8* pPal = pPalette;
     111           0 :             pAcc->SetPaletteEntryCount( nColors );
     112           0 :             for ( sal_uInt16 i = 0; i < nColors; i++, pPal += 3 )
     113             :             {
     114           0 :                 pAcc->SetPaletteColor( i, BitmapColor ( pPal[ 0 ], pPal[ 1 ], pPal[ 2 ] ) );
     115             :             }
     116             :         }
     117             :         // Bitmap-Daten einlesen
     118           0 :         ImplReadBody();
     119             : 
     120             :         // Wenn erweiterte Farbpalette am Ende von PCX, dann diese einlesen, und nochmals
     121             :         // in Palette schreiben:
     122           0 :         if ( nDestBitsPerPixel == 8 && nStatus )
     123             :         {
     124           0 :             sal_uInt8* pPal = pPalette;
     125           0 :             m_rPCX.SeekRel(1);
     126           0 :             ImplReadPalette(256);
     127           0 :             pAcc->SetPaletteEntryCount( 256 );
     128           0 :             for ( sal_uInt16 i = 0; i < 256; i++, pPal += 3 )
     129             :             {
     130           0 :                 pAcc->SetPaletteColor( i, BitmapColor ( pPal[ 0 ], pPal[ 1 ], pPal[ 2 ] ) );
     131             :             }
     132             :         }
     133             :     /*
     134             :         // Aufloesung einstellen:
     135             :         if (nResX!=0 && nResY!=0) {
     136             :             MapMode aMapMode(MAP_INCH,Point(0,0),Fraction(1,nResX),Fraction(1,nResY));
     137             :             rBitmap.SetPrefMapMode(aMapMode);
     138             :             rBitmap.SetPrefSize(Size(nWidth,nHeight));
     139             :         }
     140           0 :     */  if ( nStatus && pAcc )
     141             :         {
     142           0 :             aBmp.ReleaseAccess( pAcc ), pAcc = NULL;
     143           0 :             rGraphic = aBmp;
     144           0 :             return sal_True;
     145             :         }
     146             :     }
     147           0 :     return sal_False;
     148             : }
     149             : 
     150           0 : void PCXReader::ImplReadHeader()
     151             : {
     152             :     sal_uInt8 nbyte;
     153             :     sal_uInt16 nushort;
     154             :     sal_uInt16 nMinX,nMinY,nMaxX,nMaxY;
     155             : 
     156           0 :     m_rPCX >> nbyte >> nVersion >> nEncoding;
     157           0 :     if ( nbyte!=0x0a || (nVersion != 0 && nVersion != 2 && nVersion != 3 && nVersion != 5) || nEncoding > 1 )
     158             :     {
     159           0 :         nStatus = sal_False;
     160             :         return;
     161             :     }
     162             : 
     163           0 :     m_rPCX >> nbyte; nBitsPerPlanePix = (sal_uLong)nbyte;
     164           0 :     m_rPCX >> nMinX >> nMinY >> nMaxX >> nMaxY;
     165             : 
     166           0 :     if ((nMinX > nMaxX) || (nMinY > nMaxY))
     167             :     {
     168           0 :         nStatus = sal_False;
     169             :         return;
     170             :     }
     171             : 
     172           0 :     nWidth = nMaxX-nMinX+1;
     173           0 :     nHeight = nMaxY-nMinY+1;
     174             : 
     175           0 :     m_rPCX >> nResX;
     176           0 :     m_rPCX >> nResY;
     177           0 :     if ( nResX >= nWidth || nResY >= nHeight || ( nResX != nResY ) )
     178           0 :         nResX = nResY = 0;
     179             : 
     180           0 :     ImplReadPalette( 16 );
     181             : 
     182           0 :     m_rPCX.SeekRel( 1 );
     183           0 :     m_rPCX >> nbyte;   nPlanes = (sal_uLong)nbyte;
     184           0 :     m_rPCX >> nushort; nBytesPerPlaneLin = (sal_uLong)nushort;
     185           0 :     m_rPCX >> nPaletteInfo;
     186             : 
     187           0 :     m_rPCX.SeekRel( 58 );
     188             : 
     189           0 :     nDestBitsPerPixel = (sal_uInt16)( nBitsPerPlanePix * nPlanes );
     190           0 :     if (nDestBitsPerPixel == 2 || nDestBitsPerPixel == 3) nDestBitsPerPixel = 4;
     191             : 
     192           0 :     if ( ( nDestBitsPerPixel != 1 && nDestBitsPerPixel != 4 && nDestBitsPerPixel != 8 && nDestBitsPerPixel != 24 )
     193             :         || nPlanes > 4 || nBytesPerPlaneLin < ( ( nWidth * nBitsPerPlanePix+7 ) >> 3 ) )
     194             :     {
     195           0 :         nStatus = sal_False;
     196             :         return;
     197             :     }
     198             : 
     199             :     // Wenn das Bild nur 2 Farben hat, ist die Palette zumeist ungueltig, und es handelt sich
     200             :     // immer (?) um ein schwarz-weiss-Bild:
     201           0 :     if ( nPlanes == 1 && nBitsPerPlanePix == 1 )
     202             :     {
     203           0 :         pPalette[ 0 ] = pPalette[ 1 ] = pPalette[ 2 ] = 0x00;
     204           0 :         pPalette[ 3 ] = pPalette[ 4 ] = pPalette[ 5 ] = 0xff;
     205             :     }
     206             : }
     207             : 
     208           0 : void PCXReader::ImplReadBody()
     209             : {
     210             :     sal_uInt8   *pPlane[ 4 ], * pDest, * pSource1, * pSource2, * pSource3, *pSource4;
     211             :     sal_uLong   i, nx, ny, np, nCount, nPercent;
     212           0 :     sal_uLong   nLastPercent = 0;
     213           0 :     sal_uInt8   nDat = 0, nCol = 0;
     214             : 
     215           0 :     for( np = 0; np < nPlanes; np++ )
     216           0 :         pPlane[ np ] = new sal_uInt8[ nBytesPerPlaneLin ];
     217             : 
     218           0 :     nCount = 0;
     219           0 :     for ( ny = 0; ny < nHeight; ny++ )
     220             :     {
     221           0 :         if (m_rPCX.GetError() || m_rPCX.IsEof())
     222             :         {
     223           0 :             nStatus = sal_False;
     224           0 :             break;
     225             :         }
     226           0 :         nPercent = ny * 60 / nHeight + 10;
     227           0 :         if ( ny == 0 || nLastPercent + 4 <= nPercent )
     228             :         {
     229           0 :             nLastPercent = nPercent;
     230           0 :             if ( Callback( (sal_uInt16)nPercent ) == sal_True )
     231           0 :                 break;
     232             :         }
     233           0 :         for ( np = 0; np < nPlanes; np++)
     234             :         {
     235           0 :             if ( nEncoding == 0)
     236           0 :                 m_rPCX.Read( (void *)pPlane[ np ], nBytesPerPlaneLin );
     237             :             else
     238             :             {
     239           0 :                 pDest = pPlane[ np ];
     240           0 :                 nx = nBytesPerPlaneLin;
     241           0 :                 while ( nCount > 0 && nx > 0)
     242             :                 {
     243           0 :                     *(pDest++) = nDat;
     244           0 :                     nx--;
     245           0 :                     nCount--;
     246             :                 }
     247           0 :                 while ( nx > 0 )
     248             :                 {
     249           0 :                     m_rPCX >> nDat;
     250           0 :                     if ( ( nDat & 0xc0 ) == 0xc0 )
     251             :                     {
     252           0 :                         nCount =( (sal_uLong)nDat ) & 0x003f;
     253           0 :                         m_rPCX >> nDat;
     254           0 :                         if ( nCount < nx )
     255             :                         {
     256           0 :                             nx -= nCount;
     257           0 :                             while ( nCount > 0)
     258             :                             {
     259           0 :                                 *(pDest++) = nDat;
     260           0 :                                 nCount--;
     261             :                             }
     262             :                         }
     263             :                         else
     264             :                         {
     265           0 :                             nCount -= nx;
     266           0 :                             do
     267             :                             {
     268           0 :                                 *(pDest++) = nDat;
     269           0 :                                 nx--;
     270             :                             }
     271             :                             while ( nx > 0 );
     272           0 :                             break;
     273             :                         }
     274             :                     }
     275             :                     else
     276             :                     {
     277           0 :                         *(pDest++) = nDat;
     278           0 :                         nx--;
     279             :                     }
     280             :                 }
     281             :             }
     282             :         }
     283           0 :         pSource1 = pPlane[ 0 ];
     284           0 :         pSource2 = pPlane[ 1 ];
     285           0 :         pSource3 = pPlane[ 2 ];
     286           0 :         pSource4 = pPlane[ 3 ];
     287           0 :         switch ( nBitsPerPlanePix + ( nPlanes << 8 ) )
     288             :         {
     289             :             // 2 colors
     290             :             case 0x101 :
     291           0 :                 for ( i = 0; i < nWidth; i++ )
     292             :                 {
     293           0 :                     sal_uLong nShift = ( i & 7 ) ^ 7;
     294           0 :                     if ( nShift == 0 )
     295           0 :                         pAcc->SetPixel( ny, i, ( *pSource1++ & 1 ) );
     296             :                     else
     297             :                         pAcc->SetPixel(
     298             :                             ny, i,
     299             :                             sal::static_int_cast< sal_uInt8 >(
     300           0 :                                 ( *pSource1 >> nShift ) & 1) );
     301             :                 }
     302           0 :                 break;
     303             :             // 4 colors
     304             :             case 0x102 :
     305           0 :                 for ( i = 0; i < nWidth; i++ )
     306             :                 {
     307           0 :                     switch( i & 3 )
     308             :                     {
     309             :                         case 0 :
     310           0 :                             nCol = *pSource1 >> 6;
     311           0 :                             break;
     312             :                         case 1 :
     313           0 :                             nCol = ( *pSource1 >> 4 ) & 0x03 ;
     314           0 :                             break;
     315             :                         case 2 :
     316           0 :                             nCol = ( *pSource1 >> 2 ) & 0x03;
     317           0 :                             break;
     318             :                         case 3 :
     319           0 :                             nCol = ( *pSource1++ ) & 0x03;
     320           0 :                             break;
     321             :                     }
     322           0 :                     pAcc->SetPixel( ny, i, nCol );
     323             :                 }
     324           0 :                 break;
     325             :             // 256 colors
     326             :             case 0x108 :
     327           0 :                 for ( i = 0; i < nWidth; i++ )
     328             :                 {
     329           0 :                     pAcc->SetPixel( ny, i, *pSource1++ );
     330             :                 }
     331           0 :                 break;
     332             :             // 8 colors
     333             :             case 0x301 :
     334           0 :                 for ( i = 0; i < nWidth; i++ )
     335             :                 {
     336           0 :                     sal_uLong nShift = ( i & 7 ) ^ 7;
     337           0 :                     if ( nShift == 0 )
     338             :                     {
     339           0 :                         nCol = ( *pSource1++ & 1) + ( ( *pSource2++ << 1 ) & 2 ) + ( ( *pSource3++ << 2 ) & 4 );
     340           0 :                         pAcc->SetPixel( ny, i, nCol );
     341             :                     }
     342             :                     else
     343             :                     {
     344             :                         nCol = sal::static_int_cast< sal_uInt8 >(
     345             :                             ( ( *pSource1 >> nShift ) & 1)  + ( ( ( *pSource2 >> nShift ) << 1 ) & 2 ) +
     346           0 :                             ( ( ( *pSource3 >> nShift ) << 2 ) & 4 ));
     347           0 :                         pAcc->SetPixel( ny, i, nCol );
     348             :                     }
     349             :                 }
     350           0 :                 break;
     351             :             // 16 colors
     352             :             case 0x401 :
     353           0 :                 for ( i = 0; i < nWidth; i++ )
     354             :                 {
     355           0 :                     sal_uLong nShift = ( i & 7 ) ^ 7;
     356           0 :                     if ( nShift == 0 )
     357             :                     {
     358             :                         nCol = ( *pSource1++ & 1) + ( ( *pSource2++ << 1 ) & 2 ) + ( ( *pSource3++ << 2 ) & 4 ) +
     359           0 :                             ( ( *pSource4++ << 3 ) & 8 );
     360           0 :                         pAcc->SetPixel( ny, i, nCol );
     361             :                     }
     362             :                     else
     363             :                     {
     364             :                         nCol = sal::static_int_cast< sal_uInt8 >(
     365             :                             ( ( *pSource1 >> nShift ) & 1)  + ( ( ( *pSource2 >> nShift ) << 1 ) & 2 ) +
     366           0 :                             ( ( ( *pSource3 >> nShift ) << 2 ) & 4 ) + ( ( ( *pSource4 >> nShift ) << 3 ) & 8 ));
     367           0 :                         pAcc->SetPixel( ny, i, nCol );
     368             :                     }
     369             :                 }
     370           0 :                 break;
     371             :             // 16m colors
     372             :             case 0x308 :
     373           0 :                 for ( i = 0; i < nWidth; i++ )
     374             :                 {
     375           0 :                     pAcc->SetPixel( ny, i, Color( *pSource1++, *pSource2++, *pSource3++ ) );
     376             : 
     377             :                 }
     378           0 :                 break;
     379             :             default :
     380           0 :                 nStatus = sal_False;
     381           0 :                 break;
     382             :         }
     383             :     }
     384           0 :     for ( np = 0; np < nPlanes; np++ )
     385           0 :         delete[] pPlane[ np ];
     386           0 : }
     387             : 
     388           0 : void PCXReader::ImplReadPalette( sal_uLong nCol )
     389             : {
     390             :     sal_uInt8   r, g, b;
     391           0 :     sal_uInt8*  pPtr = pPalette;
     392           0 :     for ( sal_uLong i = 0; i < nCol; i++ )
     393             :     {
     394           0 :         m_rPCX >> r >> g >> b;
     395           0 :         *pPtr++ = r;
     396           0 :         *pPtr++ = g;
     397           0 :         *pPtr++ = b;
     398             :     }
     399           0 : }
     400             : 
     401             : //================== GraphicImport - die exportierte Funktion ================
     402             : 
     403             : #ifdef DISABLE_DYNLOADING
     404             : #define GraphicImport ipxGraphicImport
     405             : #endif
     406             : 
     407             : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL
     408           0 : GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool)
     409             : {
     410           0 :     PCXReader aPCXReader(rStream);
     411           0 :     sal_Bool nRetValue = aPCXReader.ReadPCX(rGraphic);
     412           0 :     if ( nRetValue == sal_False )
     413           0 :         rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
     414           0 :     return nRetValue;
     415             : }
     416             : 
     417             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10