am f73c044f: am d34d5cc5: reconcile main tree with open-source eclair

Merge commit 'f73c044f4fd4e8f51fcb0aa93e5a79e9e4f10b25'

* commit 'f73c044f4fd4e8f51fcb0aa93e5a79e9e4f10b25':
  android-2.1_r1 snapshot
diff --git a/exif.c b/exif.c
index 1efe3d9..f7a6365 100644
--- a/exif.c
+++ b/exif.c
@@ -717,7 +717,8 @@
             case TAG_FOCALLENGTH:
                 // Nice digital cameras actually save the focal length as a function
                 // of how farthey are zoomed in.
-                ImageInfo.FocalLength = (float)ConvertAnyFormat(ValuePtr, Format);
+                ImageInfo.FocalLength.num = Get32u(ValuePtr);
+                ImageInfo.FocalLength.denom = Get32u(4+(char *)ValuePtr);
                 break;
 
             case TAG_SUBJECT_DISTANCE:
@@ -1047,10 +1048,13 @@
         // that Jhad can do about it - its a camera problem.
         ImageInfo.CCDWidth = (float)(ExifImageWidth * FocalplaneUnits / FocalplaneXRes);
 
-        if (ImageInfo.FocalLength && ImageInfo.FocalLength35mmEquiv == 0){
+        if (ImageInfo.FocalLength.num != 0 && ImageInfo.FocalLength.denom != 0
+            && ImageInfo.FocalLength35mmEquiv == 0){
             // Compute 35 mm equivalent focal length based on sensor geometry if we haven't
             // already got it explicitly from a tag.
-            ImageInfo.FocalLength35mmEquiv = (int)(ImageInfo.FocalLength/ImageInfo.CCDWidth*36 + 0.5);
+            ImageInfo.FocalLength35mmEquiv = (int)(
+                (double)ImageInfo.FocalLength.num / ImageInfo.FocalLength.denom
+                / ImageInfo.CCDWidth * 36 + 0.5);
         }
     }
 }
@@ -1559,8 +1563,8 @@
     }
 
 
-    if (ImageInfo.FocalLength){
-        printf("Focal length : %4.1fmm",(double)ImageInfo.FocalLength);
+    if (ImageInfo.FocalLength.num != 0 && ImageInfo.FocalLength.denom != 0) {
+        printf("Focal length : %4.1fmm",(double)ImageInfo.FocalLength.num / ImageInfo.FocalLength.denom);
         if (ImageInfo.FocalLength35mmEquiv){
             printf("  (35mm equivalent: %dmm)", ImageInfo.FocalLength35mmEquiv);
         }
diff --git a/gpsinfo.c b/gpsinfo.c
index 18b9d07..afd4b12 100644
--- a/gpsinfo.c
+++ b/gpsinfo.c
@@ -15,7 +15,8 @@
 #define TAG_GPS_LONG       4
 #define TAG_GPS_ALT_REF    5
 #define TAG_GPS_ALT        6
-
+#define TAG_GPS_TIMESTAMP  7
+#define TAG_GPS_DATESTAMP  29
 
 static TagTable_t GpsTags[]= {
     { 0x00, "GPSVersionID", FMT_BYTE, 4},
@@ -135,6 +136,8 @@
     strcpy(ImageInfo.GpsLat, "? ?");
     strcpy(ImageInfo.GpsLong, "? ?");
     ImageInfo.GpsAlt[0] = 0;
+    bzero(ImageInfo.GpsTimeStamp, sizeof(ImageInfo.GpsTimeStamp));
+    bzero(ImageInfo.GpsDateStamp, sizeof(ImageInfo.GpsDateStamp));
 
     for (de=0;de<NumDirEntries;de++){
         unsigned Tag, Format, Components;
@@ -248,6 +251,19 @@
                 sprintf(ImageInfo.GpsAlt + 1, "%.2fm", 
                     ConvertAnyFormat(ValuePtr, Format));
                 break;
+
+            case TAG_GPS_TIMESTAMP:
+                snprintf(ImageInfo.GpsTimeStamp,
+                    sizeof(ImageInfo.GpsTimeStamp), "%d:%d:%d",
+                    (int) ConvertAnyFormat(ValuePtr, Format),
+                    (int) ConvertAnyFormat(ValuePtr + 8, Format),
+                    (int) ConvertAnyFormat(ValuePtr + 16, Format)
+                );
+                break;
+
+            case TAG_GPS_DATESTAMP:
+                strncpy(ImageInfo.GpsDateStamp, (char*)ValuePtr, sizeof(ImageInfo.GpsDateStamp));
+                break;
         }
 
         if (ShowTags){
diff --git a/jhead.c b/jhead.c
index 88bd527..5740db6 100644
--- a/jhead.c
+++ b/jhead.c
@@ -115,8 +115,8 @@
 //--------------------------------------------------------------------------
 void ErrNonfatal(char * msg, int a1, int a2)
 {
-    LOGE("Nonfatal Error : ");
-    LOGE(msg, a1, a2);
+    LOGV("Nonfatal Error : ");
+    LOGV(msg, a1, a2);
     if (SupressNonFatalErrors) return;
 
     fprintf(stderr,"\nNonfatal Error : ");
diff --git a/jhead.h b/jhead.h
index 1540d94..f12393b 100644
--- a/jhead.h
+++ b/jhead.h
@@ -1,9 +1,9 @@
 //--------------------------------------------------------------------------
 // Include file for jhead program.
 //
-// This include file only defines stuff that goes across modules.  
-// I like to keep the definitions for macros and structures as close to 
-// where they get used as possible, so include files only get stuff that 
+// This include file only defines stuff that goes across modules.
+// I like to keep the definitions for macros and structures as close to
+// where they get used as possible, so include files only get stuff that
 // gets used in more than one file.
 //--------------------------------------------------------------------------
 #define _CRT_SECURE_NO_DEPRECATE 1
@@ -14,6 +14,7 @@
 #include <time.h>
 #include <errno.h>
 #include <ctype.h>
+#include <stdint.h>
 
 //--------------------------------------------------------------------------
 
@@ -59,6 +60,11 @@
 
 #define MAX_DATE_COPIES 10
 
+typedef struct {
+    uint32_t num;
+    uint32_t denom;
+} rat_t;
+
 //--------------------------------------------------------------------------
 // This structure stores Exif header image elements in a simple manner
 // Used to store camera data as extracted from the various ways that it can be
@@ -75,7 +81,7 @@
     int   IsColor;
     int   Process;
     int   FlashUsed;
-    float FocalLength;
+    rat_t FocalLength;
     float ExposureTime;
     float ApertureFNumber;
     float Distance;
@@ -113,6 +119,9 @@
     char GpsLongRaw[31];
     char GpsLongRef[2];
     char GpsAlt[20];
+    // gps-datestamp is 11 bytes ascii in EXIF 2.2
+    char GpsDateStamp[11];
+    char GpsTimeStamp[11];
 }ImageInfo_t;
 
 
@@ -171,7 +180,7 @@
 extern const int BytesPerFormat[];
 #define NUM_FORMATS 12
 
-#define FMT_BYTE       1 
+#define FMT_BYTE       1
 #define FMT_STRING     2
 #define FMT_USHORT     3
 #define FMT_ULONG      4
@@ -190,7 +199,7 @@
                  unsigned char * OffsetBase, unsigned ExifLength);
 
 // gpsinfo.c prototypes
-void ProcessGpsInfo(unsigned char * ValuePtr, int ByteCount, 
+void ProcessGpsInfo(unsigned char * ValuePtr, int ByteCount,
                 unsigned char * OffsetBase, unsigned ExifLength);
 int IsGpsTag(const char* tag);
 int GpsTagToFormatType(unsigned short tag);
@@ -255,7 +264,7 @@
 #define M_JFIF  0xE0          // Jfif marker
 #define M_EXIF  0xE1          // Exif marker.  Also used for XMP data!
 #define M_XMP   0x10E1        // Not a real tag (same value in file as Exif!)
-#define M_COM   0xFE          // COMment 
+#define M_COM   0xFE          // COMment
 #define M_DQT   0xDB
 #define M_DHT   0xC4
 #define M_DRI   0xDD
diff --git a/main.c b/main.c
index f0bc9be..6ea1219 100644
--- a/main.c
+++ b/main.c
@@ -517,6 +517,13 @@
     return addKeyValueString(buf, bufLen, key, valueStr);
 }
 
+// Returns new buffer length. Rational value will be appended as "numerator/denominator".
+static int addKeyValueRational(char** buf, int bufLen, const char* key, rat_t value) {
+    char valueStr[25];
+    snprintf(valueStr, sizeof(valueStr), "%u/%u", value.num, value.denom);
+    return addKeyValueString(buf, bufLen, key, valueStr);
+}
+
 static jstring getAttributes(JNIEnv *env, jobject jobj, jstring jfilename)
 {
 #ifdef SUPERDEBUG
@@ -571,8 +578,8 @@
     bufLen = addKeyValueInt(&buf, bufLen, "Flash", ImageInfo.FlashUsed);
     if (bufLen == 0) return NULL;
 
-    if (ImageInfo.FocalLength){
-        bufLen = addKeyValueInt(&buf, bufLen, "FocalLength", ImageInfo.FocalLength);
+    if (ImageInfo.FocalLength.num != 0 && ImageInfo.FocalLength.denom != 0) {
+        bufLen = addKeyValueRational(&buf, bufLen, "FocalLength", ImageInfo.FocalLength);
         if (bufLen == 0) return NULL;
     }
 
@@ -651,6 +658,14 @@
             bufLen = addKeyValueString(&buf, bufLen, "GPSAltitude", ImageInfo.GpsAlt);
             if (bufLen == 0) return NULL;
         }
+        if (ImageInfo.GpsDateStamp[0]) {
+            bufLen = addKeyValueString(&buf, bufLen, "GPSDateStamp", ImageInfo.GpsDateStamp);
+            if (bufLen == 0) return NULL;
+        }
+        if (ImageInfo.GpsTimeStamp[0]) {
+            bufLen = addKeyValueString(&buf, bufLen, "GPSTimeStamp", ImageInfo.GpsTimeStamp);
+            if (bufLen == 0) return NULL;
+        }
     }
 
     if (ImageInfo.Comments[0]) {