summaryrefslogtreecommitdiff
path: root/libopie2
Unidiff
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiemm/opieexif.cpp54
-rw-r--r--libopie2/opiemm/opieexif.h7
2 files changed, 12 insertions, 49 deletions
diff --git a/libopie2/opiemm/opieexif.cpp b/libopie2/opiemm/opieexif.cpp
index 0860ea8..de49937 100644
--- a/libopie2/opiemm/opieexif.cpp
+++ b/libopie2/opiemm/opieexif.cpp
@@ -184,193 +184,192 @@ int ExifData::ReadJpegSections (QFile & infile, ReadMode_t ReadMode)
184 } 184 }
185 185
186 Sections[SectionsRead].Size = itemlen; 186 Sections[SectionsRead].Size = itemlen;
187 187
188 Data = (uchar *)malloc(itemlen+1); // Add 1 to allow sticking a 0 at the end. 188 Data = (uchar *)malloc(itemlen+1); // Add 1 to allow sticking a 0 at the end.
189 Sections[SectionsRead].Data = Data; 189 Sections[SectionsRead].Data = Data;
190 190
191 // Store first two pre-read bytes. 191 // Store first two pre-read bytes.
192 Data[0] = (uchar)lh; 192 Data[0] = (uchar)lh;
193 Data[1] = (uchar)ll; 193 Data[1] = (uchar)ll;
194 194
195 got = infile.readBlock((char*)Data+2, itemlen-2); // Read the whole section. 195 got = infile.readBlock((char*)Data+2, itemlen-2); // Read the whole section.
196 if (( unsigned ) got != itemlen-2){ 196 if (( unsigned ) got != itemlen-2){
197 return false; 197 return false;
198 } 198 }
199 SectionsRead++; 199 SectionsRead++;
200 200
201 switch(marker){ 201 switch(marker){
202 202
203 case M_SOS: // stop before hitting compressed data 203 case M_SOS: // stop before hitting compressed data
204 // If reading entire image is requested, read the rest of the data. 204 // If reading entire image is requested, read the rest of the data.
205 if (ReadMode & READ_IMAGE){ 205 if (ReadMode & READ_IMAGE){
206 unsigned long size; 206 unsigned long size;
207 207
208 size = QMAX( 0ul, infile.size()-infile.at() ); 208 size = QMAX( 0ul, infile.size()-infile.at() );
209 Data = (uchar *)malloc(size); 209 Data = (uchar *)malloc(size);
210 if (Data == NULL){ 210 if (Data == NULL){
211 return false; 211 return false;
212 } 212 }
213 213
214 got = infile.readBlock((char*)Data, size); 214 got = infile.readBlock((char*)Data, size);
215 if (( unsigned ) got != size){ 215 if (( unsigned ) got != size){
216 return false; 216 return false;
217 } 217 }
218 218
219 Sections[SectionsRead].Data = Data; 219 Sections[SectionsRead].Data = Data;
220 Sections[SectionsRead].Size = size; 220 Sections[SectionsRead].Size = size;
221 Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER; 221 Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER;
222 SectionsRead ++; 222 SectionsRead ++;
223 //HaveAll = 1; 223 //HaveAll = 1;
224 } 224 }
225 return true; 225 return true;
226 226
227 case M_EOI: // in case it's a tables-only JPEG stream 227 case M_EOI: // in case it's a tables-only JPEG stream
228 owarn << "No image in jpeg!" << oendl; 228 owarn << "No image in jpeg!" << oendl;
229 return false; 229 return false;
230 230
231 case M_COM: // Comment section 231 case M_COM: // Comment section
232 // pieczy 2002-02-12 232 // pieczy 2002-02-12
233 // now the User comment goes to UserComment 233 // now the User comment goes to UserComment
234 // so we can store a Comment section also in READ_EXIF mode 234 // so we can store a Comment section also in READ_EXIF mode
235 process_COM(Data, itemlen); 235 process_COM(Data, itemlen);
236 break; 236 break;
237 237
238 case M_JFIF: 238 case M_JFIF:
239 // Regular jpegs always have this tag, exif images have the exif 239 // Regular jpegs always have this tag, exif images have the exif
240 // marker instead, althogh ACDsee will write images with both markers. 240 // marker instead, althogh ACDsee will write images with both markers.
241 // this program will re-create this marker on absence of exif marker. 241 // this program will re-create this marker on absence of exif marker.
242 // hence no need to keep the copy from the file. 242 // hence no need to keep the copy from the file.
243 free(Sections[--SectionsRead].Data); 243 free(Sections[--SectionsRead].Data);
244 break; 244 break;
245 245
246 case M_EXIF: 246 case M_EXIF:
247 // Seen files from some 'U-lead' software with Vivitar scanner 247 // Seen files from some 'U-lead' software with Vivitar scanner
248 // that uses marker 31 for non exif stuff. Thus make sure 248 // that uses marker 31 for non exif stuff. Thus make sure
249 // it says 'Exif' in the section before treating it as exif. 249 // it says 'Exif' in the section before treating it as exif.
250 if ((ReadMode & READ_EXIF) && memcmp(Data+2, "Exif", 4) == 0){ 250 if ((ReadMode & READ_EXIF) && memcmp(Data+2, "Exif", 4) == 0){
251 process_EXIF((uchar *)Data, itemlen); 251 process_EXIF((uchar *)Data, itemlen);
252 }else{ 252 }else{
253 // Discard this section. 253 // Discard this section.
254 free(Sections[--SectionsRead].Data); 254 free(Sections[--SectionsRead].Data);
255 } 255 }
256 break; 256 break;
257 257
258 case M_SOF0: 258 case M_SOF0:
259 case M_SOF1: 259 case M_SOF1:
260 case M_SOF2: 260 case M_SOF2:
261 case M_SOF3: 261 case M_SOF3:
262 case M_SOF5: 262 case M_SOF5:
263 case M_SOF6: 263 case M_SOF6:
264 case M_SOF7: 264 case M_SOF7:
265 case M_SOF9: 265 case M_SOF9:
266 case M_SOF10: 266 case M_SOF10:
267 case M_SOF11: 267 case M_SOF11:
268 case M_SOF13: 268 case M_SOF13:
269 case M_SOF14: 269 case M_SOF14:
270 case M_SOF15: 270 case M_SOF15:
271 process_SOFn(Data, marker); 271 process_SOFn(Data, marker);
272 default: 272 default:
273 break; 273 break;
274 break; 274 break;
275 } 275 }
276 } 276 }
277 return true; 277 return true;
278} 278}
279 279
280
281//-------------------------------------------------------------------------- 280//--------------------------------------------------------------------------
282// Discard read data. 281// Discard read data.
283//-------------------------------------------------------------------------- 282//--------------------------------------------------------------------------
284void ExifData::DiscardData(void) 283void ExifData::DiscardData(void)
285{ 284{
286 for (int a=0; a < SectionsRead; a++) 285 for (int a=0; a < SectionsRead; a++)
287 free(Sections[a].Data); 286 free(Sections[a].Data);
288 SectionsRead = 0; 287 SectionsRead = 0;
289} 288}
290 289
291//-------------------------------------------------------------------------- 290//--------------------------------------------------------------------------
292// Convert a 16 bit unsigned value from file's native byte order 291// Convert a 16 bit unsigned value from file's native byte order
293//-------------------------------------------------------------------------- 292//--------------------------------------------------------------------------
294int ExifData::Get16u(void * Short) 293int ExifData::Get16u(void * Short)
295{ 294{
296 if (MotorolaOrder){ 295 if (MotorolaOrder){
297 return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1]; 296 return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1];
298 }else{ 297 }else{
299 return (((uchar *)Short)[1] << 8) | ((uchar *)Short)[0]; 298 return (((uchar *)Short)[1] << 8) | ((uchar *)Short)[0];
300 } 299 }
301} 300}
302 301
303//-------------------------------------------------------------------------- 302//--------------------------------------------------------------------------
304// Convert a 32 bit signed value from file's native byte order 303// Convert a 32 bit signed value from file's native byte order
305//-------------------------------------------------------------------------- 304//--------------------------------------------------------------------------
306int ExifData::Get32s(void * Long) 305int ExifData::Get32s(void * Long)
307{ 306{
308 if (MotorolaOrder){ 307 if (MotorolaOrder){
309 return ((( char *)Long)[0] << 24) | (((uchar *)Long)[1] << 16) 308 return ((( char *)Long)[0] << 24) | (((uchar *)Long)[1] << 16)
310 | (((uchar *)Long)[2] << 8 ) | (((uchar *)Long)[3] << 0 ); 309 | (((uchar *)Long)[2] << 8 ) | (((uchar *)Long)[3] << 0 );
311 }else{ 310 }else{
312 return ((( char *)Long)[3] << 24) | (((uchar *)Long)[2] << 16) 311 return ((( char *)Long)[3] << 24) | (((uchar *)Long)[2] << 16)
313 | (((uchar *)Long)[1] << 8 ) | (((uchar *)Long)[0] << 0 ); 312 | (((uchar *)Long)[1] << 8 ) | (((uchar *)Long)[0] << 0 );
314 } 313 }
315} 314}
316 315
317//-------------------------------------------------------------------------- 316//--------------------------------------------------------------------------
318// Convert a 32 bit unsigned value from file's native byte order 317// Convert a 32 bit unsigned value from file's native byte order
319//-------------------------------------------------------------------------- 318//--------------------------------------------------------------------------
320unsigned ExifData::Get32u(void * Long) 319unsigned ExifData::Get32u(void * Long)
321{ 320{
322 return (unsigned)Get32s(Long) & 0xffffffff; 321 return (unsigned)Get32s(Long) & 0xffffffff;
323} 322}
324 323
325//-------------------------------------------------------------------------- 324//--------------------------------------------------------------------------
326// Evaluate number, be it int, rational, or float from directory. 325// Evaluate number, be it int, rational, or float from directory.
327//-------------------------------------------------------------------------- 326//--------------------------------------------------------------------------
328double ExifData::ConvertAnyFormat(void * ValuePtr, int Format) 327double ExifData::ConvertAnyFormat(void * ValuePtr, int Format)
329{ 328{
330 double Value; 329 double Value;
331 Value = 0; 330 Value = 0;
332 331
333 switch(Format){ 332 switch(Format){
334 case FMT_SBYTE: Value = *(signed char *)ValuePtr; break; 333 case FMT_SBYTE: Value = *(signed char *)ValuePtr; break;
335 case FMT_BYTE: Value = *(uchar *)ValuePtr; break; 334 case FMT_BYTE: Value = *(uchar *)ValuePtr; break;
336 335
337 case FMT_USHORT: Value = Get16u(ValuePtr); break; 336 case FMT_USHORT: Value = Get16u(ValuePtr); break;
338 337
339 case FMT_ULONG: Value = Get32u(ValuePtr); break; 338 case FMT_ULONG: Value = Get32u(ValuePtr); break;
340 339
341 case FMT_URATIONAL: 340 case FMT_URATIONAL:
342 case FMT_SRATIONAL: 341 case FMT_SRATIONAL:
343 { 342 {
344 int Num,Den; 343 int Num,Den;
345 Num = Get32s(ValuePtr); 344 Num = Get32s(ValuePtr);
346 Den = Get32s(4+(char *)ValuePtr); 345 Den = Get32s(4+(char *)ValuePtr);
347 if (Den == 0){ 346 if (Den == 0){
348 Value = 0; 347 Value = 0;
349 }else{ 348 }else{
350 Value = (double)Num/Den; 349 Value = (double)Num/Den;
351 } 350 }
352 break; 351 break;
353 } 352 }
354 353
355 case FMT_SSHORT: Value = (signed short)Get16u(ValuePtr); break; 354 case FMT_SSHORT: Value = (signed short)Get16u(ValuePtr); break;
356 case FMT_SLONG: Value = Get32s(ValuePtr); break; 355 case FMT_SLONG: Value = Get32s(ValuePtr); break;
357 356
358 // Not sure if this is correct (never seen float used in Exif format) 357 // Not sure if this is correct (never seen float used in Exif format)
359 case FMT_SINGLE: Value = (double)*(float *)ValuePtr; break; 358 case FMT_SINGLE: Value = (double)*(float *)ValuePtr; break;
360 case FMT_DOUBLE: Value = *(double *)ValuePtr; break; 359 case FMT_DOUBLE: Value = *(double *)ValuePtr; break;
361 } 360 }
362 return Value; 361 return Value;
363} 362}
364 363
365//-------------------------------------------------------------------------- 364//--------------------------------------------------------------------------
366// Process one of the nested EXIF directories. 365// Process one of the nested EXIF directories.
367//-------------------------------------------------------------------------- 366//--------------------------------------------------------------------------
368void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength) 367void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength)
369{ 368{
370 int de; 369 int de;
371 int a; 370 int a;
372 int NumDirEntries; 371 int NumDirEntries;
373 unsigned ThumbnailOffset = 0; 372 unsigned ThumbnailOffset = 0;
374 unsigned ThumbnailSize = 0; 373 unsigned ThumbnailSize = 0;
375 374
376 NumDirEntries = Get16u(DirStart); 375 NumDirEntries = Get16u(DirStart);
@@ -916,280 +915,237 @@ static QImage rotate_90_8( const QImage &img ) {
916 return dest; 915 return dest;
917} 916}
918 917
919static QImage rotate_90_all( const QImage& img ) { 918static QImage rotate_90_all( const QImage& img ) {
920 dest.create(img.height(), img.width(), img.depth()); 919 dest.create(img.height(), img.width(), img.depth());
921 for ( y=0; y < img.height(); ++y ) { 920 for ( y=0; y < img.height(); ++y ) {
922 srcData = (unsigned int *)img.scanLine(y); 921 srcData = (unsigned int *)img.scanLine(y);
923 for ( x=0; x < img.width(); ++x ) { 922 for ( x=0; x < img.width(); ++x ) {
924 destData = (unsigned int *)dest.scanLine(x); 923 destData = (unsigned int *)dest.scanLine(x);
925 destData[img.height()-y-1] = srcData[x]; 924 destData[img.height()-y-1] = srcData[x];
926 } 925 }
927 } 926 }
928 927
929 return dest; 928 return dest;
930} 929}
931 930
932 931
933static QImage rotate_90( const QImage & img ) { 932static QImage rotate_90( const QImage & img ) {
934 if ( img.depth() > 8) 933 if ( img.depth() > 8)
935 return rotate_90_all( img ); 934 return rotate_90_all( img );
936 else 935 else
937 return rotate_90_8( img ); 936 return rotate_90_8( img );
938} 937}
939 938
940static QImage rotate_180_all( const QImage& img ) { 939static QImage rotate_180_all( const QImage& img ) {
941 dest.create(img.width(), img.height(), img.depth()); 940 dest.create(img.width(), img.height(), img.depth());
942 for ( y=0; y < img.height(); ++y ){ 941 for ( y=0; y < img.height(); ++y ){
943 srcData = (unsigned int *)img.scanLine(y); 942 srcData = (unsigned int *)img.scanLine(y);
944 destData = (unsigned int *)dest.scanLine(img.height()-y-1); 943 destData = (unsigned int *)dest.scanLine(img.height()-y-1);
945 for ( x=0; x < img.width(); ++x ) 944 for ( x=0; x < img.width(); ++x )
946 destData[img.width()-x-1] = srcData[x]; 945 destData[img.width()-x-1] = srcData[x];
947 } 946 }
948 return dest; 947 return dest;
949} 948}
950 949
951static QImage rotate_180_8( const QImage& img ) { 950static QImage rotate_180_8( const QImage& img ) {
952 dest.create(img.width(), img.height(), img.depth()); 951 dest.create(img.width(), img.height(), img.depth());
953 dest.setNumColors(img.numColors()); 952 dest.setNumColors(img.numColors());
954 srcTable = (unsigned int *)img.colorTable(); 953 srcTable = (unsigned int *)img.colorTable();
955 destTable = (unsigned int *)dest.colorTable(); 954 destTable = (unsigned int *)dest.colorTable();
956 for ( x=0; x < img.numColors(); ++x ) 955 for ( x=0; x < img.numColors(); ++x )
957 destTable[x] = srcTable[x]; 956 destTable[x] = srcTable[x];
958 for ( y=0; y < img.height(); ++y ){ 957 for ( y=0; y < img.height(); ++y ){
959 srcData8 = (unsigned char *)img.scanLine(y); 958 srcData8 = (unsigned char *)img.scanLine(y);
960 destData8 = (unsigned char *)dest.scanLine(img.height()-y-1); 959 destData8 = (unsigned char *)dest.scanLine(img.height()-y-1);
961 for ( x=0; x < img.width(); ++x ) 960 for ( x=0; x < img.width(); ++x )
962 destData8[img.width()-x-1] = srcData8[x]; 961 destData8[img.width()-x-1] = srcData8[x];
963 } 962 }
964 return dest; 963 return dest;
965} 964}
966 965
967static QImage rotate_180( const QImage& img ) { 966static QImage rotate_180( const QImage& img ) {
968 if ( img.depth() > 8 ) 967 if ( img.depth() > 8 )
969 return rotate_180_all( img ); 968 return rotate_180_all( img );
970 else 969 else
971 return rotate_180_8( img ); 970 return rotate_180_8( img );
972} 971}
973 972
974 973
975static QImage rotate_270_8( const QImage& img ) { 974static QImage rotate_270_8( const QImage& img ) {
976 dest.create(img.height(), img.width(), img.depth()); 975 dest.create(img.height(), img.width(), img.depth());
977 dest.setNumColors(img.numColors()); 976 dest.setNumColors(img.numColors());
978 srcTable = (unsigned int *)img.colorTable(); 977 srcTable = (unsigned int *)img.colorTable();
979 destTable = (unsigned int *)dest.colorTable(); 978 destTable = (unsigned int *)dest.colorTable();
980 for ( x=0; x < img.numColors(); ++x ) 979 for ( x=0; x < img.numColors(); ++x )
981 destTable[x] = srcTable[x]; 980 destTable[x] = srcTable[x];
982 for ( y=0; y < img.height(); ++y ){ 981 for ( y=0; y < img.height(); ++y ){
983 srcData8 = (unsigned char *)img.scanLine(y); 982 srcData8 = (unsigned char *)img.scanLine(y);
984 for ( x=0; x < img.width(); ++x ){ 983 for ( x=0; x < img.width(); ++x ){
985 destData8 = (unsigned char *)dest.scanLine(img.width()-x-1); 984 destData8 = (unsigned char *)dest.scanLine(img.width()-x-1);
986 destData8[y] = srcData8[x]; 985 destData8[y] = srcData8[x];
987 } 986 }
988 } 987 }
989 988
990 return dest; 989 return dest;
991} 990}
992 991
993static QImage rotate_270_all( const QImage& img ) { 992static QImage rotate_270_all( const QImage& img ) {
994 dest.create(img.height(), img.width(), img.depth()); 993 dest.create(img.height(), img.width(), img.depth());
995 for ( y=0; y < img.height(); ++y ){ 994 for ( y=0; y < img.height(); ++y ){
996 srcData = (unsigned int *)img.scanLine(y); 995 srcData = (unsigned int *)img.scanLine(y);
997 for ( x=0; x < img.width(); ++x ){ 996 for ( x=0; x < img.width(); ++x ){
998 destData = (unsigned int *)dest.scanLine(img.width()-x-1); 997 destData = (unsigned int *)dest.scanLine(img.width()-x-1);
999 destData[y] = srcData[x]; 998 destData[y] = srcData[x];
1000 } 999 }
1001 } 1000 }
1002 return dest; 1001 return dest;
1003} 1002}
1004 1003
1005static QImage rotate_270( const QImage& img ) { 1004static QImage rotate_270( const QImage& img ) {
1006 if ( img.depth() > 8 ) 1005 if ( img.depth() > 8 )
1007 return rotate_270_all( img ); 1006 return rotate_270_all( img );
1008 else 1007 else
1009 return rotate_270_8( img ); 1008 return rotate_270_8( img );
1010} 1009}
1011 1010
1012 1011QString ExifData::color_mode_to_string( bool b ) {
1013static QString color_mode_to_string( bool b ) {
1014 return b ? QObject::tr( "Colormode: Color\n" ) : QObject::tr( "Colormode: Black and white\n" ); 1012 return b ? QObject::tr( "Colormode: Color\n" ) : QObject::tr( "Colormode: Black and white\n" );
1015} 1013}
1016 1014
1017static QString compression_to_string( int level ) { 1015QString ExifData::compression_to_string( int level ) {
1018 QString str; 1016 QString str;
1019 switch( level ) { 1017 switch( level ) {
1020 case 1: 1018 case 1:
1021 str = QObject::tr( "Basic" ); 1019 str = QObject::tr( "Basic" );
1022 break; 1020 break;
1023 case 2: 1021 case 2:
1024 str = QObject::tr( "Normal" ); 1022 str = QObject::tr( "Normal" );
1025 break; 1023 break;
1026 case 4: 1024 case 4:
1027 str = QObject::tr( "Fine" ); 1025 str = QObject::tr( "Fine" );
1028 break; 1026 break;
1029 default: 1027 default:
1030 str = QObject::tr( "Unknown" ); 1028 str = QObject::tr( "Unknown" );
1031 1029
1032 } 1030 }
1033 return QObject::tr("Quality: %1\n").arg(str); 1031 return QObject::tr("Quality: %1\n").arg(str);
1034} 1032}
1035 1033
1036 1034QString ExifData::white_balance_string( int i ) {
1037static QDateTime parseDateTime( const QString& string )
1038{
1039 QDateTime dt;
1040 if ( string.length() != 19 )
1041 return dt;
1042
1043 QString year = string.left( 4 );
1044 QString month = string.mid( 5, 2 );
1045 QString day = string.mid( 8, 2 );
1046 QString hour = string.mid( 11, 2 );
1047 QString minute = string.mid( 14, 2 );
1048 QString seconds = string.mid( 18, 2 );
1049
1050 bool ok;
1051 bool allOk = true;
1052 int y = year.toInt( &ok );
1053 allOk &= ok;
1054
1055 int mo = month.toInt( &ok );
1056 allOk &= ok;
1057
1058 int d = day.toInt( &ok );
1059 allOk &= ok;
1060
1061 int h = hour.toInt( &ok );
1062 allOk &= ok;
1063
1064 int mi = minute.toInt( &ok );
1065 allOk &= ok;
1066
1067 int s = seconds.toInt( &ok );
1068 allOk &= ok;
1069
1070 if ( allOk ) {
1071 dt.setDate( QDate( y, mo, d ) );
1072 dt.setTime( QTime( h, mi, s ) );
1073 }
1074
1075 return dt;
1076}
1077
1078static QString white_balance_string( int i ) {
1079 QString balance; 1035 QString balance;
1080 switch ( i ) { 1036 switch ( i ) {
1081 case 0: 1037 case 0:
1082 balance = QObject::tr( "Unknown" ); 1038 balance = QObject::tr( "Unknown" );
1083 break; 1039 break;
1084 case 1: 1040 case 1:
1085 balance = QObject::tr( "Daylight" ); 1041 balance = QObject::tr( "Daylight" );
1086 break; 1042 break;
1087 case 2: 1043 case 2:
1088 balance = QObject::tr( "Fluorescent" ); 1044 balance = QObject::tr( "Fluorescent" );
1089 break; 1045 break;
1090 case 3: 1046 case 3:
1091 balance = QObject::tr( "Tungsten" ); 1047 balance = QObject::tr( "Tungsten" );
1092 break; 1048 break;
1093 case 17: 1049 case 17:
1094 balance = QObject::tr( "Standard light A" ); 1050 balance = QObject::tr( "Standard light A" );
1095 break; 1051 break;
1096 case 18: 1052 case 18:
1097 balance = QObject::tr( "Standard light B" ); 1053 balance = QObject::tr( "Standard light B" );
1098 break; 1054 break;
1099 case 19: 1055 case 19:
1100 balance = QObject::tr( "Standard light C" ); 1056 balance = QObject::tr( "Standard light C" );
1101 break; 1057 break;
1102 case 20: 1058 case 20:
1103 balance = QObject::tr( "D55" ); 1059 balance = QObject::tr( "D55" );
1104 break; 1060 break;
1105 case 21: 1061 case 21:
1106 balance = QObject::tr( "D65" ); 1062 balance = QObject::tr( "D65" );
1107 break; 1063 break;
1108 case 22: 1064 case 22:
1109 balance = QObject::tr( "D75" ); 1065 balance = QObject::tr( "D75" );
1110 break; 1066 break;
1111 case 255: 1067 case 255:
1112 balance = QObject::tr( "Other" ); 1068 balance = QObject::tr( "Other" );
1113 break; 1069 break;
1114 default: 1070 default:
1115 balance = QObject::tr( "Unknown" ); 1071 balance = QObject::tr( "Unknown" );
1116 } 1072 }
1117 return QObject::tr( "White Balance: %1\n" ).arg( balance ); 1073 return QObject::tr( "White Balance: %1\n" ).arg( balance );
1118 1074
1119} 1075}
1120 1076
1121 1077
1122static QString metering_mode( int i) { 1078QString ExifData::metering_mode( int i) {
1123 QString meter; 1079 QString meter;
1124 switch( i ) { 1080 switch( i ) {
1125 case 0: 1081 case 0:
1126 meter = QObject::tr( "Unknown" ); 1082 meter = QObject::tr( "Unknown" );
1127 break; 1083 break;
1128 case 1: 1084 case 1:
1129 meter = QObject::tr( "Average" ); 1085 meter = QObject::tr( "Average" );
1130 break; 1086 break;
1131 case 2: 1087 case 2:
1132 meter = QObject::tr( "Center weighted average" ); 1088 meter = QObject::tr( "Center weighted average" );
1133 break; 1089 break;
1134 case 3: 1090 case 3:
1135 meter = QObject::tr( "Spot" ); 1091 meter = QObject::tr( "Spot" );
1136 break; 1092 break;
1137 case 4: 1093 case 4:
1138 meter = QObject::tr( "MultiSpot" ); 1094 meter = QObject::tr( "MultiSpot" );
1139 break; 1095 break;
1140 case 5: 1096 case 5:
1141 meter = QObject::tr( "Pattern" ); 1097 meter = QObject::tr( "Pattern" );
1142 break; 1098 break;
1143 case 6: 1099 case 6:
1144 meter = QObject::tr( "Partial" ); 1100 meter = QObject::tr( "Partial" );
1145 break; 1101 break;
1146 case 255: 1102 case 255:
1147 meter = QObject::tr( "Other" ); 1103 meter = QObject::tr( "Other" );
1148 break; 1104 break;
1149 default: 1105 default:
1150 meter = QObject::tr( "Unknown" ); 1106 meter = QObject::tr( "Unknown" );
1151 } 1107 }
1152 1108
1153 return QObject::tr( "Metering Mode: %1\n" ).arg( meter ); 1109 return QObject::tr( "Metering Mode: %1\n" ).arg( meter );
1154} 1110}
1155 1111
1156 1112
1157static QString exposure_program( int i ) { 1113QString ExifData::exposure_program( int i ) {
1158 QString exp; 1114 QString exp;
1159 switch( i ) { 1115 switch( i ) {
1160 case 0: 1116 case 0:
1161 exp = QObject::tr( "Not defined" ); 1117 exp = QObject::tr( "Not defined" );
1162 break; 1118 break;
1163 case 1: 1119 case 1:
1164 exp = QObject::tr( "Manual" ); 1120 exp = QObject::tr( "Manual" );
1165 break; 1121 break;
1166 case 2: 1122 case 2:
1167 exp = QObject::tr( "Normal progam" ); 1123 exp = QObject::tr( "Normal progam" );
1168 break; 1124 break;
1169 case 3: 1125 case 3:
1170 exp = QObject::tr( "Aperture priority" ); 1126 exp = QObject::tr( "Aperture priority" );
1171 break; 1127 break;
1172 case 4: 1128 case 4:
1173 exp = QObject::tr( "Shutter priority" ); 1129 exp = QObject::tr( "Shutter priority" );
1174 break; 1130 break;
1175 case 5: 1131 case 5:
1176 exp = QObject::tr( "Creative progam\n(biased toward fast shutter speed" ); 1132 exp = QObject::tr( "Creative progam\n(biased toward fast shutter speed" );
1177 break; 1133 break;
1178 case 6: 1134 case 6:
1179 exp = QObject::tr( "Action progam\n(biased toward fast shutter speed)" ); 1135 exp = QObject::tr( "Action progam\n(biased toward fast shutter speed)" );
1180 break; 1136 break;
1181 case 7: 1137 case 7:
1182 exp = QObject::tr( "Portrait mode\n(for closeup photos with the background out of focus)" ); 1138 exp = QObject::tr( "Portrait mode\n(for closeup photos with the background out of focus)" );
1183 break; 1139 break;
1184 case 8: 1140 case 8:
1185 exp = QObject::tr( "Landscape mode\n(for landscape photos with the background in focus)" ); 1141 exp = QObject::tr( "Landscape mode\n(for landscape photos with the background in focus)" );
1186 break; 1142 break;
1187 default: 1143 default:
1188 exp = QObject::tr( "Unknown" ); 1144 exp = QObject::tr( "Unknown" );
1189 } 1145 }
1190 1146
1191 return QObject::tr( "Exposure Program: %1\n" ).arg( exp ); 1147 return QObject::tr( "Exposure Program: %1\n" ).arg( exp );
1192} 1148}
1193 1149
1194} // namespace MM 1150} // namespace MM
1195} // namespace OPIE 1151} // namespace OPIE
diff --git a/libopie2/opiemm/opieexif.h b/libopie2/opiemm/opieexif.h
index efaed71..fb06bf8 100644
--- a/libopie2/opiemm/opieexif.h
+++ b/libopie2/opiemm/opieexif.h
@@ -39,101 +39,108 @@ public:
39 uchar * Data; 39 uchar * Data;
40 int Type; 40 int Type;
41 unsigned Size; 41 unsigned Size;
42 }; 42 };
43 43
44 struct TagTable_t { 44 struct TagTable_t {
45 unsigned short Tag; 45 unsigned short Tag;
46 const char*const Desc; 46 const char*const Desc;
47 }; 47 };
48 48
49private: 49private:
50 static const int MAX_SECTIONS=20; 50 static const int MAX_SECTIONS=20;
51 static const unsigned int PSEUDO_IMAGE_MARKER=0x123; 51 static const unsigned int PSEUDO_IMAGE_MARKER=0x123;
52 Section_t Sections[MAX_SECTIONS]; 52 Section_t Sections[MAX_SECTIONS];
53 53
54 QString CameraMake; 54 QString CameraMake;
55 QString CameraModel; 55 QString CameraModel;
56 QString DateTime; 56 QString DateTime;
57 int Orientation; 57 int Orientation;
58 int Height, Width; 58 int Height, Width;
59 int ExifImageLength, ExifImageWidth; 59 int ExifImageLength, ExifImageWidth;
60 int IsColor; 60 int IsColor;
61 int Process; 61 int Process;
62 int FlashUsed; 62 int FlashUsed;
63 float FocalLength; 63 float FocalLength;
64 float ExposureTime; 64 float ExposureTime;
65 float ApertureFNumber; 65 float ApertureFNumber;
66 float Distance; 66 float Distance;
67 int Whitebalance; 67 int Whitebalance;
68 int MeteringMode; 68 int MeteringMode;
69 float CCDWidth; 69 float CCDWidth;
70 float ExposureBias; 70 float ExposureBias;
71 int ExposureProgram; 71 int ExposureProgram;
72 int ISOequivalent; 72 int ISOequivalent;
73 int CompressionLevel; 73 int CompressionLevel;
74 QString UserComment; 74 QString UserComment;
75 QString Comment; 75 QString Comment;
76 QImage Thumbnail; 76 QImage Thumbnail;
77 77
78 unsigned char * LastExifRefd; 78 unsigned char * LastExifRefd;
79 int ExifSettingsLength; 79 int ExifSettingsLength;
80 double FocalplaneXRes; 80 double FocalplaneXRes;
81 double FocalplaneUnits; 81 double FocalplaneUnits;
82 int MotorolaOrder; 82 int MotorolaOrder;
83 int SectionsRead; 83 int SectionsRead;
84 84
85 int ReadJpegSections (QFile & infile, ReadMode_t ReadMode); 85 int ReadJpegSections (QFile & infile, ReadMode_t ReadMode);
86 void DiscardData(void); 86 void DiscardData(void);
87 int Get16u(void * Short); 87 int Get16u(void * Short);
88 int Get32s(void * Long); 88 int Get32s(void * Long);
89 unsigned Get32u(void * Long); 89 unsigned Get32u(void * Long);
90 double ConvertAnyFormat(void * ValuePtr, int Format); 90 double ConvertAnyFormat(void * ValuePtr, int Format);
91 void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength); 91 void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength);
92 void process_COM (const uchar * Data, int length); 92 void process_COM (const uchar * Data, int length);
93 void process_SOFn (const uchar * Data, int marker); 93 void process_SOFn (const uchar * Data, int marker);
94 int Get16m(const void * Short); 94 int Get16m(const void * Short);
95 void process_EXIF(unsigned char * CharBuf, unsigned int length); 95 void process_EXIF(unsigned char * CharBuf, unsigned int length);
96 int Exif2tm(struct ::tm * timeptr, char * ExifTime); 96 int Exif2tm(struct ::tm * timeptr, char * ExifTime);
97 97
98public: 98public:
99 //! Contructor for initialising 99 //! Contructor for initialising
100 ExifData(); 100 ExifData();
101 //! destructor 101 //! destructor
102 virtual ~ExifData(); 102 virtual ~ExifData();
103 //! scan a given file 103 //! scan a given file
104 /*! 104 /*!
105 * try to scan the EXIF data of a image file 105 * try to scan the EXIF data of a image file
106 * \param aFile the file to scan 106 * \param aFile the file to scan
107 * \return true if success, otherwise false 107 * \return true if success, otherwise false
108 */ 108 */
109 bool scan(const QString &aFile); 109 bool scan(const QString &aFile);
110 QString getCameraMake() { return CameraMake; } 110 QString getCameraMake() { return CameraMake; }
111 QString getCameraModel() { return CameraModel; } 111 QString getCameraModel() { return CameraModel; }
112 QString getDateTime() { return DateTime; } 112 QString getDateTime() { return DateTime; }
113 int getOrientation() { return Orientation; } 113 int getOrientation() { return Orientation; }
114 int getHeight() { return Height; } 114 int getHeight() { return Height; }
115 int getWidth() { return Width; } 115 int getWidth() { return Width; }
116 int getIsColor() { return IsColor; } 116 int getIsColor() { return IsColor; }
117 int getProcess() { return Process; } 117 int getProcess() { return Process; }
118 int getFlashUsed() { return FlashUsed; } 118 int getFlashUsed() { return FlashUsed; }
119 float getFocalLength() { return FocalLength; } 119 float getFocalLength() { return FocalLength; }
120 float getExposureTime() { return ExposureTime; } 120 float getExposureTime() { return ExposureTime; }
121 float getApertureFNumber() { return ApertureFNumber; } 121 float getApertureFNumber() { return ApertureFNumber; }
122 float getDistance() { return Distance; } 122 float getDistance() { return Distance; }
123 int getWhitebalance() { return Whitebalance; } 123 int getWhitebalance() { return Whitebalance; }
124 int getMeteringMode() { return MeteringMode; } 124 int getMeteringMode() { return MeteringMode; }
125 float getCCDWidth() { return CCDWidth; } 125 float getCCDWidth() { return CCDWidth; }
126 float getExposureBias() { return ExposureBias; } 126 float getExposureBias() { return ExposureBias; }
127 int getExposureProgram() { return ExposureProgram; } 127 int getExposureProgram() { return ExposureProgram; }
128 int getISOequivalent() { return ISOequivalent; } 128 int getISOequivalent() { return ISOequivalent; }
129 int getCompressionLevel() { return CompressionLevel; } 129 int getCompressionLevel() { return CompressionLevel; }
130 QString getUserComment() { return UserComment; } 130 QString getUserComment() { return UserComment; }
131 QString getComment() { return Comment; } 131 QString getComment() { return Comment; }
132 QImage getThumbnail(); 132 QImage getThumbnail();
133 bool isThumbnailSane(); 133 bool isThumbnailSane();
134 bool isNullThumbnail() { return !isThumbnailSane(); } 134 bool isNullThumbnail() { return !isThumbnailSane(); }
135
136 // some helpers
137 static QString color_mode_to_string( bool b );
138 static QString compression_to_string( int level );
139 static QString white_balance_string( int i );
140 static QString metering_mode( int i);
141 static QString exposure_program( int i );
135}; 142};
136 143
137} 144}
138} 145}
139#endif 146#endif