From: Pat Thoyts Date: Thu, 11 Oct 2018 15:00:11 +0000 (+0100) Subject: Added image information structure definition. X-Git-Url: https://privyetmir.co.uk/gitweb.cgi?a=commitdiff_plain;h=c0588096792e67eff95c878b93bd1420493eeb98;p=srfdump Added image information structure definition. Corrected the Windows build. --- diff --git a/srfdump.c b/srfdump.c index 78e68fc..56ffb7f 100644 --- a/srfdump.c +++ b/srfdump.c @@ -13,6 +13,7 @@ #include "surfacefile.h" #ifdef WIN32 +#include #include #else #include "compat/tchar.h" @@ -20,12 +21,15 @@ 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; diff --git a/surfacefile.h b/surfacefile.h index 1582ec4..26e9c53 100644 --- a/surfacefile.h +++ b/surfacefile.h @@ -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)