|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Mifconv MIF converters class. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "mifconv.h" |
|
20 #include "mifconv_mifconverter.h" |
|
21 #include "mifconv_util.h" |
|
22 #include "mifconv_exception.h" |
|
23 #include "mifconv_argumentmanager.h" |
|
24 |
|
25 // File versions: |
|
26 // V1 - first version. |
|
27 // V2 - stores information if icon location (MIF/MBM) inside the MIF file (bitmap offsets array). |
|
28 // This way, icon IDs in MBG header can be always the same regardless of which icons are in MIF |
|
29 // file and which in MBM file. |
|
30 static const int KFileVersion(2); |
|
31 static const int KIconVersion(1); |
|
32 |
|
33 static const int FileHeaderSizeInBytes = 4*4; |
|
34 static const int IconHeaderSizeInBytes = 4*8; |
|
35 static const int KUidAvkonMultiIconFile(0x034232342); |
|
36 static const int KUidAvkonMultiIcon(0x034232343); |
|
37 |
|
38 //static const int IconFormatType_BMP(0); |
|
39 //static const int IconFormatType_SVG(1); |
|
40 |
|
41 static const unsigned int svgbSignatureLow (0x03FA56CC); //66737868 |
|
42 static const unsigned int svgbSignatureHigh(0x03FA56CF); //66737871 |
|
43 |
|
44 static const unsigned int nvgSignatureLow (0x0067766E); //('n'+'v'+'g'+0) |
|
45 static const unsigned int nvgSignatureHigh(0xFF67766E); //('n'+'v'+'g'+255) |
|
46 |
|
47 /** |
|
48 * |
|
49 */ |
|
50 MifConvMifConverter::MifConvMifConverter() |
|
51 { |
|
52 MifConvArgumentManager* argMgr = MifConvArgumentManager::Instance(); |
|
53 iTargetFilename = argMgr->TargetFile(); |
|
54 } |
|
55 |
|
56 /** |
|
57 * |
|
58 */ |
|
59 MifConvMifConverter::~MifConvMifConverter() |
|
60 { |
|
61 // Delete file contents |
|
62 for( StringPtrVector::iterator i = iContentPointers.begin(); i != iContentPointers.end(); ++i ) |
|
63 { |
|
64 delete[] *i; |
|
65 } |
|
66 } |
|
67 |
|
68 /** |
|
69 * |
|
70 */ |
|
71 void MifConvMifConverter::Init() |
|
72 { |
|
73 CleanupTargetFiles(); |
|
74 } |
|
75 |
|
76 /** |
|
77 * |
|
78 */ |
|
79 void MifConvMifConverter::CleanupTargetFiles() |
|
80 { |
|
81 if( MifConvUtil::FileExists(iTargetFilename) ) |
|
82 { |
|
83 // Try to remove file MIFCONV_MAX_REMOVE_TRIES times, no exception in case of failure: |
|
84 MifConvUtil::RemoveFile(iTargetFilename, MIFCONV_MAX_REMOVE_TRIES, true); |
|
85 } |
|
86 } |
|
87 |
|
88 /** |
|
89 * |
|
90 */ |
|
91 void MifConvMifConverter::AppendFile( const MifConvSourceFile& sourcefile ) |
|
92 { |
|
93 if( MifConvUtil::FileExtension( sourcefile.Filename() ) == BMP_FILE_EXTENSION || |
|
94 MifConvUtil::FileExtension( sourcefile.Filename() ) == SVG_FILE_EXTENSION || |
|
95 MifConvUtil::FileExtension( sourcefile.Filename() ) == SVGB_BINARY_FILE_EXTENSION ) |
|
96 { |
|
97 iSourceFiles.push_back( sourcefile ); |
|
98 } |
|
99 } |
|
100 |
|
101 void MifConvMifConverter::Convert() |
|
102 { |
|
103 ReadFileContents(); |
|
104 cout << "Writing mif: " << MifConvArgumentManager::Instance()->TargetFile() << endl; |
|
105 ConvertToMif(); |
|
106 } |
|
107 |
|
108 void MifConvMifConverter::ReadFileContents() |
|
109 { |
|
110 for( MifConvSourceFileList::iterator i = iSourceFiles.begin(); i != iSourceFiles.end(); ++i ) |
|
111 { |
|
112 // Just read the contents of the .svgb files |
|
113 if( MifConvUtil::FileExtension( i->Filename() ) != BMP_FILE_EXTENSION ) |
|
114 { |
|
115 if( MifConvUtil::FileExists(i->Filename()) == false ) |
|
116 { |
|
117 THROW_ERROR_COMMON("Unable to open file for reading! " + i->Filename(), MifConvString(__FILE__), __LINE__ ); |
|
118 } |
|
119 cout << "Loading file: " << i->Filename() << endl; |
|
120 MifConvFileData retVal = MifConvUtil::FileContents(i->Filename()); |
|
121 iContentPointers.push_back(retVal.first); // Save pointer for deleting it later |
|
122 i->SetContent(retVal.first, retVal.second); |
|
123 } |
|
124 } |
|
125 } |
|
126 |
|
127 |
|
128 void MifConvMifConverter::Cleanup(bool err) |
|
129 { |
|
130 CleanupTempFiles(); |
|
131 if( err ) |
|
132 { |
|
133 CleanupTargetFiles(); |
|
134 } |
|
135 } |
|
136 |
|
137 void MifConvMifConverter::ConvertToMif() |
|
138 { |
|
139 try { |
|
140 OpenTargetFile(); |
|
141 } |
|
142 catch( MifConvException& e ) |
|
143 { |
|
144 // If file creation/opening was not successful, give warning and return: |
|
145 MifConvString debugStr("WARNING: Target file " + iTargetFilename + " cannot be opened for writing."); |
|
146 cout << debugStr << endl; |
|
147 MifConvUtil::DebugLog(debugStr); |
|
148 return; |
|
149 } |
|
150 WriteTargetHeader(); |
|
151 WriteIconArray(); |
|
152 WriteIcons(); |
|
153 } |
|
154 |
|
155 void MifConvMifConverter::OpenTargetFile() |
|
156 { |
|
157 iTargetFile.open( iTargetFilename.c_str(), ios::out|ios::binary ); |
|
158 |
|
159 if (!iTargetFile.is_open()) |
|
160 { |
|
161 // Create path if it does not exist. |
|
162 MifConvUtil::EnsurePathExists(iTargetFilename, true); |
|
163 iTargetFile.clear(); |
|
164 iTargetFile.open( iTargetFilename.c_str(), ios::out|ios::binary ); |
|
165 } |
|
166 if (!iTargetFile.is_open()) |
|
167 { |
|
168 THROW_ERROR_COMMON("Cannot write to file! " + iTargetFilename, MifConvString(__FILE__), __LINE__); |
|
169 } |
|
170 } |
|
171 |
|
172 void MifConvMifConverter::WriteTargetHeader() |
|
173 { |
|
174 size_t arraySize = iSourceFiles.size() * 2; |
|
175 int offset = FileHeaderSizeInBytes; |
|
176 iTargetFile.write( (char*) &KUidAvkonMultiIconFile, 4 ); |
|
177 iTargetFile.write( (char*) &KFileVersion, 4 ); |
|
178 iTargetFile.write( (char*) &offset, 4 ); |
|
179 iTargetFile.write( (char*) &arraySize, 4 ); |
|
180 } |
|
181 |
|
182 void MifConvMifConverter::CleanupTempFiles() |
|
183 { |
|
184 } |
|
185 |
|
186 void MifConvMifConverter::WriteIcons() |
|
187 { |
|
188 for( MifConvSourceFileList::iterator i = iSourceFiles.begin(); i != iSourceFiles.end(); ++i ) |
|
189 { |
|
190 if( i->ContentLength() > 0 ) |
|
191 { |
|
192 WriteIconHeader(*i); |
|
193 WriteIconData(*i); |
|
194 } |
|
195 } |
|
196 } |
|
197 |
|
198 MifConvDefs::IconFormatType MifConvMifConverter::ReadIconBinaryType(const MifConvSourceFile& src) |
|
199 { |
|
200 MifConvDefs::IconFormatType ret = MifConvDefs::IconFormatType_SVG; |
|
201 |
|
202 if( src.ContentLength() >= 4 ) |
|
203 { |
|
204 const char* iconData = src.Content(); |
|
205 |
|
206 if( iconData[0] == 'n' && |
|
207 iconData[1] == 'v' && |
|
208 iconData[2] == 'g' ) |
|
209 { |
|
210 ret = MifConvDefs::IconFormatType_NVG; |
|
211 } |
|
212 } |
|
213 |
|
214 return ret; |
|
215 } |
|
216 |
|
217 void MifConvMifConverter::WriteIconHeader(const MifConvSourceFile& src) |
|
218 { |
|
219 int type = 0; |
|
220 if( MifConvUtil::FileExtension(src.Filename()) == BMP_FILE_EXTENSION ) |
|
221 type = MifConvDefs::IconFormatType_BMP; |
|
222 else |
|
223 type = ReadIconBinaryType(src); |
|
224 //type = IconFormatType_SVG; |
|
225 |
|
226 int animated = (int) src.IsAnimated(); |
|
227 int dataLen = src.ContentLength(); |
|
228 int depth = src.DisplayMode(); |
|
229 int mask = src.MaskDisplayMode(); |
|
230 int dataoffset = IconHeaderSizeInBytes; // 8 = number of writes in this method. |
|
231 |
|
232 iTargetFile.write((char*)&KUidAvkonMultiIcon, 4); // 1 |
|
233 iTargetFile.write((char*)&KIconVersion, 4); // 2 |
|
234 iTargetFile.write((char*)&dataoffset, 4); // 3 |
|
235 iTargetFile.write((char*)&dataLen, 4); // 4 |
|
236 iTargetFile.write((char*)&type, 4); // 5 |
|
237 iTargetFile.write((char*)&depth, 4); // 6 |
|
238 iTargetFile.write((char*)&animated, 4); // 7 |
|
239 iTargetFile.write((char*)&mask, 4); // 8 |
|
240 } |
|
241 |
|
242 void MifConvMifConverter::WriteIconData(const MifConvSourceFile& src) |
|
243 { |
|
244 if( src.Content() ) |
|
245 { |
|
246 iTargetFile.write(src.Content(), src.ContentLength()); |
|
247 } |
|
248 } |
|
249 |
|
250 /** |
|
251 * |
|
252 */ |
|
253 void MifConvMifConverter::WriteIconArray() |
|
254 { |
|
255 int offset = (int) FileHeaderSizeInBytes + (int)iSourceFiles.size()*4*2*2; |
|
256 MifConvSourceFileList::iterator i = iSourceFiles.begin(); |
|
257 |
|
258 int mbmIndex = 0; |
|
259 int zero = 0; |
|
260 |
|
261 for( ; i != iSourceFiles.end(); ++i ) |
|
262 { |
|
263 // MIF icon |
|
264 if( MifConvUtil::FileExtension(i->Filename()) != BMP_FILE_EXTENSION ) |
|
265 { |
|
266 int length = i->ContentLength() + IconHeaderSizeInBytes; |
|
267 iTargetFile.write( (char*) &offset, 4 ); |
|
268 iTargetFile.write( (char*) &length, 4 ); |
|
269 // same information for the mask... |
|
270 iTargetFile.write( (char*) &offset, 4 ); |
|
271 iTargetFile.write( (char*) &length, 4 ); |
|
272 |
|
273 offset += length; |
|
274 } |
|
275 // MBM icon |
|
276 else |
|
277 { |
|
278 iTargetFile.write( (char*) &mbmIndex, 4 ); |
|
279 iTargetFile.write( (char*) &zero, 4 ); |
|
280 |
|
281 // Masked MBM icon -> There is own MBM index for the mask. |
|
282 if(i->MaskDepth() != IconMaskDepth_Undefined ) |
|
283 { |
|
284 mbmIndex--; |
|
285 } |
|
286 |
|
287 iTargetFile.write( (char*) &mbmIndex, 4 ); |
|
288 iTargetFile.write( (char*) &zero, 4 ); |
|
289 |
|
290 // MBM incides are coded as negative in the 'offset' field, |
|
291 // so that they can be easily separated from the actual MIF offsets. |
|
292 mbmIndex--; |
|
293 } |
|
294 } |
|
295 } |