1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <vcl/graph.hxx>
22 #include <vcl/bmpacc.hxx>
24 class FilterConfigItem
;
26 //============================ PBMReader ==================================
32 SvStream
& mrPBM
; // the PBM file to read
35 sal_Bool mbRemark
; // sal_False if the stream is in a comment
36 sal_Bool mbRaw
; // RAW/ASCII MODE
37 sal_uLong mnMode
; // 0->PBM, 1->PGM, 2->PPM
39 BitmapWriteAccess
* mpAcc
;
40 sal_uLong mnWidth
, mnHeight
; // dimensions in pixel
42 sal_uLong mnMaxVal
; // max value in the <missing comment>
43 sal_Bool
ImplCallback( sal_uInt16 nPercent
);
44 sal_Bool
ImplReadBody();
45 sal_Bool
ImplReadHeader();
48 PBMReader(SvStream
& rPBM
);
50 sal_Bool
ReadPBM(Graphic
& rGraphic
);
53 //=================== Methods of PBMReader ==============================
55 PBMReader::PBMReader(SvStream
& rPBM
)
57 , mbStatus( sal_True
)
58 , mbRemark( sal_False
)
64 PBMReader::~PBMReader()
68 sal_Bool
PBMReader::ImplCallback( sal_uInt16
/*nPercent*/ )
71 if ( pCallback != NULL )
73 if ( ( (*pCallback)( pCallerData, nPercent ) ) == sal_True )
75 mrPBM.SetError( SVSTREAM_FILEFORMAT_ERROR );
83 sal_Bool
PBMReader::ReadPBM(Graphic
& rGraphic
)
87 if ( mrPBM
.GetError() )
90 mrPBM
.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
94 if ( ( mbStatus
= ImplReadHeader() ) == sal_False
)
97 if ( ( mnMaxVal
== 0 ) || ( mnWidth
== 0 ) || ( mnHeight
== 0 ) )
100 // 0->PBM, 1->PGM, 2->PPM
104 maBmp
= Bitmap( Size( mnWidth
, mnHeight
), 1 );
105 if ( ( mpAcc
= maBmp
.AcquireWriteAccess() ) == sal_False
)
107 mpAcc
->SetPaletteEntryCount( 2 );
108 mpAcc
->SetPaletteColor( 0, BitmapColor( 0xff, 0xff, 0xff ) );
109 mpAcc
->SetPaletteColor( 1, BitmapColor( 0x00, 0x00, 0x00 ) );
114 maBmp
= Bitmap( Size( mnWidth
, mnHeight
), 1);
115 else if ( mnMaxVal
<= 15 )
116 maBmp
= Bitmap( Size( mnWidth
, mnHeight
), 4);
118 maBmp
= Bitmap( Size( mnWidth
, mnHeight
), 8);
120 if ( ( mpAcc
= maBmp
.AcquireWriteAccess() ) == sal_False
)
122 mnCol
= (sal_uInt16
)mnMaxVal
+ 1;
126 mpAcc
->SetPaletteEntryCount( 256 );
127 for ( i
= 0; i
< mnCol
; i
++ )
129 sal_uLong nCount
= 255 * i
/ mnCol
;
130 mpAcc
->SetPaletteColor( i
, BitmapColor( (sal_uInt8
)nCount
, (sal_uInt8
)nCount
, (sal_uInt8
)nCount
) );
134 maBmp
= Bitmap( Size( mnWidth
, mnHeight
), 24 );
135 if ( ( mpAcc
= maBmp
.AcquireWriteAccess() ) == sal_False
)
141 mbStatus
= ImplReadBody();
145 maBmp
.ReleaseAccess( mpAcc
), mpAcc
= NULL
;
153 sal_Bool
PBMReader::ImplReadHeader()
157 sal_uInt8 nMax
, nCount
= 0;
158 sal_Bool bFinished
= sal_False
;
160 mrPBM
>> nID
[ 0 ] >> nID
[ 1 ];
161 if ( nID
[ 0 ] != 'P' )
163 mnMaxVal
= mnWidth
= mnHeight
= 0;
170 nMax
= 2; // number of parameters in Header
188 while ( bFinished
== sal_False
)
190 if ( mrPBM
.GetError() )
200 else if ( ( nDat
== 0x0d ) || ( nDat
== 0x0a ) )
202 mbRemark
= sal_False
;
208 if ( ( nDat
== 0x20 ) || ( nDat
== 0x09 ) )
210 if ( ( nCount
== 0 ) && mnWidth
)
212 else if ( ( nCount
== 1 ) && mnHeight
)
214 if ( ++nCount
== nMax
)
215 bFinished
= sal_True
;
217 else if ( ( nCount
== 2 ) && mnMaxVal
)
219 bFinished
= sal_True
;
223 if ( ( nDat
>= '0' ) && ( nDat
<= '9' ) )
231 else if ( nCount
== 1 )
236 else if ( nCount
== 2 )
248 sal_Bool
PBMReader::ImplReadBody()
250 sal_Bool bPara
, bFinished
= sal_False
;
251 sal_uInt8 nDat
= 0, nCount
;
252 sal_uLong nGrey
, nRGB
[3];
253 sal_uLong nWidth
= 0;
254 sal_uLong nHeight
= 0;
258 signed char nShift
= 0;
264 while ( nHeight
!= mnHeight
)
266 if ( mrPBM
.IsEof() || mrPBM
.GetError() )
274 mpAcc
->SetPixelIndex( nHeight
, nWidth
, nDat
>> nShift
);
275 if ( ++nWidth
== mnWidth
)
280 ImplCallback( (sal_uInt16
)( ( 100 * nHeight
) / mnHeight
) ); // processing output in percent
287 while ( nHeight
!= mnHeight
)
289 if ( mrPBM
.IsEof() || mrPBM
.GetError() )
293 mpAcc
->SetPixelIndex( nHeight
, nWidth
++, nDat
);
295 if ( nWidth
== mnWidth
)
299 ImplCallback( (sal_uInt16
)( ( 100 * nHeight
) / mnHeight
) ); // processing output in percent
306 while ( nHeight
!= mnHeight
)
308 if ( mrPBM
.IsEof() || mrPBM
.GetError() )
311 sal_uInt8 nR
, nG
, nB
;
312 sal_uLong nRed
, nGreen
, nBlue
;
313 mrPBM
>> nR
>> nG
>> nB
;
314 nRed
= 255 * nR
/ mnMaxVal
;
315 nGreen
= 255 * nG
/ mnMaxVal
;
316 nBlue
= 255 * nB
/ mnMaxVal
;
317 mpAcc
->SetPixel( nHeight
, nWidth
++, BitmapColor( (sal_uInt8
)nRed
, (sal_uInt8
)nGreen
, (sal_uInt8
)nBlue
) );
318 if ( nWidth
== mnWidth
)
322 ImplCallback( (sal_uInt16
) ( ( 100 * nHeight
) / mnHeight
) ); // processing output in percent
328 else switch ( mnMode
)
332 while ( bFinished
== sal_False
)
334 if ( mrPBM
.IsEof() || mrPBM
.GetError() )
344 else if ( ( nDat
== 0x0d ) || ( nDat
== 0x0a ) )
346 mbRemark
= sal_False
;
349 if ( mbRemark
|| nDat
== 0x20 || nDat
== 0x09 )
352 if ( nDat
== '0' || nDat
== '1' )
354 mpAcc
->SetPixelIndex( nHeight
, nWidth
, static_cast<sal_uInt8
>(nDat
- '0') );
356 if ( nWidth
== mnWidth
)
359 if ( ++nHeight
== mnHeight
)
360 bFinished
= sal_True
;
361 ImplCallback( (sal_uInt16
) ( ( 100 * nHeight
) / mnHeight
) ); // processing output in percent
376 while ( bFinished
== sal_False
)
381 if ( nGrey
<= mnMaxVal
)
382 nGrey
= 255 * nGrey
/ mnMaxVal
;
383 mpAcc
->SetPixelIndex( nHeight
, nWidth
++, static_cast<sal_uInt8
>(nGrey
) );
385 if ( nWidth
== mnWidth
)
388 if ( ++nHeight
== mnHeight
)
389 bFinished
= sal_True
;
390 ImplCallback( (sal_uInt16
) ( ( 100 * nHeight
) / mnHeight
) ); // processing output in percent
395 if ( mrPBM
.IsEof() || mrPBM
.GetError() )
410 else if ( ( nDat
== 0x0d ) || ( nDat
== 0x0a ) )
412 mbRemark
= sal_False
;
421 if ( nDat
== 0x20 || nDat
== 0x09 )
430 if ( nDat
>= '0' && nDat
<= '9' )
449 nRGB
[ 0 ] = nRGB
[ 1 ] = nRGB
[ 2 ] = 0;
451 while ( bFinished
== sal_False
)
456 mpAcc
->SetPixel( nHeight
, nWidth
++, BitmapColor( static_cast< sal_uInt8
>( ( nRGB
[ 0 ] * 255 ) / mnMaxVal
),
457 static_cast< sal_uInt8
>( ( nRGB
[ 1 ] * 255 ) / mnMaxVal
),
458 static_cast< sal_uInt8
>( ( nRGB
[ 2 ] * 255 ) / mnMaxVal
) ) );
460 nRGB
[ 0 ] = nRGB
[ 1 ] = nRGB
[ 2 ] = 0;
461 if ( nWidth
== mnWidth
)
464 if ( ++nHeight
== mnHeight
)
465 bFinished
= sal_True
;
466 ImplCallback( (sal_uInt16
) ( ( 100 * nHeight
) / mnHeight
) ); // processing output in percent
471 if ( mrPBM
.IsEof() || mrPBM
.GetError() )
486 else if ( ( nDat
== 0x0d ) || ( nDat
== 0x0a ) )
488 mbRemark
= sal_False
;
497 if ( nDat
== 0x20 || nDat
== 0x09 )
506 if ( nDat
>= '0' && nDat
<= '9' )
509 nRGB
[ nCount
] *= 10;
510 nRGB
[ nCount
] += nDat
-'0';
521 //================== GraphicImport - the exported function ================
523 // this needs to be kept in sync with
524 // ImpFilterLibCacheEntry::GetImportFunction() from
525 // vcl/source/filter/graphicfilter.cxx
526 #if defined(DISABLE_DYNLOADING)
527 #define GraphicImport ipbGraphicImport
530 extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL
531 GraphicImport(SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
*, sal_Bool
)
533 PBMReader
aPBMReader(rStream
);
535 return aPBMReader
.ReadPBM(rGraphic
);
538 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */