Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <stdio.h>
22 : #include <signal.h>
23 : #include <ctype.h>
24 :
25 : #include <rtl/strbuf.hxx>
26 : #include <tools/fsys.hxx>
27 : #include <tools/stream.hxx>
28 : #include <vcl/svapp.hxx>
29 : #include "svtools/filter.hxx"
30 :
31 : #define EXIT_NOERROR 0x00000000
32 : #define EXIT_COMMONERROR 0x00000001
33 : #define EXIT_INVALID_FILE 0x00000002
34 : #define EXIT_INVALID_GRAPHICFILTER 0x00000004
35 : #define EXIT_INVALID_INPUTGRAPHIC 0x00000008
36 : #define EXIT_OUTPUTERROR 0x00000010
37 :
38 : #define LOWERHEXTONUM( _def_Char ) (((_def_Char)<='9') ? ((_def_Char)-'0') : ((_def_Char)-'a'+10))
39 :
40 : // ----------
41 : // - G2GApp -
42 : // ----------
43 :
44 : class G2GApp
45 : {
46 : private:
47 :
48 : sal_uInt8 cExitCode;
49 :
50 : void ShowUsage();
51 : sal_Bool GetCommandOption( const ::std::vector< String >& rArgs, const String& rSwitch, String& rParam );
52 0 : void SetExitCode( sal_uInt8 cExit ) { if( ( EXIT_NOERROR == cExitCode ) || ( cExit != EXIT_NOERROR ) ) cExitCode = cExit; }
53 :
54 : virtual void Message( const String& rText, sal_uInt8 cExitCode = EXIT_NOERROR );
55 :
56 : public:
57 :
58 : G2GApp();
59 : virtual ~G2GApp();
60 :
61 : int Start( const ::std::vector< String >& rArgs );
62 : };
63 :
64 : // -----------------------------------------------------------------------
65 :
66 0 : G2GApp::G2GApp()
67 : {
68 0 : }
69 :
70 : // -----------------------------------------------------------------------
71 :
72 0 : G2GApp::~G2GApp()
73 : {
74 0 : }
75 :
76 : // -----------------------------------------------------------------------
77 :
78 0 : sal_Bool G2GApp::GetCommandOption( const ::std::vector< String >& rArgs, const String& rSwitch, String& rParam )
79 : {
80 0 : sal_Bool bRet = sal_False;
81 :
82 0 : for( int i = 0, nCount = rArgs.size(); ( i < nCount ) && !bRet; i++ )
83 : {
84 0 : rtl::OUString aTestStr( '-' );
85 :
86 0 : for( int n = 0; ( n < 2 ) && !bRet; n++ )
87 : {
88 0 : aTestStr += rSwitch;
89 :
90 0 : if( aTestStr.equalsIgnoreAsciiCase( rArgs[ i ] ) )
91 : {
92 0 : bRet = sal_True;
93 :
94 0 : if( i < ( nCount - 1 ) )
95 0 : rParam = rArgs[ i + 1 ];
96 : else
97 0 : rParam = String();
98 : }
99 :
100 0 : if( 0 == n )
101 0 : aTestStr = rtl::OUString('/');
102 : }
103 0 : }
104 :
105 0 : return bRet;
106 : }
107 :
108 : // -----------------------------------------------------------------------
109 :
110 0 : void G2GApp::Message( const String& rText, sal_uInt8 nExitCode )
111 : {
112 0 : if( EXIT_NOERROR != nExitCode )
113 0 : SetExitCode( nExitCode );
114 :
115 0 : rtl::OStringBuffer aText(rtl::OUStringToOString(rText, RTL_TEXTENCODING_UTF8));
116 0 : aText.append(RTL_CONSTASCII_STRINGPARAM("\r\n"));
117 0 : fprintf(stderr, "%s", aText.getStr());
118 0 : }
119 :
120 : // -----------------------------------------------------------------------------
121 :
122 0 : void G2GApp::ShowUsage()
123 : {
124 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( "Usage:" ) ) );
125 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( " g2g inputfile outputfile -format exportformat -filterpath path [ -# RRGGBB ]" ) ) );
126 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( "Options:" ) ) );
127 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( " -format short name of export filter to use ( e.g. gif, png, jpg, ... )" ) ) );
128 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( " -filterpath path to externally loaded filter libraries" ) ) );
129 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( " -# hex value of color to be set transparent in export file (optional)" ) ) );
130 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( "Examples:" ) ) );
131 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( " g2g /home/test.bmp /home/test.jpg -format jpg -filterpath /home/filter" ) ) );
132 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( " g2g /home/test.bmp /home/test.gif -format gif -filterpath /home/filter -# C0C0C0" ) ) );
133 0 : }
134 :
135 : // -----------------------------------------------------------------------------
136 :
137 0 : int G2GApp::Start( const ::std::vector< String >& rArgs )
138 : {
139 0 : size_t nCmdCount = rArgs.size();
140 :
141 0 : cExitCode = EXIT_NOERROR;
142 :
143 0 : if( nCmdCount >= 6 )
144 : {
145 0 : GraphicFilter aFilter( sal_False );
146 0 : String aInFile, aOutFile, aFilterStr, aFilterPath, aTransColStr;
147 0 : size_t nCurCmd = 0;
148 :
149 0 : aInFile = rArgs[ nCurCmd++ ];
150 0 : aOutFile = rArgs[ nCurCmd++ ];
151 0 : GetCommandOption( rArgs, rtl::OUString("format"), aFilterStr );
152 0 : GetCommandOption( rArgs, rtl::OUString("filterpath"), aFilterPath );
153 0 : GetCommandOption( rArgs, rtl::OUString('#'), aTransColStr );
154 :
155 0 : aFilter.SetFilterPath( aFilterPath );
156 :
157 0 : if( aInFile.Len() && aOutFile.Len() && aFilterStr.Len() )
158 : {
159 0 : const sal_uInt16 nExportFilter = aFilter.GetExportFormatNumberForShortName( aFilterStr );
160 :
161 0 : if( GRFILTER_FORMAT_NOTFOUND == nExportFilter )
162 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( "invalid graphic filter" ) ), EXIT_INVALID_GRAPHICFILTER );
163 : else
164 : {
165 0 : if( DirEntry( aInFile ).Exists() )
166 : {
167 0 : SvFileStream aInStm( aInFile, STREAM_READ );
168 0 : Graphic aGraphic;
169 0 : const GfxLink aGfxLink;
170 :
171 0 : aGraphic.SetLink( aGfxLink );
172 :
173 0 : if( aFilter.ImportGraphic( aGraphic, aInFile, aInStm ) == GRFILTER_OK )
174 : {
175 0 : SvFileStream aOutStm( aOutFile, STREAM_WRITE | STREAM_TRUNC );
176 :
177 0 : if( ( aTransColStr.Len() == 6 ) && aFilter.IsExportPixelFormat( nExportFilter ) )
178 : {
179 : rtl::OString aHexStr(rtl::OUStringToOString(aTransColStr, RTL_TEXTENCODING_ASCII_US).
180 0 : toAsciiLowerCase());
181 0 : sal_Bool bHex = sal_True;
182 :
183 0 : for( sal_uInt16 i = 0; ( i < 6 ) && bHex; i++ )
184 0 : if( !isxdigit( aHexStr[i] ) )
185 0 : bHex = sal_False;
186 :
187 0 : if( bHex )
188 : {
189 0 : const sal_uInt8 cTransR = ( LOWERHEXTONUM( aHexStr[0] ) << 4 ) | LOWERHEXTONUM( aHexStr[1] );
190 0 : const sal_uInt8 cTransG = ( LOWERHEXTONUM( aHexStr[2] ) << 4 ) | LOWERHEXTONUM( aHexStr[3] );
191 0 : const sal_uInt8 cTransB = ( LOWERHEXTONUM( aHexStr[4] ) << 4 ) | LOWERHEXTONUM( aHexStr[5] );
192 :
193 0 : BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
194 0 : Bitmap aOldBmp( aBmpEx.GetBitmap() );
195 0 : Bitmap aOldMask( aBmpEx.GetMask() );
196 0 : Bitmap aNewMask( aOldBmp.CreateMask( Color( cTransR, cTransG, cTransB ) ) );
197 :
198 0 : if( !aOldMask.IsEmpty() )
199 0 : aNewMask.CombineSimple( aOldMask, BMP_COMBINE_OR );
200 :
201 0 : aGraphic = BitmapEx( aOldBmp, aNewMask );
202 0 : }
203 : }
204 :
205 0 : aFilter.ExportGraphic( aGraphic, aOutFile, aOutStm, nExportFilter );
206 :
207 0 : if( aOutStm.GetError() )
208 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( "could not write output file" ) ), EXIT_OUTPUTERROR );
209 : }
210 : else
211 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( "could import graphic" ) ), EXIT_INVALID_INPUTGRAPHIC );
212 : }
213 : else
214 0 : Message( String( RTL_CONSTASCII_USTRINGPARAM( "invalid file(s)" ) ), EXIT_INVALID_FILE );
215 : }
216 0 : }
217 : }
218 : else
219 0 : ShowUsage();
220 :
221 0 : return cExitCode;
222 : }
223 :
224 : // --------
225 : // - Main -
226 : // --------
227 :
228 0 : int main( int nArgCount, char* ppArgs[] )
229 : {
230 0 : ::std::vector< String > aArgs;
231 0 : G2GApp aG2GApp;
232 :
233 0 : InitVCL();
234 :
235 0 : for( int i = 1; i < nArgCount; i++ )
236 0 : aArgs.push_back( String( ppArgs[ i ], RTL_TEXTENCODING_ASCII_US ) );
237 :
238 0 : return aG2GApp.Start( aArgs );
239 : }
240 :
241 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|