diff options
Diffstat (limited to 'filter/source/graphicfilter/ipbm/ipbm.cxx')
-rw-r--r-- | filter/source/graphicfilter/ipbm/ipbm.cxx | 540 |
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: */ |