Update ooo320-m1
[ooovba.git] / svtools / bmpmaker / bmpsum.cxx
blobed52a75e0adac2169a6aee1a01739eeba08f04ad
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"
34 #include <cstdio>
35 #include <csignal>
36 #include <vector>
37 #include <set>
38 #include <map>
40 #include <rtl/crc.h>
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
54 // ----------
55 // - BmpSum -
56 // ----------
58 class BmpSum
60 private:
62 sal_uInt32 cExitCode;
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 ) )
70 cExitCode = cExit;
72 void ShowUsage();
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 );
80 public:
82 BmpSum();
83 ~BmpSum();
85 int Start( const ::std::vector< String >& rArgs );
88 // -----------------------------------------------------------------------------
90 BmpSum::BmpSum()
94 // -----------------------------------------------------------------------------
96 BmpSum::~BmpSum()
100 // -----------------------------------------------------------------------
102 BOOL BmpSum::GetCommandOption( const ::std::vector< String >& rArgs, const String& rSwitch, String& rParam )
104 BOOL bRet = FALSE;
106 for( int i = 0, nCount = rArgs.size(); ( i < nCount ) && !bRet; i++ )
108 String aTestStr( '-' );
110 for( int n = 0; ( n < 2 ) && !bRet; n++ )
112 aTestStr += rSwitch;
114 if( aTestStr.CompareIgnoreCaseToAscii( rArgs[ i ] ) == COMPARE_EQUAL )
116 bRet = TRUE;
118 if( i < ( nCount - 1 ) )
119 rParam = rArgs[ i + 1 ];
120 else
121 rParam = String();
124 if( 0 == n )
125 aTestStr = '/';
129 return bRet;
132 // -----------------------------------------------------------------------
134 BOOL BmpSum::GetCommandOptions( const ::std::vector< String >& rArgs, const String& rSwitch, ::std::vector< String >& rParams )
136 BOOL bRet = FALSE;
138 for( int i = 0, nCount = rArgs.size(); ( i < nCount ); i++ )
140 String aTestStr( '-' );
142 for( int n = 0; ( n < 2 ) && !bRet; n++ )
144 aTestStr += rSwitch;
146 if( aTestStr.CompareIgnoreCaseToAscii( rArgs[ i ] ) == COMPARE_EQUAL )
148 if( i < ( nCount - 1 ) )
149 rParams.push_back( rArgs[ i + 1 ] );
150 else
151 rParams.push_back( String() );
153 break;
156 if( 0 == n )
157 aTestStr = '/';
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 );
206 else
208 ProcessFile( rArgs[ 0 ] );
211 else
213 ShowUsage();
214 cExitCode = EXIT_COMMONERROR;
217 return cExitCode;
220 // -----------------------------------------------------------------------------
222 sal_uInt64 BmpSum::GetCRC( const BitmapEx& rBmpEx )
224 Bitmap aBmp( rBmpEx.GetBitmap() );
225 BitmapReadAccess* pRAcc = aBmp.AcquireReadAccess();
226 AlphaMask aAlpha;
227 BitmapReadAccess* pAAcc = NULL;
228 sal_uInt64 nRet = 0;
229 sal_uInt32 nCrc = 0;
231 if( rBmpEx.IsTransparent() )
233 aAlpha = rBmpEx.GetAlpha();
234 pAAcc = aAlpha.AcquireReadAccess();
237 if( pRAcc && pRAcc->Width() && pRAcc->Height() )
239 SVBT32 aBT32;
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 );
256 if( pAAcc )
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 );
277 if( pAAcc )
278 aAlpha.ReleaseAccess( pAAcc);
280 aBmp.ReleaseAccess( pRAcc );
282 return nRet;
285 // -----------------------------------------------------------------------------
287 void BmpSum::ProcessFile( const String& rBmpFileName )
289 SvFileStream aIStm( rBmpFileName, STREAM_READ );
291 if( aIStm.IsOpen() )
293 BitmapEx aBmpEx;
295 aIStm >> aBmpEx;
297 if( !aBmpEx.IsEmpty() )
299 fprintf( stdout, "%" SAL_PRIuUINT64 "\r\n", GetCRC( aBmpEx ) );
301 else
303 aIStm.ResetError();
304 aIStm.Seek( 0 );
306 ::vcl::PNGReader aPngReader( aIStm );
308 aBmpEx = aPngReader.Read();
310 if( !aBmpEx.IsEmpty() )
312 fprintf( stdout, "%" SAL_PRIuUINT64 "\r\n", GetCRC( aBmpEx ) );
314 else
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 );
330 if( rOutPath.Len() )
331 aBaseDir.MakeDir();
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[] =
347 "chinsim",
348 "chintrad",
349 "dtch",
350 "enus",
351 "fren",
352 "hebrew"
353 "ital",
354 "japn",
355 "korean",
356 "pol",
357 "poln",
358 "port",
359 "russ",
360 "span",
361 "turk"
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 );
377 aReadLine.Erase();
380 aIStm.Close();
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 );
389 sal_uInt64 nCRC = 0;
391 if( aBmpStm.IsOpen() )
393 BitmapEx aBmpEx;
395 aBmpStm >> aBmpEx;
397 if( !aBmpEx.IsEmpty() )
398 nCRC = GetCRC( aBmpEx );
399 else
401 aBmpStm.ResetError();
402 aBmpStm.Seek( 0 );
404 ::vcl::PNGReader aPngReader( aBmpStm );
406 aBmpEx = aPngReader.Read();
408 if( !aBmpEx.IsEmpty() )
409 nCRC = GetCRC( aBmpEx );
411 else
412 fprintf( stderr, "%s could not be opened\n", aStr.GetBuffer() );
415 aBmpStm.Close();
418 if( nCRC )
420 ::std::map< sal_uInt64, ::std::vector< ByteString > >::iterator aFound( aFileNameMap.find( nCRC ) );
422 if( aFound != aFileNameMap.end() )
423 (*aFound).second.push_back( aStr );
424 else
426 ::std::vector< ByteString > aVector( 1, aStr );
427 aFileNameMap[ nCRC ] = aVector;
431 else
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 );
446 // write new entries
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 );
453 aStr += '\t';
454 aStr += aFileName;
456 aOStm.WriteLine( aStr );
458 // copy bitmap
459 if( rOutPath.Len() )
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, '/' ) );
472 aNewDir.MakeDir();
475 aNewDir += DirEntry( aFileName.GetToken( nTokenCount - 1, '/' ) );
476 aSrcFile.CopyTo( aNewDir, FSYS_ACTION_COPYFILE );
480 ++nFileCount;
483 fprintf(
484 stdout, "unique file count: %lu",
485 sal::static_int_cast< unsigned long >(nFileCount) );
489 // --------
490 // - Main -
491 // --------
493 int main( int nArgCount, char* ppArgs[] )
495 #ifdef UNX
496 static char aDisplayVar[ 1024 ];
498 strcpy( aDisplayVar, "DISPLAY=" );
499 putenv( aDisplayVar );
500 #endif
502 ::std::vector< String > aArgs;
503 BmpSum aBmpSum;
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 );