Update ooo320-m1
[ooovba.git] / goodies / source / filter.vcl / ipcx / ipcx.cxx
blobd6cddb1fe37ba1b4780c3fe4a5ebda2a63d891d8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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 ==================================
40 class PCXReader {
42 private:
44 SvStream* pPCX; // Die einzulesende PCX-Datei
46 Bitmap aBmp;
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
53 USHORT nPaletteInfo;
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
58 BYTE* pPalette; //
59 BOOL nStatus; // status nun nicht mehr am stream abfragen ( SJ )
62 BOOL Callback( USHORT nPercent );
63 void ImplReadBody();
64 void ImplReadPalette( ULONG nCol );
65 void ImplReadHeader();
67 public:
68 PCXReader();
69 ~PCXReader();
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() :
77 pAcc ( NULL )
79 pPalette = new BYTE[ 768 ];
82 PCXReader::~PCXReader()
84 delete[] pPalette;
87 BOOL PCXReader::Callback( USHORT /*nPercent*/ )
90 if (pCallback!=NULL) {
91 if (((*pCallback)(pCallerData,nPercent))==TRUE) {
92 nStatus = FALSE;
93 return TRUE;
97 return FALSE;
100 BOOL PCXReader::ReadPCX( SvStream & rPCX, Graphic & rGraphic )
102 if ( rPCX.GetError() )
103 return FALSE;
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
109 // gibt;
111 pPCX = &rPCX;
112 pPCX->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
114 // Kopf einlesen:
116 nStatus = TRUE;
118 ImplReadHeader();
120 // BMP-Header und ggf. (eventuell zunaechst ungueltige) Farbpalette schreiben:
121 if ( nStatus )
123 aBmp = Bitmap( Size( nWidth, nHeight ), nDestBitsPerPixel );
124 if ( ( pAcc = aBmp.AcquireWriteAccess() ) == FALSE )
125 return 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
138 ImplReadBody();
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;
145 pPCX->SeekRel(1);
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;
163 rGraphic = aBmp;
164 return TRUE;
167 return FALSE;
170 void PCXReader::ImplReadHeader()
172 BYTE nbyte;
173 USHORT nushort;
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 )
179 nStatus = FALSE;
180 return;
183 *pPCX >> nbyte; nBitsPerPlanePix = (ULONG)nbyte;
184 *pPCX >> nMinX >> nMinY >> nMaxX >> nMaxY;
186 if ((nMinX > nMaxX) || (nMinY > nMaxY))
188 nStatus = FALSE;
189 return;
192 nWidth = nMaxX-nMinX+1;
193 nHeight = nMaxY-nMinY+1;
195 *pPCX >> nResX;
196 *pPCX >> nResY;
197 if ( nResX >= nWidth || nResY >= nHeight || ( nResX != nResY ) )
198 nResX = nResY = 0;
200 ImplReadPalette( 16 );
202 pPCX->SeekRel( 1 );
203 *pPCX >> nbyte; nPlanes = (ULONG)nbyte;
204 *pPCX >> nushort; nBytesPerPlaneLin = (ULONG)nushort;
205 *pPCX >> nPaletteInfo;
207 pPCX->SeekRel( 58 );
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 ) )
215 nStatus = FALSE;
216 return;
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 ];
241 nCount = 0;
242 for ( ny = 0; ny < nHeight; ny++ )
244 if (pPCX->GetError() || pPCX->IsEof())
246 nStatus = FALSE;
247 break;
249 nPercent = ny * 60 / nHeight + 10;
250 if ( ny == 0 || nLastPercent + 4 <= nPercent )
252 nLastPercent = nPercent;
253 if ( Callback( (USHORT)nPercent ) == TRUE )
254 break;
256 for ( np = 0; np < nPlanes; np++)
258 if ( nEncoding == 0)
259 pPCX->Read( (void *)pPlane[ np ], nBytesPerPlaneLin );
260 else
262 pDest = pPlane[ np ];
263 nx = nBytesPerPlaneLin;
264 while ( nCount > 0 && nx > 0)
266 *(pDest++) = nDat;
267 nx--;
268 nCount--;
270 while ( nx > 0 )
272 *pPCX >> nDat;
273 if ( ( nDat & 0xc0 ) == 0xc0 )
275 nCount =( (ULONG)nDat ) & 0x003f;
276 *pPCX >> nDat;
277 if ( nCount < nx )
279 nx -= nCount;
280 while ( nCount > 0)
282 *(pDest++) = nDat;
283 nCount--;
286 else
288 nCount -= nx;
291 *(pDest++) = nDat;
292 nx--;
294 while ( nx > 0 );
295 break;
298 else
300 *(pDest++) = nDat;
301 nx--;
306 pSource1 = pPlane[ 0 ];
307 pSource2 = pPlane[ 1 ];
308 pSource3 = pPlane[ 2 ];
309 pSource4 = pPlane[ 3 ];
310 switch ( nBitsPerPlanePix + ( nPlanes << 8 ) )
312 // 2 colors
313 case 0x101 :
314 for ( i = 0; i < nWidth; i++ )
316 ULONG nShift = ( i & 7 ) ^ 7;
317 if ( nShift == 0 )
318 pAcc->SetPixel( ny, i, ( *pSource1++ & 1 ) );
319 else
320 pAcc->SetPixel(
321 ny, i,
322 sal::static_int_cast< BYTE >(
323 ( *pSource1 >> nShift ) & 1) );
325 break;
326 // 4 colors
327 case 0x102 :
328 for ( i = 0; i < nWidth; i++ )
330 switch( i & 3 )
332 case 0 :
333 nCol = *pSource1 >> 6;
334 break;
335 case 1 :
336 nCol = ( *pSource1 >> 4 ) & 0x03 ;
337 break;
338 case 2 :
339 nCol = ( *pSource1 >> 2 ) & 0x03;
340 break;
341 case 3 :
342 nCol = ( *pSource1++ ) & 0x03;
343 break;
345 pAcc->SetPixel( ny, i, nCol );
347 break;
348 // 256 colors
349 case 0x108 :
350 for ( i = 0; i < nWidth; i++ )
352 pAcc->SetPixel( ny, i, *pSource1++ );
354 break;
355 // 8 colors
356 case 0x301 :
357 for ( i = 0; i < nWidth; i++ )
359 ULONG nShift = ( i & 7 ) ^ 7;
360 if ( nShift == 0 )
362 nCol = ( *pSource1++ & 1) + ( ( *pSource2++ << 1 ) & 2 ) + ( ( *pSource3++ << 2 ) & 4 );
363 pAcc->SetPixel( ny, i, nCol );
365 else
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 );
373 break;
374 // 16 colors
375 case 0x401 :
376 for ( i = 0; i < nWidth; i++ )
378 ULONG nShift = ( i & 7 ) ^ 7;
379 if ( nShift == 0 )
381 nCol = ( *pSource1++ & 1) + ( ( *pSource2++ << 1 ) & 2 ) + ( ( *pSource3++ << 2 ) & 4 ) +
382 ( ( *pSource4++ << 3 ) & 8 );
383 pAcc->SetPixel( ny, i, nCol );
385 else
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 );
393 break;
394 // 16m colors
395 case 0x308 :
396 for ( i = 0; i < nWidth; i++ )
398 pAcc->SetPixel( ny, i, Color( *pSource1++, *pSource2++, *pSource3++ ) );
401 break;
402 default :
403 nStatus = FALSE;
404 break;
407 for ( np = 0; np < nPlanes; np++ )
408 delete[] pPlane[ np ];
411 void PCXReader::ImplReadPalette( ULONG nCol )
413 BYTE r, g, b;
414 BYTE* pPtr = pPalette;
415 for ( ULONG i = 0; i < nCol; i++ )
417 *pPCX >> r >> g >> b;
418 *pPtr++ = r;
419 *pPtr++ = g;
420 *pPtr++ = 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 );
432 return nRetValue;
435 //================== ein bischen Muell fuer Windows ==========================
436 #ifndef GCC
437 #endif
439 #ifdef WIN
441 static HINSTANCE hDLLInst = 0; // HANDLE der DLL
443 extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
445 #ifndef WNT
446 if ( nHeap )
447 UnlockData( 0 );
448 #endif
450 hDLLInst = hDLL;
452 return TRUE;
455 extern "C" int CALLBACK WEP( int )
457 return 1;
460 #endif