diff options
Diffstat (limited to 'filter/source/graphicfilter/ipcd/ipcd.cxx')
-rw-r--r-- | filter/source/graphicfilter/ipcd/ipcd.cxx | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/filter/source/graphicfilter/ipcd/ipcd.cxx b/filter/source/graphicfilter/ipcd/ipcd.cxx new file mode 100644 index 000000000000..0d44993c252d --- /dev/null +++ b/filter/source/graphicfilter/ipcd/ipcd.cxx @@ -0,0 +1,422 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_filter.hxx" + +#include "rtl/alloc.h" +#include <vcl/graph.hxx> +#include <vcl/bmpacc.hxx> +#include <vcl/svapp.hxx> +#include <svtools/fltcall.hxx> +#include <svl/solar.hrc> +#include <svtools/FilterConfigItem.hxx> + +//============================ PCDReader ================================== + +// Diese Aufloesungen sind in einer PCD-Datei enthalten: +enum PCDResolution { + PCDRES_BASE16, // 192 x 128 + PCDRES_BASE4, // 384 x 256 + PCDRES_BASE, // 768 x 512 + // Die folgenden sind komprimiert und koennen + // von uns NICHT gelesen werden: + PCDRES_4BASE, // 1536 x 1024 + PCDRES_16BASE // 3072 x 3072 +}; + +class PCDReader { + +private: + + BOOL bStatus; + + ULONG nLastPercent; + + SvStream* pPCD; + BitmapWriteAccess* mpAcc; + + BYTE nOrientation; // Ausrichtung des Bildes in der PCD-Datei: + // 0 - Turmspitze zeigt nach oben + // 1 - Turmspitze zeigt nach rechts + // 2 - Turmspitze zeigt nach unten + // 3 - Turmspitze zeigt nach links + + PCDResolution eResolution; // Welche Aufloesung wir haben wollen + + ULONG nWidth; // Breite des PCD-Bildes + ULONG nHeight; // Hoehe des PCD-Bildes + ULONG nImagePos; // Position des Bildes in der PCD-Datei + + // Temporare BLue-Green-Red-Bitmap + ULONG nBMPWidth; + ULONG nBMPHeight; + + void MayCallback(ULONG nPercent); + + void CheckPCDImagePacFile(); + // Prueft, ob es eine Photo-CD-Datei mit 'Image Pac' ist. + + void ReadOrientation(); + // Liest die Ausrichtung und setzt nOrientation + + void ReadImage(ULONG nMinPercent, ULONG nMaxPercent); + +public: + + PCDReader() {} + ~PCDReader() {} + + BOOL ReadPCD( SvStream & rPCD, Graphic & rGraphic, FilterConfigItem* pConfigItem ); +}; + +//=================== Methoden von PCDReader ============================== + +BOOL PCDReader::ReadPCD( SvStream & rPCD, Graphic & rGraphic, FilterConfigItem* pConfigItem ) +{ + Bitmap aBmp; + + bStatus = TRUE; + nLastPercent = 0; + pPCD = &rPCD; + + MayCallback( 0 ); + + // Ist es eine PCD-Datei mit Bild ? ( setzt bStatus == FALSE, wenn nicht ): + CheckPCDImagePacFile(); + + // Orientierung des Bildes einlesen: + ReadOrientation(); + + // Welche Aufloesung wollen wir ?: + eResolution = PCDRES_BASE; + if ( pConfigItem ) + { + sal_Int32 nResolution = pConfigItem->ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), 2 ); + if ( nResolution == 1 ) + eResolution = PCDRES_BASE4; + else if ( nResolution == 0 ) + eResolution = PCDRES_BASE16; + } + // Groesse und Position (Position in PCD-Datei) des Bildes bestimmen: + switch (eResolution) + { + case PCDRES_BASE16 : + nWidth = 192; + nHeight = 128; + nImagePos = 8192; + break; + + case PCDRES_BASE4 : + nWidth = 384; + nHeight = 256; + nImagePos = 47104; + break; + + case PCDRES_BASE : + nWidth = 768; + nHeight = 512; + nImagePos = 196608; + break; + + default: + bStatus = FALSE; + } + if ( bStatus ) + { + if ( ( nOrientation & 0x01 ) == 0 ) + { + nBMPWidth = nWidth; + nBMPHeight = nHeight; + } + else + { + nBMPWidth = nHeight; + nBMPHeight = nWidth; + } + aBmp = Bitmap( Size( nBMPWidth, nBMPHeight ), 24 ); + if ( ( mpAcc = aBmp.AcquireWriteAccess() ) == FALSE ) + return FALSE; + + ReadImage( 5 ,65 ); + + aBmp.ReleaseAccess( mpAcc ), mpAcc = NULL; + rGraphic = aBmp; + } + return bStatus; +} + +// ------------------------------------------------------------------------------------------- + +void PCDReader::MayCallback(ULONG /*nPercent*/) +{ +/* + if ( nPercent >= nLastPercent + 3 ) + { + nLastPercent=nPercent; + if ( pCallback != NULL && nPercent <= 100 && bStatus == TRUE ) + { + if ( ( (*pCallback)( pCallerData, (USHORT)nPercent ) ) == TRUE ) + bStatus = FALSE; + } + } +*/ +} + +// ------------------------------------------------------------------------------------------- + +void PCDReader::CheckPCDImagePacFile() +{ + char Buf[ 8 ]; + + pPCD->Seek( 2048 ); + pPCD->Read( Buf, 7 ); + Buf[ 7 ] = 0; + if ( ByteString( Buf ).CompareTo( "PCD_IPI" ) != COMPARE_EQUAL ) + bStatus = FALSE; +} + +// ------------------------------------------------------------------------------------------- + +void PCDReader::ReadOrientation() +{ + if ( bStatus == FALSE ) + return; + pPCD->Seek( 194635 ); + *pPCD >> nOrientation; + nOrientation &= 0x03; +} + +// ------------------------------------------------------------------------------------------- + +void PCDReader::ReadImage(ULONG nMinPercent, ULONG nMaxPercent) +{ + ULONG nx,ny,nW2,nH2,nYPair,ndy,nXPair; + long nL,nCb,nCr,nRed,nGreen,nBlue; + BYTE * pt; + BYTE * pL0; // Luminanz fuer jeden Pixel der 1. Zeile des aktuellen Zeilen-Paars + BYTE * pL1; // Luminanz fuer jeden Pixel der 2. Zeile des aktuellen Zeilen-Paars + BYTE * pCb; // Blau-Chrominanz fuer je 2x2 Pixel des aktuellen Zeilen-Paars + BYTE * pCr; // Rot-Chrominanz fuer je 2x2 Pixel des aktuellen Zeilen-Paars + BYTE * pL0N, * pL1N, * pCbN, * pCrN; // wie oben, nur fuer das naechste Zeilen-Paar + + if ( bStatus == FALSE ) + return; + + nW2=nWidth>>1; + nH2=nHeight>>1; + + pL0 =(BYTE*)rtl_allocateMemory( nWidth ); + pL1 =(BYTE*)rtl_allocateMemory( nWidth ); + pCb =(BYTE*)rtl_allocateMemory( nW2+1 ); + pCr =(BYTE*)rtl_allocateMemory( nW2+1 ); + pL0N=(BYTE*)rtl_allocateMemory( nWidth ); + pL1N=(BYTE*)rtl_allocateMemory( nWidth ); + pCbN=(BYTE*)rtl_allocateMemory( nW2+1 ); + pCrN=(BYTE*)rtl_allocateMemory( nW2+1 ); + + if ( pL0 == NULL || pL1 == NULL || pCb == NULL || pCr == NULL || + pL0N == NULL || pL1N == NULL || pCbN == NULL || pCrN == NULL) + { + rtl_freeMemory((void*)pL0 ); + rtl_freeMemory((void*)pL1 ); + rtl_freeMemory((void*)pCb ); + rtl_freeMemory((void*)pCr ); + rtl_freeMemory((void*)pL0N); + rtl_freeMemory((void*)pL1N); + rtl_freeMemory((void*)pCbN); + rtl_freeMemory((void*)pCrN); + bStatus = FALSE; + return; + } + + pPCD->Seek( nImagePos ); + + // naechstes Zeilen-Paar := erstes Zeile-Paar: + pPCD->Read( pL0N, nWidth ); + pPCD->Read( pL1N, nWidth ); + pPCD->Read( pCbN, nW2 ); + pPCD->Read( pCrN, nW2 ); + pCbN[ nW2 ] = pCbN[ nW2 - 1 ]; + pCrN[ nW2 ] = pCrN[ nW2 - 1 ]; + + for ( nYPair = 0; nYPair < nH2; nYPair++ ) + { + // aktuelles Zeilen-Paar := naechstes Zeilen-Paar + pt=pL0; pL0=pL0N; pL0N=pt; + pt=pL1; pL1=pL1N; pL1N=pt; + pt=pCb; pCb=pCbN; pCbN=pt; + pt=pCr; pCr=pCrN; pCrN=pt; + + // naechstes Zeilen-Paar holen: + if ( nYPair < nH2 - 1 ) + { + pPCD->Read( pL0N, nWidth ); + pPCD->Read( pL1N, nWidth ); + pPCD->Read( pCbN, nW2 ); + pPCD->Read( pCrN, nW2 ); + pCbN[nW2]=pCbN[ nW2 - 1 ]; + pCrN[nW2]=pCrN[ nW2 - 1 ]; + } + else + { + for ( nXPair = 0; nXPair < nW2; nXPair++ ) + { + pCbN[ nXPair ] = pCb[ nXPair ]; + pCrN[ nXPair ] = pCr[ nXPair ]; + } + } + + // Schleife uber die beiden Zeilen des Zeilen-Paars: + for ( ndy = 0; ndy < 2; ndy++ ) + { + ny = ( nYPair << 1 ) + ndy; + + // Schleife ueber X: + for ( nx = 0; nx < nWidth; nx++ ) + { + // nL,nCb,nCr fuer den Pixel nx,ny holen/berechenen: + nXPair = nx >> 1; + if ( ndy == 0 ) + { + nL = (long)pL0[ nx ]; + if (( nx & 1 ) == 0 ) + { + nCb = (long)pCb[ nXPair ]; + nCr = (long)pCr[ nXPair ]; + } + else + { + nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCb[ nXPair + 1 ] ) ) >> 1; + nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCr[ nXPair + 1 ] ) ) >> 1; + } + } + else { + nL = pL1[ nx ]; + if ( ( nx & 1 ) == 0 ) + { + nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCbN[ nXPair ] ) ) >> 1; + nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCrN[ nXPair ] ) ) >> 1; + } + else + { + nCb = ( ( (long)pCb[ nXPair ] ) + ( (long)pCb[ nXPair + 1 ] ) + + ( (long)pCbN[ nXPair ] ) + ( (long)pCbN[ nXPair + 1 ] ) ) >> 2; + nCr = ( ( (long)pCr[ nXPair ] ) + ( (long)pCr[ nXPair + 1] ) + + ( (long)pCrN[ nXPair ] ) + ( (long)pCrN[ nXPair + 1 ] ) ) >> 2; + } + } + // Umwandlung von nL,nCb,nCr in nRed,nGreen,nBlue: + nL *= 89024L; + nCb -= 156; + nCr -= 137; + nRed = ( nL + nCr * 119374L + 0x8000 ) >> 16; + if ( nRed < 0 ) + nRed = 0; + if ( nRed > 255) + nRed = 255; + nGreen = ( nL - nCb * 28198L - nCr * 60761L + 0x8000 ) >> 16; + if ( nGreen < 0 ) + nGreen = 0; + if ( nGreen > 255 ) + nGreen = 255; + nBlue = ( nL + nCb * 145352L + 0x8000 ) >> 16; + if ( nBlue < 0 ) + nBlue = 0; + if ( nBlue > 255 ) + nBlue = 255; + + // Farbwert in pBMPMap eintragen: + if ( nOrientation < 2 ) + { + if ( nOrientation == 0 ) + mpAcc->SetPixel( ny, nx, BitmapColor( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) ); + else + mpAcc->SetPixel( nWidth - 1 - nx, ny, BitmapColor( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) ); + } + else + { + if ( nOrientation == 2 ) + mpAcc->SetPixel( nHeight - 1 - ny, ( nWidth - 1 - nx ), BitmapColor( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) ); + else + mpAcc->SetPixel( nx, ( nHeight - 1 - ny ), BitmapColor( (BYTE)nRed, (BYTE)nGreen, (BYTE)nBlue ) ); + } + } + } + + if ( pPCD->GetError() ) + bStatus = FALSE; + MayCallback( nMinPercent + ( nMaxPercent - nMinPercent ) * nYPair / nH2 ); + if ( bStatus == FALSE ) + break; + } + rtl_freeMemory((void*)pL0 ); + rtl_freeMemory((void*)pL1 ); + rtl_freeMemory((void*)pCb ); + rtl_freeMemory((void*)pCr ); + rtl_freeMemory((void*)pL0N); + rtl_freeMemory((void*)pL1N); + rtl_freeMemory((void*)pCbN); + rtl_freeMemory((void*)pCrN); +} + +//================== GraphicImport - die exportierte Funktion ================ + +extern "C" BOOL __LOADONCALLAPI GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pConfigItem, BOOL ) +{ + PCDReader aPCDReader; + return aPCDReader.ReadPCD( rStream, rGraphic, pConfigItem ); +} + +//============================= fuer Windows ================================== +#ifndef GCC +#endif + +#ifdef WIN + +static HINSTANCE hDLLInst = 0; // HANDLE der DLL + +extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR ) +{ +#ifndef WNT + if ( nHeap ) + UnlockData( 0 ); +#endif + + hDLLInst = hDLL; + + return TRUE; +} + +extern "C" int CALLBACK WEP( int ) +{ + return 1; +} + +#endif + + |