LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/ipbm - ipbm.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 88 262 33.6 %
Date: 2014-11-03 Functions: 9 9 100.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             : #include <sal/config.h>
      21             : 
      22             : #include <vcl/FilterConfigItem.hxx>
      23             : #include <vcl/graph.hxx>
      24             : #include <vcl/bmpacc.hxx>
      25             : 
      26             : //============================ PBMReader ==================================
      27             : 
      28             : class PBMReader {
      29             : 
      30             : private:
      31             : 
      32             :     SvStream&           mrPBM;              // the PBM file to read
      33             : 
      34             :     bool            mbStatus;
      35             :     bool            mbRemark;           // sal_False if the stream is in a comment
      36             :     bool            mbRaw;              // RAW/ASCII MODE
      37             :     sal_uLong           mnMode;             // 0->PBM, 1->PGM, 2->PPM
      38             :     Bitmap              maBmp;
      39             :     BitmapWriteAccess*  mpAcc;
      40             :     sal_uLong           mnWidth, mnHeight;  // dimensions in pixel
      41             :     sal_uLong           mnCol;
      42             :     sal_uLong           mnMaxVal;           // max value in the <missing comment>
      43             :     bool            ImplCallback( sal_uInt16 nPercent );
      44             :     bool            ImplReadBody();
      45             :     bool            ImplReadHeader();
      46             : 
      47             : public:
      48             :                         PBMReader(SvStream & rPBM);
      49             :                         ~PBMReader();
      50             :     bool                ReadPBM(Graphic & rGraphic );
      51             : };
      52             : 
      53             : //=================== Methods of PBMReader ==============================
      54             : 
      55          52 : PBMReader::PBMReader(SvStream & rPBM)
      56             :     : mrPBM(rPBM)
      57             :     , mbStatus(true)
      58             :     , mbRemark(false)
      59             :     , mbRaw(true)
      60             :     , mnMode(0)
      61             :     , mpAcc(NULL)
      62             :     , mnWidth(0)
      63             :     , mnHeight(0)
      64             :     , mnCol(0)
      65          52 :     , mnMaxVal(0)
      66             : {
      67          52 : }
      68             : 
      69          52 : PBMReader::~PBMReader()
      70             : {
      71          52 : }
      72             : 
      73       11920 : bool PBMReader::ImplCallback( sal_uInt16 /*nPercent*/ )
      74             : {
      75             : /*
      76             :     if ( pCallback != NULL )
      77             :     {
      78             :         if ( ( (*pCallback)( pCallerData, nPercent ) ) == sal_True )
      79             :         {
      80             :             mrPBM.SetError( SVSTREAM_FILEFORMAT_ERROR );
      81             :             return sal_True;
      82             :         }
      83             :     }
      84             : */
      85       11920 :     return false;
      86             : }
      87             : 
      88          52 : bool PBMReader::ReadPBM(Graphic & rGraphic )
      89             : {
      90             :     sal_uInt16 i;
      91             : 
      92          52 :     if ( mrPBM.GetError() )
      93           0 :         return false;
      94             : 
      95          52 :     mrPBM.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
      96             : 
      97             :     // read header:
      98             : 
      99          52 :     if ( ( mbStatus = ImplReadHeader() ) == false )
     100           2 :         return false;
     101             : 
     102          50 :     if ( ( mnMaxVal == 0 ) || ( mnWidth == 0 ) || ( mnHeight == 0 ) )
     103           0 :         return false;
     104             : 
     105             :     // 0->PBM, 1->PGM, 2->PPM
     106          50 :     switch ( mnMode )
     107             :     {
     108             :         case 0 :
     109           0 :             maBmp = Bitmap( Size( mnWidth, mnHeight ), 1 );
     110           0 :             if ( ( mpAcc = maBmp.AcquireWriteAccess() ) == 0 )
     111           0 :                 return false;
     112           0 :             mpAcc->SetPaletteEntryCount( 2 );
     113           0 :             mpAcc->SetPaletteColor( 0, BitmapColor( 0xff, 0xff, 0xff ) );
     114           0 :             mpAcc->SetPaletteColor( 1, BitmapColor( 0x00, 0x00, 0x00 ) );
     115           0 :             break;
     116             : 
     117             :         case 1 :
     118           0 :             if ( mnMaxVal <= 1 )
     119           0 :                 maBmp = Bitmap( Size( mnWidth, mnHeight ), 1);
     120           0 :             else if ( mnMaxVal <= 15 )
     121           0 :                 maBmp = Bitmap( Size( mnWidth, mnHeight ), 4);
     122             :             else
     123           0 :                 maBmp = Bitmap( Size( mnWidth, mnHeight ), 8);
     124             : 
     125           0 :             if ( ( mpAcc = maBmp.AcquireWriteAccess() ) == 0 )
     126           0 :                 return false;
     127           0 :             mnCol = (sal_uInt16)mnMaxVal + 1;
     128           0 :             if ( mnCol > 256 )
     129           0 :                 mnCol = 256;
     130             : 
     131           0 :             mpAcc->SetPaletteEntryCount( 256 );
     132           0 :             for ( i = 0; i < mnCol; i++ )
     133             :             {
     134           0 :                 sal_uLong nCount = 255 * i / mnCol;
     135           0 :                 mpAcc->SetPaletteColor( i, BitmapColor( (sal_uInt8)nCount, (sal_uInt8)nCount, (sal_uInt8)nCount ) );
     136             :             }
     137           0 :             break;
     138             :         case 2 :
     139          50 :             maBmp = Bitmap( Size( mnWidth, mnHeight ), 24 );
     140          50 :             if ( ( mpAcc = maBmp.AcquireWriteAccess() ) == 0 )
     141           0 :                 return false;
     142          50 :             break;
     143             :     }
     144             : 
     145             :     // read bitmap data
     146          50 :     mbStatus = ImplReadBody();
     147             : 
     148          50 :     if ( mpAcc )
     149             :     {
     150          50 :         maBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
     151             :     }
     152          50 :     if ( mbStatus )
     153          50 :         rGraphic = maBmp;
     154             : 
     155          50 :     return mbStatus;
     156             : }
     157             : 
     158          52 : bool PBMReader::ImplReadHeader()
     159             : {
     160             :     sal_uInt8   nID[ 2 ];
     161             :     sal_uInt8   nDat;
     162          52 :     sal_uInt8   nMax, nCount = 0;
     163          52 :     bool    bFinished = false;
     164             : 
     165          52 :     mrPBM.ReadUChar( nID[ 0 ] ).ReadUChar( nID[ 1 ] );
     166          52 :     if ( nID[ 0 ] != 'P' )
     167           0 :         return false;
     168          52 :     mnMaxVal = mnWidth = mnHeight = 0;
     169          52 :     switch ( nID[ 1 ] )
     170             :     {
     171             :         case '1' :
     172           0 :             mbRaw = false;
     173             :             //fall-through
     174             :         case '4' :
     175           0 :             mnMode = 0;
     176           0 :             nMax = 2;               // number of parameters in Header
     177           0 :             mnMaxVal = 1;
     178           0 :             break;
     179             :         case '2' :
     180           0 :             mbRaw = false;
     181             :             //fall-through
     182             :         case '5' :
     183           0 :             mnMode = 1;
     184           0 :             nMax = 3;
     185           0 :             break;
     186             :         case '3' :
     187           2 :             mbRaw = false;
     188             :             //fall-through
     189             :         case '6' :
     190          52 :             mnMode = 2;
     191          52 :             nMax = 3;
     192          52 :             break;
     193             :         default:
     194           0 :             return false;
     195             :     }
     196         646 :     while ( bFinished == false )
     197             :     {
     198         544 :         if ( mrPBM.GetError() )
     199           0 :             return false;
     200             : 
     201         544 :         mrPBM.ReadUChar( nDat );
     202             : 
     203         544 :         if ( nDat == '#' )
     204             :         {
     205           0 :             mbRemark = true;
     206           0 :             continue;
     207             :         }
     208         544 :         else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
     209             :         {
     210         104 :             mbRemark = false;
     211         104 :             nDat = 0x20;
     212             :         }
     213         544 :         if ( mbRemark )
     214           0 :             continue;
     215             : 
     216         544 :         if ( ( nDat == 0x20 ) || ( nDat == 0x09 ) )
     217             :         {
     218         200 :             if ( ( nCount == 0 ) && mnWidth )
     219          50 :                 nCount++;
     220         150 :             else if ( ( nCount == 1 ) && mnHeight )
     221             :             {
     222         100 :                 if ( ++nCount == nMax )
     223           0 :                     bFinished = true;
     224             :             }
     225         100 :             else if ( ( nCount == 2 ) && mnMaxVal )
     226             :             {
     227          50 :                 bFinished = true;
     228             :             }
     229         200 :             continue;
     230             :         }
     231         344 :         if ( ( nDat >= '0' ) && ( nDat <= '9' ) )
     232             :         {
     233         342 :             nDat -= '0';
     234         684 :             if ( nCount == 0 )
     235             :             {
     236          96 :                 mnWidth *= 10;
     237          96 :                 mnWidth += nDat;
     238             :             }
     239         246 :             else if ( nCount == 1 )
     240             :             {
     241          96 :                 mnHeight *= 10;
     242          96 :                 mnHeight += nDat;
     243             :             }
     244         150 :             else if ( nCount == 2 )
     245             :             {
     246         150 :                 mnMaxVal *= 10;
     247         150 :                 mnMaxVal += nDat;
     248             :             }
     249             :         }
     250             :         else
     251           2 :             return false;
     252             :     }
     253          50 :     return mbStatus;
     254             : }
     255             : 
     256          50 : bool PBMReader::ImplReadBody()
     257             : {
     258          50 :     bool    bPara, bFinished = false;
     259          50 :     sal_uInt8   nDat = 0, nCount;
     260             :     sal_uLong   nGrey, nRGB[3];
     261          50 :     sal_uLong   nWidth = 0;
     262          50 :     sal_uLong   nHeight = 0;
     263             : 
     264          50 :     if ( mbRaw )
     265             :     {
     266          50 :         signed char nShift = 0;
     267          50 :         switch ( mnMode )
     268             :         {
     269             : 
     270             :             // PBM
     271             :             case 0 :
     272           0 :                 while ( nHeight != mnHeight )
     273             :                 {
     274           0 :                     if ( mrPBM.IsEof() || mrPBM.GetError() )
     275           0 :                         return false;
     276             : 
     277           0 :                     if ( --nShift < 0 )
     278             :                     {
     279           0 :                         mrPBM.ReadUChar( nDat );
     280           0 :                         nShift = 7;
     281             :                     }
     282           0 :                     mpAcc->SetPixelIndex( nHeight, nWidth, nDat >> nShift );
     283           0 :                     if ( ++nWidth == mnWidth )
     284             :                     {
     285           0 :                         nShift = 0;
     286           0 :                         nWidth = 0;
     287           0 :                         nHeight++;
     288           0 :                         ImplCallback( (sal_uInt16)( ( 100 * nHeight ) / mnHeight ) );   // processing output in percent
     289             :                     }
     290             :                 }
     291           0 :                 break;
     292             : 
     293             :             // PGM
     294             :             case 1 :
     295           0 :                 while ( nHeight != mnHeight )
     296             :                 {
     297           0 :                     if ( mrPBM.IsEof() || mrPBM.GetError() )
     298           0 :                         return false;
     299             : 
     300           0 :                     mrPBM.ReadUChar( nDat );
     301           0 :                     mpAcc->SetPixelIndex( nHeight, nWidth++, nDat);
     302             : 
     303           0 :                     if ( nWidth == mnWidth )
     304             :                     {
     305           0 :                         nWidth = 0;
     306           0 :                         nHeight++;
     307           0 :                         ImplCallback( (sal_uInt16)( ( 100 * nHeight ) / mnHeight ) );   // processing output in percent
     308             :                     }
     309             :                 }
     310           0 :                 break;
     311             : 
     312             :             // PPM
     313             :             case 2 :
     314     6138476 :                 while ( nHeight != mnHeight )
     315             :                 {
     316     6138376 :                     if ( mrPBM.IsEof() || mrPBM.GetError() )
     317           0 :                         return false;
     318             : 
     319             :                     sal_uInt8   nR, nG, nB;
     320             :                     sal_uLong   nRed, nGreen, nBlue;
     321     6138376 :                     mrPBM.ReadUChar( nR ).ReadUChar( nG ).ReadUChar( nB );
     322     6138376 :                     nRed = 255 * nR / mnMaxVal;
     323     6138376 :                     nGreen = 255 * nG / mnMaxVal;
     324     6138376 :                     nBlue = 255 * nB / mnMaxVal;
     325     6138376 :                     mpAcc->SetPixel( nHeight, nWidth++, BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
     326     6138376 :                     if ( nWidth == mnWidth )
     327             :                     {
     328       11920 :                         nWidth = 0;
     329       11920 :                         nHeight++;
     330       11920 :                         ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) );  // processing output in percent
     331             :                     }
     332             :                 }
     333          50 :                 break;
     334             :         }
     335             :     }
     336           0 :     else switch  ( mnMode )
     337             :     {
     338             :         // PBM
     339             :         case 0 :
     340           0 :             while ( bFinished == false )
     341             :             {
     342           0 :                 if ( mrPBM.IsEof() || mrPBM.GetError() )
     343           0 :                     return false;
     344             : 
     345           0 :                 mrPBM.ReadUChar( nDat );
     346             : 
     347           0 :                 if ( nDat == '#' )
     348             :                 {
     349           0 :                     mbRemark = true;
     350           0 :                     continue;
     351             :                 }
     352           0 :                 else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
     353             :                 {
     354           0 :                     mbRemark = false;
     355           0 :                     continue;
     356             :                 }
     357           0 :                 if ( mbRemark || nDat == 0x20 || nDat == 0x09 )
     358           0 :                     continue;
     359             : 
     360           0 :                 if ( nDat == '0' || nDat == '1' )
     361             :                 {
     362           0 :                     mpAcc->SetPixelIndex( nHeight, nWidth, static_cast<sal_uInt8>(nDat - '0') );
     363           0 :                     nWidth++;
     364           0 :                     if ( nWidth == mnWidth )
     365             :                     {
     366           0 :                         nWidth = 0;
     367           0 :                         if ( ++nHeight == mnHeight )
     368           0 :                             bFinished = true;
     369           0 :                         ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) );  // processing output in percent
     370             :                     }
     371             :                 }
     372             :                 else
     373           0 :                     return false;
     374             :             }
     375           0 :             break;
     376             : 
     377             :         // PGM
     378             :         case 1 :
     379             : 
     380           0 :             bPara = false;
     381           0 :             nCount = 0;
     382           0 :             nGrey = 0;
     383             : 
     384           0 :             while ( bFinished == false )
     385             :             {
     386           0 :                 if ( nCount )
     387             :                 {
     388           0 :                     nCount--;
     389           0 :                     if ( nGrey <= mnMaxVal )
     390           0 :                         nGrey = 255 * nGrey / mnMaxVal;
     391           0 :                     mpAcc->SetPixelIndex( nHeight, nWidth++, static_cast<sal_uInt8>(nGrey) );
     392           0 :                     nGrey = 0;
     393           0 :                     if ( nWidth == mnWidth )
     394             :                     {
     395           0 :                         nWidth = 0;
     396           0 :                         if ( ++nHeight == mnHeight )
     397           0 :                             bFinished = true;
     398           0 :                         ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) );  // processing output in percent
     399             :                     }
     400           0 :                     continue;
     401             :                 }
     402             : 
     403           0 :                 if ( mrPBM.IsEof() || mrPBM.GetError() )
     404           0 :                     return false;
     405             : 
     406           0 :                 mrPBM.ReadUChar( nDat );
     407             : 
     408           0 :                 if ( nDat == '#' )
     409             :                 {
     410           0 :                     mbRemark = true;
     411           0 :                     if ( bPara )
     412             :                     {
     413           0 :                         bPara = false;
     414           0 :                         nCount++;
     415             :                     }
     416           0 :                     continue;
     417             :                 }
     418           0 :                 else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
     419             :                 {
     420           0 :                     mbRemark = false;
     421           0 :                     if ( bPara )
     422             :                     {
     423           0 :                         bPara = false;
     424           0 :                         nCount++;
     425             :                     }
     426           0 :                     continue;
     427             :                 }
     428             : 
     429           0 :                 if ( nDat == 0x20 || nDat == 0x09 )
     430             :                 {
     431           0 :                     if ( bPara )
     432             :                     {
     433           0 :                         bPara = false;
     434           0 :                         nCount++;
     435             :                     }
     436           0 :                     continue;
     437             :                 }
     438           0 :                 if ( nDat >= '0' && nDat <= '9' )
     439             :                 {
     440           0 :                     bPara = true;
     441           0 :                     nGrey *= 10;
     442           0 :                     nGrey += nDat-'0';
     443           0 :                     continue;
     444             :                 }
     445             :                 else
     446           0 :                     return false;
     447             :             }
     448           0 :             break;
     449             : 
     450             : 
     451             : 
     452             :         // PPM
     453             :         case 2 :
     454             : 
     455           0 :             bPara = false;
     456           0 :             nCount = 0;
     457           0 :             nRGB[ 0 ] = nRGB[ 1 ] = nRGB[ 2 ] = 0;
     458             : 
     459           0 :             while ( bFinished == false )
     460             :             {
     461           0 :                 if ( nCount == 3 )
     462             :                 {
     463           0 :                     nCount = 0;
     464           0 :                     mpAcc->SetPixel( nHeight, nWidth++, BitmapColor( static_cast< sal_uInt8 >( ( nRGB[ 0 ] * 255 ) / mnMaxVal ),
     465           0 :                                                                      static_cast< sal_uInt8 >( ( nRGB[ 1 ] * 255 ) / mnMaxVal ),
     466           0 :                                                                      static_cast< sal_uInt8 >( ( nRGB[ 2 ] * 255 ) / mnMaxVal ) ) );
     467           0 :                     nRGB[ 0 ] = nRGB[ 1 ] = nRGB[ 2 ] = 0;
     468           0 :                     if ( nWidth == mnWidth )
     469             :                     {
     470           0 :                         nWidth = 0;
     471           0 :                         if ( ++nHeight == mnHeight )
     472           0 :                             bFinished = true;
     473           0 :                         ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) );  // processing output in percent
     474             :                     }
     475           0 :                     continue;
     476             :                 }
     477             : 
     478           0 :                 if ( mrPBM.IsEof() || mrPBM.GetError() )
     479           0 :                     return false;
     480             : 
     481           0 :                 mrPBM.ReadUChar( nDat );
     482             : 
     483           0 :                 if ( nDat == '#' )
     484             :                 {
     485           0 :                     mbRemark = true;
     486           0 :                     if ( bPara )
     487             :                     {
     488           0 :                         bPara = false;
     489           0 :                         nCount++;
     490             :                     }
     491           0 :                     continue;
     492             :                 }
     493           0 :                 else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
     494             :                 {
     495           0 :                     mbRemark = false;
     496           0 :                     if ( bPara )
     497             :                     {
     498           0 :                         bPara = false;
     499           0 :                         nCount++;
     500             :                     }
     501           0 :                     continue;
     502             :                 }
     503             : 
     504           0 :                 if ( nDat == 0x20 || nDat == 0x09 )
     505             :                 {
     506           0 :                     if ( bPara )
     507             :                     {
     508           0 :                         bPara = false;
     509           0 :                         nCount++;
     510             :                     }
     511           0 :                     continue;
     512             :                 }
     513           0 :                 if ( nDat >= '0' && nDat <= '9' )
     514             :                 {
     515           0 :                     bPara = true;
     516           0 :                     nRGB[ nCount ] *= 10;
     517           0 :                     nRGB[ nCount ] += nDat-'0';
     518           0 :                     continue;
     519             :                 }
     520             :                 else
     521           0 :                     return false;
     522             :             }
     523           0 :             break;
     524             :     }
     525          50 :     return mbStatus;
     526             : }
     527             : 
     528             : //================== GraphicImport - the exported function ================
     529             : 
     530             : // this needs to be kept in sync with
     531             : // ImpFilterLibCacheEntry::GetImportFunction() from
     532             : // vcl/source/filter/graphicfilter.cxx
     533             : #if defined(DISABLE_DYNLOADING)
     534             : #define GraphicImport ipbGraphicImport
     535             : #endif
     536             : 
     537             : extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL
     538          52 : GraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
     539             : {
     540          52 :     PBMReader aPBMReader(rStream);
     541             : 
     542          52 :     return aPBMReader.ReadPBM(rGraphic );
     543          30 : }
     544             : 
     545             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10