Added image information structure definition.
authorPat Thoyts <patthoyts@users.sourceforge.net>
Thu, 11 Oct 2018 15:00:11 +0000 (16:00 +0100)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Thu, 11 Oct 2018 22:30:11 +0000 (23:30 +0100)
Corrected the Windows build.

srfdump.c
surfacefile.h

index 78e68fc1508b24a70ec4fd97330cae67aa5bea8b..56ffb7f6ef824d7bfe9d6704b037f3ec15166e83 100644 (file)
--- a/srfdump.c
+++ b/srfdump.c
@@ -13,6 +13,7 @@
 #include "surfacefile.h"
 
 #ifdef WIN32
+#include <direct.h>
 #include <tchar.h>
 #else
 #include "compat/tchar.h"
 
 static size_t fcopy(FILE *src, FILE *dst, size_t count)
 {
-    size_t total = 0, n = 0;
     char buf[4096];
-    do {
-        n = fread(buf, 1, sizeof(buf), src);
-        total += fwrite(buf, 1, n, dst);
-    } while (n == sizeof(buf));
+    size_t total = 0, n = 0;
+    while (count > 0)
+    {
+        size_t requested = count < sizeof(buf) ? count : sizeof(buf);
+        size_t received = fread(buf, 1, requested, src);
+        total += fwrite(buf, 1, received, dst);
+        count -= received;
+    }
     return total;
 }
 
@@ -34,12 +38,17 @@ static uint32_t * ReadImageTable(SurfaceFileHeader *hdrPtr, FILE *fp)
     uint32_t *table = NULL;
     if (hdrPtr->num_images > 0)
     {
-        table = (uint32_t *)malloc(sizeof(uint32_t) * (hdrPtr->num_images + 1));
-        fread(table + 1, sizeof(uint32_t), hdrPtr->num_images, fp);
+        table = (uint32_t *)calloc(sizeof(uint32_t), (hdrPtr->num_images + 1));
+        if (table == NULL)
+        {
+            _tperror("calloc table");
+            exit(1);
+        }
+        size_t check = fread(table + 1, sizeof(uint32_t), hdrPtr->num_images, fp);
         // set first image to the end of the table.
-        table[0] = ftell(fp);
+        table[0] = (long)ftell(fp);
         // convert offsets from relative to table to file absolute positions
-        for (int n = 1; n < hdrPtr->num_images+1; ++n)
+        for (uint32_t n = 1; n < hdrPtr->num_images + 1; ++n)
             table[n] += table[0];
     }
     return table;
@@ -61,17 +70,24 @@ static SurfacePoint * ReadPoints(SurfaceFileHeader *hdrPtr, FILE *fp)
     SurfacePoint *points = NULL;
     if (hdrPtr->num_points > 0)
     {
-        points = (SurfacePoint *)malloc(sizeof(SurfacePoint) * hdrPtr->num_points);
-        double *buffer = (double *)malloc(sizeof(double) * hdrPtr->num_points);
-        fread(buffer, sizeof(double), hdrPtr->num_points, fp);
-        for (int n = 0; n < hdrPtr->num_points; ++n)
-            points[n].x = buffer[n];
-        fread(buffer, sizeof(double), hdrPtr->num_points, fp);
-        for (int n = 0; n < hdrPtr->num_points; ++n)
-            points[n].y = buffer[n];
-        fread(buffer, sizeof(double), hdrPtr->num_points, fp);
-        for (int n = 0; n < hdrPtr->num_points; ++n)
-            points[n].z = buffer[n];
+        size_t count = 0;
+        points = (SurfacePoint *)calloc(sizeof(SurfacePoint), hdrPtr->num_points);
+        double *buffer = (double *)calloc(sizeof(double), hdrPtr->num_points);
+        if ((count = fread(buffer, sizeof(double), hdrPtr->num_points, fp)) == hdrPtr->num_points)
+        {
+            for (uint32_t n = 0; n < hdrPtr->num_points; ++n)
+                points[n].x = buffer[n];
+        }
+        if ((count = fread(buffer, sizeof(double), hdrPtr->num_points, fp)) == hdrPtr->num_points)
+        {
+            for (uint32_t n = 0; n < hdrPtr->num_points; ++n)
+                points[n].y = buffer[n];
+        }
+        if ((count = fread(buffer, sizeof(double), hdrPtr->num_points, fp)) == hdrPtr->num_points)
+        {
+            for (uint32_t n = 0; n < hdrPtr->num_points; ++n)
+                points[n].z = buffer[n];
+        }
         free(buffer);
     }
     return points;
@@ -116,9 +132,9 @@ static int SrfDump(FILE *fp)
     SurfacePoint *points = ReadPoints(&hdr, fp);
     if (points)
     {
-        for (int n = 0; n < hdr.num_points; ++n)
+        for (uint32_t n = 0; n < hdr.num_points; ++n)
         {
-            printf("  point %d: %.6g %.6g %.6g\n",
+            printf("  point %u: %.6g %.6g %.6g\n",
                 n, points[n].x, points[n].y, points[n].z);
         }
         free(points);
@@ -136,45 +152,35 @@ static int SrfDump(FILE *fp)
     if (offsets)
     {
         printf("  image base: %#08x\n", table_base);
+#ifdef WIN32
+        _tmkdir(_T("images"));
+#else
         mkdir("images", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
-        for (int n = 0; n < hdr.num_images; ++n)
+#endif // !WIN32
+        for (uint32_t n = 0; n < hdr.num_images; ++n)
         {
-            uint32_t image_size = offsets[n+1] - offsets[n] - 60;
-            printf("  image %d: %#08x size %#04x\n",
-                n, offsets[n], image_size);
-
             TCHAR name[32 + 16] = {0};
-            _stprintf(name, _T("images/img%d.jpg"), n);
-            FILE *fp2 = _tfopen(name, "w");
+            _stprintf(name, _T("images/img%u.jpg"), n);
+            FILE *fp2 = _tfopen(name, "wb");
             if (fp2 == NULL) {
-                _tperror("fopen");
+                _tperror("fopen image file");
                 exit(1);
             }
-            // TODO: deal with the 60 bytes of additional data per image....
-            // first 24 bytes are the image point position
-            // {
-            //     SurfacePoint point; // in um
-            //     double image_width_microns; // field of view x
-            //     double image_height_microns; // field of view y
-            //     uint32_t image_width; // in pixels ?
-            //     uint32_t image_height; // in pixels ?
-            //     uint32_t unknown[3];
-            // }
-            fseek(fp, offsets[n], SEEK_SET);
 
-            char data[60] = {0};
-            fread(data, 1, 60, fp);
-            fcopy(fp, fp2, image_size);
+            // this calculated image size is off by 4 bytes. why?
+            uint32_t image_size = offsets[n + 1] - offsets[n] - sizeof(SurfaceImageInfo);
+            SurfaceImageInfo info = { 0 };
+            fseek(fp, offsets[n], SEEK_SET);
+            fread(&info, sizeof(SurfaceImageInfo), 1, fp);
+            size_t len = fcopy(fp, fp2, info.image_size);
             fclose(fp2);
 
-            _stprintf(name, _T("images/img%d.dat"), n);
-            fp2 = _tfopen(name, "w");
-            if (fp2 == NULL) {
-                _tperror("fopen data");
-                exit(1);
-            }
-            fwrite(data, 1, 60, fp2);
-            fclose(fp2);
+            printf("  img:%d: %#08x @(%.3f,%.3f,%.3f) fov:%.3f,%.3f res:%u,%u off:%d,%d siz:%#08x %d\n",
+                n, offsets[n], 
+                info.point.x, info.point.y, info.point.z,
+                info.image_width_microns, info.image_height_microns,
+                info.resolution_x, info.resolution_y,
+                info.xoffset, info.yoffset, info.image_size, len-image_size);
         }
         free(offsets);
     }
@@ -189,7 +195,7 @@ int _tmain(int argc, TCHAR *argv[])
         return 1;
     }
 
-    FILE *fp = _tfopen(argv[1], _T("r"));
+    FILE *fp = _tfopen(argv[1], _T("rb"));
     if (fp == NULL) {
         _tperror(_T("fopen"));
         return 1;
index 1582ec4f7fd95af694752197d9efc6c923f0c94f..26e9c539b41d9192c8258515f2a4f333c4aeaecf 100644 (file)
@@ -88,6 +88,29 @@ typedef struct SurfaceFileHeader {
     };
 } SurfaceFileHeader;
 
+typedef struct SurfaceImageInfo
+{
+    /// Position of the top left point of the image in microns
+    /// EXIF custom field 0xFEA0
+    struct SurfacePoint point;
+    /// Field-of-view X value is the width of the image in microns at the focal plane.
+    /// EXIF field FocalPlaneXResolution
+    double image_width_microns;
+    /// Field-of-view Y value is the height of the image in microns at the focal plane.
+    /// EXIF field FocalPlaneYResolution
+    double image_height_microns;
+    /// image width in pixels?
+    uint32_t resolution_x;
+    /// image height in pixels ??
+    uint32_t resolution_y;
+    /// Offset in pixels (from where?)
+    int xoffset;
+    /// Vertical offset in pixels (from where?)
+    int yoffset;
+    /// Size of the stored image data in bytes.
+    uint32_t image_size;
+} SurfaceImageInfo;
+
 #pragma pack(pop)
 
 #if defined(__cplusplus)