From 197cd5c4432b0396c69eb89fb13604debd84b29a Mon Sep 17 00:00:00 2001 From: Stefan Jahn Date: Wed, 9 Nov 2022 18:11:24 +0100 Subject: [PATCH] SER file format works now for writing. --- main.cc | 1 + ser.cc | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++------- ser.h | 43 +++++++++++++++++++++++++++++-- 3 files changed, 112 insertions(+), 11 deletions(-) diff --git a/main.cc b/main.cc index 7016a30..a2893d2 100644 --- a/main.cc +++ b/main.cc @@ -12,6 +12,7 @@ #include "filter.h" #include "detect.h" #include "convert.h" +#include "ser.h" /************************************************************************** * global variables diff --git a/ser.cc b/ser.cc index ee338c8..9201cff 100644 --- a/ser.cc +++ b/ser.cc @@ -24,7 +24,7 @@ SER::SER() { header.LittleEndian = 1; header.ImageWidth = 0; header.ImageHeight = 0; - header.PixelDepthPerPlane = 0; + header.PixelDepthPerPlane = 8; header.FrameCount = 0; header.DateTime = 0; header.DateTimeUTC = 0; @@ -33,11 +33,15 @@ SER::SER() { Frame = NULL; } - +/* + Class destructor. Free resources. +*/ SER::~SER() { + /* Close file if necessary */ if(fd) { fclose(fd); } + /* Free frame memory if necessary */ if(Frame) { free(Frame); } @@ -89,11 +93,13 @@ int SER::setFile(char *name) { } else { fprintf(stdout, "Debug: created file '%s' for writing SER file\n", name); + fd = file; return 0; } } fprintf(stdout, "Debug: opened file '%s' for reading SER file\n", name); + fd = file; return 0; } @@ -102,15 +108,25 @@ int SER::setFile(char *name) { */ int SER::writeHeader(void) { + int err; + + /* adjust time stamps for header */ + setDateTime(); + + if(fd == NULL) { + fprintf(stderr, "Error: writing header, SER file not yet specified\n"); + return -1; + } + /* goto file beginning */ - if(fseek(fd, 0, SEEK_SET) == -1) { - fprintf(stderr, "Error: failed seek SER file beginning (%s)\n", strerror(errno)); + if((err = fseek(fd, 0, SEEK_SET)) == -1) { + fprintf(stderr, "Error: failed seek SER file beginning (%d, %s)\n", err, strerror(errno)); return -1; } - + /* write header data */ - if(fwrite(&header, sizeof(header), 1, fd) != sizeof(header)) { - fprintf(stderr, "Error: failed writing SER header (%s)\n", strerror(errno)); + if((err = fwrite(&header, sizeof(header), 1, fd)) != 1) { + fprintf(stderr, "Error: failed writing SER header (%d, %s)\n", err, strerror(errno)); return -1; } return 0; @@ -122,8 +138,13 @@ int SER::writeHeader(void) { */ int SER::appendFrame(void *data) { + if(fd == NULL) { + fprintf(stderr, "Error: appending frame, SER file not yet specified\n"); + return -1; + } + /* write frame data */ - if(fwrite(data, FrameSize, 1, fd) != FrameSize) { + if(fwrite(data, FrameSize, 1, fd) != 1) { fprintf(stderr, "Error: failed write SER frame (%s)\n", strerror(errno)); return -1; } @@ -140,6 +161,30 @@ void SER::updateHeaderData(void) { FrameSize = header.ImageWidth * header.ImageHeight * BytesPerPixel; } +/* + Sets the pixel depth in bits. + */ +int SER::setPixelDepth(int pixeldepth) { + header.PixelDepthPerPlane = pixeldepth; + updateHeaderData(); + return 0; +} + +/* + Returns the pixel depth in bits. + */ +int SER::getPixelDepth(void) { + return header.PixelDepthPerPlane; +} + +/* + Returns the number of bytes in an allocated frame. + */ +size_t SER::getFrameSize(void) { + updateHeaderData(); + return FrameSize; +} + /* Sets the image width. */ @@ -149,6 +194,13 @@ int SER::setWidth(int width) { return 0; } +/* + Gets the image width. + */ +int SER::getWidth(void) { + return header.ImageWidth; +} + /* Sets the image height. */ @@ -158,6 +210,13 @@ int SER::setHeight(int height) { return 0; } +/* + Gets the image height. + */ +int SER::getHeight(void) { + return header.ImageHeight; +} + /* Sets the color ID. */ @@ -181,12 +240,14 @@ void * SER::allocFrame(void) { /* Try allocating new frame data. */ if((Frame = malloc(FrameSize)) == NULL) { - fprintf(stderr, "Error: failed to allocate %lu bytes for frame\n", FrameSize); + fprintf(stderr, "Error: failed to allocate %d bytes for frame\n", FrameSize); return NULL; } return Frame; } + + /* The function reads a single frame at the current file position. Frame size is determined by internal header data. diff --git a/ser.h b/ser.h index b07c257..c460ab5 100644 --- a/ser.h +++ b/ser.h @@ -1,6 +1,40 @@ #ifndef _SER_H_ #define _SER_H_ +/* + Example usage of the class: + --------------------------- + + SER *ser = new SER(); + ser->setWidth(640); + ser->setHeight(480); + ser->setColorID(SER_COLORID_RGB); + ser->setPixelDepth(8); + ser->setFile((char *)"test.ser"); + ser->setNumberOfFrames(1); + ser->writeHeader(); + uint8_t * data = (uint8_t *) ser->allocFrame(); + memset(data, 0, ser->getFrameSize()); + for(int y = 0; y < ser->getHeight()/3; y++) { + for(int x = 0; x < ser->getWidth(); x++) { + data[y*ser->getWidth()*3 + x*3 + 0] = 0xff; + } + } + for(int y = ser->getHeight()/3; y < 2*ser->getHeight()/3; y++) { + for(int x = 0; x < ser->getWidth(); x++) { + data[y*ser->getWidth()*3 + x*3 + 1] = 0xff; + } + } + for(int y = 2*ser->getHeight()/3; y < 3*ser->getHeight()/3; y++) { + for(int x = 0; x < ser->getWidth(); x++) { + data[y*ser->getWidth()*3 + x*3 + 2] = 0xff; + } + } + ser->appendFrame(data); + delete ser; + + */ + enum { SER_COLORID_MONO = 0, SER_COLORID_BAYER_RGGB = 8, @@ -15,8 +49,8 @@ enum { SER_COLORID_BGR = 101 }; -struct SER_Header { - char FileID[40]; /* "LUCAM-RECORDER" (fix) */ +struct __attribute__((__packed__)) SER_Header { + char FileID[14]; /* "LUCAM-RECORDER" (fix) */ int32_t LuID; /* Lumenera camera series ID (currently unused; default = 0) */ int32_t ColorID; /* see SER_COLORID_* */ int32_t LittleEndian; /* 0 (FALSE) for big-endian, 1 (TRUE) for little-endian */ @@ -55,11 +89,16 @@ class SER { int setTelescope(char *); int setWidth(int); int setHeight(int); + int getWidth(void); + int getHeight(void); int setColorID(int); + int setPixelDepth(int); + int getPixelDepth(void); int32_t getNumberOfFrames(void); void setNumberOfFrames(int32_t); int64_t setDateTime(void); int64_t differenceLocalUTC(void); + size_t getFrameSize(void); int setFile(char *); int writeHeader(void);