diff --git a/CMakeLists.txt b/CMakeLists.txt index e6578cc..5453bba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.5) project(openexr-viewer - VERSION 0.6.0 + VERSION 0.6.1 DESCRIPTION "Simple Viewer for OpenEXR files with detailed metadata display" HOMEPAGE_URL "https://github.com/afichet/openexr-viewer" LANGUAGES CXX diff --git a/LICENSE b/LICENSE index 54190aa..63ac461 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2021, Alban Fichet +Copyright (c) 2021 - 2023, Alban Fichet All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/deploy/linux/openexr-viewer.desktop b/deploy/linux/openexr-viewer.desktop index ad85cca..bb5fcb7 100644 --- a/deploy/linux/openexr-viewer.desktop +++ b/deploy/linux/openexr-viewer.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Type=Application -Version=0.6.0 +Version=0.6.1 Name=OpenEXR Viewer Comment=Viewer for OpenEXR images Icon=openexr-viewer diff --git a/deploy/linux/openexr-viewer.metainfo.xml b/deploy/linux/openexr-viewer.metainfo.xml index 0354152..76e3385 100644 --- a/deploy/linux/openexr-viewer.metainfo.xml +++ b/deploy/linux/openexr-viewer.metainfo.xml @@ -11,6 +11,7 @@ openexr-viewer.desktop + diff --git a/src/model/framebuffer/FramebufferModel.cpp b/src/model/framebuffer/FramebufferModel.cpp index 4f21ba7..379b669 100644 --- a/src/model/framebuffer/FramebufferModel.cpp +++ b/src/model/framebuffer/FramebufferModel.cpp @@ -39,7 +39,6 @@ FramebufferModel::FramebufferModel(QObject* parent) : QObject(parent) - , m_pixelBuffer(nullptr) , m_width(0) , m_height(0) , m_isImageLoaded(false) @@ -59,7 +58,4 @@ QRect FramebufferModel::getDataWindow() const return m_dataWindow; } -FramebufferModel::~FramebufferModel() -{ - delete[] m_pixelBuffer; -} +FramebufferModel::~FramebufferModel() {} diff --git a/src/model/framebuffer/FramebufferModel.h b/src/model/framebuffer/FramebufferModel.h index b0067db..7993fb5 100644 --- a/src/model/framebuffer/FramebufferModel.h +++ b/src/model/framebuffer/FramebufferModel.h @@ -37,7 +37,7 @@ #include #include #include -#include +#include class FramebufferModel: public QObject { @@ -67,9 +67,11 @@ class FramebufferModel: public QObject void loadFailed(QString message); protected: - float* m_pixelBuffer; - QImage m_image; + std::vector m_pixelBuffer; + QImage m_image; + // Right now, the width and height are defined as Vec2i in OpenEXR + // i.e. int type. int m_width, m_height; bool m_isImageLoaded; diff --git a/src/model/framebuffer/RGBFramebufferModel.cpp b/src/model/framebuffer/RGBFramebufferModel.cpp index f345470..66fd78c 100644 --- a/src/model/framebuffer/RGBFramebufferModel.cpp +++ b/src/model/framebuffer/RGBFramebufferModel.cpp @@ -81,6 +81,23 @@ void RGBFramebufferModel::load( m_displayWindow = QRect(dispW.min.x, dispW.min.y, dispW_width, dispW_height); + // Check to avoid type overflow, width and height are 32bits int + // representing a 2 dimentional image. Can overflow the type when + // multiplied together. + // 0x1FFFFFFF is a save limit for 4 * 0x7FFFFFFF the max + // representable int since we need 4 channels. + // TODO: Use larger type when manipulating framebuffer + const uint64_t partial_size + = (uint64_t)m_width * (uint64_t)m_height; + + if (partial_size > 0x1FFFFFFF) { + throw std::runtime_error( + "The total image size is too large. May be supported in a " + "future revision."); + } + + m_pixelBuffer.resize(4 * m_width * m_height); + // Check if there is specific chromaticities tied to the color // representation in this part. const Imf::ChromaticitiesAttribute* c @@ -93,8 +110,6 @@ void RGBFramebufferModel::load( chromaticities = c->value(); } - m_pixelBuffer = new float[4 * m_width * m_height]; - // Check if there is alpha channel if (hasAlpha) { std::string aLayer = m_parentLayer + "A"; @@ -190,12 +205,12 @@ void RGBFramebufferModel::load( Imf::FrameBuffer framebuffer; - Imf::Rgba* buff1 = new Imf::Rgba[m_width * m_height]; - Imf::Rgba* buff2 = new Imf::Rgba[m_width * m_height]; + std::vector buff1(m_width * m_height); + std::vector buff2(m_width * m_height); - float* yBuffer = new float[m_width * m_height]; - float* ryBuffer = new float[m_width / 2 * m_height / 2]; - float* byBuffer = new float[m_width / 2 * m_height / 2]; + std::vector yBuffer(m_width * m_height); + std::vector ryBuffer(m_width / 2 * m_height / 2); + std::vector byBuffer(m_width / 2 * m_height / 2); Imf::Slice ySlice = Imf::Slice::Make( Imf::PixelType::FLOAT, @@ -335,12 +350,6 @@ void RGBFramebufferModel::load( m_pixelBuffer[4 * (y * m_width + x) + 2] = rgb.z; } } - - delete[] yBuffer; - delete[] ryBuffer; - delete[] byBuffer; - delete[] buff1; - delete[] buff2; } break; diff --git a/src/model/framebuffer/YFramebufferModel.cpp b/src/model/framebuffer/YFramebufferModel.cpp index 06f388c..7310c6e 100644 --- a/src/model/framebuffer/YFramebufferModel.cpp +++ b/src/model/framebuffer/YFramebufferModel.cpp @@ -90,12 +90,25 @@ void YFramebufferModel::load(Imf::MultiPartInputFile& file, int partId) dispW_width / 2, dispW_height / 2); - m_pixelBuffer = new float[m_width * m_height]; + // Check to avoid type overflow, width and height are 32bits int + // representing a 2 dimentional image. Can overflow the type when + // multiplied together + // TODO: Use larger type when manipulating framebuffer + const uint64_t partial_size + = (uint64_t)m_width * (uint64_t)m_height; + + if (partial_size > 0x7FFFFFFF) { + throw std::runtime_error( + "The total image size is too large. May be supported in " + "a future revision."); + } + + m_pixelBuffer.resize(m_width * m_height); // Luminance Chroma channels graySlice = Imf::Slice::Make( Imf::PixelType::FLOAT, - m_pixelBuffer, + m_pixelBuffer.data(), datW, sizeof(float), m_width * sizeof(float), @@ -112,11 +125,11 @@ void YFramebufferModel::load(Imf::MultiPartInputFile& file, int partId) m_displayWindow = QRect(dispW.min.x, dispW.min.y, dispW_width, dispW_height); - m_pixelBuffer = new float[m_width * m_height]; + m_pixelBuffer.resize(m_width * m_height); graySlice = Imf::Slice::Make( Imf::PixelType::FLOAT, - m_pixelBuffer, + m_pixelBuffer.data(), datW); }