diff --git a/CMakeLists.txt b/CMakeLists.txt index 6762cdc..92e099a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ set(TENMON_SRC src/filemanager.h src/filemanager.cpp src/filemanager.ui src/filesystemwidget.cpp src/filesystemwidget.h src/fitskeyword.ui + src/fitswrapper.h src/fitswrapper.cpp src/histogram.cpp src/histogram.h src/httpdownloader.h src/httpdownloader.cpp src/imageinfo.cpp src/imageinfo.h diff --git a/src/fitswrapper.cpp b/src/fitswrapper.cpp new file mode 100644 index 0000000..6bce410 --- /dev/null +++ b/src/fitswrapper.cpp @@ -0,0 +1,89 @@ +#include "fitswrapper.h" +#include +#include + +FITSWrapper::FITSWrapper(const QString &path, int mode, bool open) +{ + _path = path; + _mode = mode; + + if(open) + fits_open_diskfile(&_file, path.toLocal8Bit().data(), mode, &_status); + else + fits_create_diskfile(&_file, path.toLocal8Bit().data(), &_status); + + if(_status == FILE_NOT_OPENED || _status == FILE_NOT_CREATED) + { + qWarning() << "Could not open file directly trying memfile workaround" << path; + if(open) + { + QFile fr(path); + if(fr.open(QIODevice::ReadOnly)) + { + _bufferSize = fr.size(); + _bufferPtr = malloc(_bufferSize); + fr.read((char*)_bufferPtr, _bufferSize); + _status = 0; + fits_open_memfile(&_file, "memfile", mode, &_bufferPtr, &_bufferSize, 0, realloc, &_status); + if(_status) + { + free(_bufferPtr); + _bufferPtr = nullptr; + _bufferSize = 0; + qWarning() << "fits_open_memfile failed"; + } + } + else + { + qWarning() << "QFile failed to open file" << path; + _status = FILE_NOT_OPENED; + } + } + else + { + _bufferSize = 2880; + _bufferPtr = malloc(_bufferSize); + fits_create_memfile(&_file, &_bufferPtr, &_bufferSize, 0, realloc, &_status); + if(_status) + { + free(_bufferPtr); + _bufferPtr = nullptr; + _bufferSize = 0; + } + } + } +} + +FITSWrapper::~FITSWrapper() +{ + if(_file) + { + _status = 0; + fits_close_file(_file, &_status); + } + + if(_mode == READWRITE && _bufferPtr) + { + qDebug() << "Writing FITS memfile" << _bufferSize; + QFile fw(_path); + if(fw.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + if(fw.write((char*)_bufferPtr, _bufferSize) != (qint64)_bufferSize) + qWarning() << "Failed to write to file"; + } + else + qWarning() << "Failed to open fits file for writing"; + } + + free(_bufferPtr); +} + +int FITSWrapper::status() const +{ + return _status; +} + +FITSWrapper::operator fitsfile *() +{ + return _file; +} diff --git a/src/fitswrapper.h b/src/fitswrapper.h new file mode 100644 index 0000000..9a400e3 --- /dev/null +++ b/src/fitswrapper.h @@ -0,0 +1,25 @@ +#ifndef FITSWRAPPER_H +#define FITSWRAPPER_H + +#include +#include +#include + +class FITSWrapper +{ +public: + explicit FITSWrapper(const QString &path, int mode, bool open); + ~FITSWrapper(); + FITSWrapper(FITSWrapper &other) = delete; + int status() const; + operator fitsfile*(); +private: + QString _path; + int _status = 0; + int _mode = 0; + fitsfile *_file; + size_t _bufferSize = 0; + void *_bufferPtr = nullptr; +}; + +#endif // FITSWRAPPER_H diff --git a/src/loadimage.cpp b/src/loadimage.cpp index 4cc99e7..cb11259 100644 --- a/src/loadimage.cpp +++ b/src/loadimage.cpp @@ -1,13 +1,13 @@ #include "loadimage.h" -#include -#include -#include -#include -#include -#include #include "libxisf.h" -#include #include "rawimage.h" +#include +#include +#include +#include +#include +#include +#include "fitswrapper.h" QString makeUNCPath(const QString &path) { @@ -85,7 +85,6 @@ int loadFITSHeader(fitsfile *file, ImageInfoData &info) bool loadFITS(const QString path, ImageInfoData &info, std::shared_ptr &image, bool planar, uint32_t index) { - fitsfile *file; int status = 0; int num = 0; long naxes[3] = {0}; @@ -99,29 +98,9 @@ bool loadFITS(const QString path, ImageInfoData &info, std::shared_ptr return false; }; - fits_open_diskfile(&file, path.toLocal8Bit().data(), READONLY, &status); + FITSWrapper file(path, READONLY, true); + status = file.status(); - QByteArray buffer; - size_t bufferSize = 0; - void *bufferPtr = nullptr; - if(status == FILE_NOT_OPENED) - { - qWarning() << "Could not open file directly tring memfile workaround" << path; - QFile fr(path); - if(fr.open(QIODevice::ReadOnly)) - { - buffer = fr.readAll(); - bufferSize = buffer.size(); - bufferPtr = buffer.data(); - status = 0; - fits_open_memfile(&file, "memfile", READONLY, &bufferPtr, &bufferSize, 0, NULL, &status); - } - else - { - qWarning() << "QFile failed to open file" << path; - return false; - } - } if(status)return checkError(); fits_get_num_hdus(file, &num, &status); if(status)return checkError(); @@ -244,7 +223,6 @@ noload: } } - fits_close_file(file, &status); return true; } @@ -367,37 +345,14 @@ bool loadXISF(const QString &path, ImageInfoData &info, std::shared_ptr +#include #include #include -#include -#include #include #include -#include "rawimage.h" -#include "loadimage.h" #include LoadRunable::LoadRunable(const QString &file, Image *receiver, AnalyzeLevel level, int index, bool thumbnail) : @@ -282,9 +283,10 @@ void ConvertRunable::run() if(m_format == "fits") { int status = 0; - fitsfile *fw; if(QFileInfo(m_outfile).exists())QFile::remove(m_outfile); - fits_create_diskfile(&fw, m_outfile.toLocal8Bit().data(), &status); + FITSWrapper fw(m_outfile, READWRITE, false); + if(fw.status())return; + if(!m_params.compressionType.isEmpty()) { if(m_params.compressionType == "gzip") @@ -293,7 +295,6 @@ void ConvertRunable::run() fits_set_compression_type(fw, RICE_1, &status); } writeFITSImage(fw, rawimage, imageinfo); - fits_close_file(fw, &status); return; } diff --git a/src/scriptengine.cpp b/src/scriptengine.cpp index f248db7..7aba1fb 100644 --- a/src/scriptengine.cpp +++ b/src/scriptengine.cpp @@ -1,16 +1,17 @@ #include "scriptengine.h" -#include -#include -#include -#include -#include -#include +#include "batchprocessing.h" +#include "fitswrapper.h" +#include "libxisf.h" +#include "loadimage.h" #include "loadrunable.h" #include "rawimage.h" -#include "loadimage.h" -#include "batchprocessing.h" +#include +#include +#include +#include +#include +#include #include -#include "libxisf.h" #ifdef PLATESOLVER #include "solver.h" #endif // PLATESOLVER @@ -672,31 +673,11 @@ bool File::modifyFITSRecords(const FITSRecordModify *modify) if(isFITS(suffix())) { - fitsfile *file; int status = 0; QString path = makeUNCPath(_path); - fits_open_diskfile(&file, path.toLocal8Bit().data(), READWRITE, &status); - QByteArray buffer; - size_t bufferSize = 0; - void *bufferPtr = nullptr; - if(status == FILE_NOT_OPENED) - { - qWarning() << "Could not open file directly tring memfile workaround" << path; - QFile fr(path); - if(fr.open(QIODevice::ReadOnly)) - { - buffer = fr.readAll(); - bufferSize = buffer.size(); - bufferPtr = buffer.data(); - status = 0; - fits_open_memfile(&file, "memfile", READONLY, &bufferPtr, &bufferSize, 0, NULL, &status); - } - else - { - qWarning() << "QFile failed to open file" << path; - return false; - } - } + FITSWrapper file(path, READWRITE, true); + status = file.status(); + int num = 0; fits_get_num_hdus(file, &num, &status); if(status) @@ -816,8 +797,7 @@ bool File::modifyFITSRecords(const FITSRecordModify *modify) return false; } } - fits_close_file(file, &status); - + if(status)qWarning() << "Failed to modify FITS header" << status; return status == 0; } else if(isXISF(suffix()))