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: bmpsum.cxx,v $
10 * $Revision: 1.13.150.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_svtools.hxx"
41 #include <tools/stream.hxx>
42 #include <tools/fsys.hxx>
43 #include <vcl/svapp.hxx>
44 #include <vcl/bitmap.hxx>
45 #include <vcl/bmpacc.hxx>
46 #include <vcl/pngread.hxx>
48 #include "svtools/solar.hrc"
50 #define EXIT_NOERROR 0x00000000
51 #define EXIT_INVALIDFILE 0x00000001
52 #define EXIT_COMMONERROR 0x80000000
64 BOOL
GetCommandOption( const ::std::vector
< String
>& rArgs
, const String
& rSwitch
, String
& rSwitchParam
);
65 BOOL
GetCommandOptions( const ::std::vector
< String
>& rArgs
, const String
& rSwitch
, ::std::vector
< String
>& rSwitchParams
);
67 void SetExitCode( BYTE cExit
)
69 if( ( EXIT_NOERROR
== cExitCode
) || ( cExit
!= EXIT_NOERROR
) )
73 void Message( const String
& rText
, BYTE cExitCode
);
75 sal_uInt64
GetCRC( const BitmapEx
& rBmpEx
);
77 void ProcessFile( const String
& rBmpFileName
);
78 void ProcessFileList( const String
& rInFileList
, const String
& rOutFileList
, const String
& rOutPath
);
85 int Start( const ::std::vector
< String
>& rArgs
);
88 // -----------------------------------------------------------------------------
94 // -----------------------------------------------------------------------------
100 // -----------------------------------------------------------------------
102 BOOL
BmpSum::GetCommandOption( const ::std::vector
< String
>& rArgs
, const String
& rSwitch
, String
& rParam
)
106 for( int i
= 0, nCount
= rArgs
.size(); ( i
< nCount
) && !bRet
; i
++ )
108 String
aTestStr( '-' );
110 for( int n
= 0; ( n
< 2 ) && !bRet
; n
++ )
114 if( aTestStr
.CompareIgnoreCaseToAscii( rArgs
[ i
] ) == COMPARE_EQUAL
)
118 if( i
< ( nCount
- 1 ) )
119 rParam
= rArgs
[ i
+ 1 ];
132 // -----------------------------------------------------------------------
134 BOOL
BmpSum::GetCommandOptions( const ::std::vector
< String
>& rArgs
, const String
& rSwitch
, ::std::vector
< String
>& rParams
)
138 for( int i
= 0, nCount
= rArgs
.size(); ( i
< nCount
); i
++ )
140 String
aTestStr( '-' );
142 for( int n
= 0; ( n
< 2 ) && !bRet
; n
++ )
146 if( aTestStr
.CompareIgnoreCaseToAscii( rArgs
[ i
] ) == COMPARE_EQUAL
)
148 if( i
< ( nCount
- 1 ) )
149 rParams
.push_back( rArgs
[ i
+ 1 ] );
151 rParams
.push_back( String() );
161 return( rParams
.size() > 0 );
164 // -----------------------------------------------------------------------
166 void BmpSum::Message( const String
& rText
, BYTE nExitCode
)
168 if( EXIT_NOERROR
!= nExitCode
)
169 SetExitCode( nExitCode
);
171 ByteString
aText( rText
, RTL_TEXTENCODING_UTF8
);
172 aText
.Append( "\r\n" );
173 fprintf( stderr
, "%s", aText
.GetBuffer() );
176 // -----------------------------------------------------------------------------
178 void BmpSum::ShowUsage()
180 Message( String( RTL_CONSTASCII_USTRINGPARAM( "Usage:" ) ), EXIT_NOERROR
);
181 Message( String( RTL_CONSTASCII_USTRINGPARAM( " bmpsum bmp_inputfile" ) ), EXIT_NOERROR
);
182 Message( String( RTL_CONSTASCII_USTRINGPARAM( " bmpsum -i input_filelist -o output_filelist [-p path_for_copied_bitmaps]" ) ), EXIT_NOERROR
);
183 Message( String( RTL_CONSTASCII_USTRINGPARAM( "Options:" ) ), EXIT_NOERROR
);
184 Message( String( RTL_CONSTASCII_USTRINGPARAM( "Examples:" ) ), EXIT_NOERROR
);
185 Message( String( RTL_CONSTASCII_USTRINGPARAM( " bmpsum /home/test.bmp" ) ), EXIT_NOERROR
);
186 Message( String( RTL_CONSTASCII_USTRINGPARAM( " bmpsum -i /home/inlist.txt -o /home/outlist.txt" ) ), EXIT_NOERROR
);
187 Message( String( RTL_CONSTASCII_USTRINGPARAM( " bmpsum -i /home/inlist.txt -o /home/outlist.txt -p /home/outpath" ) ), EXIT_NOERROR
);
190 // -----------------------------------------------------------------------------
192 int BmpSum::Start( const ::std::vector
< String
>& rArgs
)
194 cExitCode
= EXIT_NOERROR
;
196 if( rArgs
.size() >= 1 )
198 String aInFileList
, aOutFileList
, aOutPath
;
200 if( GetCommandOption( rArgs
, 'i', aInFileList
) &&
201 GetCommandOption( rArgs
, 'o', aOutFileList
) )
203 GetCommandOption( rArgs
, 'p', aOutPath
);
204 ProcessFileList( aInFileList
, aOutFileList
, aOutPath
);
208 ProcessFile( rArgs
[ 0 ] );
214 cExitCode
= EXIT_COMMONERROR
;
220 // -----------------------------------------------------------------------------
222 sal_uInt64
BmpSum::GetCRC( const BitmapEx
& rBmpEx
)
224 Bitmap
aBmp( rBmpEx
.GetBitmap() );
225 BitmapReadAccess
* pRAcc
= aBmp
.AcquireReadAccess();
227 BitmapReadAccess
* pAAcc
= NULL
;
231 if( rBmpEx
.IsTransparent() )
233 aAlpha
= rBmpEx
.GetAlpha();
234 pAAcc
= aAlpha
.AcquireReadAccess();
237 if( pRAcc
&& pRAcc
->Width() && pRAcc
->Height() )
241 for( long nY
= 0; nY
< pRAcc
->Height(); ++nY
)
243 for( long nX
= 0; nX
< pRAcc
->Width(); ++nX
)
245 const BitmapColor
aCol( pRAcc
->GetColor( nY
, nX
) );
247 UInt32ToSVBT32( aCol
.GetRed(), aBT32
);
248 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
250 UInt32ToSVBT32( aCol
.GetGreen(), aBT32
);
251 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
253 UInt32ToSVBT32( aCol
.GetBlue(), aBT32
);
254 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
258 const BitmapColor
aMaskCol( pAAcc
->GetColor( nY
, nX
) );
260 UInt32ToSVBT32( aMaskCol
.GetRed(), aBT32
);
261 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
263 UInt32ToSVBT32( aMaskCol
.GetGreen(), aBT32
);
264 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
266 UInt32ToSVBT32( aMaskCol
.GetBlue(), aBT32
);
267 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
272 nRet
= ( ( (sal_uInt64
) pRAcc
->Width() ) << 48 ) |
273 ( ( (sal_uInt64
) pRAcc
->Height() ) << 32 ) |
274 ( (sal_uInt64
) nCrc
);
278 aAlpha
.ReleaseAccess( pAAcc
);
280 aBmp
.ReleaseAccess( pRAcc
);
285 // -----------------------------------------------------------------------------
287 void BmpSum::ProcessFile( const String
& rBmpFileName
)
289 SvFileStream
aIStm( rBmpFileName
, STREAM_READ
);
297 if( !aBmpEx
.IsEmpty() )
299 fprintf( stdout
, "%" SAL_PRIuUINT64
"\r\n", GetCRC( aBmpEx
) );
306 ::vcl::PNGReader
aPngReader( aIStm
);
308 aBmpEx
= aPngReader
.Read();
310 if( !aBmpEx
.IsEmpty() )
312 fprintf( stdout
, "%" SAL_PRIuUINT64
"\r\n", GetCRC( aBmpEx
) );
315 Message( String( RTL_CONSTASCII_USTRINGPARAM( "file not valid" ) ), EXIT_INVALIDFILE
);
320 // -----------------------------------------------------------------------------
322 void BmpSum::ProcessFileList( const String
& rInFileList
,
323 const String
& rOutFileList
,
324 const String
& rOutPath
)
326 SvFileStream
aIStm( rInFileList
, STREAM_READ
);
327 SvFileStream
aOStm( rOutFileList
, STREAM_WRITE
| STREAM_TRUNC
);
328 const DirEntry
aBaseDir( rOutPath
);
333 if( aIStm
.IsOpen() && aOStm
.IsOpen() )
335 ByteString aReadLine
;
336 ::std::set
< ByteString
> aFileNameSet
;
338 while( aIStm
.ReadLine( aReadLine
) )
340 if( aReadLine
.Len() )
341 aFileNameSet
.insert( aReadLine
);
343 if( aReadLine
.Search( "enus" ) != STRING_NOTFOUND
)
345 static const char* aLanguages
[] =
364 for( sal_uInt32 n
= 0; n
< 14; ++n
)
366 ByteString
aLangPath( aReadLine
);
368 aLangPath
.SearchAndReplace( "enus", aLanguages
[ n
] );
370 DirEntry
aTestFile( aLangPath
);
372 if( aTestFile
.Exists() )
373 aFileNameSet
.insert( aLangPath
);
382 ::std::set
< ByteString
>::iterator
aIter( aFileNameSet
.begin() );
383 ::std::map
< sal_uInt64
, ::std::vector
< ByteString
> > aFileNameMap
;
385 while( aIter
!= aFileNameSet
.end() )
387 ByteString
aStr( *aIter
++ );
388 SvFileStream
aBmpStm( String( aStr
.GetBuffer(), RTL_TEXTENCODING_ASCII_US
), STREAM_READ
);
391 if( aBmpStm
.IsOpen() )
397 if( !aBmpEx
.IsEmpty() )
398 nCRC
= GetCRC( aBmpEx
);
401 aBmpStm
.ResetError();
404 ::vcl::PNGReader
aPngReader( aBmpStm
);
406 aBmpEx
= aPngReader
.Read();
408 if( !aBmpEx
.IsEmpty() )
409 nCRC
= GetCRC( aBmpEx
);
412 fprintf( stderr
, "%s could not be opened\n", aStr
.GetBuffer() );
420 ::std::map
< sal_uInt64
, ::std::vector
< ByteString
> >::iterator
aFound( aFileNameMap
.find( nCRC
) );
422 if( aFound
!= aFileNameMap
.end() )
423 (*aFound
).second
.push_back( aStr
);
426 ::std::vector
< ByteString
> aVector( 1, aStr
);
427 aFileNameMap
[ nCRC
] = aVector
;
433 ::std::vector
< ByteString
> aVector( 1, aStr
);
434 aFileNameMap
[ nCRC
] = aVector
;
438 ::std::map
< sal_uInt64
, ::std::vector
< ByteString
> >::iterator
aMapIter( aFileNameMap
.begin() );
439 sal_uInt32 nFileCount
= 0;
441 while( aMapIter
!= aFileNameMap
.end() )
443 ::std::pair
< const sal_uInt64
, ::std::vector
< ByteString
> > aPair( *aMapIter
++ );
444 ::std::vector
< ByteString
> aFileNameVector( aPair
.second
);
447 for( sal_uInt32 i
= 0; i
< aFileNameVector
.size(); ++i
)
449 ByteString
aStr( ByteString::CreateFromInt64( aPair
.first
) );
450 ByteString
aFileName( aFileNameVector
[ i
] );
451 DirEntry
aSrcFile( aFileName
);
456 aOStm
.WriteLine( aStr
);
461 if( aFileName
.Search( ":\\" ) != STRING_NOTFOUND
)
462 aFileName
.Erase( 0, aFileName
.Search( ":\\" ) + 2 );
464 aFileName
.SearchAndReplaceAll( '\\', '/' );
466 sal_uInt16 nTokenCount
= aFileName
.GetTokenCount( '/' );
467 DirEntry
aNewDir( aBaseDir
);
469 for( sal_uInt16 n
= 0; ( n
< nTokenCount
- 1 ); n
++ )
471 aNewDir
+= DirEntry( aFileName
.GetToken( n
, '/' ) );
475 aNewDir
+= DirEntry( aFileName
.GetToken( nTokenCount
- 1, '/' ) );
476 aSrcFile
.CopyTo( aNewDir
, FSYS_ACTION_COPYFILE
);
484 stdout
, "unique file count: %lu",
485 sal::static_int_cast
< unsigned long >(nFileCount
) );
493 int main( int nArgCount
, char* ppArgs
[] )
496 static char aDisplayVar
[ 1024 ];
498 strcpy( aDisplayVar
, "DISPLAY=" );
499 putenv( aDisplayVar
);
502 ::std::vector
< String
> aArgs
;
505 InitVCL( com::sun::star::uno::Reference
< com::sun::star::lang::XMultiServiceFactory
>() );
507 for( int i
= 1; i
< nArgCount
; i
++ )
508 aArgs
.push_back( String( ppArgs
[ i
], RTL_TEXTENCODING_ASCII_US
) );
510 return aBmpSum
.Start( aArgs
);