/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_filter.hxx" #include #include #include //============================ PBMReader ================================== class PBMReader { private: SvStream* mpPBM; // 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(); ~PBMReader(); sal_Bool ReadPBM( SvStream & rPBM, Graphic & rGraphic ); }; //=================== Methoden von PBMReader ============================== PBMReader::PBMReader() : 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 ) { mpPBM->SetError( SVSTREAM_FILEFORMAT_ERROR ); return sal_True; } } */ return sal_False; } sal_Bool PBMReader::ReadPBM( SvStream & rPBM, Graphic & rGraphic ) { sal_uInt16 i; if ( rPBM.GetError() ) return sal_False; mpPBM = &rPBM; mpPBM->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 ); mpAcc = maBmp.AcquireWriteAccess(); if ( !mpAcc ) 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); mpAcc = maBmp.AcquireWriteAccess(); if ( !mpAcc ) 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 ); mpAcc = maBmp.AcquireWriteAccess(); if ( !mpAcc ) 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; *mpPBM >> 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 ( mpPBM->GetError() ) return sal_False; *mpPBM >> 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; signed char nShift = 0; if ( mbRaw ) { switch ( mnMode ) { // PBM case 0 : while ( nHeight != mnHeight ) { if ( mpPBM->IsEof() || mpPBM->GetError() ) return sal_False; if ( --nShift < 0 ) { *mpPBM >> nDat; nShift = 7; } mpAcc->SetPixelIndex( 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 ( mpPBM->IsEof() || mpPBM->GetError() ) return sal_False; *mpPBM >> nDat; mpAcc->SetPixelIndex( 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 ( mpPBM->IsEof() || mpPBM->GetError() ) return sal_False; sal_uInt8 nR, nG, nB; sal_uLong nRed, nGreen, nBlue; *mpPBM >> 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 ( mpPBM->IsEof() || mpPBM->GetError() ) return sal_False; *mpPBM >> 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->SetPixelIndex( nHeight, nWidth, static_cast(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->SetPixelIndex( nHeight, nWidth++, static_cast(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 ( mpPBM->IsEof() || mpPBM->GetError() ) return sal_False; *mpPBM >> 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 ( mpPBM->IsEof() || mpPBM->GetError() ) return sal_False; *mpPBM >> 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; return aPBMReader.ReadPBM( rStream, rGraphic ); }