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: ipcd.cxx,v $
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:
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
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
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
);
97 BOOL
ReadPCD( SvStream
& rPCD
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
);
100 //=================== Methoden von PCDReader ==============================
102 BOOL
PCDReader::ReadPCD( SvStream
& rPCD
, Graphic
& rGraphic
, FilterConfigItem
* pConfigItem
)
112 // Ist es eine PCD-Datei mit Bild ? ( setzt bStatus == FALSE, wenn nicht ):
113 CheckPCDImagePacFile();
115 // Orientierung des Bildes einlesen:
118 // Welche Aufloesung wollen wir ?:
119 eResolution
= PCDRES_BASE
;
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:
154 if ( ( nOrientation
& 0x01 ) == 0 )
157 nBMPHeight
= nHeight
;
164 aBmp
= Bitmap( Size( nBMPWidth
, nBMPHeight
), 24 );
165 if ( ( mpAcc
= aBmp
.AcquireWriteAccess() ) == FALSE
)
170 aBmp
.ReleaseAccess( mpAcc
), mpAcc
= NULL
;
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 )
193 // -------------------------------------------------------------------------------------------
195 void PCDReader::CheckPCDImagePacFile()
200 pPCD
->Read( Buf
, 7 );
202 if ( ByteString( Buf
).CompareTo( "PCD_IPI" ) != COMPARE_EQUAL
)
206 // -------------------------------------------------------------------------------------------
208 void PCDReader::ReadOrientation()
210 if ( bStatus
== FALSE
)
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
;
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
)
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
);
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 ];
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
;
303 for ( nx
= 0; nx
< nWidth
; nx
++ )
305 // nL,nCb,nCr fuer den Pixel nx,ny holen/berechenen:
309 nL
= (long)pL0
[ nx
];
310 if (( nx
& 1 ) == 0 )
312 nCb
= (long)pCb
[ nXPair
];
313 nCr
= (long)pCr
[ nXPair
];
317 nCb
= ( ( (long)pCb
[ nXPair
] ) + ( (long)pCb
[ nXPair
+ 1 ] ) ) >> 1;
318 nCr
= ( ( (long)pCr
[ nXPair
] ) + ( (long)pCr
[ nXPair
+ 1 ] ) ) >> 1;
323 if ( ( nx
& 1 ) == 0 )
325 nCb
= ( ( (long)pCb
[ nXPair
] ) + ( (long)pCbN
[ nXPair
] ) ) >> 1;
326 nCr
= ( ( (long)pCr
[ nXPair
] ) + ( (long)pCrN
[ nXPair
] ) ) >> 1;
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:
340 nRed
= ( nL
+ nCr
* 119374L + 0x8000 ) >> 16;
345 nGreen
= ( nL
- nCb
* 28198L - nCr
* 60761L + 0x8000 ) >> 16;
350 nBlue
= ( nL
+ nCb
* 145352L + 0x8000 ) >> 16;
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
) );
362 mpAcc
->SetPixel( nWidth
- 1 - nx
, ny
, BitmapColor( (BYTE
)nRed
, (BYTE
)nGreen
, (BYTE
)nBlue
) );
366 if ( nOrientation
== 2 )
367 mpAcc
->SetPixel( nHeight
- 1 - ny
, ( nWidth
- 1 - nx
), BitmapColor( (BYTE
)nRed
, (BYTE
)nGreen
, (BYTE
)nBlue
) );
369 mpAcc
->SetPixel( nx
, ( nHeight
- 1 - ny
), BitmapColor( (BYTE
)nRed
, (BYTE
)nGreen
, (BYTE
)nBlue
) );
374 if ( pPCD
->GetError() )
376 MayCallback( nMinPercent
+ ( nMaxPercent
- nMinPercent
) * nYPair
/ nH2
);
377 if ( bStatus
== FALSE
)
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 ==================================
404 static HINSTANCE hDLLInst
= 0; // HANDLE der DLL
406 extern "C" int CALLBACK
LibMain( HINSTANCE hDLL
, WORD
, WORD nHeap
, LPSTR
)
418 extern "C" int CALLBACK
WEP( int )