Update ooo320-m1
[ooovba.git] / goodies / source / filter.vcl / ipcd / ipcd.cxx
blob0fc973eb6f53411e1a836e10f08b802deb0a5b4d
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: ipcd.cxx,v $
10 * $Revision: 1.9 $
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 "rtl/alloc.h"
35 #include <vcl/graph.hxx>
36 #include <vcl/bmpacc.hxx>
37 #include <vcl/svapp.hxx>
38 #include <svtools/fltcall.hxx>
39 #include <svtools/solar.hrc>
40 #include <svtools/FilterConfigItem.hxx>
42 //============================ PCDReader ==================================
44 // Diese Aufloesungen sind in einer PCD-Datei enthalten:
45 enum PCDResolution {
46 PCDRES_BASE16, // 192 x 128
47 PCDRES_BASE4, // 384 x 256
48 PCDRES_BASE, // 768 x 512
49 // Die folgenden sind komprimiert und koennen
50 // von uns NICHT gelesen werden:
51 PCDRES_4BASE, // 1536 x 1024
52 PCDRES_16BASE // 3072 x 3072
55 class PCDReader {
57 private:
59 BOOL bStatus;
61 ULONG nLastPercent;
63 SvStream* pPCD;
64 BitmapWriteAccess* mpAcc;
66 BYTE nOrientation; // Ausrichtung des Bildes in der PCD-Datei:
67 // 0 - Turmspitze zeigt nach oben
68 // 1 - Turmspitze zeigt nach rechts
69 // 2 - Turmspitze zeigt nach unten
70 // 3 - Turmspitze zeigt nach links
72 PCDResolution eResolution; // Welche Aufloesung wir haben wollen
74 ULONG nWidth; // Breite des PCD-Bildes
75 ULONG nHeight; // Hoehe des PCD-Bildes
76 ULONG nImagePos; // Position des Bildes in der PCD-Datei
78 // Temporare BLue-Green-Red-Bitmap
79 ULONG nBMPWidth;
80 ULONG nBMPHeight;
82 void MayCallback(ULONG nPercent);
84 void CheckPCDImagePacFile();
85 // Prueft, ob es eine Photo-CD-Datei mit 'Image Pac' ist.
87 void ReadOrientation();
88 // Liest die Ausrichtung und setzt nOrientation
90 void ReadImage(ULONG nMinPercent, ULONG nMaxPercent);
92 public:
94 PCDReader() {}
95 ~PCDReader() {}
97 BOOL ReadPCD( SvStream & rPCD, Graphic & rGraphic, FilterConfigItem* pConfigItem );
100 //=================== Methoden von PCDReader ==============================
102 BOOL PCDReader::ReadPCD( SvStream & rPCD, Graphic & rGraphic, FilterConfigItem* pConfigItem )
104 Bitmap aBmp;
106 bStatus = TRUE;
107 nLastPercent = 0;
108 pPCD = &rPCD;
110 MayCallback( 0 );
112 // Ist es eine PCD-Datei mit Bild ? ( setzt bStatus == FALSE, wenn nicht ):
113 CheckPCDImagePacFile();
115 // Orientierung des Bildes einlesen:
116 ReadOrientation();
118 // Welche Aufloesung wollen wir ?:
119 eResolution = PCDRES_BASE;
120 if ( pConfigItem )
122 sal_Int32 nResolution = pConfigItem->ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), 2 );
123 if ( nResolution == 1 )
124 eResolution = PCDRES_BASE4;
125 else if ( nResolution == 0 )
126 eResolution = PCDRES_BASE16;
128 // Groesse und Position (Position in PCD-Datei) des Bildes bestimmen:
129 switch (eResolution)
131 case PCDRES_BASE16 :
132 nWidth = 192;
133 nHeight = 128;
134 nImagePos = 8192;
135 break;
137 case PCDRES_BASE4 :
138 nWidth = 384;
139 nHeight = 256;
140 nImagePos = 47104;
141 break;
143 case PCDRES_BASE :
144 nWidth = 768;
145 nHeight = 512;
146 nImagePos = 196608;
147 break;
149 default:
150 bStatus = FALSE;
152 if ( bStatus )
154 if ( ( nOrientation & 0x01 ) == 0 )
156 nBMPWidth = nWidth;
157 nBMPHeight = nHeight;
159 else
161 nBMPWidth = nHeight;
162 nBMPHeight = nWidth;
164 aBmp = Bitmap( Size( nBMPWidth, nBMPHeight ), 24 );
165 if ( ( mpAcc = aBmp.AcquireWriteAccess() ) == FALSE )
166 return FALSE;
168 ReadImage( 5 ,65 );
170 aBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
171 rGraphic = aBmp;
173 return bStatus;
176 // -------------------------------------------------------------------------------------------
178 void PCDReader::MayCallback(ULONG /*nPercent*/)
181 if ( nPercent >= nLastPercent + 3 )
183 nLastPercent=nPercent;
184 if ( pCallback != NULL && nPercent <= 100 && bStatus == TRUE )
186 if ( ( (*pCallback)( pCallerData, (USHORT)nPercent ) ) == TRUE )
187 bStatus = FALSE;
193 // -------------------------------------------------------------------------------------------
195 void PCDReader::CheckPCDImagePacFile()
197 char Buf[ 8 ];
199 pPCD->Seek( 2048 );
200 pPCD->Read( Buf, 7 );
201 Buf[ 7 ] = 0;
202 if ( ByteString( Buf ).CompareTo( "PCD_IPI" ) != COMPARE_EQUAL )
203 bStatus = FALSE;
206 // -------------------------------------------------------------------------------------------
208 void PCDReader::ReadOrientation()
210 if ( bStatus == FALSE )
211 return;
212 pPCD->Seek( 194635 );
213 *pPCD >> nOrientation;
214 nOrientation &= 0x03;
217 // -------------------------------------------------------------------------------------------
219 void PCDReader::ReadImage(ULONG nMinPercent, ULONG nMaxPercent)
221 ULONG nx,ny,nW2,nH2,nYPair,ndy,nXPair;
222 long nL,nCb,nCr,nRed,nGreen,nBlue;
223 BYTE * pt;
224 BYTE * pL0; // Luminanz fuer jeden Pixel der 1. Zeile des aktuellen Zeilen-Paars
225 BYTE * pL1; // Luminanz fuer jeden Pixel der 2. Zeile des aktuellen Zeilen-Paars
226 BYTE * pCb; // Blau-Chrominanz fuer je 2x2 Pixel des aktuellen Zeilen-Paars
227 BYTE * pCr; // Rot-Chrominanz fuer je 2x2 Pixel des aktuellen Zeilen-Paars
228 BYTE * pL0N, * pL1N, * pCbN, * pCrN; // wie oben, nur fuer das naechste Zeilen-Paar
230 if ( bStatus == FALSE )
231 return;
233 nW2=nWidth>>1;
234 nH2=nHeight>>1;
236 pL0 =(BYTE*)rtl_allocateMemory( nWidth );
237 pL1 =(BYTE*)rtl_allocateMemory( nWidth );
238 pCb =(BYTE*)rtl_allocateMemory( nW2+1 );
239 pCr =(BYTE*)rtl_allocateMemory( nW2+1 );
240 pL0N=(BYTE*)rtl_allocateMemory( nWidth );
241 pL1N=(BYTE*)rtl_allocateMemory( nWidth );
242 pCbN=(BYTE*)rtl_allocateMemory( nW2+1 );
243 pCrN=(BYTE*)rtl_allocateMemory( nW2+1 );
245 if ( pL0 == NULL || pL1 == NULL || pCb == NULL || pCr == NULL ||
246 pL0N == NULL || pL1N == NULL || pCbN == NULL || pCrN == NULL)
248 rtl_freeMemory((void*)pL0 );
249 rtl_freeMemory((void*)pL1 );
250 rtl_freeMemory((void*)pCb );
251 rtl_freeMemory((void*)pCr );
252 rtl_freeMemory((void*)pL0N);
253 rtl_freeMemory((void*)pL1N);
254 rtl_freeMemory((void*)pCbN);
255 rtl_freeMemory((void*)pCrN);
256 bStatus = FALSE;
257 return;
260 pPCD->Seek( nImagePos );
262 // naechstes Zeilen-Paar := erstes Zeile-Paar:
263 pPCD->Read( pL0N, nWidth );
264 pPCD->Read( pL1N, nWidth );
265 pPCD->Read( pCbN, nW2 );
266 pPCD->Read( pCrN, nW2 );
267 pCbN[ nW2 ] = pCbN[ nW2 - 1 ];
268 pCrN[ nW2 ] = pCrN[ nW2 - 1 ];
270 for ( nYPair = 0; nYPair < nH2; nYPair++ )
272 // aktuelles Zeilen-Paar := naechstes Zeilen-Paar
273 pt=pL0; pL0=pL0N; pL0N=pt;
274 pt=pL1; pL1=pL1N; pL1N=pt;
275 pt=pCb; pCb=pCbN; pCbN=pt;
276 pt=pCr; pCr=pCrN; pCrN=pt;
278 // naechstes Zeilen-Paar holen:
279 if ( nYPair < nH2 - 1 )
281 pPCD->Read( pL0N, nWidth );
282 pPCD->Read( pL1N, nWidth );
283 pPCD->Read( pCbN, nW2 );
284 pPCD->Read( pCrN, nW2 );
285 pCbN[nW2]=pCbN[ nW2 - 1 ];
286 pCrN[nW2]=pCrN[ nW2 - 1 ];
288 else
290 for ( nXPair = 0; nXPair < nW2; nXPair++ )
292 pCbN[ nXPair ] = pCb[ nXPair ];
293 pCrN[ nXPair ] = pCr[ nXPair ];
297 // Schleife uber die beiden Zeilen des Zeilen-Paars:
298 for ( ndy = 0; ndy < 2; ndy++ )
300 ny = ( nYPair << 1 ) + ndy;
302 // Schleife ueber X:
303 for ( nx = 0; nx < nWidth; nx++ )
305 // nL,nCb,nCr fuer den Pixel nx,ny holen/berechenen:
306 nXPair = nx >> 1;
307 if ( ndy == 0 )
309 nL = (long)pL0[ nx ];
310 if (( nx & 1 ) == 0 )
312 nCb = (long)pCb[ nXPair ];
313 nCr = (long)pCr[ nXPair ];
315 else
317 nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCb[ nXPair + 1 ] ) ) >> 1;
318 nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCr[ nXPair + 1 ] ) ) >> 1;
321 else {
322 nL = pL1[ nx ];
323 if ( ( nx & 1 ) == 0 )
325 nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCbN[ nXPair ] ) ) >> 1;
326 nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCrN[ nXPair ] ) ) >> 1;
328 else
330 nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCb[ nXPair + 1 ] ) +
331 ( (long)pCbN[ nXPair ] ) + ( (long)pCbN[ nXPair + 1 ] ) ) >> 2;
332 nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCr[ nXPair + 1] ) +
333 ( (long)pCrN[ nXPair ] ) + ( (long)pCrN[ nXPair + 1 ] ) ) >> 2;
336 // Umwandlung von nL,nCb,nCr in nRed,nGreen,nBlue:
337 nL *= 89024L;
338 nCb -= 156;
339 nCr -= 137;
340 nRed = ( nL + nCr * 119374L + 0x8000 ) >> 16;
341 if ( nRed < 0 )
342 nRed = 0;
343 if ( nRed > 255)
344 nRed = 255;
345 nGreen = ( nL - nCb * 28198L - nCr * 60761L + 0x8000 ) >> 16;
346 if ( nGreen < 0 )
347 nGreen = 0;
348 if ( nGreen > 255 )
349 nGreen = 255;
350 nBlue = ( nL + nCb * 145352L + 0x8000 ) >> 16;
351 if ( nBlue < 0 )
352 nBlue = 0;
353 if ( nBlue > 255 )
354 nBlue = 255;
356 // Farbwert in pBMPMap eintragen:
357 if ( nOrientation < 2 )
359 if ( nOrientation == 0 )
360 mpAcc->SetPixel( ny, nx, BitmapColor( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) );
361 else
362 mpAcc->SetPixel( nWidth - 1 - nx, ny, BitmapColor( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) );
364 else
366 if ( nOrientation == 2 )
367 mpAcc->SetPixel( nHeight - 1 - ny, ( nWidth - 1 - nx ), BitmapColor( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) );
368 else
369 mpAcc->SetPixel( nx, ( nHeight - 1 - ny ), BitmapColor( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) );
374 if ( pPCD->GetError() )
375 bStatus = FALSE;
376 MayCallback( nMinPercent + ( nMaxPercent - nMinPercent ) * nYPair / nH2 );
377 if ( bStatus == FALSE )
378 break;
380 rtl_freeMemory((void*)pL0 );
381 rtl_freeMemory((void*)pL1 );
382 rtl_freeMemory((void*)pCb );
383 rtl_freeMemory((void*)pCr );
384 rtl_freeMemory((void*)pL0N);
385 rtl_freeMemory((void*)pL1N);
386 rtl_freeMemory((void*)pCbN);
387 rtl_freeMemory((void*)pCrN);
390 //================== GraphicImport - die exportierte Funktion ================
392 extern "C" BOOL __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pConfigItem, BOOL )
394 PCDReader aPCDReader;
395 return aPCDReader.ReadPCD( rStream, rGraphic, pConfigItem );
398 //============================= fuer Windows ==================================
399 #ifndef GCC
400 #endif
402 #ifdef WIN
404 static HINSTANCE hDLLInst = 0; // HANDLE der DLL
406 extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
408 #ifndef WNT
409 if ( nHeap )
410 UnlockData( 0 );
411 #endif
413 hDLLInst = hDLL;
415 return TRUE;
418 extern "C" int CALLBACK WEP( int )
420 return 1;
423 #endif