Coverage Report

Created: 2021-08-22 09:07

/src/skia/third_party/externals/dng_sdk/source/dng_date_time.h
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************/
2
// Copyright 2006-2008 Adobe Systems Incorporated
3
// All Rights Reserved.
4
//
5
// NOTICE:  Adobe permits you to use, modify, and distribute this file in
6
// accordance with the terms of the Adobe license agreement accompanying it.
7
/*****************************************************************************/
8
9
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_date_time.h#1 $ */ 
10
/* $DateTime: 2012/05/30 13:28:51 $ */
11
/* $Change: 832332 $ */
12
/* $Author: tknoll $ */
13
14
/** \file
15
 * Functions and classes for working with dates and times in DNG files.
16
 */
17
18
/*****************************************************************************/
19
20
#ifndef __dng_date_time__
21
#define __dng_date_time__
22
23
/*****************************************************************************/
24
25
#include "dng_classes.h"
26
#include "dng_string.h"
27
#include "dng_types.h"
28
29
/*****************************************************************************/
30
31
/// \brief Class for holding a date/time and converting to and from relevant
32
/// date/time formats
33
34
class dng_date_time
35
  {
36
  
37
  public:
38
    
39
    uint32 fYear;
40
    uint32 fMonth;
41
    uint32 fDay;
42
    uint32 fHour;
43
    uint32 fMinute;
44
    uint32 fSecond;
45
    
46
  public:
47
  
48
    /// Construct an invalid date/time
49
50
    dng_date_time ();
51
52
    /// Construct a date/time with specific values.
53
    /// \param year Year to use as actual integer value, such as 2006.
54
    /// \param month Month to use from 1 - 12, where 1 is January.
55
    /// \param day Day of month to use from 1 -31, where 1 is the first.
56
    /// \param hour Hour of day to use from 0 - 23, where 0 is midnight.
57
    /// \param minute Minute of hour to use from 0 - 59.
58
    /// \param second Second of minute to use from 0 - 59.
59
60
    dng_date_time (uint32 year,
61
             uint32 month,
62
             uint32 day,
63
             uint32 hour,
64
             uint32 minute,
65
             uint32 second);
66
67
    /// Predicate to determine if a date is valid.
68
    /// \retval true if all fields are within range.
69
70
    bool IsValid () const;
71
    
72
    /// Predicate to determine if a date is invalid.
73
    /// \retval true if any field is out of range.
74
75
    bool NotValid () const
76
0
      {
77
0
      return !IsValid ();
78
0
      }
79
      
80
    /// Equal operator.
81
82
    bool operator== (const dng_date_time &dt) const
83
0
      {
84
0
      return fYear   == dt.fYear   &&
85
0
           fMonth  == dt.fMonth  &&
86
0
           fDay    == dt.fDay    &&
87
0
           fHour   == dt.fHour   &&
88
0
           fMinute == dt.fMinute &&
89
0
           fSecond == dt.fSecond;
90
0
      }
91
      
92
    // Not-equal operator.
93
    
94
    bool operator!= (const dng_date_time &dt) const
95
0
      {
96
0
      return !(*this == dt);
97
0
      }
98
      
99
    /// Set date to an invalid value.
100
101
    void Clear ();
102
103
    /// Parse an EXIF format date string.
104
    /// \param s Input date string to parse.
105
    /// \retval true if date was parsed successfully and date is valid.
106
107
    bool Parse (const char *s);
108
      
109
  };
110
  
111
/*****************************************************************************/
112
113
/// \brief Class for holding a time zone.
114
115
class dng_time_zone
116
  {
117
  
118
  private:
119
  
120
    enum
121
      {
122
      
123
      kMaxOffsetHours = 15,
124
      kMinOffsetHours = -kMaxOffsetHours,
125
      
126
      kMaxOffsetMinutes = kMaxOffsetHours * 60,
127
      kMinOffsetMinutes = kMinOffsetHours * 60,
128
      
129
      kInvalidOffset = kMinOffsetMinutes - 1
130
      
131
      };
132
      
133
    // Offset from GMT in minutes.  Positive numbers are
134
    // ahead of GMT, negative number are behind GMT.
135
  
136
    int32 fOffsetMinutes;
137
    
138
  public:
139
  
140
    dng_time_zone ()
141
      : fOffsetMinutes (kInvalidOffset)
142
21.3k
      {
143
21.3k
      }
144
      
145
    void Clear ()
146
0
      {
147
0
      fOffsetMinutes = kInvalidOffset;
148
0
      }
149
      
150
    void SetOffsetHours (int32 offset)
151
121
      {
152
121
      fOffsetMinutes = SafeInt32Mult(offset, 60);
153
121
      }
154
      
155
    void SetOffsetMinutes (int32 offset)
156
0
      {
157
0
      fOffsetMinutes = offset;
158
0
      }
159
      
160
    void SetOffsetSeconds (int32 offset)
161
0
      {
162
0
      fOffsetMinutes = (offset > 0) ? ((offset + 30) / 60)
163
0
                      : ((offset - 30) / 60);
164
0
      }
165
166
    bool IsValid () const
167
0
      {
168
0
      return fOffsetMinutes >= kMinOffsetMinutes &&
169
0
           fOffsetMinutes <= kMaxOffsetMinutes;
170
0
      }
171
      
172
    bool NotValid () const
173
0
      {
174
0
      return !IsValid ();
175
0
      }
176
      
177
    int32 OffsetMinutes () const
178
0
      {
179
0
      return fOffsetMinutes;
180
0
      }
181
      
182
    bool IsExactHourOffset () const
183
0
      {
184
0
      return IsValid () && ((fOffsetMinutes % 60) == 0);
185
0
      }
186
      
187
    int32 ExactHourOffset () const
188
0
      {
189
0
      return fOffsetMinutes / 60;
190
0
      }
191
      
192
    dng_string Encode_ISO_8601 () const;
193
      
194
  };
195
196
/*****************************************************************************/
197
198
/// \brief Class for holding complete data/time/zone information.
199
200
class dng_date_time_info
201
  {
202
  
203
  private:
204
  
205
    // Is only the date valid and not the time? 
206
  
207
    bool fDateOnly;
208
    
209
    // Date and time.
210
    
211
    dng_date_time fDateTime;
212
    
213
    // Subseconds string (stored in a separate tag in EXIF).
214
    
215
    dng_string fSubseconds;
216
    
217
    // Time zone, if known.
218
    
219
    dng_time_zone fTimeZone;
220
    
221
  public:
222
  
223
    dng_date_time_info ();
224
    
225
    bool IsValid () const;
226
    
227
    bool NotValid () const
228
2.83k
      {
229
2.83k
      return !IsValid ();
230
2.83k
      }
231
      
232
    void Clear ()
233
0
      {
234
0
      *this = dng_date_time_info ();
235
0
      }
236
      
237
    const dng_date_time & DateTime () const
238
0
      {
239
0
      return fDateTime;
240
0
      }
241
      
242
    void SetDateTime (const dng_date_time &dt)
243
440
      {
244
440
      fDateOnly = false;
245
440
      fDateTime = dt;
246
440
      }
247
      
248
    const dng_string & Subseconds () const
249
0
      {
250
0
      return fSubseconds;
251
0
      }
252
      
253
    void SetSubseconds (const dng_string &s)
254
362
      {
255
362
      fSubseconds = s;
256
362
      }
257
      
258
    const dng_time_zone & TimeZone () const
259
0
      {
260
0
      return fTimeZone;
261
0
      }
262
      
263
    void SetZone (const dng_time_zone &zone)
264
104
      {
265
104
      fTimeZone = zone;
266
104
      }
267
      
268
    void Decode_ISO_8601 (const char *s);
269
    
270
    dng_string Encode_ISO_8601 () const;
271
    
272
    void Decode_IPTC_Date (const char *s);
273
    
274
    dng_string Encode_IPTC_Date () const;
275
  
276
    void Decode_IPTC_Time (const char *s);
277
    
278
    dng_string Encode_IPTC_Time () const;
279
    
280
  private:
281
  
282
    void SetDate (uint32 year,
283
            uint32 month,
284
            uint32 day);
285
            
286
    void SetTime (uint32 hour,
287
            uint32 minute,
288
            uint32 second);
289
            
290
  };
291
292
/*****************************************************************************/
293
294
/// Get the current date/time and timezone.
295
/// \param info Receives current data/time/zone.
296
297
void CurrentDateTimeAndZone (dng_date_time_info &info);
298
299
/*****************************************************************************/
300
301
/// Convert UNIX "seconds since Jan 1, 1970" time to a dng_date_time
302
303
void DecodeUnixTime (uint32 unixTime, dng_date_time &dt);
304
305
/*****************************************************************************/
306
307
/// Return timezone of current location at a given date.
308
/// \param dt Date at which to compute timezone difference. (For example, used 
309
/// to determine Daylight Savings, etc.)
310
/// \retval Time zone for date/time dt.
311
312
dng_time_zone LocalTimeZone (const dng_date_time &dt);
313
314
/*****************************************************************************/
315
316
/// Tag to encode date represenation format
317
318
enum dng_date_time_format
319
  {
320
  dng_date_time_format_unknown            = 0, /// Date format not known
321
  dng_date_time_format_exif               = 1, /// EXIF date string
322
  dng_date_time_format_unix_little_endian = 2, /// 32-bit UNIX time as 4-byte little endian
323
  dng_date_time_format_unix_big_endian    = 3  /// 32-bit UNIX time as 4-byte big endian
324
  };
325
326
/*****************************************************************************/
327
328
/// \brief Store file offset from which date was read.
329
///
330
/// Used internally by Adobe to update date in original file.
331
/// \warning Use at your own risk.
332
333
class dng_date_time_storage_info
334
  {
335
  
336
  private:
337
  
338
    uint64 fOffset;
339
    
340
    dng_date_time_format fFormat;
341
  
342
  public:
343
  
344
    /// The default constructor initializes to an invalid state.
345
346
    dng_date_time_storage_info ();
347
    
348
    /// Construct with file offset and date format.
349
350
    dng_date_time_storage_info (uint64 offset,
351
                  dng_date_time_format format);
352
    
353
    /// Predicate to determine if an offset is valid.
354
    /// \retval true if offset is valid.
355
356
    bool IsValid () const;
357
    
358
    // The accessors throw if the data is not valid.
359
360
    /// Getter for offset in file.
361
    /// \exception dng_exception with fErrorCode equal to dng_error_unknown
362
    /// if offset is not valid.
363
364
    uint64 Offset () const;
365
      
366
    /// Get for format date was originally stored in file. Throws a 
367
    /// dng_error_unknown exception if offset is invalid.
368
    /// \exception dng_exception with fErrorCode equal to dng_error_unknown
369
    /// if offset is not valid.
370
371
    dng_date_time_format Format () const;
372
  
373
  };
374
375
/*****************************************************************************/
376
377
// Kludge: Global boolean to turn on fake time zones in XMP for old software.
378
379
extern bool gDNGUseFakeTimeZonesInXMP;
380
381
/*****************************************************************************/
382
383
#endif
384
  
385
/*****************************************************************************/