1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ipcx.cxx,v $
10 * $Revision: 1.8.30.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
34 #include <vcl/graph.hxx>
35 #include <vcl/bmpacc.hxx>
36 #include <svtools/fltcall.hxx>
38 //============================ PCXReader ==================================
44 SvStream
* pPCX
; // Die einzulesende PCX-Datei
47 BitmapWriteAccess
* pAcc
;
48 BYTE nVersion
; // PCX-Version
49 BYTE nEncoding
; // Art der Komprimierung
50 ULONG nBitsPerPlanePix
; // Bits Pro Ebene pro Pixel
51 ULONG nPlanes
; // Anzahl Ebenen
52 ULONG nBytesPerPlaneLin
; // Bytes in einer Ebenen pro Zeile
55 ULONG nWidth
, nHeight
; // Bildausmass in Pixeln
56 USHORT nResX
, nResY
; // Aufloesung in Pixel pro Inch oder 0,0
57 USHORT nDestBitsPerPixel
; // Bits pro Pixel der Zielbitmap 1,4,8 oder 24
59 BOOL nStatus
; // status nun nicht mehr am stream abfragen ( SJ )
62 BOOL
Callback( USHORT nPercent
);
64 void ImplReadPalette( ULONG nCol
);
65 void ImplReadHeader();
70 BOOL
ReadPCX( SvStream
& rPCX
, Graphic
& rGraphic
);
71 // Liesst aus dem Stream eine PCX-Datei und fuellt das GDIMetaFile
74 //=================== Methoden von PCXReader ==============================
76 PCXReader::PCXReader() :
79 pPalette
= new BYTE
[ 768 ];
82 PCXReader::~PCXReader()
87 BOOL
PCXReader::Callback( USHORT
/*nPercent*/ )
90 if (pCallback!=NULL) {
91 if (((*pCallback)(pCallerData,nPercent))==TRUE) {
100 BOOL
PCXReader::ReadPCX( SvStream
& rPCX
, Graphic
& rGraphic
)
102 if ( rPCX
.GetError() )
105 ULONG
* pDummy
= new ULONG
; delete pDummy
; // damit unter OS/2
106 // das richtige (Tools-)new
107 // verwendet wird, da es sonst
108 // in dieser DLL nur Vector-news
112 pPCX
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
120 // BMP-Header und ggf. (eventuell zunaechst ungueltige) Farbpalette schreiben:
123 aBmp
= Bitmap( Size( nWidth
, nHeight
), nDestBitsPerPixel
);
124 if ( ( pAcc
= aBmp
.AcquireWriteAccess() ) == FALSE
)
127 if ( nDestBitsPerPixel
<= 8 )
129 USHORT nColors
= 1 << nDestBitsPerPixel
;
130 BYTE
* pPal
= pPalette
;
131 pAcc
->SetPaletteEntryCount( nColors
);
132 for ( USHORT i
= 0; i
< nColors
; i
++, pPal
+= 3 )
134 pAcc
->SetPaletteColor( i
, BitmapColor ( pPal
[ 0 ], pPal
[ 1 ], pPal
[ 2 ] ) );
137 // Bitmap-Daten einlesen
140 // Wenn erweiterte Farbpalette am Ende von PCX, dann diese einlesen, und nochmals
141 // in Palette schreiben:
142 if ( nDestBitsPerPixel
== 8 && nStatus
)
144 BYTE
* pPal
= pPalette
;
146 ImplReadPalette(256);
147 pAcc
->SetPaletteEntryCount( 256 );
148 for ( USHORT i
= 0; i
< 256; i
++, pPal
+= 3 )
150 pAcc
->SetPaletteColor( i
, BitmapColor ( pPal
[ 0 ], pPal
[ 1 ], pPal
[ 2 ] ) );
154 // Aufloesung einstellen:
155 if (nResX!=0 && nResY!=0) {
156 MapMode aMapMode(MAP_INCH,Point(0,0),Fraction(1,nResX),Fraction(1,nResY));
157 rBitmap.SetPrefMapMode(aMapMode);
158 rBitmap.SetPrefSize(Size(nWidth,nHeight));
160 */ if ( nStatus
&& pAcc
)
162 aBmp
.ReleaseAccess( pAcc
), pAcc
= NULL
;
170 void PCXReader::ImplReadHeader()
174 USHORT nMinX
,nMinY
,nMaxX
,nMaxY
;
176 *pPCX
>> nbyte
>> nVersion
>> nEncoding
;
177 if ( nbyte
!=0x0a || (nVersion
!= 0 && nVersion
!= 2 && nVersion
!= 3 && nVersion
!= 5) || nEncoding
> 1 )
183 *pPCX
>> nbyte
; nBitsPerPlanePix
= (ULONG
)nbyte
;
184 *pPCX
>> nMinX
>> nMinY
>> nMaxX
>> nMaxY
;
186 if ((nMinX
> nMaxX
) || (nMinY
> nMaxY
))
192 nWidth
= nMaxX
-nMinX
+1;
193 nHeight
= nMaxY
-nMinY
+1;
197 if ( nResX
>= nWidth
|| nResY
>= nHeight
|| ( nResX
!= nResY
) )
200 ImplReadPalette( 16 );
203 *pPCX
>> nbyte
; nPlanes
= (ULONG
)nbyte
;
204 *pPCX
>> nushort
; nBytesPerPlaneLin
= (ULONG
)nushort
;
205 *pPCX
>> nPaletteInfo
;
209 nDestBitsPerPixel
= (USHORT
)( nBitsPerPlanePix
* nPlanes
);
210 if (nDestBitsPerPixel
== 2 || nDestBitsPerPixel
== 3) nDestBitsPerPixel
= 4;
212 if ( ( nDestBitsPerPixel
!= 1 && nDestBitsPerPixel
!= 4 && nDestBitsPerPixel
!= 8 && nDestBitsPerPixel
!= 24 )
213 || nPlanes
> 4 || nBytesPerPlaneLin
< ( ( nWidth
* nBitsPerPlanePix
+7 ) >> 3 ) )
219 // Wenn das Bild nur 2 Farben hat, ist die Palette zumeist ungueltig, und es handelt sich
220 // immer (?) um ein schwarz-weiss-Bild:
221 if ( nPlanes
== 1 && nBitsPerPlanePix
== 1 )
223 pPalette
[ 0 ] = pPalette
[ 1 ] = pPalette
[ 2 ] = 0x00;
224 pPalette
[ 3 ] = pPalette
[ 4 ] = pPalette
[ 5 ] = 0xff;
228 void PCXReader::ImplReadBody()
230 BYTE
*pPlane
[ 4 ], * pDest
, * pSource1
, * pSource2
, * pSource3
, *pSource4
;
231 ULONG i
, nx
, ny
, np
, nCount
, nUsedLineSize
, nLineSize
, nPercent
;
232 ULONG nLastPercent
= 0;
233 BYTE nDat
= 0, nCol
= 0;
235 nUsedLineSize
= (ULONG
)( ( ( nWidth
* (ULONG
)nDestBitsPerPixel
) + 7 ) >> 3 );
236 nLineSize
= ( nUsedLineSize
+ 3 ) & 0xfffc;
238 for( np
= 0; np
< nPlanes
; np
++ )
239 pPlane
[ np
] = new BYTE
[ nBytesPerPlaneLin
];
242 for ( ny
= 0; ny
< nHeight
; ny
++ )
244 if (pPCX
->GetError() || pPCX
->IsEof())
249 nPercent
= ny
* 60 / nHeight
+ 10;
250 if ( ny
== 0 || nLastPercent
+ 4 <= nPercent
)
252 nLastPercent
= nPercent
;
253 if ( Callback( (USHORT
)nPercent
) == TRUE
)
256 for ( np
= 0; np
< nPlanes
; np
++)
259 pPCX
->Read( (void *)pPlane
[ np
], nBytesPerPlaneLin
);
262 pDest
= pPlane
[ np
];
263 nx
= nBytesPerPlaneLin
;
264 while ( nCount
> 0 && nx
> 0)
273 if ( ( nDat
& 0xc0 ) == 0xc0 )
275 nCount
=( (ULONG
)nDat
) & 0x003f;
306 pSource1
= pPlane
[ 0 ];
307 pSource2
= pPlane
[ 1 ];
308 pSource3
= pPlane
[ 2 ];
309 pSource4
= pPlane
[ 3 ];
310 switch ( nBitsPerPlanePix
+ ( nPlanes
<< 8 ) )
314 for ( i
= 0; i
< nWidth
; i
++ )
316 ULONG nShift
= ( i
& 7 ) ^ 7;
318 pAcc
->SetPixel( ny
, i
, ( *pSource1
++ & 1 ) );
322 sal::static_int_cast
< BYTE
>(
323 ( *pSource1
>> nShift
) & 1) );
328 for ( i
= 0; i
< nWidth
; i
++ )
333 nCol
= *pSource1
>> 6;
336 nCol
= ( *pSource1
>> 4 ) & 0x03 ;
339 nCol
= ( *pSource1
>> 2 ) & 0x03;
342 nCol
= ( *pSource1
++ ) & 0x03;
345 pAcc
->SetPixel( ny
, i
, nCol
);
350 for ( i
= 0; i
< nWidth
; i
++ )
352 pAcc
->SetPixel( ny
, i
, *pSource1
++ );
357 for ( i
= 0; i
< nWidth
; i
++ )
359 ULONG nShift
= ( i
& 7 ) ^ 7;
362 nCol
= ( *pSource1
++ & 1) + ( ( *pSource2
++ << 1 ) & 2 ) + ( ( *pSource3
++ << 2 ) & 4 );
363 pAcc
->SetPixel( ny
, i
, nCol
);
367 nCol
= sal::static_int_cast
< BYTE
>(
368 ( ( *pSource1
>> nShift
) & 1) + ( ( ( *pSource2
>> nShift
) << 1 ) & 2 ) +
369 ( ( ( *pSource3
>> nShift
) << 2 ) & 4 ));
370 pAcc
->SetPixel( ny
, i
, nCol
);
376 for ( i
= 0; i
< nWidth
; i
++ )
378 ULONG nShift
= ( i
& 7 ) ^ 7;
381 nCol
= ( *pSource1
++ & 1) + ( ( *pSource2
++ << 1 ) & 2 ) + ( ( *pSource3
++ << 2 ) & 4 ) +
382 ( ( *pSource4
++ << 3 ) & 8 );
383 pAcc
->SetPixel( ny
, i
, nCol
);
387 nCol
= sal::static_int_cast
< BYTE
>(
388 ( ( *pSource1
>> nShift
) & 1) + ( ( ( *pSource2
>> nShift
) << 1 ) & 2 ) +
389 ( ( ( *pSource3
>> nShift
) << 2 ) & 4 ) + ( ( ( *pSource4
>> nShift
) << 3 ) & 8 ));
390 pAcc
->SetPixel( ny
, i
, nCol
);
396 for ( i
= 0; i
< nWidth
; i
++ )
398 pAcc
->SetPixel( ny
, i
, Color( *pSource1
++, *pSource2
++, *pSource3
++ ) );
407 for ( np
= 0; np
< nPlanes
; np
++ )
408 delete[] pPlane
[ np
];
411 void PCXReader::ImplReadPalette( ULONG nCol
)
414 BYTE
* pPtr
= pPalette
;
415 for ( ULONG i
= 0; i
< nCol
; i
++ )
417 *pPCX
>> r
>> g
>> b
;
424 //================== GraphicImport - die exportierte Funktion ================
426 extern "C" BOOL __LOADONCALLAPI
GraphicImport(SvStream
& rStream
, Graphic
& rGraphic
, FilterConfigItem
*, BOOL
)
428 PCXReader aPCXReader
;
429 BOOL nRetValue
= aPCXReader
.ReadPCX( rStream
, rGraphic
);
430 if ( nRetValue
== FALSE
)
431 rStream
.SetError( SVSTREAM_FILEFORMAT_ERROR
);
435 //================== ein bischen Muell fuer Windows ==========================
441 static HINSTANCE hDLLInst
= 0; // HANDLE der DLL
443 extern "C" int CALLBACK
LibMain( HINSTANCE hDLL
, WORD
, WORD nHeap
, LPSTR
)
455 extern "C" int CALLBACK
WEP( int )