diff --git a/src/hdtv/rootext/mfile-root/CMakeLists.txt b/src/hdtv/rootext/mfile-root/CMakeLists.txt index 5a4c7423..cf24f06b 100644 --- a/src/hdtv/rootext/mfile-root/CMakeLists.txt +++ b/src/hdtv/rootext/mfile-root/CMakeLists.txt @@ -7,11 +7,7 @@ project(mfile-root LANGUAGES C CXX) set(SOURCES MatOp.cc MFileHist.cc - MFileRoot.cc VMatrix.cc - matop/matop_adjust.c - matop/matop_conv.c - matop/matop_project.c mfile/src/callindir.c mfile/src/converters.c mfile/src/disk_access.c @@ -39,15 +35,7 @@ set(SOURCES mfile/src/txt_getput.c mfile/src/txt_minfo.c) -set(HEADERS - MatOp.hh - MFileHist.hh - MFileRoot.hh - VMatrix.hh - matop/matop.h - matop/matop_adjust.h - matop/matop_conv.h - matop/matop_project.h) +set(HEADERS MatOp.hh MFileHist.hh VMatrix.hh) find_package(ROOT REQUIRED COMPONENTS Core Hist) message(STATUS "ROOT Version ${ROOT_VERSION} found in ${ROOT_root_CMD}") @@ -78,11 +66,8 @@ set_target_properties( "${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.rootmap;${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}_rdict.pcm" ) target_include_directories( - ${PROJECT_NAME} - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/matop - ${CMAKE_CURRENT_SOURCE_DIR}/mfile/include - ${CMAKE_CURRENT_SOURCE_DIR}/mfile/src) + ${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/mfile/include + ${CMAKE_CURRENT_SOURCE_DIR}/mfile/src) target_link_libraries(${PROJECT_NAME} ROOT::Core ROOT::Hist) # For mfile diff --git a/src/hdtv/rootext/mfile-root/MFileRoot.cc b/src/hdtv/rootext/mfile-root/MFileRoot.cc deleted file mode 100644 index 9fc38d00..00000000 --- a/src/hdtv/rootext/mfile-root/MFileRoot.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * HDTV - A ROOT-based spectrum analysis software - * Copyright (C) 2006-2010 The HDTV development team (see file AUTHORS) - * - * This file is part of HDTV. - * - * HDTV is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * HDTV is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with HDTV; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#include "MFileRoot.hh" -#include - -MFile::MFile(const char *fname, const char *mode) : fZombie(false), fFile(nullptr) { - if (fname) { - fFile = mopen(const_cast(fname), const_cast(mode)); - if (fFile == nullptr) { - fZombie = true; - } - } -} - -MFile::~MFile() { - if (IsZombie() || IsNull()) { - return; - } - - if (mclose(fFile) != 0) { - std::cerr << "WARNING: mclose() failed" << std::endl; - } -} diff --git a/src/hdtv/rootext/mfile-root/MFileRoot.hh b/src/hdtv/rootext/mfile-root/MFileRoot.hh deleted file mode 100644 index e059fa51..00000000 --- a/src/hdtv/rootext/mfile-root/MFileRoot.hh +++ /dev/null @@ -1,43 +0,0 @@ -/* - * HDTV - A ROOT-based spectrum analysis software - * Copyright (C) 2006-2010 The HDTV development team (see file AUTHORS) - * - * This file is part of HDTV. - * - * HDTV is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * HDTV is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with HDTV; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#ifndef __MFileRoot_h__ -#define __MFileRoot_h__ - -#include - -class MFile { -public: - explicit MFile(const char *fname = nullptr, const char *mode = "r"); - ~MFile(); - - bool IsZombie() { return fZombie; } - bool IsNull() { return fFile == nullptr; } - MFILE *File() { return fFile; } - explicit operator MFILE *() { return fFile; } - -private: - bool fZombie; - MFILE *fFile; -}; - -#endif diff --git a/src/hdtv/rootext/mfile-root/MatOp.cc b/src/hdtv/rootext/mfile-root/MatOp.cc index c234ae51..30c2a9af 100644 --- a/src/hdtv/rootext/mfile-root/MatOp.cc +++ b/src/hdtv/rootext/mfile-root/MatOp.cc @@ -1,6 +1,6 @@ /* * HDTV - A ROOT-based spectrum analysis software - * Copyright (C) 2006-2010 The HDTV development team (see file AUTHORS) + * Copyright (C) 2006-2026 The HDTV development team (see file AUTHORS) * * This file is part of HDTV. * @@ -22,12 +22,11 @@ #include "MatOp.hh" -#include +#include +#include +#include -#include "MFileRoot.hh" -#include "matop/matop_adjust.h" -#include "matop/matop_conv.h" -#include "matop/matop_project.h" +#include const int MatOp::ERR_SUCCESS = 0; const int MatOp::ERR_UNKNOWN = 1; @@ -56,85 +55,285 @@ const char *MatOp::ErrDesc[] = { "Transposition failed" // ERR_TRANS_FAIL }; -int MatOp::Project(const char *src_fname, const char *prx_fname, const char *pry_fname) { - if (prx_fname && !(*prx_fname)) { - prx_fname = nullptr; +const char *MatOp::GetErrorString(int error_nr) { + if (error_nr < 0 || error_nr > MAX_ERR) { + error_nr = ERR_UNKNOWN; } - if (pry_fname && !(*pry_fname)) { - pry_fname = nullptr; + + return ErrDesc[error_nr]; +} + +namespace { +template +int ProjectGeneric(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src) { + minfo info; + mgetinfo(src, &info); + if (level >= info.levels) { + return MatOp::ERR_PROJ_FAIL; } - MFile in_matrix(src_fname, "r"); - if (in_matrix.IsZombie()) { - return ERR_SRC_OPEN; + auto lbuf = std::make_unique(info.columns); + auto prx = dstx ? std::make_unique(info.columns) : nullptr; + auto pry = dsty ? std::make_unique(info.lines) : nullptr; + + for (uint32_t l = 0; l < info.lines; l++) { + if (static_cast(mget_(src, lbuf.get(), level, l, 0, info.columns)) != info.columns) { + return MatOp::ERR_PROJ_FAIL; + } + + if (prx) { + for (uint32_t c = 0; prx && c < info.columns; c++) { + prx[c] += lbuf[c]; + } + } + + if (pry) { + T sum = 0; + for (uint32_t c = 0; c < info.columns; c++) { + sum += lbuf[c]; + } + pry[l] += sum; + } } - // std::cout << "Info: input format is " << mgetfmt(in_matrix, NULL) << - // std::endl; + int err = MatOp::ERR_SUCCESS; + if (prx && static_cast(mput_(dstx, prx.get(), level, 0, 0, info.columns)) != info.columns) { + err = MatOp::ERR_PROJ_FAIL; + } + + if (pry && static_cast(mput_(dsty, pry.get(), level, 0, 0, info.lines)) != info.lines) { + err = MatOp::ERR_PROJ_FAIL; + } + return err; +} +} // namespace + +int MatOp::Project(const char *src_fname, const char *prx_fname, const char *pry_fname) { + int err = ERR_SUCCESS; + + MFILE *src_matrix = nullptr; + MFILE *prx_matrix = nullptr; + MFILE *pry_matrix = nullptr; - MFile out_prx(prx_fname, "w"); - if (out_prx.IsZombie()) { - return ERR_PRX_OPEN; + src_matrix = mopen(src_fname, "r"); + if (src_matrix == nullptr) { + err = ERR_SRC_OPEN; + goto exit; } - if (!out_prx.IsNull()) { - if (matop_adjustfmts_prx(static_cast(out_prx), static_cast(in_matrix)) != 0) { - return ERR_PRX_FMT; + minfo src_info; + mgetinfo(src_matrix, &src_info); + if (src_info.levels > 2) { + err = ERR_PROJ_FAIL; + goto exit; + } + + if (prx_fname != nullptr && *prx_fname != '\0') { + prx_matrix = mopen(prx_fname, "w"); + if (prx_matrix == nullptr) { + err = ERR_PRX_OPEN; + goto exit; + } + + minfo prx_info; + mgetinfo(prx_matrix, &prx_info); + + prx_info.levels = src_info.levels; + prx_info.lines = 1; + prx_info.columns = src_info.columns; + + if (msetinfo(prx_matrix, &prx_info)) { + err = ERR_PRX_FMT; + goto exit; } } - MFile out_pry(pry_fname, "w"); - if (out_pry.IsZombie()) { - return ERR_PRY_OPEN; + if (pry_fname != nullptr && *pry_fname != '\0') { + pry_matrix = mopen(pry_fname, "w"); + if (pry_matrix == nullptr) { + err = ERR_PRY_OPEN; + goto exit; + } + + minfo pry_info; + mgetinfo(pry_matrix, &pry_info); + + pry_info.levels = src_info.levels; + pry_info.lines = 1; + pry_info.columns = src_info.lines; + + if (msetinfo(pry_matrix, &pry_info)) { + err = ERR_PRY_FMT; + goto exit; + } } - if (!out_pry.IsNull()) { - if (matop_adjustfmts_pry(static_cast(out_pry), static_cast(in_matrix)) != 0) { - return ERR_PRY_FMT; + // Projection of level 0 and 1. src_info.levels is <= 2 + for (uint32_t l = 0; l < src_info.levels; l++) { + switch (src_matrix->filetype) { + case MAT_LE2: + case MAT_LE4: + case MAT_HE2: + case MAT_HE4: + + case MAT_LE2T: + case MAT_LE4T: + case MAT_HE2T: + case MAT_HE4T: + + case MAT_SHM: + case MAT_LC: + case MAT_MATE: + case MAT_TRIXI: + err = ProjectGeneric(prx_matrix, pry_matrix, l, src_matrix); + break; + case MAT_LF4: + case MAT_HF4: + case MAT_VAXF: + err = ProjectGeneric(prx_matrix, pry_matrix, l, src_matrix); + break; + case MAT_LF8: + case MAT_HF8: + case MAT_VAXG: + case MAT_TXT: + err = ProjectGeneric(prx_matrix, pry_matrix, l, src_matrix); + break; + default: + err = ERR_PROJ_FAIL; + goto exit; + } + + if (err != ERR_SUCCESS) { + break; } } - if (matop_proj(static_cast(out_prx), static_cast(out_pry), static_cast(in_matrix)) != 0) { - return ERR_PROJ_FAIL; +exit: + // using mclose on a nullptr has no effect + mclose(src_matrix); + mclose(prx_matrix); + mclose(pry_matrix); + + return err; +} + +namespace { +// This function is implemented in this way because the default matrix type of libmfile is MAT_LC, +// which is a line-compressed format. This format does not allow writes to random positions. +// Only (sequential) writes of full lines are possible. Otherwise the matrix file will contain garbage. +template +int TransposeGeneric(MFILE *dst_matrix, MFILE *src_matrix) { + minfo info; + mgetinfo(src_matrix, &info); + + constexpr int32_t MAX_BUFFER_ELEMENTS = 16 * 1024 * 1024 / sizeof(T); + + int32_t buffered_dst_columns = std::max(1, MAX_BUFFER_ELEMENTS / static_cast(info.lines)); + auto src_buffer = std::make_unique(buffered_dst_columns); + auto dst_buffer = std::make_unique(buffered_dst_columns * info.lines); + + for (int32_t level = 0; level < static_cast(info.levels); level++) { + for (int32_t column = 0; column < static_cast(info.columns); column += buffered_dst_columns) { + + int32_t cc = std::min(buffered_dst_columns, static_cast(info.columns) - column); + + for (int32_t line = 0; line < static_cast(info.lines); line++) { + if (mget_(src_matrix, &src_buffer[0], level, line, column, cc) != cc) { + return MatOp::ERR_TRANS_FAIL; + } + for (auto c = 0; c < buffered_dst_columns; c++) { + dst_buffer[(c * info.lines) + line] = src_buffer[c]; + } + } + + for (auto c = 0; c < cc; c++) { + if (mput_(dst_matrix, &dst_buffer[c * info.lines], level, column + c, 0, info.lines) != + static_cast(info.lines)) { + return MatOp::ERR_TRANS_FAIL; + } + } + } } - return ERR_SUCCESS; + return MatOp::ERR_SUCCESS; } +} // namespace int MatOp::Transpose(const char *src_fname, const char *dst_fname) { - MFile in_matrix(src_fname, "r"); - if (in_matrix.IsZombie()) { - return ERR_SRC_OPEN; - } + int err = ERR_SUCCESS; - // std::cout << "Info: input format is " << mgetfmt(in_matrix, NULL) << - // std::endl; + // All MFILE* are initialized to have defined behavior when exiting early + MFILE *src_matrix = nullptr; + MFILE *dst_matrix = nullptr; - MFile out_matrix(dst_fname, "w"); - if (out_matrix.IsZombie()) { - return ERR_TRANS_OPEN; + src_matrix = mopen(src_fname, "r"); + if (src_matrix == nullptr) { + err = ERR_SRC_OPEN; + goto exit; } - if (matop_adjustfmts_trans(static_cast(out_matrix), static_cast(in_matrix)) != 0) { - return ERR_TRANS_FMT; + dst_matrix = mopen(dst_fname, "w"); + if (dst_matrix == nullptr) { + err = ERR_TRANS_OPEN; + goto exit; } - // std::cout << "Info: output format is " << mgetfmt(out_matrix, NULL) << - // std::endl; + minfo src_info; + minfo dst_info; + + mgetinfo(src_matrix, &src_info); + mgetinfo(dst_matrix, &dst_info); - if (matop_conv(static_cast(out_matrix), static_cast(in_matrix), MAT_TRANS) != 0) { - return ERR_TRANS_FAIL; + dst_info.levels = src_info.levels; + dst_info.lines = src_info.columns; + dst_info.columns = src_info.lines; + if (msetinfo(dst_matrix, &dst_info)) { + err = ERR_TRANS_FMT; + goto exit; } - matop_conv_free_cache(); + switch (src_matrix->filetype) { + case MAT_LE2: + case MAT_LE4: + case MAT_HE2: + case MAT_HE4: - return ERR_SUCCESS; -} + case MAT_LE2T: + case MAT_LE4T: + case MAT_HE2T: + case MAT_HE4T: -const char *MatOp::GetErrorString(int error_nr) { - if (error_nr < 0 || error_nr > MAX_ERR) { - error_nr = ERR_UNKNOWN; + case MAT_SHM: + case MAT_LC: + case MAT_MATE: + case MAT_TRIXI: + err = TransposeGeneric(dst_matrix, src_matrix); + break; + case MAT_LF4: + case MAT_HF4: + case MAT_VAXF: + err = TransposeGeneric(dst_matrix, src_matrix); + break; + case MAT_LF8: + case MAT_HF8: + case MAT_VAXG: + case MAT_TXT: + err = TransposeGeneric(dst_matrix, src_matrix); + break; + default: + err = ERR_TRANS_FAIL; } - return ErrDesc[error_nr]; +exit: + // using mclose on a nullpointer has no effect + mclose(src_matrix); + mclose(dst_matrix); + + return err; } diff --git a/src/hdtv/rootext/mfile-root/matop/matop.h b/src/hdtv/rootext/mfile-root/matop/matop.h deleted file mode 100644 index 9bc77edf..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#ifndef __MATOP_H__ -#define __MATOP_H__ - -/* 16 MByte Buffer for Symm. und Transpose */ -#define MBUFSIZE 16 * 1024 * 1024 - -enum MAT_OP { - MAT_OP_NONE, - MAT_CONV, - MAT_SYMM, - MAT_TRANS, - MAT_PROJ, - MAT_SUM, - MAT_SUB, - MAT_POLY, - MAT_MINMAX, - MAT_FILE, - MAT_STAT -}; - -#endif diff --git a/src/hdtv/rootext/mfile-root/matop/matop_adjust.c b/src/hdtv/rootext/mfile-root/matop/matop_adjust.c deleted file mode 100644 index 91f55136..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_adjust.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#include "matop_adjust.h" - -int matop_adjustfmts(MFILE *matw, MFILE *matr) { - - minfo infor; - minfo infow; - - mgetinfo(matr, &infor); - mgetinfo(matw, &infow); - - if (infow.levels && infow.lines && infow.columns) { - infor.levels = infow.levels; - infor.lines = infow.lines; - infor.columns = infow.columns; - return msetinfo(matr, &infor); - } else { - infow.levels = infor.levels; - infow.lines = infor.lines; - infow.columns = infor.columns; - return msetinfo(matw, &infow); - } -} - -int matop_adjustfmts_trans(MFILE *matw, MFILE *matr) { - - minfo infor; - minfo infow; - - mgetinfo(matr, &infor); - mgetinfo(matw, &infow); - - if (infow.levels && infow.lines && infow.columns) { - infor.levels = infow.levels; - infor.lines = infow.columns; - infor.columns = infow.lines; - return msetinfo(matr, &infor); - } else { - infow.levels = infor.levels; - infow.lines = infor.columns; - infow.columns = infor.lines; - return msetinfo(matw, &infow); - } -} - -int matop_adjustfmts_prx(MFILE *matw, MFILE *matr) { - - minfo infor; - minfo infow; - - mgetinfo(matr, &infor); - mgetinfo(matw, &infow); - - if (infor.levels > 2) - return -1; // FIXME - - infow.levels = infor.levels; - infow.lines = 1; - infow.columns = infor.columns; - - return msetinfo(matw, &infow); -} - -int matop_adjustfmts_pry(MFILE *matw, MFILE *matr) { - - minfo infor; - minfo infow; - - mgetinfo(matr, &infor); - mgetinfo(matw, &infow); - - if (infor.levels > 2) - return -1; // FIXME - - infow.levels = infor.levels; - infow.lines = 1; - infow.columns = infor.lines; - - return msetinfo(matw, &infow); -} diff --git a/src/hdtv/rootext/mfile-root/matop/matop_adjust.h b/src/hdtv/rootext/mfile-root/matop/matop_adjust.h deleted file mode 100644 index 46b00bd0..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_adjust.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#ifndef __MATOP_ADJUST_H__ -#define __MATOP_ADJUST_H__ - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -#include - -extern int matop_adjustfmts(MFILE *matw, MFILE *matr); -extern int matop_adjustfmts_prx(MFILE *matw, MFILE *matr); -extern int matop_adjustfmts_pry(MFILE *matw, MFILE *matr); -extern int matop_adjustfmts_trans(MFILE *matw, MFILE *matr); - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif diff --git a/src/hdtv/rootext/mfile-root/matop/matop_conv.c b/src/hdtv/rootext/mfile-root/matop/matop_conv.c deleted file mode 100644 index cd399747..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_conv.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -/* - * matop_conv: Copyright by - * Stefan Esser - * Institute for Nuclear Physics - * University of Cologne, Germany - * - */ - -/* Description: - * - * program to convert between different matrix file formats without - * changing the contents of the file (except rounding, depending on - * the precision and range of the data representations) - */ - -#include "matop_conv.h" -#include -#include - -static int mcopyint(MFILE *dst, MFILE *src, int op); -static int mcopyflt(MFILE *dst, MFILE *src, int op); -static int mcopydbl(MFILE *dst, MFILE *src, int op); - -struct cache_int_t { - int *buf; - int size, lines, columns; - int level, col, cachecols; - MFILE *mat; -}; -struct cache_int_t cache_int = {NULL}; - -static int mgetint_col(MFILE *mat, int *buf, int level, int line, int col, int num) { - if (mat != cache_int.mat) { - int size; - int columns = mat->columns; - int lines = mat->lines; - int cachecols = (int)(MBUFSIZE / (lines * sizeof(*cache_int.buf))); - if (cachecols < 1) - cachecols = 1; - if (cachecols > columns) - cachecols = columns; - - size = lines * cachecols; - - if (size > cache_int.size) { - cache_int.size = 0; - if (cache_int.buf) - free(cache_int.buf); - cache_int.buf = (int *)malloc(size * sizeof(*cache_int.buf)); - if (cache_int.buf) - cache_int.size = size; - } - cache_int.mat = mat; - cache_int.cachecols = cachecols; - cache_int.level = -1; - cache_int.lines = lines; - cache_int.columns = columns; - } - - if (level != cache_int.level || col < cache_int.col || col >= cache_int.col + cache_int.cachecols) { - - int n; - int l; - int *p = cache_int.buf; - - cache_int.level = -1; - n = cache_int.cachecols; - if (col + n > cache_int.columns) - n = cache_int.columns - col; - - for (l = 0; l < cache_int.lines; l++) { - int nread; - nread = mgetint(mat, p, level, l, col, n); - if (nread != n) - return -1; - p += cache_int.cachecols; - } - cache_int.level = level; - cache_int.col = col; - } - { - int i; - int *p = cache_int.buf + (line * cache_int.cachecols + col - cache_int.col); - - for (i = 0; i < num; i++) { - *buf++ = *p; - p += cache_int.cachecols; - } - } - return num; -} - -/* ======================================================================== */ -struct cache_flt_t { - float *buf; - int size, lines, columns; - int level, col, cachecols; - MFILE *mat; -}; -struct cache_flt_t cache_flt = {NULL}; - -static int mgetflt_col(MFILE *mat, float *buf, int level, int line, int col, int num) { - if (mat != cache_flt.mat) { - int size; - int columns = mat->columns; - int lines = mat->lines; - int cachecols = (int)(MBUFSIZE / (lines * sizeof(*cache_flt.buf))); - if (cachecols < 1) - cachecols = 1; - if (cachecols > columns) - cachecols = columns; - - size = lines * cachecols; - - if (size > cache_flt.size) { - cache_flt.size = 0; - if (cache_flt.buf) - free(cache_flt.buf); - cache_flt.buf = (float *)malloc(size * sizeof(*cache_flt.buf)); - if (cache_flt.buf) - cache_flt.size = size; - } - cache_flt.mat = mat; - cache_flt.cachecols = cachecols; - cache_flt.level = -1; - cache_flt.lines = lines; - cache_flt.columns = columns; - } - - if (level != cache_flt.level || col < cache_flt.col || col >= cache_flt.col + cache_flt.cachecols) { - - int n; - int l; - float *p = cache_flt.buf; - - cache_flt.level = -1; - n = cache_flt.cachecols; - if (col + n > cache_flt.columns) - n = cache_flt.columns - col; - - for (l = 0; l < cache_flt.lines; l++) { - int nread; - nread = mgetflt(mat, p, level, l, col, n); - if (nread != n) - return -1; - p += cache_flt.cachecols; - } - cache_flt.level = level; - cache_flt.col = col; - } - { - int i; - float *p = cache_flt.buf + (line * cache_flt.cachecols + col - cache_flt.col); - - for (i = 0; i < num; i++) { - *buf++ = *p; - p += cache_flt.cachecols; - } - } - return num; -} - -/* ======================================================================== */ -struct cache_dbl_t { - double *buf; - int size, lines, columns; - int level, col, cachecols; - MFILE *mat; -}; -struct cache_dbl_t cache_dbl = {NULL}; - -static int mgetdbl_col(MFILE *mat, double *buf, int level, int line, int col, int num) { - if (mat != cache_dbl.mat) { - int size; - int columns = mat->columns; - int lines = mat->lines; - int cachecols = (int)(MBUFSIZE / (lines * sizeof(*cache_dbl.buf))); - if (cachecols < 1) - cachecols = 1; - if (cachecols > columns) - cachecols = columns; - - size = lines * cachecols; - - if (size > cache_dbl.size) { - cache_dbl.size = 0; - if (cache_dbl.buf) - free(cache_dbl.buf); - cache_dbl.buf = (double *)malloc(size * sizeof(*cache_dbl.buf)); - if (cache_dbl.buf) - cache_dbl.size = size; - } - cache_dbl.mat = mat; - cache_dbl.cachecols = cachecols; - cache_dbl.level = -1; - cache_dbl.lines = lines; - cache_dbl.columns = columns; - } - - if (level != cache_dbl.level || col < cache_dbl.col || col >= cache_dbl.col + cache_dbl.cachecols) { - - int n; - int l; - double *p = cache_dbl.buf; - - cache_dbl.level = -1; - n = cache_dbl.cachecols; - if (col + n > cache_dbl.columns) - n = cache_dbl.columns - col; - - for (l = 0; l < cache_dbl.lines; l++) { - int nread; - nread = mgetdbl(mat, p, level, l, col, n); - if (nread != n) - return -1; - p += cache_dbl.cachecols; - } - cache_dbl.level = level; - cache_dbl.col = col; - } - { - int i; - double *p = cache_dbl.buf + (line * cache_dbl.cachecols + col - cache_dbl.col); - - for (i = 0; i < num; i++) { - *buf++ = *p; - p += cache_dbl.cachecols; - } - } - return num; -} - -/* ======================================================================== */ - -int matop_conv(MFILE *dst, MFILE *src, int op) { - - switch (src->filetype) { - case MAT_LE2: - case MAT_LE4: - case MAT_HE2: - case MAT_HE4: - - case MAT_LE2T: - case MAT_LE4T: - case MAT_HE2T: - case MAT_HE4T: - - case MAT_SHM: - case MAT_LC: - case MAT_MATE: - case MAT_TRIXI: - return mcopyint(dst, src, op); - - case MAT_LF4: - case MAT_HF4: - case MAT_VAXF: - return mcopyflt(dst, src, op); - - case MAT_LF8: - case MAT_HF8: - case MAT_VAXG: - case MAT_TXT: - return mcopydbl(dst, src, op); - } - return -1; -} - -void matop_conv_free_cache(void) { - if (cache_int.buf) - free(cache_int.buf); - memset(&cache_int, 0, sizeof(cache_int)); - - if (cache_flt.buf) - free(cache_flt.buf); - memset(&cache_flt, 0, sizeof(cache_flt)); - - if (cache_dbl.buf) - free(cache_dbl.buf); - memset(&cache_dbl, 0, sizeof(cache_dbl)); -} - -static int mcopyint(MFILE *dst, MFILE *src, int op) { - - int sc = src->columns; - int dc = dst->columns; - - int *sbuf = NULL; - int *dbuf = NULL; - - int err = 0; - - dbuf = (int *)malloc(dc * sizeof(*dbuf)); - - if (op == MAT_SYMM) { - sbuf = (int *)malloc(sc * sizeof(*sbuf)); - } else { - sbuf = dbuf; - } - - if (sbuf && dbuf) { - int v, l; - int vmax = src->levels; - int lmax = src->lines; - - /* For asymmetric matrices, columns and rows are exchanged */ - if (op == MAT_TRANS) { - lmax = src->columns; - } - - for (v = 0; !err && v < vmax; v++) { - for (l = 0; !err && l < lmax; l++) { - - if (op == MAT_CONV || op == MAT_SYMM) { - if (mgetint(src, sbuf, v, l, 0, sc) != sc) - err = -1; - } - - if (op == MAT_TRANS || op == MAT_SYMM) { - if (mgetint_col(src, dbuf, v, 0, l, dc) != dc) - err = -1; - } - - if (op == MAT_SYMM) { - int c; - for (c = 0; c < sc; c++) - dbuf[c] += sbuf[c]; - } - - if (!err && mputint(dst, dbuf, v, l, 0, dc) != dc) - err = -1; - } - } - } else { - err = -1; - } - - if (mflush(dst) != 0) - err = -1; - - if (dbuf) - free(dbuf); - if (op == MAT_SYMM && sbuf) - free(sbuf); - - return err; -} - -static int mcopyflt(MFILE *dst, MFILE *src, int op) { - - int sc = src->columns; - int dc = dst->columns; - - float *sbuf = NULL; - float *dbuf = NULL; - - int err = 0; - - dbuf = (float *)malloc(dc * sizeof(*dbuf)); - - if (op == MAT_SYMM) { - sbuf = (float *)malloc(sc * sizeof(*sbuf)); - } else { - sbuf = dbuf; - } - - if (sbuf && dbuf) { - int v, l; - int vmax = src->levels; - int lmax = src->lines; - - for (v = 0; !err && v < vmax; v++) { - for (l = 0; !err && l < lmax; l++) { - - if (op == MAT_CONV || op == MAT_SYMM) { - if (mgetflt(src, sbuf, v, l, 0, sc) != sc) - err = -1; - } - - if (op == MAT_TRANS || op == MAT_SYMM) { - if (mgetflt_col(src, dbuf, v, 0, l, dc) != dc) - err = -1; - } - - if (op == MAT_SYMM) { - int c; - for (c = 0; c < sc; c++) - dbuf[c] += sbuf[c]; - } - - if (mputflt(dst, dbuf, v, l, 0, dc) != dc) - err = -1; - } - } - } else { - err = -1; - } - - if (mflush(dst) != 0) - err = -1; - - if (dbuf) - free(dbuf); - if (op == MAT_SYMM && sbuf) - free(sbuf); - - return err; -} - -static int mcopydbl(MFILE *dst, MFILE *src, int op) { - - int sc = src->columns; - int dc = dst->columns; - - double *sbuf = NULL; - double *dbuf = NULL; - - int err = 0; - - dbuf = (double *)malloc(dc * sizeof(*dbuf)); - - if (op == MAT_SYMM) { - sbuf = (double *)malloc(sc * sizeof(*sbuf)); - } else { - sbuf = dbuf; - } - - if (sbuf && dbuf) { - int v, l; - int vmax = src->levels; - int lmax = src->lines; - - for (v = 0; !err && v < vmax; v++) { - for (l = 0; !err && l < lmax; l++) { - - if (op == MAT_CONV || op == MAT_SYMM) { - if (mgetdbl(src, sbuf, v, l, 0, sc) != sc) - err = -1; - } - - if (op == MAT_TRANS || op == MAT_SYMM) { - if (mgetdbl_col(src, dbuf, v, 0, l, dc) != dc) - err = -1; - } - - if (op == MAT_SYMM) { - int c; - for (c = 0; c < sc; c++) - dbuf[c] += sbuf[c]; - } - - if (mputdbl(dst, dbuf, v, l, 0, dc) != dc) - err = -1; - } - } - } else { - err = -1; - } - - if (mflush(dst) != 0) - err = -1; - - if (dbuf) - free(dbuf); - if (op == MAT_SYMM && sbuf) - free(sbuf); - - return err; -} diff --git a/src/hdtv/rootext/mfile-root/matop/matop_conv.h b/src/hdtv/rootext/mfile-root/matop/matop_conv.h deleted file mode 100644 index 55cbcf45..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_conv.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#ifndef __MATOP_CONV_H__ -#define __MATOP_CONV_H__ - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -#include "matop.h" -#include - -extern int matop_conv(MFILE *dst, MFILE *src, int op); -extern void matop_conv_free_cache(void); - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif diff --git a/src/hdtv/rootext/mfile-root/matop/matop_project.c b/src/hdtv/rootext/mfile-root/matop/matop_project.c deleted file mode 100644 index 8066df89..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_project.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#include "matop_project.h" -#include -#include - -static int mprojint(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src); -static int mprojflt(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src); -static int mprojdbl(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src); -static int matop_proj_single(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src); - -int matop_proj(MFILE *dstx, MFILE *dsty, MFILE *src) { - int err; - minfo info; - - mgetinfo(src, &info); - - if (info.levels > 2) - return -1; - - err = matop_proj_single(dstx, dsty, 0, src); - if (err != 0) - return err; - - if (info.levels > 1) - err = matop_proj_single(dstx, dsty, 1, src); - - return err; -} - -int matop_proj_single(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src) { - - switch (src->filetype) { - case MAT_LE2: - case MAT_LE4: - case MAT_HE2: - case MAT_HE4: - - case MAT_LE2T: - case MAT_LE4T: - case MAT_HE2T: - case MAT_HE4T: - - case MAT_SHM: - case MAT_LC: - case MAT_MATE: - case MAT_TRIXI: - return mprojint(dstx, dsty, level, src); - - case MAT_LF4: - case MAT_HF4: - case MAT_VAXF: - return mprojflt(dstx, dsty, level, src); - - case MAT_LF8: - case MAT_HF8: - case MAT_VAXG: - case MAT_TXT: - return mprojdbl(dstx, dsty, level, src); - } - return -1; -} - -static int mprojint(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src) { - - int err = 0; - int exitstatus = -1; - minfo info; - int *lbuf; - int *prx = NULL; - int *pry = NULL; - - int columns; - int lines; - - mgetinfo(src, &info); - columns = info.columns; - lines = info.lines; - if (level >= info.levels) - goto errexit; - - lbuf = (int *)malloc(columns * sizeof(int)); - if (dstx) - prx = (int *)malloc(columns * sizeof(int)); - if (dsty) - pry = (int *)malloc(lines * sizeof(int)); - - if (!lbuf || (dstx && !prx) || (dsty && !pry)) - goto errexit; - - { - int l, c; - - if (prx) - memset(prx, 0, columns * sizeof(int)); - if (pry) - memset(pry, 0, lines * sizeof(int)); - - for (l = 0; l < lines; l++) { - if (mgetint(src, lbuf, level, l, 0, columns) != columns) - goto errexit; - - if (prx) { - for (c = 0; c < columns; c++) { - prx[c] += lbuf[c]; - } - } - if (pry) { - int sum = 0; - for (c = 0; c < columns; c++) { - sum += lbuf[c]; - } - pry[l] += sum; - } - } - } - - free(lbuf); - - if (prx) { - if (mputint(dstx, prx, level, 0, 0, columns) != columns) - err = -1; - free(prx); - } - - if (pry) { - if (mputint(dsty, pry, level, 0, 0, lines) != lines) - err = -1; - free(pry); - } - - exitstatus = err; - -errexit: - - return exitstatus; -} - -static int mprojflt(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src) { - - int err = 0; - int exitstatus = -1; - minfo info; - float *lbuf; - float *prx = NULL; - float *pry = NULL; - - int columns; - int lines; - - mgetinfo(src, &info); - columns = info.columns; - lines = info.lines; - if (level >= info.levels) - goto errexit; - - lbuf = (float *)malloc(columns * sizeof(float)); - if (dstx) - prx = (float *)malloc(columns * sizeof(float)); - if (dsty) - pry = (float *)malloc(lines * sizeof(float)); - - if (!lbuf || (dstx && !prx) || (dsty && !pry)) - goto errexit; - - { - int l, c; - - if (prx) - memset(prx, 0, columns * sizeof(float)); - if (pry) - memset(pry, 0, lines * sizeof(float)); - - for (l = 0; l < lines; l++) { - if (mgetflt(src, lbuf, level, l, 0, columns) != columns) - goto errexit; - - if (prx) { - for (c = 0; c < columns; c++) { - prx[c] += lbuf[c]; - } - } - if (pry) { - float sum = 0; - for (c = 0; c < columns; c++) { - sum += lbuf[c]; - } - pry[l] += sum; - } - } - } - - free(lbuf); - - if (prx) { - if (mputflt(dstx, prx, level, 0, 0, columns) != columns) - err = -1; - free(prx); - } - - if (pry) { - if (mputflt(dsty, pry, level, 0, 0, lines) != lines) - err = -1; - free(pry); - } - - exitstatus = err; - -errexit: - - return exitstatus; -} - -static int mprojdbl(MFILE *dstx, MFILE *dsty, unsigned int level, MFILE *src) { - - int err = 0; - int exitstatus = -1; - minfo info; - double *lbuf; - double *prx = NULL; - double *pry = NULL; - - int columns; - int lines; - - mgetinfo(src, &info); - columns = info.columns; - lines = info.lines; - if (level >= info.levels) - goto errexit; - - lbuf = (double *)malloc(columns * sizeof(double)); - if (dstx) - prx = (double *)malloc(columns * sizeof(double)); - if (dsty) - pry = (double *)malloc(lines * sizeof(double)); - - if (!lbuf || (dstx && !prx) || (dsty && !pry)) - goto errexit; - - { - int l, c; - - if (prx) - memset(prx, 0, columns * sizeof(double)); - if (pry) - memset(pry, 0, lines * sizeof(double)); - - for (l = 0; l < lines; l++) { - if (mgetdbl(src, lbuf, level, l, 0, columns) != columns) - goto errexit; - - if (prx) { - for (c = 0; c < columns; c++) { - prx[c] += lbuf[c]; - } - } - if (pry) { - double sum = 0; - for (c = 0; c < columns; c++) { - sum += lbuf[c]; - } - pry[l] += sum; - } - } - } - - free(lbuf); - - if (prx) { - if (mputdbl(dstx, prx, level, 0, 0, columns) != columns) - err = -1; - free(prx); - } - - if (pry) { - if (mputdbl(dsty, pry, level, 0, 0, lines) != lines) - err = -1; - free(pry); - } - - exitstatus = err; - -errexit: - - return exitstatus; -} diff --git a/src/hdtv/rootext/mfile-root/matop/matop_project.h b/src/hdtv/rootext/mfile-root/matop/matop_project.h deleted file mode 100644 index e5393bbc..00000000 --- a/src/hdtv/rootext/mfile-root/matop/matop_project.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 1992-2008, Stefan Esser - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code was derived from the matop package, the license of which is - * reproduced above. - * - * Adapted for HDTV by Norbert Braun, 2010. - */ - -#ifndef __MATOP_PROJECT_H__ -#define __MATOP_PROJECT_H__ - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -#include - -extern int matop_proj(MFILE *dstx, MFILE *dsty, MFILE *src); - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif diff --git a/tests/rootext/complex.mtx b/tests/rootext/complex.mtx new file mode 100644 index 00000000..8d63a5ee Binary files /dev/null and b/tests/rootext/complex.mtx differ diff --git a/tests/rootext/complex.tmtx b/tests/rootext/complex.tmtx new file mode 100644 index 00000000..9f3b0c52 Binary files /dev/null and b/tests/rootext/complex.tmtx differ diff --git a/tests/rootext/create_mtx.c b/tests/rootext/create_mtx.c new file mode 100644 index 00000000..5e6b6df3 --- /dev/null +++ b/tests/rootext/create_mtx.c @@ -0,0 +1,254 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2026 Thomas Heijligen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * This program generates matrices to test the HDTV MatOp Transpose function. + * + * First build src/hdtv/rootext/mfile-root/mfile and copy the libmfile.so and + * mfile.h into this directory. To compile this file, run + * + * cc -o create_mtx create_mtx.c -Wl,-rpath,'$ORIGIN' -I. -L. -lmfile + * + * To create a matrix and it's transpose, run + * + * ./create_mtx + * + * E.g. `./create_mtx simple 600 800` creates a 'simple.mtx' with 600 lines and + * 800 columns, and a transposed 'simple.tmtx' with 800 lines and 600 columns. + * + * The `simple` mode produces a matrix with it's 1st column set to 600 and a + * transposed matrix with it's 1st line set to 600. + * + * 0------- 0----- + * |6 0 0 0 |6 6 6 + * |6 0 0 0 => |0 0 0 + * |6 0 0 0 |0 0 0 + * |0 0 0 + * + * The `complex` mode produces a matrix where every value is unique. Since the + * default format is MAT_LC (line compressed), the resulting matrices are quite + * large. + * + * 0------- 0----- + * |0 1 2 3 |0 4 8 + * |4 5 6 7 => |1 5 9 + * |8 9 A B |2 6 A + * |3 7 B + * + */ + +#include +#include +#include +#include +#include + +#include "mfile.h" + +static MFILE *mcreate(const char *name, unsigned lines, unsigned columns) { + MFILE *mtx = mopen(name, "w"); + if (!mtx) { + return NULL; + } + + minfo info; + if (mgetinfo(mtx, &info)) { + mclose(mtx); + return NULL; + } + + info.levels = 1; + info.lines = lines; + info.columns = columns; + + if (msetinfo(mtx, &info)) { + mclose(mtx); + return NULL; + } + + return mtx; +} + +static int simple(unsigned lines, unsigned columns) { + const char *MTX_NAME = "simple.mtx"; + const char *TMTX_NAME = "simple.tmtx"; + const double VALUE = 600; + MFILE *mtx; + double *buffer; + + mtx = mcreate(MTX_NAME, lines, columns); + if (!mtx) { + printf("Failed to create '%s'\n", MTX_NAME); + return -1; + } + + buffer = calloc(columns, sizeof(*buffer)); + if (!buffer) { + mclose(mtx); + printf("Failed to create buffer of size %u\n", columns); + return -1; + } + buffer[0] = VALUE; + + for (unsigned l = 0; l < lines; l++) { + if (mputdbl(mtx, buffer, 0, (int32_t)l, 0, (int32_t)columns) != (int32_t)columns) { + free(buffer); + mclose(mtx); + printf("Failed to write '%s' line %u\n", MTX_NAME, l); + return -1; + } + } + free(buffer); + mclose(mtx); + + mtx = mcreate(TMTX_NAME, columns, lines); + if (!mtx) { + printf("Failed to create '%s'\n", TMTX_NAME); + return -1; + } + + buffer = calloc(lines, sizeof(*buffer)); + if (!buffer) { + mclose(mtx); + printf("Failed to create buffer of size %u\n", columns); + return -1; + } + for (unsigned i = 0; i < lines; i++) { + buffer[i] = VALUE; + } + + if (mputdbl(mtx, buffer, 0, 0, 0, (int32_t)lines) != (int32_t)lines) { + free(buffer); + mclose(mtx); + printf("Failed to write '%s' line 0\n", TMTX_NAME); + return -1; + } + + for (unsigned i = 0; i < lines; i++) { + buffer[i] = 0; + } + + for (unsigned c = 1; c < columns; c++) { + if (mputdbl(mtx, buffer, 0, (int32_t)c, 0, (int32_t)lines) != (int32_t)lines) { + free(buffer); + mclose(mtx); + printf("Failed to write '%s' line %u\n", TMTX_NAME, c); + return -1; + } + } + free(buffer); + mclose(mtx); + + return 0; +} + +static int complex(unsigned lines, unsigned columns) { + const char *MTX_NAME = "complex.mtx"; + const char *TMTX_NAME = "complex.tmtx"; + MFILE *mtx; + double *buffer; + + mtx = mcreate(MTX_NAME, lines, columns); + if (!mtx) { + printf("Failed to create '%s'\n", MTX_NAME); + return -1; + } + + buffer = calloc(columns, sizeof(*buffer)); + if (!buffer) { + mclose(mtx); + printf("Failed to create buffer of size %u\n", columns); + return -1; + } + + for (unsigned l = 0; l < lines; l++) { + for (unsigned c = 0; c < columns; c++) { + buffer[c] = (l * lines) + c; + } + if (mputdbl(mtx, buffer, 0, (int32_t)l, 0, (int32_t)columns) != (int32_t)columns) { + free(buffer); + mclose(mtx); + printf("Failed to write '%s' line %u\n", MTX_NAME, l); + return -1; + } + } + + free(buffer); + mclose(mtx); + + mtx = mcreate(TMTX_NAME, columns, lines); + if (!mtx) { + printf("Failed to create '%s'\n", TMTX_NAME); + return -1; + } + + buffer = calloc(lines, sizeof(*buffer)); + if (!buffer) { + mclose(mtx); + printf("Failed to create buffer of size %u\n", lines); + return -1; + } + + for (unsigned c = 0; c < columns; c++) { + for (unsigned l = 0; l < lines; l++) { + buffer[l] = (l * lines) + c; + } + if (mputdbl(mtx, buffer, 0, (int32_t)c, 0, (int32_t)lines) != (int32_t)lines) { + free(buffer); + mclose(mtx); + printf("Failed to write '%s' line %u\n", MTX_NAME, c); + return -1; + } + } + + free(buffer); + mclose(mtx); + + return 0; +} + +static void print_help(const char *argv0) { + printf("Usage %s \n\n" + " e.g. '%s simple 600 800` creates a 'simple.mtx' with 600 lines and 800" + " columns, and a transposed 'simple.tmtx' with 800 lines and 600 columns", + argv0, argv0); +} + +int main(int argc, char *argv[]) { + if (argc != 4) { + print_help(argv[0]); + return -1; + } + + errno = 0; + const unsigned lines = (unsigned)strtoul(argv[2], NULL, 10); + if (errno == ERANGE) { + printf("Failed to parse \n\n"); + print_help(argv[0]); + return -1; + } + const unsigned columns = (unsigned)strtoul(argv[3], NULL, 10); + if (errno == ERANGE) { + printf("Failed to parse \n\n"); + print_help(argv[0]); + return -1; + } + + if (!strcmp(argv[1], "simple")) { + return simple(lines, columns); + } + + if (!strcmp(argv[1], "complex")) { + return complex(lines, columns); + } + + print_help(argv[0]); + return -1; +} diff --git a/tests/rootext/simple.mtx b/tests/rootext/simple.mtx new file mode 100644 index 00000000..b7a6f22e Binary files /dev/null and b/tests/rootext/simple.mtx differ diff --git a/tests/rootext/simple.tmtx b/tests/rootext/simple.tmtx new file mode 100644 index 00000000..b32045c0 Binary files /dev/null and b/tests/rootext/simple.tmtx differ diff --git a/tests/rootext/test_matop.py b/tests/rootext/test_matop.py new file mode 100644 index 00000000..1e6d00f6 --- /dev/null +++ b/tests/rootext/test_matop.py @@ -0,0 +1,69 @@ +# HDTV - A ROOT-based spectrum analysis software +# Copyright (C) 2006-2019 The HDTV development team (see file AUTHORS) +# +# This file is part of HDTV. +# +# HDTV is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# HDTV is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with HDTV; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +""" +Test whether the rootext Matop Transpose operation performs as intended. + +At time of writing, there is no interface to generate mfiles with Python. +The test files were generated using create_mtx.c. +Note that the checked-in test files are deliberately small and may not +cover all edge cases of the transpose implementation. Generate larger +files to trigger these cases. + +""" +import hashlib +import os +import tempfile + +import pytest +import ROOT + + +@pytest.fixture +def load_rootext(lib="mfile-root"): + import hdtv.rootext.dlmgr + hdtv.rootext.dlmgr.LoadLibrary(lib) + +@pytest.mark.parametrize( + "mtx, tmtx",[ + ("simple.mtx", "simple.tmtx"), + ("simple.tmtx", "simple.mtx"), + ("complex.mtx", "complex.tmtx"), + ("complex.tmtx", "complex.mtx"), + ] +) +def test_matop_transpose(mtx : str, tmtx : str): + mtx = os.path.join(os.path.dirname(__file__), mtx) + tmtx = os.path.join(os.path.dirname(__file__), tmtx) + + tmtx_hash = hashlib.md5() + with open(tmtx, "rb") as _tmtx: + for block in iter(lambda: _tmtx.read(65536), b''): + tmtx_hash.update(block) + + calc_hash = hashlib.md5() + with tempfile.NamedTemporaryFile(mode= "r+b", delete=True) as _tmtx: + result = ROOT.MatOp.Transpose(mtx, _tmtx.name) + assert result == 0, \ + f"MatOp.Transpose failed with error code {result}: {ROOT.MatOp.GetErrorString(result)}" + for block in iter(lambda: _tmtx.read(65536), b''): + calc_hash.update(block) + + assert calc_hash.digest() == tmtx_hash.digest(), \ + f"Hash mismatch: expected {tmtx_hash.hexdigest()}, got {calc_hash.hexdigest()}"