summaryrefslogtreecommitdiff
path: root/filter/source/graphicfilter/ipbm/ipbm.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/graphicfilter/ipbm/ipbm.cxx')
-rw-r--r--filter/source/graphicfilter/ipbm/ipbm.cxx540
1 files changed, 540 insertions, 0 deletions
diff --git a/filter/source/graphicfilter/ipbm/ipbm.cxx b/filter/source/graphicfilter/ipbm/ipbm.cxx
new file mode 100644
index 000000000000..6f6fd876d583
--- /dev/null
+++ b/filter/source/graphicfilter/ipbm/ipbm.cxx
@@ -0,0 +1,540 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_filter.hxx"
+
+#include <vcl/graph.hxx>
+#include <vcl/bmpacc.hxx>
+#include <svtools/fltcall.hxx>
+
+//============================ PBMReader ==================================
+
+class PBMReader {
+
+private:
+
+ SvStream& mrPBM; // Die einzulesende PBM-Datei
+
+ sal_Bool mbStatus;
+ sal_Bool mbRemark; // sal_False wenn sich stream in einem Kommentar befindet
+ sal_Bool mbRaw; // RAW/ASCII MODE
+ sal_uLong mnMode; // 0->PBM, 1->PGM, 2->PPM
+ Bitmap maBmp;
+ BitmapWriteAccess* mpAcc;
+ sal_uLong mnWidth, mnHeight; // Bildausmass in Pixeln
+ sal_uLong mnCol;
+ sal_uLong mnMaxVal; // maximaler wert in den
+ sal_Bool ImplCallback( sal_uInt16 nPercent );
+ sal_Bool ImplReadBody();
+ sal_Bool ImplReadHeader();
+
+public:
+ PBMReader(SvStream & rPBM);
+ ~PBMReader();
+ sal_Bool ReadPBM(Graphic & rGraphic );
+};
+
+//=================== Methoden von PBMReader ==============================
+
+PBMReader::PBMReader(SvStream & rPBM)
+ : mrPBM( rPBM )
+ , mbStatus( sal_True )
+ , mbRemark( sal_False )
+ , mbRaw( sal_True )
+ , mpAcc( NULL )
+{
+}
+
+PBMReader::~PBMReader()
+{
+}
+
+sal_Bool PBMReader::ImplCallback( sal_uInt16 /*nPercent*/ )
+{
+/*
+ if ( pCallback != NULL )
+ {
+ if ( ( (*pCallback)( pCallerData, nPercent ) ) == sal_True )
+ {
+ mrPBM.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return sal_True;
+ }
+ }
+*/
+ return sal_False;
+}
+
+sal_Bool PBMReader::ReadPBM(Graphic & rGraphic )
+{
+ sal_uInt16 i;
+
+ if ( mrPBM.GetError() )
+ return sal_False;
+
+ mrPBM.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ // Kopf einlesen:
+
+ if ( ( mbStatus = ImplReadHeader() ) == sal_False )
+ return sal_False;
+
+ if ( ( mnMaxVal == 0 ) || ( mnWidth == 0 ) || ( mnHeight == 0 ) )
+ return sal_False;
+
+ // 0->PBM, 1->PGM, 2->PPM
+ switch ( mnMode )
+ {
+ case 0 :
+ maBmp = Bitmap( Size( mnWidth, mnHeight ), 1 );
+ if ( ( mpAcc = maBmp.AcquireWriteAccess() ) == sal_False )
+ return sal_False;
+ mpAcc->SetPaletteEntryCount( 2 );
+ mpAcc->SetPaletteColor( 0, BitmapColor( 0xff, 0xff, 0xff ) );
+ mpAcc->SetPaletteColor( 1, BitmapColor( 0x00, 0x00, 0x00 ) );
+ break;
+
+ case 1 :
+ if ( mnMaxVal <= 1 )
+ maBmp = Bitmap( Size( mnWidth, mnHeight ), 1);
+ else if ( mnMaxVal <= 15 )
+ maBmp = Bitmap( Size( mnWidth, mnHeight ), 4);
+ else
+ maBmp = Bitmap( Size( mnWidth, mnHeight ), 8);
+
+ if ( ( mpAcc = maBmp.AcquireWriteAccess() ) == sal_False )
+ return sal_False;
+ mnCol = (sal_uInt16)mnMaxVal + 1;
+ if ( mnCol > 256 )
+ mnCol = 256;
+
+ mpAcc->SetPaletteEntryCount( 256 );
+ for ( i = 0; i < mnCol; i++ )
+ {
+ sal_uLong nCount = 255 * i / mnCol;
+ mpAcc->SetPaletteColor( i, BitmapColor( (sal_uInt8)nCount, (sal_uInt8)nCount, (sal_uInt8)nCount ) );
+ }
+ break;
+ case 2 :
+ maBmp = Bitmap( Size( mnWidth, mnHeight ), 24 );
+ if ( ( mpAcc = maBmp.AcquireWriteAccess() ) == sal_False )
+ return sal_False;
+ break;
+ }
+
+ // Bitmap-Daten einlesen
+ mbStatus = ImplReadBody();
+
+ if ( mpAcc )
+ {
+ maBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
+ }
+ if ( mbStatus )
+ rGraphic = maBmp;
+
+ return mbStatus;
+}
+
+sal_Bool PBMReader::ImplReadHeader()
+{
+ sal_uInt8 nID[ 2 ];
+ sal_uInt8 nDat;
+ sal_uInt8 nMax, nCount = 0;
+ sal_Bool bFinished = sal_False;
+
+ mrPBM >> nID[ 0 ] >> nID[ 1 ];
+ if ( nID[ 0 ] != 'P' )
+ return sal_False;
+ mnMaxVal = mnWidth = mnHeight = 0;
+ switch ( nID[ 1 ] )
+ {
+ case '1' :
+ mbRaw = sal_False;
+ case '4' :
+ mnMode = 0;
+ nMax = 2; // number of parameters in Header
+ mnMaxVal = 1;
+ break;
+ case '2' :
+ mbRaw = sal_False;
+ case '5' :
+ mnMode = 1;
+ nMax = 3;
+ break;
+ case '3' :
+ mbRaw = sal_False;
+ case '6' :
+ mnMode = 2;
+ nMax = 3;
+ break;
+ default:
+ return sal_False;
+ }
+ while ( bFinished == sal_False )
+ {
+ if ( mrPBM.GetError() )
+ return sal_False;
+
+ mrPBM >> nDat;
+
+ if ( nDat == '#' )
+ {
+ mbRemark = sal_True;
+ continue;
+ }
+ else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
+ {
+ mbRemark = sal_False;
+ nDat = 0x20;
+ }
+ if ( mbRemark )
+ continue;
+
+ if ( ( nDat == 0x20 ) || ( nDat == 0x09 ) )
+ {
+ if ( ( nCount == 0 ) && mnWidth )
+ nCount++;
+ else if ( ( nCount == 1 ) && mnHeight )
+ {
+ if ( ++nCount == nMax )
+ bFinished = sal_True;
+ }
+ else if ( ( nCount == 2 ) && mnMaxVal )
+ {
+ bFinished = sal_True;
+ }
+ continue;
+ }
+ if ( ( nDat >= '0' ) && ( nDat <= '9' ) )
+ {
+ nDat -= '0';
+ if ( nCount == 0 )
+ {
+ mnWidth *= 10;
+ mnWidth += nDat;
+ }
+ else if ( nCount == 1 )
+ {
+ mnHeight *= 10;
+ mnHeight += nDat;
+ }
+ else if ( nCount == 2 )
+ {
+ mnMaxVal *= 10;
+ mnMaxVal += nDat;
+ }
+ }
+ else
+ return sal_False;
+ }
+ return mbStatus;
+}
+
+sal_Bool PBMReader::ImplReadBody()
+{
+ sal_Bool bPara, bFinished = sal_False;
+ sal_uInt8 nDat = 0, nCount;
+ sal_uLong nGrey, nRGB[3];
+ sal_uLong nWidth = 0;
+ sal_uLong nHeight = 0;
+
+ if ( mbRaw )
+ {
+ signed char nShift = 0;
+ switch ( mnMode )
+ {
+
+ // PBM
+ case 0 :
+ while ( nHeight != mnHeight )
+ {
+ if ( mrPBM.IsEof() || mrPBM.GetError() )
+ return sal_False;
+
+ if ( --nShift < 0 )
+ {
+ mrPBM >> nDat;
+ nShift = 7;
+ }
+ mpAcc->SetPixel( nHeight, nWidth, nDat >> nShift );
+ if ( ++nWidth == mnWidth )
+ {
+ nShift = 0;
+ nWidth = 0;
+ nHeight++;
+ ImplCallback( (sal_uInt16)( ( 100 * nHeight ) / mnHeight ) ); // processing output in percent
+ }
+ }
+ break;
+
+ // PGM
+ case 1 :
+ while ( nHeight != mnHeight )
+ {
+ if ( mrPBM.IsEof() || mrPBM.GetError() )
+ return sal_False;
+
+ mrPBM >> nDat;
+ mpAcc->SetPixel( nHeight, nWidth++, nDat);
+
+ if ( nWidth == mnWidth )
+ {
+ nWidth = 0;
+ nHeight++;
+ ImplCallback( (sal_uInt16)( ( 100 * nHeight ) / mnHeight ) ); // processing output in percent
+ }
+ }
+ break;
+
+ // PPM
+ case 2 :
+ while ( nHeight != mnHeight )
+ {
+ if ( mrPBM.IsEof() || mrPBM.GetError() )
+ return sal_False;
+
+ sal_uInt8 nR, nG, nB;
+ sal_uLong nRed, nGreen, nBlue;
+ mrPBM >> nR >> nG >> nB;
+ nRed = 255 * nR / mnMaxVal;
+ nGreen = 255 * nG / mnMaxVal;
+ nBlue = 255 * nB / mnMaxVal;
+ mpAcc->SetPixel( nHeight, nWidth++, BitmapColor( (sal_uInt8)nRed, (sal_uInt8)nGreen, (sal_uInt8)nBlue ) );
+ if ( nWidth == mnWidth )
+ {
+ nWidth = 0;
+ nHeight++;
+ ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) ); // processing output in percent
+ }
+ }
+ break;
+ }
+ }
+ else switch ( mnMode )
+ {
+ // PBM
+ case 0 :
+ while ( bFinished == sal_False )
+ {
+ if ( mrPBM.IsEof() || mrPBM.GetError() )
+ return sal_False;
+
+ mrPBM >> nDat;
+
+ if ( nDat == '#' )
+ {
+ mbRemark = sal_True;
+ continue;
+ }
+ else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
+ {
+ mbRemark = sal_False;
+ continue;
+ }
+ if ( mbRemark || nDat == 0x20 || nDat == 0x09 )
+ continue;
+
+ if ( nDat == '0' || nDat == '1' )
+ {
+ mpAcc->SetPixel( nHeight, nWidth, (sal_uInt8)nDat-'0' );
+ nWidth++;
+ if ( nWidth == mnWidth )
+ {
+ nWidth = 0;
+ if ( ++nHeight == mnHeight )
+ bFinished = sal_True;
+ ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) ); // processing output in percent
+ }
+ }
+ else
+ return sal_False;
+ }
+ break;
+
+ // PGM
+ case 1 :
+
+ bPara = sal_False;
+ nCount = 0;
+ nGrey = 0;
+
+ while ( bFinished == sal_False )
+ {
+ if ( nCount )
+ {
+ nCount--;
+ if ( nGrey <= mnMaxVal )
+ nGrey = 255 * nGrey / mnMaxVal;
+ mpAcc->SetPixel( nHeight, nWidth++, (sal_uInt8)nGrey );
+ nGrey = 0;
+ if ( nWidth == mnWidth )
+ {
+ nWidth = 0;
+ if ( ++nHeight == mnHeight )
+ bFinished = sal_True;
+ ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) ); // processing output in percent
+ }
+ continue;
+ }
+
+ if ( mrPBM.IsEof() || mrPBM.GetError() )
+ return sal_False;
+
+ mrPBM >> nDat;
+
+ if ( nDat == '#' )
+ {
+ mbRemark = sal_True;
+ if ( bPara )
+ {
+ bPara = sal_False;
+ nCount++;
+ }
+ continue;
+ }
+ else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
+ {
+ mbRemark = sal_False;
+ if ( bPara )
+ {
+ bPara = sal_False;
+ nCount++;
+ }
+ continue;
+ }
+
+ if ( nDat == 0x20 || nDat == 0x09 )
+ {
+ if ( bPara )
+ {
+ bPara = sal_False;
+ nCount++;
+ }
+ continue;
+ }
+ if ( nDat >= '0' && nDat <= '9' )
+ {
+ bPara = sal_True;
+ nGrey *= 10;
+ nGrey += nDat-'0';
+ continue;
+ }
+ else
+ return sal_False;
+ }
+ break;
+
+
+
+ // PPM
+ case 2 :
+
+ bPara = sal_False;
+ nCount = 0;
+ nRGB[ 0 ] = nRGB[ 1 ] = nRGB[ 2 ] = 0;
+
+ while ( bFinished == sal_False )
+ {
+ if ( nCount == 3 )
+ {
+ nCount = 0;
+ mpAcc->SetPixel( nHeight, nWidth++, BitmapColor( static_cast< sal_uInt8 >( ( nRGB[ 0 ] * 255 ) / mnMaxVal ),
+ static_cast< sal_uInt8 >( ( nRGB[ 1 ] * 255 ) / mnMaxVal ),
+ static_cast< sal_uInt8 >( ( nRGB[ 2 ] * 255 ) / mnMaxVal ) ) );
+ nCount = 0;
+ nRGB[ 0 ] = nRGB[ 1 ] = nRGB[ 2 ] = 0;
+ if ( nWidth == mnWidth )
+ {
+ nWidth = 0;
+ if ( ++nHeight == mnHeight )
+ bFinished = sal_True;
+ ImplCallback( (sal_uInt16) ( ( 100 * nHeight ) / mnHeight ) ); // processing output in percent
+ }
+ continue;
+ }
+
+ if ( mrPBM.IsEof() || mrPBM.GetError() )
+ return sal_False;
+
+ mrPBM >> nDat;
+
+ if ( nDat == '#' )
+ {
+ mbRemark = sal_True;
+ if ( bPara )
+ {
+ bPara = sal_False;
+ nCount++;
+ }
+ continue;
+ }
+ else if ( ( nDat == 0x0d ) || ( nDat == 0x0a ) )
+ {
+ mbRemark = sal_False;
+ if ( bPara )
+ {
+ bPara = sal_False;
+ nCount++;
+ }
+ continue;
+ }
+
+ if ( nDat == 0x20 || nDat == 0x09 )
+ {
+ if ( bPara )
+ {
+ bPara = sal_False;
+ nCount++;
+ }
+ continue;
+ }
+ if ( nDat >= '0' && nDat <= '9' )
+ {
+ bPara = sal_True;
+ nRGB[ nCount ] *= 10;
+ nRGB[ nCount ] += nDat-'0';
+ continue;
+ }
+ else
+ return sal_False;
+ }
+ break;
+ }
+ return mbStatus;
+}
+
+//================== GraphicImport - die exportierte Funktion ================
+
+extern "C" sal_Bool __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool )
+{
+ PBMReader aPBMReader(rStream);
+
+ return aPBMReader.ReadPBM(rGraphic );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */