diff -ru jhead-2.4/exif.c jhead-2.4-nikon/exif.c
--- jhead-2.4/exif.c	2005-06-10 15:39:56.000000000 +0200
+++ jhead-2.4-nikon/exif.c	2005-11-20 14:35:26.000000000 +0100
@@ -5,6 +5,8 @@
 // This module parses the very complicated exif structures.
 //
 // Matthias Wandel,  Dec 1999 - Dec 2002 
+//
+// adapted Nikon support to jhead-2.4 - Heiko Purnhagen 2005-11-20
 //--------------------------------------------------------------------------
 #include <stdio.h>
 #include <stdlib.h>
@@ -33,6 +35,8 @@
 static double FocalplaneUnits;
 static int ExifImageWidth;
 static int MotorolaOrder = 0;
+static int isNikonEmbedded = 0;
+
 
 // for fixing the rotation.
 static void * OrientationPtr;
@@ -88,8 +92,8 @@
     "transverse",       // flipped about top-right <--> bottom-left axis
     "rotate 270",       // rotate 270 to right it.
 };
-
-const int BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
+
+const int BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
 
 //--------------------------------------------------------------------------
 // Describes tag values
@@ -130,6 +134,18 @@
 #define TAG_DIGITALZOOMRATIO   0xA404
 #define TAG_FOCALLENGTH_35MM   0xa405
 
+/* Nikon specific tags */
+#define TAG_NIKON_ISO_EQUIVALENT        0x0013
+#define TAG_NIKON_LENS_INFO             0x0084
+#define TAG_NIKON_NOISE_REDUCTION       0x0095
+#define TAG_NIKON_FLASH_SETTING         0x0008
+#define TAG_NIKON_FLASH_METERING        0x0009
+#define TAG_NIKON_IMAGE_SHARPENING      0x0006
+#define TAG_NIKON_AF_POSITION           0x0088
+#define TAG_NIKON_WHITEBALANCE          0x0005
+#define TAG_NIKON_WHITEBALANCE_BIAS     0x000B
+#define TAG_NIKON_FOCUSMODE             0x0007
+ 
 static const TagTable_t TagTable[] = {
   { 0x001,   "InteropIndex"},
   { 0x002,   "InteropVersion"},
@@ -234,6 +250,41 @@
 
 #define TAG_TABLE_SIZE  (sizeof(TagTable) / sizeof(TagTable_t))
 
+static TagTable_t NikonTagTable[] = {
+  {    0x1,  "NikonDataVersion"}, // Unknown
+  {    0x2,  "NikonISOEquiv"}, // ISO 
+  {    0x4,  "NikonJPEGQuality"},
+  {    0x5,  "NikonWhiteBalance"}, // White balance
+  {    0x6,  "NikonImageSharpening"}, // Image sharpening
+  {    0x7,  "NikonFocusMode"},
+  {    0x8,  "NikonFlashSetting"}, // Flash setting
+  {    0x9,  "NikonFlashMeteringMode"}, 
+  {    0xb,  "NikonWhiteBalanceBias"},
+  {    0xd,  "NikonUnknown000d"},
+  {    0xe,  "NikonUnknown000e"},
+  {   0x11,  "NikonUnknown0011"},
+  {   0x12,  "NikonUnknown0012"},
+  {   0x13,  "NikonISOEquiv2"}, // ISO again?
+  {   0x81,  "NikonToneCompensation"},
+  {   0x83,  "NikonUnknown0083"},
+  {   0x84,  "NikonLensInformation"}, // 
+  {   0x87,  "NikonUnknown0087"},
+  {   0x88,  "NikonAFFocusPosition"},
+  {   0x89,  "NikonShootingMode"},
+  {   0x8a,  "NikonUnknown008a"},
+  {   0x8b,  "NikonUnknown008b"}, 
+  {   0x8d,  "NikonColorMode"},
+  {   0x90,  "NikonFlashIdentifier"}, // SPEEDLIGHT (others?)
+  {   0x91,  "NikonUnknown0091"}, // binary
+  {   0x92,  "NikonHueAdjustment"},
+  {   0x95,  "NikonNoiseReduction"},
+  {   0x97,  "NikonUnknown0097"}, // binary
+  {   0x98,  "NikonUnknown0098"}, // binary
+  {   0x9a,  "NikonUnknown009a"}, // 7.8, 7.8
+};
+
+#define NIKON_TAG_TABLE_SIZE  (sizeof(NikonTagTable) / sizeof(TagTable_t))
+
 //--------------------------------------------------------------------------
 // Convert a 16 bit unsigned value from file's native byte order
 //--------------------------------------------------------------------------
@@ -442,6 +493,19 @@
         if (ShowTags){
             // Show tag name
             for (a=0;;a++){
+		if (isNikonEmbedded != 0){
+		    if (a >= NIKON_TAG_TABLE_SIZE){
+			printf(IndentString);
+			printf("    Unknown NikonTag %04x Value = ", Tag);
+			break;
+		    }
+		    if (NikonTagTable[a].Tag == Tag){
+			printf(IndentString);
+			printf("    %s = ",NikonTagTable[a].Desc);
+			break;
+	    	    }
+		    continue;
+	        }
                 if (a >= TAG_TABLE_SIZE){
                     printf(IndentString);
                     printf("    Unknown Tag %04x Value = ", Tag);
@@ -500,7 +564,6 @@
                 strncpy(ImageInfo.CameraModel, ValuePtr, 39);
                 break;
 
-
             case TAG_DATETIME_ORIGINAL:
                 // If we get a DATETIME_ORIGINAL, we use that one.
                 strncpy(ImageInfo.DateTime, ValuePtr, 19);
@@ -557,7 +620,6 @@
                 break;
 
             case TAG_APERTURE:
-            case TAG_MAXAPERTURE:
                 // More relevant info always comes earlier, so only use this field if we don't 
                 // have appropriate aperture information yet.
                 if (ImageInfo.ApertureFNumber == 0){
@@ -566,6 +628,13 @@
                 }
                 break;
 
+            case TAG_MAXAPERTURE:
+                if (ImageInfo.MaxApertureFNumber == 0){
+                    ImageInfo.MaxApertureFNumber 
+                        = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2)*0.5);
+                }
+                break;
+
             case TAG_FOCALLENGTH:
                 // Nice digital cameras actually save the focal length as a function
                 // of how farthey are zoomed in.
@@ -697,7 +766,6 @@
 
             case TAG_EXIF_OFFSET:
                 if (ShowTags) printf("%s    Exif Dir:",IndentString);
-
             case TAG_INTEROP_OFFSET:
                 if (Tag == TAG_INTEROP_OFFSET && ShowTags) printf("%s    Interop Dir:",IndentString);
                 {
@@ -732,6 +800,55 @@
                 // computing it from sensor geometry and actual focal length.
                 ImageInfo.FocalLength35mmEquiv = (unsigned)ConvertAnyFormat(ValuePtr, Format);
                 break;
+
+            case TAG_NIKON_ISO_EQUIVALENT:
+                ImageInfo.ISOequivalent = (int)ConvertAnyFormat(ValuePtr+2,Format);
+                break;
+                
+            case TAG_NIKON_LENS_INFO:
+                {
+                    int minMM, maxMM;
+		    float minAper, maxAper;
+                
+		    minMM = (int)ConvertAnyFormat(ValuePtr+0,Format);
+		    maxMM = (int)ConvertAnyFormat(ValuePtr+8,Format);
+		    minAper = (float)ConvertAnyFormat(ValuePtr+16,Format);
+		    maxAper = (float)ConvertAnyFormat(ValuePtr+24,Format);
+		    snprintf(ImageInfo.Lens,55,"%d-%d mm f/%.1f-%.1f",
+			     minMM, maxMM, minAper, maxAper);
+                }
+                break;
+            
+            case TAG_NIKON_NOISE_REDUCTION:
+                if (memcmp(ValuePtr,"OFF",3))
+                        ImageInfo.NoiseReduction = 1;
+                    else 
+                        ImageInfo.NoiseReduction = 0;
+                break;
+            
+            case TAG_NIKON_FLASH_SETTING:
+                strncpy(ImageInfo.FlashSetting,ValuePtr,15);
+                break;
+            case TAG_NIKON_FLASH_METERING:
+                strncpy(ImageInfo.FlashMetering,ValuePtr,15);
+                break;
+            case TAG_NIKON_IMAGE_SHARPENING:
+                strncpy(ImageInfo.ImageSharpening,ValuePtr,15);
+                break;
+            case TAG_NIKON_WHITEBALANCE:
+                strncpy(ImageInfo.WhitebalanceName,ValuePtr,15);
+                break;
+            case TAG_NIKON_WHITEBALANCE_BIAS:
+                ImageInfo.WhitebalanceBias = (float)ConvertAnyFormat(ValuePtr, Format);
+                break;
+            case TAG_NIKON_AF_POSITION:
+                ImageInfo.AFPosition = *(long *)ValuePtr;
+                break;
+                
+            case TAG_NIKON_FOCUSMODE:
+                strncpy(ImageInfo.FocusMode, ValuePtr, 15);
+                break;
+
         }
     }
 
@@ -802,13 +919,20 @@
     ExifImageWidth = 0;
     OrientationPtr = NULL;
 
-
     if (ShowTags){
         printf("Exif header %d bytes long\n",length);
     }
-
+    isNikonEmbedded = 0;
     {   // Check the EXIF header component
         static uchar ExifHeader[] = "Exif\0\0";
+
+        if (memcmp(ExifSection+2, "\x6e\0\2\0\0\0", 6)==0) {
+	    // This is an embedded EXIF header in a Nikon MakerNote
+            isNikonEmbedded = 1;
+	} else if (memcmp(ExifSection+2, "\x6e\0\2\x10\0\0", 6)==0) {
+	    // This is an embedded EXIF header in a Nikon MakerNote (D70 HP20050129)
+            isNikonEmbedded = 1;
+	} else
         if (memcmp(ExifSection+2, ExifHeader,6)){
             ErrNonfatal("Incorrect Exif header",0,0);
             return;
@@ -847,6 +971,7 @@
     // First directory starts 16 bytes in.  All offset are relative to 8 bytes in.
     ProcessExifDir(ExifSection+8+FirstOffset, ExifSection+8, length-6, 0);
 
+    isNikonEmbedded = 0;
     // Compute the CCD width, in millimeters.
     if (FocalplaneXRes != 0){
         // Note: With some cameras, its not possible to compute this correctly because
@@ -863,7 +988,7 @@
     }
 
     if (ShowTags){
-        printf("Non settings part of Exif header: %d bytes\n",ExifSection+length-LastExifRefd);
+      printf("Non settings part of Exif header: %d bytes\n",(int)(ExifSection+length-LastExifRefd));
     }
 }
 
@@ -1000,6 +1125,8 @@
         printf("Camera make  : %s\n",ImageInfo.CameraMake);
         printf("Camera model : %s\n",ImageInfo.CameraModel);
     }
+    if (ImageInfo.Lens[0])
+        printf("Lens         : %s\n",ImageInfo.Lens);
     if (ImageInfo.DateTime[0]){
         printf("Date/Time    : %s\n",ImageInfo.DateTime);
     }
@@ -1036,6 +1163,10 @@
 	            case 0x5d:printf(" (auto, red eye reduction mode, return light not detected)"); break;
 	            case 0x5f:printf(" (auto, red eye reduction mode, return light detected)"); break;
             }
+            if (ImageInfo.FlashSetting[0])
+                printf(", %s", ImageInfo.FlashSetting);
+            if (ImageInfo.FlashMetering[0])
+                printf(", metering %s", ImageInfo.FlashMetering);
         }else{
             printf("Flash used   : No");
             switch (ImageInfo.FlashUsed){
@@ -1045,18 +1176,17 @@
         printf("\n");
     }
 
-
     if (ImageInfo.FocalLength){
-        printf("Focal length : %4.1fmm",(double)ImageInfo.FocalLength);
+        printf("Focal length : %4.1f mm",(double)ImageInfo.FocalLength);
         if (ImageInfo.FocalLength35mmEquiv){
-            printf("  (35mm equivalent: %dmm)", ImageInfo.FocalLength35mmEquiv);
+            printf("  (35 mm equivalent: %d mm)", ImageInfo.FocalLength35mmEquiv);
         }
         printf("\n");
     }
 
     if (ImageInfo.DigitalZoomRatio > 1){
         // Digital zoom used.  Shame on you!
-        printf("Digital Zoom : %1.3fx\n", (double)ImageInfo.DigitalZoomRatio);
+        printf("Digital zoom : %1.3fx\n", (double)ImageInfo.DigitalZoomRatio);
     }
 
     if (ImageInfo.CCDWidth){
@@ -1065,18 +1195,28 @@
 
     if (ImageInfo.ExposureTime){
         if (ImageInfo.ExposureTime < 0.010){
-            printf("Exposure time: %6.4f s ",(double)ImageInfo.ExposureTime);
-        }else{
+            printf("Exposure time: %7.5f s ",(double)ImageInfo.ExposureTime);
+        } else{
             printf("Exposure time: %5.3f s ",(double)ImageInfo.ExposureTime);
         }
-        if (ImageInfo.ExposureTime <= 0.5){
+        if (ImageInfo.ExposureTime <= 0.105) {
             printf(" (1/%d)",(int)(0.5 + 1/ImageInfo.ExposureTime));
+        } else if (ImageInfo.ExposureTime < 1) {
+            printf(" (1/%3.1f)",1/ImageInfo.ExposureTime);
+        } else if (ImageInfo.ExposureTime < 10) {
+            printf(" (%3.1f)",ImageInfo.ExposureTime);
+        } else {
+            printf(" (%d)",(int)(0.5 + ImageInfo.ExposureTime));
         }
         printf("\n");
     }
     if (ImageInfo.ApertureFNumber){
         printf("Aperture     : f/%3.1f\n",(double)ImageInfo.ApertureFNumber);
     }
+    if (ImageInfo.MaxApertureFNumber){
+        printf("Max Aperture : f/%3.1f\n",(double)ImageInfo.MaxApertureFNumber);
+    }
+
     if (ImageInfo.Distance){
         if (ImageInfo.Distance < 0){
             printf("Focus dist.  : Infinite\n");
@@ -1084,6 +1224,30 @@
             printf("Focus dist.  : %4.2fm\n",(double)ImageInfo.Distance);
         }
     }
+    if (ImageInfo.FocusMode[0]){
+        printf("Focus Mode   : %s\n", ImageInfo.FocusMode);
+    }
+    if (ImageInfo.AFPosition){
+        switch ((ImageInfo.AFPosition & 0x0000ff00) >> 8) {
+                case 0x00:
+                        printf("AF position  : center\n");
+                        break;
+                case 0x04:
+                        printf("AF position  : right\n");
+                        break;
+                case 0x03:
+                        printf("AF position  : left\n");
+                        break;
+                case 0x02:
+                        printf("AF position  : bottom\n");
+                        break;
+                case 0x01:
+                        printf("AF position  : top\n");
+                        break;
+                default:
+                printf("AF position  : 0x%08lx\n", ImageInfo.AFPosition);
+        }
+    }
 
     if (ImageInfo.ISOequivalent){
         printf("ISO equiv.   : %2d\n",(int)ImageInfo.ISOequivalent);
@@ -1095,6 +1259,10 @@
         printf("Exposure bias: %4.2f\n",(double)ImageInfo.ExposureBias);
     }
         
+    if (ImageInfo.WhitebalanceName[0]){
+       printf("Whitebal.name: %s\n", ImageInfo.WhitebalanceName);
+    }
+
     switch(ImageInfo.Whitebalance) {
         case 1:
             printf("Whitebalance : Manual\n");
@@ -1107,24 +1275,30 @@
     //Quercus: 17-1-2004 Added LightSource, some cams return this, whitebalance or both
     switch(ImageInfo.LightSource) {
         case 1:
-            printf("Light Source : Daylight\n");
+            printf("Light source : Daylight\n");
             break;
         case 2:
-            printf("Light Source : Fluorescent\n");
+            printf("Light source : Fluorescent\n");
             break;
         case 3:
-            printf("Light Source : Incandescent\n");
+            printf("Light source : Incandescent\n");
             break;
         case 4:
-            printf("Light Source : Flash\n");
+            printf("Light source : Flash\n");
             break;
         case 9:
-            printf("Light Source : Fine weather\n");
+            printf("Light source : Fine weather\n");
             break;
+	case 10:
+	    printf("Light source : Cloudy\n");
+	    break;
         case 11:
-            printf("Light Source : Shade\n");
+            printf("Light source : Shade\n");
             break;
-        default:; //Quercus: 17-1-2004 There are many more modes for this, check Exif2.2 specs
+        default:
+	    printf("Light source : %d (unknown)\n",ImageInfo.LightSource); 
+	    // XXX WAC - If we don't know it should be added not ignored.
+	    //Quercus: 17-1-2004 There are many more modes for this, check Exif2.2 specs
             // If it just says 'unknown' or we don't know it, then
             // don't bother showing it - it doesn't add any useful information.
     }
@@ -1132,13 +1306,13 @@
     if (ImageInfo.MeteringMode){ // 05-jan-2001 vcs
         switch(ImageInfo.MeteringMode) {
         case 2:
-            printf("Metering Mode: center weight\n");
+            printf("Metering mode: center weight\n");
             break;
         case 3:
-            printf("Metering Mode: spot\n");
+            printf("Metering mode: spot\n");
             break;
         case 5:
-            printf("Metering Mode: matrix\n");
+            printf("Metering mode: matrix\n");
             break;
         }
     }
@@ -1149,25 +1323,25 @@
             printf("Exposure     : Manual\n");
             break;
         case 2:
-            printf("Exposure     : program (auto)\n");
+            printf("Exposure     : Program (auto)\n");
             break;
         case 3:
-            printf("Exposure     : aperture priority (semi-auto)\n");
+            printf("Exposure     : Aperture priority (semi-auto)\n");
             break;
         case 4:
-            printf("Exposure     : shutter priority (semi-auto)\n");
+            printf("Exposure     : Shutter priority (semi-auto)\n");
             break;
         case 5:
-            printf("Exposure     : Creative Program (based towards depth of field\n"); 
+            printf("Exposure     : Creative program (based towards depth of field\n"); 
             break;
         case 6:
             printf("Exposure     : Action program (based towards fast shutter speed)\n");
             break;
         case 7:
-            printf("Exposure     : Portrait Mode\n");
+            printf("Exposure     : Portrait mode\n");
             break;
         case 8:
-            printf("Exposure     : LandscapeMode \n");
+            printf("Exposure     : Landscape mode \n");
             break;
         default:
             break;
@@ -1176,8 +1350,8 @@
     switch(ImageInfo.ExposureMode){
         case 0: // Automatic (not worth cluttering up output for)
             break;
-        case 1: printf("Exposure Mode: Manual\n");
-        case 2: printf("Exposure Mode: Auto bracketing\n");
+        case 1: printf("Exposure mode: Manual\n");
+        case 2: printf("Exposure mode: Auto bracketing\n");
     }
 
 
@@ -1197,6 +1371,13 @@
             }
         }
     }
+    if (ImageInfo.NoiseReduction){
+        printf("Noise reduct.: Yes\n");
+    } else printf("Noise reduct.: No\n");
+        
+    if (ImageInfo.ImageSharpening[0])
+        printf("Sharpening   : %s\n", ImageInfo.ImageSharpening);
+
 
     if (ImageInfo.GpsInfoPresent){
         printf("GPS Latitude : %s\n",ImageInfo.GpsLat);
@@ -1237,15 +1418,57 @@
     printf(" %dx%d",ImageInfo.Width, ImageInfo.Height);
 
     if (ImageInfo.ExposureTime){
-        printf(" (1/%d)",(int)(0.5 + 1/ImageInfo.ExposureTime));
+        if (ImageInfo.ExposureTime <= 0.105) {
+            printf(" 1/%d",(int)(0.5 + 1/ImageInfo.ExposureTime));
+        } else if (ImageInfo.ExposureTime < 1) {
+            printf(" 1/%3.1f",1/ImageInfo.ExposureTime);
+        } else if (ImageInfo.ExposureTime < 10) {
+            printf(" %3.1f",ImageInfo.ExposureTime);
+        } else {
+            printf(" %d",(int)(0.5 + ImageInfo.ExposureTime));
+        }
     }
 
     if (ImageInfo.ApertureFNumber){
         printf(" f/%3.1f",(double)ImageInfo.ApertureFNumber);
     }
 
-    if (ImageInfo.FocalLength35mmEquiv){
-        printf(" f(35)=%dmm",ImageInfo.FocalLength35mmEquiv);
+    if (ImageInfo.FocalLength){
+        printf(" %4.1fmm",ImageInfo.FocalLength);
+    }
+
+    if (ImageInfo.ExposureProgram){ // 05-jan-2001 vcs
+        switch(ImageInfo.ExposureProgram) {
+        case 1:
+            printf(" M%+3.1f",(double)ImageInfo.ExposureBias);
+            break;
+        case 2:
+            printf(" P%+3.1f",(double)ImageInfo.ExposureBias);
+            break;
+        case 3:
+            printf(" A%+3.1f",(double)ImageInfo.ExposureBias);
+            break;
+        case 4:
+            printf(" S%+3.1f",(double)ImageInfo.ExposureBias);
+            break;
+        default:
+            break;
+        }
+    }
+
+    if (ImageInfo.ISOequivalent){
+        printf(" ISO:%2d",(int)ImageInfo.ISOequivalent);
+    }
+
+    if (ImageInfo.WhitebalanceName[0]){
+        char *c = ImageInfo.WhitebalanceName;
+	while(*c) { // strip trailing space
+	  if (*c==' ')
+            *c = '\0';
+          else
+            c++;
+	}
+        printf(" WB:%s", ImageInfo.WhitebalanceName);
     }
 
     if (ImageInfo.FlashUsed >= 0 && ImageInfo.FlashUsed & 1){
diff -ru jhead-2.4/jhead.c jhead-2.4-nikon/jhead.c
--- jhead-2.4/jhead.c	2005-06-10 15:39:56.000000000 +0200
+++ jhead-2.4-nikon/jhead.c	2005-11-20 14:05:18.000000000 +0100
@@ -11,6 +11,8 @@
 // Dec 1999 - Jun 2005
 //
 // by Matthias Wandel   www.sentex.net/~mwandel
+//
+// adapted Nikon support to jhead-2.4 - Heiko Purnhagen 2005-11-20
 //--------------------------------------------------------------------------
 #include <stdio.h>
 #include <stdlib.h>
@@ -22,7 +24,7 @@
 #include <errno.h>
 #include <ctype.h>
 
-#define JHEAD_VERSION "2.4-2"
+#define JHEAD_VERSION "2.4-2hp1"
 
 // This #define turns on features that are too very specific to 
 // how I organize my photos.  Best to ignore everything inside #ifdef MATTHIAS
@@ -980,6 +982,7 @@
            "  -dt        Remove exif integral thumbnails.   Typically trims 10k\n"
            "  -h         help (this text)\n"
            "  -v         even more verbose output\n"
+           "  -V         Show version info\n"
            "  -se        Supress error messages relating to corrupt exif header structure\n"
            "  -c         concise output\n"
            "  -nofinfo   Don't show file info (name/size/date)\n"
diff -ru jhead-2.4/jhead.h jhead-2.4-nikon/jhead.h
--- jhead-2.4/jhead.h	2005-06-10 15:39:56.000000000 +0200
+++ jhead-2.4-nikon/jhead.h	2005-11-20 13:56:03.000000000 +0100
@@ -49,6 +49,7 @@
     float FocalLength;
     float ExposureTime;
     float ApertureFNumber;
+    float MaxApertureFNumber;
     float Distance;
     float CCDWidth;
     float ExposureBias;
@@ -60,6 +61,17 @@
     int   ExposureMode;
     int   ISOequivalent;
     int   LightSource;
+
+    char  Lens[56];
+    int   NoiseReduction;
+    char  FlashSetting[16];
+    char  FlashMetering[16];
+    char  ImageSharpening[16];
+    char  WhitebalanceName[16];
+    long   AFPosition;
+    char  FocusMode[16];
+    float WhitebalanceBias;
+
     char  Comments[MAX_COMMENT];
 
     unsigned char * ThumbnailPointer;  // Pointer at the thumbnail
diff -ru jhead-2.4/makernote.c jhead-2.4-nikon/makernote.c
--- jhead-2.4/makernote.c	2005-06-10 15:39:56.000000000 +0200
+++ jhead-2.4-nikon/makernote.c	2005-11-20 14:05:33.000000000 +0100
@@ -1,6 +1,9 @@
 //--------------------------------------------------------------------------
 // Parse some maker specific onformation.
 // (Very limited right now - add maker specific stuff to this module)
+//
+// Added Nikon support 5 Aug 2004 - <william.a@carrel.org>
+// adapted Nikon support to jhead-2.4 - Heiko Purnhagen 2005-11-20
 //--------------------------------------------------------------------------
 #include <stdio.h>
 #include <stdlib.h>
@@ -9,12 +12,14 @@
 #include <time.h>
 #include <errno.h>
 #include <ctype.h>
-
+
 #ifndef _WIN32
     #include <limits.h>
 #endif
 
 #include "jhead.h"
+
+extern int MotorolaOrder; // Need this global from exif.c
 //--------------------------------------------------------------------------
 // Process exif format directory, as used by Cannon maker note
 //--------------------------------------------------------------------------
@@ -120,6 +125,63 @@
 }
 
 //--------------------------------------------------------------------------
+// Show Nikon maker note
+//--------------------------------------------------------------------------
+void ProcessNikonMakerNoteDir(unsigned char * DirStart, unsigned char * OffsetBase,
+        unsigned ExifLength)
+{
+/****
+    unsigned char * SubdirStart;
+    int FirstOffset, savedMotorolaOrder;
+****/
+
+//	fprintf(stderr, "XXX *** '%08x%04x' *** XXX\n", Get32u(DirStart+4),
+//		Get16u(DirStart+8));
+
+	process_EXIF(DirStart+2, ExifLength);
+
+/****
+	// Fix CCDWidth if we know it for this model
+	if (strncmp(ImageInfo.CameraModel, "NIKON D100", 10) == 0)
+		ImageInfo.CCDWidth = 23.7;
+
+	// Make sure we don't clobber this if it is in the other mode
+	savedMotorolaOrder = MotorolaOrder;
+				
+	if (memcmp(DirStart+10,"II",2) == 0){
+		if (ShowTags) printf("Exif section in Intel order\n");
+		MotorolaOrder = 0;
+	}else{
+		if (memcmp(DirStart+10,"MM",2) == 0){
+		    if (ShowTags) printf("Exif section in Motorola order\n");
+		    MotorolaOrder = 1;
+		}else{
+		    ErrNonfatal("Invalid Exif alignment marker.",0,0);
+		    MotorolaOrder = savedMotorolaOrder;
+	  	    return;
+		}
+	}
+	// Check the next value for correctness.
+	if (Get16u(DirStart+12) != 0x2a){
+		ErrNonfatal("Invalid Exif start (1)",0,0);
+		MotorolaOrder = savedMotorolaOrder;
+		return;
+	}
+	FirstOffset = Get32u(DirStart+14);
+	if (FirstOffset < 8 || FirstOffset > 16){
+		ErrNonfatal("Suspicious offset of IFD value",0,0);
+	}
+									
+	process_EXIF(DirStart+10+FirstOffset, 
+  	ProcessExifDir(DirStart+10+FirstOffset, DirStart+10, ExifLength,  
+		3); // Hardcoding the nesting level is lame XXX FIXME
+  					
+  	// Restore the endianness to whatever it was before
+  	MotorolaOrder = savedMotorolaOrder;
+****/
+}
+
+//--------------------------------------------------------------------------
 // Show generic maker note - just hex bytes.
 //--------------------------------------------------------------------------
 void ShowMakerNoteGeneric(unsigned char * ValuePtr, int ByteCount)
@@ -144,12 +206,14 @@
         unsigned char * OffsetBase, unsigned ExifLength)
 {
 
-    if (ShowTags){
-        if (strstr(ImageInfo.CameraMake, "Canon")){
-            ProcessCannonMakerNoteDir(ValuePtr, OffsetBase, ExifLength);
-        }else{
-            ShowMakerNoteGeneric(ValuePtr, ByteCount);
-        }
+    if (strstr(ImageInfo.CameraMake, "Canon")) {
+        ProcessCannonMakerNoteDir(ValuePtr, OffsetBase, ExifLength);
+    } else if (strstr(ImageInfo.CameraMake, "NIKON")) {
+        ProcessNikonMakerNoteDir(ValuePtr, OffsetBase, ExifLength);
+    } else {
+        if (ShowTags) {
+	    ShowMakerNoteGeneric(ValuePtr, ByteCount);
+	}
     }
 }
 

