[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / pictures / PictureInfoTag.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "PictureInfoTag.h"
22 #include "XBDateTime.h"
23 #include "Util.h"
24 #include "utils/Variant.h"
25 #include "utils/CharsetConverter.h"
26
27 using namespace std;
28
29 void CPictureInfoTag::Reset()
30 {
31   memset(&m_exifInfo, 0, sizeof(m_exifInfo));
32   memset(&m_iptcInfo, 0, sizeof(m_iptcInfo));
33   m_isLoaded = false;
34 }
35
36 const CPictureInfoTag& CPictureInfoTag::operator=(const CPictureInfoTag& right)
37 {
38   if (this == &right) return * this;
39   memcpy(&m_exifInfo, &right.m_exifInfo, sizeof(m_exifInfo));
40   memcpy(&m_iptcInfo, &right.m_iptcInfo, sizeof(m_iptcInfo));
41   m_isLoaded = right.m_isLoaded;
42   return *this;
43 }
44
45 bool CPictureInfoTag::Load(const CStdString &path)
46 {
47   m_isLoaded = false;
48
49   DllLibExif exifDll;
50   if (path.IsEmpty() || !exifDll.Load())
51     return false;
52
53   if (exifDll.process_jpeg(path.c_str(), &m_exifInfo, &m_iptcInfo))
54     m_isLoaded = true;
55
56   return m_isLoaded;
57 }
58
59 void CPictureInfoTag::Archive(CArchive& ar)
60 {
61   if (ar.IsStoring())
62   {
63     ar << m_isLoaded;
64     ar << m_exifInfo.ApertureFNumber;
65     ar << CStdString(m_exifInfo.CameraMake);
66     ar << CStdString(m_exifInfo.CameraModel);
67     ar << m_exifInfo.CCDWidth;
68     ar << GetInfo(SLIDE_EXIF_COMMENT); // Store and restore the comment charset converted
69     ar << CStdString(m_exifInfo.Description);
70     ar << CStdString(m_exifInfo.DateTime);
71     for (int i = 0; i < 10; i++)
72       ar << m_exifInfo.DateTimeOffsets[i];
73     ar << m_exifInfo.DigitalZoomRatio;
74     ar << m_exifInfo.Distance;
75     ar << m_exifInfo.ExposureBias;
76     ar << m_exifInfo.ExposureMode;
77     ar << m_exifInfo.ExposureProgram;
78     ar << m_exifInfo.ExposureTime;
79     ar << m_exifInfo.FlashUsed;
80     ar << m_exifInfo.FocalLength;
81     ar << m_exifInfo.FocalLength35mmEquiv;
82     ar << m_exifInfo.GpsInfoPresent;
83     ar << CStdString(m_exifInfo.GpsAlt);
84     ar << CStdString(m_exifInfo.GpsLat);
85     ar << CStdString(m_exifInfo.GpsLong);
86     ar << m_exifInfo.Height;
87     ar << m_exifInfo.IsColor;
88     ar << m_exifInfo.ISOequivalent;
89     ar << m_exifInfo.LargestExifOffset;
90     ar << m_exifInfo.LightSource;
91     ar << m_exifInfo.MeteringMode;
92     ar << m_exifInfo.numDateTimeTags;
93     ar << m_exifInfo.Orientation;
94     ar << m_exifInfo.Process;
95     ar << m_exifInfo.ThumbnailAtEnd;
96     ar << m_exifInfo.ThumbnailOffset;
97     ar << m_exifInfo.ThumbnailSize;
98     ar << m_exifInfo.ThumbnailSizeOffset;
99     ar << m_exifInfo.Whitebalance;
100     ar << m_exifInfo.Width;
101
102     ar << CStdString(m_iptcInfo.Author);
103     ar << CStdString(m_iptcInfo.Byline);
104     ar << CStdString(m_iptcInfo.BylineTitle);
105     ar << CStdString(m_iptcInfo.Caption);
106     ar << CStdString(m_iptcInfo.Category);
107     ar << CStdString(m_iptcInfo.City);
108     ar << CStdString(m_iptcInfo.Copyright);
109     ar << CStdString(m_iptcInfo.CopyrightNotice);
110     ar << CStdString(m_iptcInfo.Country);
111     ar << CStdString(m_iptcInfo.CountryCode);
112     ar << CStdString(m_iptcInfo.Credit);
113     ar << CStdString(m_iptcInfo.Date);
114     ar << CStdString(m_iptcInfo.Headline);
115     ar << CStdString(m_iptcInfo.Keywords);
116     ar << CStdString(m_iptcInfo.ObjectName);
117     ar << CStdString(m_iptcInfo.ReferenceService);
118     ar << CStdString(m_iptcInfo.Source);
119     ar << CStdString(m_iptcInfo.SpecialInstructions);
120     ar << CStdString(m_iptcInfo.State);
121     ar << CStdString(m_iptcInfo.SupplementalCategories);
122     ar << CStdString(m_iptcInfo.TransmissionReference);
123   }
124   else
125   {
126     ar >> m_isLoaded;
127     ar >> m_exifInfo.ApertureFNumber;
128     GetStringFromArchive(ar, m_exifInfo.CameraMake, sizeof(m_exifInfo.CameraMake));
129     GetStringFromArchive(ar, m_exifInfo.CameraModel, sizeof(m_exifInfo.CameraModel));
130     ar >> m_exifInfo.CCDWidth;
131     GetStringFromArchive(ar, m_exifInfo.Comments, sizeof(m_exifInfo.Comments));
132     m_exifInfo.CommentsCharset = EXIF_COMMENT_CHARSET_CONVERTED; // Store and restore the comment charset converted
133     GetStringFromArchive(ar, m_exifInfo.Description, sizeof(m_exifInfo.Description));
134     GetStringFromArchive(ar, m_exifInfo.DateTime, sizeof(m_exifInfo.DateTime));
135     for (int i = 0; i < 10; i++)
136       ar >> m_exifInfo.DateTimeOffsets[i];
137     ar >> m_exifInfo.DigitalZoomRatio;
138     ar >> m_exifInfo.Distance;
139     ar >> m_exifInfo.ExposureBias;
140     ar >> m_exifInfo.ExposureMode;
141     ar >> m_exifInfo.ExposureProgram;
142     ar >> m_exifInfo.ExposureTime;
143     ar >> m_exifInfo.FlashUsed;
144     ar >> m_exifInfo.FocalLength;
145     ar >> m_exifInfo.FocalLength35mmEquiv;
146     ar >> m_exifInfo.GpsInfoPresent;
147     GetStringFromArchive(ar, m_exifInfo.GpsAlt, sizeof(m_exifInfo.GpsAlt));
148     GetStringFromArchive(ar, m_exifInfo.GpsLat, sizeof(m_exifInfo.GpsLat));
149     GetStringFromArchive(ar, m_exifInfo.GpsLong, sizeof(m_exifInfo.GpsLong));
150     ar >> m_exifInfo.Height;
151     ar >> m_exifInfo.IsColor;
152     ar >> m_exifInfo.ISOequivalent;
153     ar >> m_exifInfo.LargestExifOffset;
154     ar >> m_exifInfo.LightSource;
155     ar >> m_exifInfo.MeteringMode;
156     ar >> m_exifInfo.numDateTimeTags;
157     ar >> m_exifInfo.Orientation;
158     ar >> m_exifInfo.Process;
159     ar >> m_exifInfo.ThumbnailAtEnd;
160     ar >> m_exifInfo.ThumbnailOffset;
161     ar >> m_exifInfo.ThumbnailSize;
162     ar >> m_exifInfo.ThumbnailSizeOffset;
163     ar >> m_exifInfo.Whitebalance;
164     ar >> m_exifInfo.Width;
165
166     GetStringFromArchive(ar, m_iptcInfo.Author, sizeof(m_iptcInfo.Author));
167     GetStringFromArchive(ar, m_iptcInfo.Byline, sizeof(m_iptcInfo.Byline));
168     GetStringFromArchive(ar, m_iptcInfo.BylineTitle, sizeof(m_iptcInfo.BylineTitle));
169     GetStringFromArchive(ar, m_iptcInfo.Caption, sizeof(m_iptcInfo.Caption));
170     GetStringFromArchive(ar, m_iptcInfo.Category, sizeof(m_iptcInfo.Category));
171     GetStringFromArchive(ar, m_iptcInfo.City, sizeof(m_iptcInfo.City));
172     GetStringFromArchive(ar, m_iptcInfo.Copyright, sizeof(m_iptcInfo.Copyright));
173     GetStringFromArchive(ar, m_iptcInfo.CopyrightNotice, sizeof(m_iptcInfo.CopyrightNotice));
174     GetStringFromArchive(ar, m_iptcInfo.Country, sizeof(m_iptcInfo.Country));
175     GetStringFromArchive(ar, m_iptcInfo.CountryCode, sizeof(m_iptcInfo.CountryCode));
176     GetStringFromArchive(ar, m_iptcInfo.Credit, sizeof(m_iptcInfo.Credit));
177     GetStringFromArchive(ar, m_iptcInfo.Date, sizeof(m_iptcInfo.Date));
178     GetStringFromArchive(ar, m_iptcInfo.Headline, sizeof(m_iptcInfo.Headline));
179     GetStringFromArchive(ar, m_iptcInfo.Keywords, sizeof(m_iptcInfo.Keywords));
180     GetStringFromArchive(ar, m_iptcInfo.ObjectName, sizeof(m_iptcInfo.ObjectName));
181     GetStringFromArchive(ar, m_iptcInfo.ReferenceService, sizeof(m_iptcInfo.ReferenceService));
182     GetStringFromArchive(ar, m_iptcInfo.Source, sizeof(m_iptcInfo.Source));
183     GetStringFromArchive(ar, m_iptcInfo.SpecialInstructions, sizeof(m_iptcInfo.SpecialInstructions));
184     GetStringFromArchive(ar, m_iptcInfo.State, sizeof(m_iptcInfo.State));
185     GetStringFromArchive(ar, m_iptcInfo.SupplementalCategories, sizeof(m_iptcInfo.SupplementalCategories));
186     GetStringFromArchive(ar, m_iptcInfo.TransmissionReference, sizeof(m_iptcInfo.TransmissionReference));
187   }
188 }
189
190 void CPictureInfoTag::Serialize(CVariant& value) const
191 {
192   value["aperturefnumber"] = m_exifInfo.ApertureFNumber;
193   value["cameramake"] = CStdString(m_exifInfo.CameraMake);
194   value["cameramodel"] = CStdString(m_exifInfo.CameraModel);
195   value["ccdwidth"] = m_exifInfo.CCDWidth;
196   value["comments"] = GetInfo(SLIDE_EXIF_COMMENT); // Charset conversion
197   value["description"] = CStdString(m_exifInfo.Description);
198   value["datetime"] = CStdString(m_exifInfo.DateTime);
199   for (int i = 0; i < 10; i++)
200     value["datetimeoffsets"][i] = m_exifInfo.DateTimeOffsets[i];
201   value["digitalzoomratio"] = m_exifInfo.DigitalZoomRatio;
202   value["distance"] = m_exifInfo.Distance;
203   value["exposurebias"] = m_exifInfo.ExposureBias;
204   value["exposuremode"] = m_exifInfo.ExposureMode;
205   value["exposureprogram"] = m_exifInfo.ExposureProgram;
206   value["exposuretime"] = m_exifInfo.ExposureTime;
207   value["flashused"] = m_exifInfo.FlashUsed;
208   value["focallength"] = m_exifInfo.FocalLength;
209   value["focallength35mmequiv"] = m_exifInfo.FocalLength35mmEquiv;
210   value["gpsinfopresent"] = m_exifInfo.GpsInfoPresent;
211   value["gpsinfo"]["alt"] = CStdString(m_exifInfo.GpsAlt);
212   value["gpsinfo"]["lat"] = CStdString(m_exifInfo.GpsLat);
213   value["gpsinfo"]["long"] = CStdString(m_exifInfo.GpsLong);
214   value["height"] = m_exifInfo.Height;
215   value["iscolor"] = m_exifInfo.IsColor;
216   value["isoequivalent"] = m_exifInfo.ISOequivalent;
217   value["largestexifoffset"] = m_exifInfo.LargestExifOffset;
218   value["lightsource"] = m_exifInfo.LightSource;
219   value["meteringmode"] = m_exifInfo.MeteringMode;
220   value["numdatetimetags"] = m_exifInfo.numDateTimeTags;
221   value["orientation"] = m_exifInfo.Orientation;
222   value["process"] = m_exifInfo.Process;
223   value["thumbnailatend"] = m_exifInfo.ThumbnailAtEnd;
224   value["thumbnailoffset"] = m_exifInfo.ThumbnailOffset;
225   value["thumbnailsize"] = m_exifInfo.ThumbnailSize;
226   value["thumbnailsizeoffset"] = m_exifInfo.ThumbnailSizeOffset;
227   value["whitebalance"] = m_exifInfo.Whitebalance;
228   value["width"] = m_exifInfo.Width;
229
230   value["author"] = CStdString(m_iptcInfo.Author);
231   value["byline"] = CStdString(m_iptcInfo.Byline);
232   value["bylinetitle"] = CStdString(m_iptcInfo.BylineTitle);
233   value["caption"] = CStdString(m_iptcInfo.Caption);
234   value["category"] = CStdString(m_iptcInfo.Category);
235   value["city"] = CStdString(m_iptcInfo.City);
236   value["copyright"] = CStdString(m_iptcInfo.Copyright);
237   value["copyrightnotice"] = CStdString(m_iptcInfo.CopyrightNotice);
238   value["country"] = CStdString(m_iptcInfo.Country);
239   value["countrycode"] = CStdString(m_iptcInfo.CountryCode);
240   value["credit"] = CStdString(m_iptcInfo.Credit);
241   value["date"] = CStdString(m_iptcInfo.Date);
242   value["headline"] = CStdString(m_iptcInfo.Headline);
243   value["keywords"] = CStdString(m_iptcInfo.Keywords);
244   value["objectname"] = CStdString(m_iptcInfo.ObjectName);
245   value["referenceservice"] = CStdString(m_iptcInfo.ReferenceService);
246   value["source"] = CStdString(m_iptcInfo.Source);
247   value["specialinstructions"] = CStdString(m_iptcInfo.SpecialInstructions);
248   value["state"] = CStdString(m_iptcInfo.State);
249   value["supplementalcategories"] = CStdString(m_iptcInfo.SupplementalCategories);
250   value["transmissionreference"] = CStdString(m_iptcInfo.TransmissionReference);
251 }
252
253 void CPictureInfoTag::ToSortable(SortItem& sortable)
254 {
255   
256 }
257
258 void CPictureInfoTag::GetStringFromArchive(CArchive &ar, char *string, size_t length)
259 {
260   CStdString temp;
261   ar >> temp;
262   length = min((size_t)temp.GetLength(), length - 1);
263   if (!temp.IsEmpty())
264     memcpy(string, temp.c_str(), length);
265   string[length] = 0;
266 }
267
268 const CStdString CPictureInfoTag::GetInfo(int info) const
269 {
270   if (!m_isLoaded)
271     return "";
272
273   CStdString value;
274   switch (info)
275   {
276   case SLIDE_RESOLUTION:
277     value.Format("%d x %d", m_exifInfo.Width, m_exifInfo.Height);
278     break;
279   case SLIDE_COLOUR:
280     value = m_exifInfo.IsColor ? "Colour" : "Black and White";
281     break;
282   case SLIDE_PROCESS:
283     switch (m_exifInfo.Process)
284     {
285       case M_SOF0:
286         // don't show it if its the plain old boring 'baseline' process, but do
287         // show it if its something else, like 'progressive' (used on web sometimes)
288         value = "Baseline";
289       break;
290       case M_SOF1:    value = "Extended sequential";      break;
291       case M_SOF2:    value = "Progressive";      break;
292       case M_SOF3:    value = "Lossless";      break;
293       case M_SOF5:    value = "Differential sequential";      break;
294       case M_SOF6:    value = "Differential progressive";      break;
295       case M_SOF7:    value = "Differential lossless";      break;
296       case M_SOF9:    value = "Extended sequential, arithmetic coding";      break;
297       case M_SOF10:   value = "Progressive, arithmetic coding";     break;
298       case M_SOF11:   value = "Lossless, arithmetic coding";     break;
299       case M_SOF13:   value = "Differential sequential, arithmetic coding";     break;
300       case M_SOF14:   value = "Differential progressive, arithmetic coding";     break;
301       case M_SOF15:   value = "Differential lossless, arithmetic coding";     break;
302       default:        value = "Unknown";   break;
303     }
304     break;
305   case SLIDE_COMMENT:
306   case SLIDE_EXIF_COMMENT:
307     // The charset used for the UserComment is stored in CommentsCharset:
308     // Ascii, Unicode (UCS2), JIS (X208-1990), Unknown (application specific)
309     if (m_exifInfo.CommentsCharset == EXIF_COMMENT_CHARSET_UNICODE)
310     {
311       g_charsetConverter.ucs2ToUTF8(CStdString16((uint16_t*)m_exifInfo.Comments), value);
312     }
313     else
314     {
315       // Ascii doesn't need to be converted (EXIF_COMMENT_CHARSET_ASCII)
316       // Archived data is already converted (EXIF_COMMENT_CHARSET_CONVERTED)
317       // Unknown data can't be converted as it could be any codec (EXIF_COMMENT_CHARSET_UNKNOWN)
318       // JIS data can't be converted as CharsetConverter and iconv lacks support (EXIF_COMMENT_CHARSET_JIS)
319       value = m_exifInfo.Comments;
320     }
321     break;
322   case SLIDE_EXIF_DATE_TIME:
323   case SLIDE_EXIF_DATE:
324     if (strlen(m_exifInfo.DateTime) >= 19 && m_exifInfo.DateTime[0] != ' ')
325     {
326       CStdString dateTime = m_exifInfo.DateTime;
327       int year  = atoi(dateTime.Mid(0, 4).c_str());
328       int month = atoi(dateTime.Mid(5, 2).c_str());
329       int day   = atoi(dateTime.Mid(8, 2).c_str());
330       int hour  = atoi(dateTime.Mid(11,2).c_str());
331       int min   = atoi(dateTime.Mid(14,2).c_str());
332       int sec   = atoi(dateTime.Mid(17,2).c_str());
333       CDateTime date(year, month, day, hour, min, sec);
334       if(SLIDE_EXIF_DATE_TIME == info)
335           value = date.GetAsLocalizedDateTime();
336       else
337           value = date.GetAsLocalizedDate();
338     }
339     break;
340   case SLIDE_EXIF_DESCRIPTION:
341     value = m_exifInfo.Description;
342     break;
343   case SLIDE_EXIF_CAMERA_MAKE:
344     value = m_exifInfo.CameraMake;
345     break;
346   case SLIDE_EXIF_CAMERA_MODEL:
347     value = m_exifInfo.CameraModel;
348     break;
349 //  case SLIDE_EXIF_SOFTWARE:
350 //    value = m_exifInfo.Software;
351   case SLIDE_EXIF_APERTURE:
352     if (m_exifInfo.ApertureFNumber)
353       value.Format("%3.1f", m_exifInfo.ApertureFNumber);
354     break;
355   case SLIDE_EXIF_ORIENTATION:
356     switch (m_exifInfo.Orientation)
357     {
358       case 1:   value = "Top Left";     break;
359       case 2:   value = "Top Right";    break;
360       case 3:   value = "Bottom Right"; break;
361       case 4:   value = "Bottom Left";  break;
362       case 5:   value = "Left Top";     break;
363       case 6:   value = "Right Top";    break;
364       case 7:   value = "Right Bottom"; break;
365       case 8:   value = "Left Bottom";  break;
366     }
367     break;
368   case SLIDE_EXIF_FOCAL_LENGTH:
369     if (m_exifInfo.FocalLength)
370     {
371       value.Format("%4.2fmm", m_exifInfo.FocalLength);
372       if (m_exifInfo.FocalLength35mmEquiv != 0)
373         value.AppendFormat("  (35mm Equivalent = %umm)", m_exifInfo.FocalLength35mmEquiv);
374     }
375     break;
376   case SLIDE_EXIF_FOCUS_DIST:
377     if (m_exifInfo.Distance < 0)
378       value = "Infinite";
379     else if (m_exifInfo.Distance > 0)
380       value.Format("%4.2fm", m_exifInfo.Distance);
381     break;
382   case SLIDE_EXIF_EXPOSURE:
383     switch (m_exifInfo.ExposureProgram)
384     {
385       case 1:  value = "Manual";              break;
386       case 2:  value = "Program (Auto)";     break;
387       case 3:  value = "Aperture priority (Semi-Auto)";    break;
388       case 4:  value = "Shutter priority (semi-auto)";     break;
389       case 5:  value = "Creative Program (based towards depth of field)";    break;
390       case 6:  value = "Action program (based towards fast shutter speed)";      break;
391       case 7:  value = "Portrait Mode";    break;
392       case 8:  value = "Landscape Mode";   break;
393     }
394     break;
395   case SLIDE_EXIF_EXPOSURE_TIME:
396     if (m_exifInfo.ExposureTime)
397     {
398       if (m_exifInfo.ExposureTime < 0.010f)
399         value.Format("%6.4fs", m_exifInfo.ExposureTime);
400       else
401         value.Format("%5.3fs", m_exifInfo.ExposureTime);
402       if (m_exifInfo.ExposureTime <= 0.5)
403         value.AppendFormat(" (1/%d)", (int)(0.5 + 1/m_exifInfo.ExposureTime));
404     }
405     break;
406   case SLIDE_EXIF_EXPOSURE_BIAS:
407     if (m_exifInfo.ExposureBias != 0)
408       value.Format("%4.2", m_exifInfo.ExposureBias);
409     break;
410   case SLIDE_EXIF_EXPOSURE_MODE:
411     switch (m_exifInfo.ExposureMode)
412     {
413       case 0:  value = "Automatic";          break;
414       case 1:  value = "Manual";             break;
415       case 2:  value = "Auto bracketing";    break;
416     }
417     break;
418   case SLIDE_EXIF_FLASH_USED:
419     if (m_exifInfo.FlashUsed >= 0)
420     {
421       if (m_exifInfo.FlashUsed & 1)
422       {
423         value = "Yes";
424         switch (m_exifInfo.FlashUsed)
425         {
426           case 0x5:  value = "Yes (Strobe light not detected)";                break;
427           case 0x7:  value = "Yes (Strobe light detected)";                  break;
428           case 0x9:  value = "Yes (Manual)";                  break;
429           case 0xd:  value = "Yes (Manual, return light not detected)";          break;
430           case 0xf:  value = "Yes (Manual, return light detected)";            break;
431           case 0x19: value = "Yes (Auto)";                    break;
432           case 0x1d: value = "Yes (Auto, return light not detected)";            break;
433           case 0x1f: value = "Yes (Auto, return light detected)";              break;
434           case 0x41: value = "Yes (Red eye reduction mode)";                  break;
435           case 0x45: value = "Yes (Red eye reduction mode return light not detected)";          break;
436           case 0x47: value = "Yes (Red eye reduction mode return light detected)";            break;
437           case 0x49: value = "Yes (Manual, red eye reduction mode)";            break;
438           case 0x4d: value = "Yes (Manual, red eye reduction mode, return light not detected)";    break;
439           case 0x4f: value = "Yes (Manual, red eye reduction mode, return light detected)";      break;
440           case 0x59: value = "Yes (Auto, red eye reduction mode)";              break;
441           case 0x5d: value = "Yes (Auto, red eye reduction mode, return light not detected)";      break;
442           case 0x5f: value = "Yes (Auto, red eye reduction mode, return light detected)";        break;
443         }
444       }
445       else
446         value = m_exifInfo.FlashUsed == 0x18 ? "No (Auto)" : "No";
447     }
448     break;
449   case SLIDE_EXIF_WHITE_BALANCE:
450     return m_exifInfo.Whitebalance ? "Manual" : "Auto";
451   case SLIDE_EXIF_LIGHT_SOURCE:
452     switch (m_exifInfo.LightSource)
453     {
454       case 1:   value = "Daylight";       break;
455       case 2:   value = "Fluorescent";    break;
456       case 3:   value = "Incandescent";   break;
457       case 4:   value = "Flash";          break;
458       case 9:   value = "Fine Weather";    break;
459       case 11:  value = "Shade";          break;
460       default:;   //Quercus: 17-1-2004 There are many more modes for this, check Exif2.2 specs
461                   // If it just says 'unknown' or we don't know it, then
462                   // don't bother showing it - it doesn't add any useful information.
463     }
464     break;
465   case SLIDE_EXIF_METERING_MODE:
466     switch (m_exifInfo.MeteringMode)
467     {
468       case 2:  value = "Center weight"; break;
469       case 3:  value = "Spot";   break;
470       case 5:  value = "Matrix"; break;
471     }
472     break;
473   case SLIDE_EXIF_ISO_EQUIV:
474     if (m_exifInfo.ISOequivalent)
475       value.Format("%2d", m_exifInfo.ISOequivalent);
476     break;
477   case SLIDE_EXIF_DIGITAL_ZOOM:
478     if (m_exifInfo.DigitalZoomRatio)
479       value.Format("%1.3fx", m_exifInfo.DigitalZoomRatio);
480     break;
481   case SLIDE_EXIF_CCD_WIDTH:
482     if (m_exifInfo.CCDWidth)
483       value.Format("%4.2fmm", m_exifInfo.CCDWidth);
484     break;
485   case SLIDE_EXIF_GPS_LATITUDE:
486     value = m_exifInfo.GpsLat;
487     break;
488   case SLIDE_EXIF_GPS_LONGITUDE:
489     value = m_exifInfo.GpsLong;
490     break;
491   case SLIDE_EXIF_GPS_ALTITUDE:
492     value = m_exifInfo.GpsAlt;
493     break;
494   case SLIDE_IPTC_SUP_CATEGORIES:   value = m_iptcInfo.SupplementalCategories;  break;
495   case SLIDE_IPTC_KEYWORDS:         value = m_iptcInfo.Keywords;                break;
496   case SLIDE_IPTC_CAPTION:          value = m_iptcInfo.Caption;                 break;
497   case SLIDE_IPTC_AUTHOR:           value = m_iptcInfo.Author;                  break;
498   case SLIDE_IPTC_HEADLINE:         value = m_iptcInfo.Headline;                break;
499   case SLIDE_IPTC_SPEC_INSTR:       value = m_iptcInfo.SpecialInstructions;     break;
500   case SLIDE_IPTC_CATEGORY:         value = m_iptcInfo.Category;                break;
501   case SLIDE_IPTC_BYLINE:           value = m_iptcInfo.Byline;                  break;
502   case SLIDE_IPTC_BYLINE_TITLE:     value = m_iptcInfo.BylineTitle;             break;
503   case SLIDE_IPTC_CREDIT:           value = m_iptcInfo.Credit;                  break;
504   case SLIDE_IPTC_SOURCE:           value = m_iptcInfo.Source;                  break;
505   case SLIDE_IPTC_COPYRIGHT_NOTICE: value = m_iptcInfo.CopyrightNotice;         break;
506   case SLIDE_IPTC_OBJECT_NAME:      value = m_iptcInfo.ObjectName;              break;
507   case SLIDE_IPTC_CITY:             value = m_iptcInfo.City;                    break;
508   case SLIDE_IPTC_STATE:            value = m_iptcInfo.State;                   break;
509   case SLIDE_IPTC_COUNTRY:          value = m_iptcInfo.Country;                 break;
510   case SLIDE_IPTC_TX_REFERENCE:     value = m_iptcInfo.TransmissionReference;   break;
511   case SLIDE_IPTC_DATE:             value = m_iptcInfo.Date;                    break;
512   case SLIDE_IPTC_COPYRIGHT:        value = m_iptcInfo.Copyright;               break;
513   case SLIDE_IPTC_COUNTRY_CODE:     value = m_iptcInfo.CountryCode;             break;
514   case SLIDE_IPTC_REF_SERVICE:      value = m_iptcInfo.ReferenceService;        break;
515   default:
516     break;
517   }
518   return value;
519 }
520
521 int CPictureInfoTag::TranslateString(const CStdString &info)
522 {
523   if (info.Equals("filename")) return SLIDE_FILE_NAME;
524   else if (info.Equals("path")) return SLIDE_FILE_PATH;
525   else if (info.Equals("filesize")) return SLIDE_FILE_SIZE;
526   else if (info.Equals("filedate")) return SLIDE_FILE_DATE;
527   else if (info.Equals("slideindex")) return SLIDE_INDEX;
528   else if (info.Equals("resolution")) return SLIDE_RESOLUTION;
529   else if (info.Equals("slidecomment")) return SLIDE_COMMENT;
530   else if (info.Equals("colour")) return SLIDE_COLOUR;
531   else if (info.Equals("process")) return SLIDE_PROCESS;
532   else if (info.Equals("exiftime")) return SLIDE_EXIF_DATE_TIME;
533   else if (info.Equals("exifdate")) return SLIDE_EXIF_DATE;
534   else if (info.Equals("exifdescription")) return SLIDE_EXIF_DESCRIPTION;
535   else if (info.Equals("cameramake")) return SLIDE_EXIF_CAMERA_MAKE;
536   else if (info.Equals("cameramodel")) return SLIDE_EXIF_CAMERA_MODEL;
537   else if (info.Equals("exifcomment")) return SLIDE_EXIF_COMMENT;
538   else if (info.Equals("exifsoftware")) return SLIDE_EXIF_SOFTWARE;
539   else if (info.Equals("apreture")) return SLIDE_EXIF_APERTURE;
540   else if (info.Equals("focallength")) return SLIDE_EXIF_FOCAL_LENGTH;
541   else if (info.Equals("focusdistance")) return SLIDE_EXIF_FOCUS_DIST;
542   else if (info.Equals("exposure")) return SLIDE_EXIF_EXPOSURE;
543   else if (info.Equals("exposuretime")) return SLIDE_EXIF_EXPOSURE_TIME;
544   else if (info.Equals("exposurebias")) return SLIDE_EXIF_EXPOSURE_BIAS;
545   else if (info.Equals("exposuremode")) return SLIDE_EXIF_EXPOSURE_MODE;
546   else if (info.Equals("flashused")) return SLIDE_EXIF_FLASH_USED;
547   else if (info.Equals("whitebalance")) return SLIDE_EXIF_WHITE_BALANCE;
548   else if (info.Equals("lightsource")) return SLIDE_EXIF_LIGHT_SOURCE;
549   else if (info.Equals("meteringmode")) return SLIDE_EXIF_METERING_MODE;
550   else if (info.Equals("isoequivalence")) return SLIDE_EXIF_ISO_EQUIV;
551   else if (info.Equals("digitalzoom")) return SLIDE_EXIF_DIGITAL_ZOOM;
552   else if (info.Equals("ccdwidth")) return SLIDE_EXIF_CCD_WIDTH;
553   else if (info.Equals("orientation")) return SLIDE_EXIF_ORIENTATION;
554   else if (info.Equals("supplementalcategories")) return SLIDE_IPTC_SUP_CATEGORIES;
555   else if (info.Equals("keywords")) return SLIDE_IPTC_KEYWORDS;
556   else if (info.Equals("caption")) return SLIDE_IPTC_CAPTION;
557   else if (info.Equals("author")) return SLIDE_IPTC_AUTHOR;
558   else if (info.Equals("healine")) return SLIDE_IPTC_HEADLINE;
559   else if (info.Equals("specialinstructions")) return SLIDE_IPTC_SPEC_INSTR;
560   else if (info.Equals("category")) return SLIDE_IPTC_CATEGORY;
561   else if (info.Equals("byline")) return SLIDE_IPTC_BYLINE;
562   else if (info.Equals("bylinetitle")) return SLIDE_IPTC_BYLINE_TITLE;
563   else if (info.Equals("credit")) return SLIDE_IPTC_CREDIT;
564   else if (info.Equals("source")) return SLIDE_IPTC_SOURCE;
565   else if (info.Equals("copyrightnotice")) return SLIDE_IPTC_COPYRIGHT_NOTICE;
566   else if (info.Equals("objectname")) return SLIDE_IPTC_OBJECT_NAME;
567   else if (info.Equals("city")) return SLIDE_IPTC_CITY;
568   else if (info.Equals("state")) return SLIDE_IPTC_STATE;
569   else if (info.Equals("country")) return SLIDE_IPTC_COUNTRY;
570   else if (info.Equals("transmissionreference")) return SLIDE_IPTC_TX_REFERENCE;
571   else if (info.Equals("iptcdate")) return SLIDE_IPTC_DATE;
572   else if (info.Equals("copyright")) return SLIDE_IPTC_COPYRIGHT;
573   else if (info.Equals("countrycode")) return SLIDE_IPTC_COUNTRY_CODE;
574   else if (info.Equals("referenceservice")) return SLIDE_IPTC_REF_SERVICE;
575   else if (info.Equals("latitude")) return SLIDE_EXIF_GPS_LATITUDE;
576   else if (info.Equals("longitude")) return SLIDE_EXIF_GPS_LONGITUDE;
577   else if (info.Equals("altitude")) return SLIDE_EXIF_GPS_ALTITUDE;
578   return 0;
579 }
580
581 void CPictureInfoTag::SetInfo(int info, const CStdString& value)
582 {
583   switch (info)
584   {
585   case SLIDE_RESOLUTION:
586     {
587       vector<CStdString> dimension;
588       CUtil::Tokenize(value, dimension, ",");
589       if (dimension.size() == 2)
590       {
591         m_exifInfo.Width = atoi(dimension[0].c_str());
592         m_exifInfo.Height = atoi(dimension[1].c_str());
593       }
594       break;
595     }
596   case SLIDE_EXIF_DATE_TIME:
597     {
598       strcpy(m_exifInfo.DateTime, value.c_str());
599       break;
600     }
601   default:
602     break;
603   }
604 }
605
606 void CPictureInfoTag::SetLoaded(bool loaded)
607 {
608   m_isLoaded = loaded;
609 }
610