Skip to content

Commit

Permalink
implement stacking with optional debayering
Browse files Browse the repository at this point in the history
  • Loading branch information
astrowander committed Oct 9, 2022
1 parent 9edc234 commit 13cbf4f
Show file tree
Hide file tree
Showing 28 changed files with 240 additions and 88 deletions.
2 changes: 2 additions & 0 deletions AstroCombiner.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<ClInclude Include="Codecs\PPM\ppmdecoder.h" />
<ClInclude Include="Codecs\PPM\ppmencoder.h" />
<ClInclude Include="Codecs\Raw\RawDecoder.h" />
<ClInclude Include="Codecs\Raw\RawSettings.h" />
<ClInclude Include="Codecs\Tiff\TiffDecoder.h" />
<ClInclude Include="Codecs\Tiff\TiffEncoder.h" />
<ClInclude Include="Core\bitmap.h" />
Expand All @@ -38,6 +39,7 @@
<ClInclude Include="Core\IPipelineElement.h" />
<ClInclude Include="Core\macros.h" />
<ClInclude Include="Core\pipeline.h" />
<ClInclude Include="Core\versioning.h" />
<ClInclude Include="Geometry\delaunator.hpp" />
<ClInclude Include="Geometry\point.h" />
<ClInclude Include="Geometry\rect.h" />
Expand Down
6 changes: 6 additions & 0 deletions AstroCombiner.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@
<ClInclude Include="Transforms\DebayerTransform.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Codecs\Raw\RawSettings.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Core\versioning.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="AGG\agg_trans_affine.cpp">
Expand Down
31 changes: 26 additions & 5 deletions Codecs/Raw/RawDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <map>
#include <string>
#include "libraw/libraw.h"
#include <tbb/blocked_range.h>
#include <tbb/parallel_for.h>

ACMB_NAMESPACE_BEGIN

Expand Down Expand Up @@ -77,7 +79,6 @@ void RawDecoder::Attach(const std::string& fileName)
_width = _pLibRaw->imgdata.sizes.iwidth;
_height = _pLibRaw->imgdata.sizes.iheight;

_pCameraSettings = std::make_shared<CameraSettings>();
_pCameraSettings->timestamp = _pLibRaw->imgdata.other.timestamp;
_pCameraSettings->sensorSizeMm = sensorSizes[_pLibRaw->imgdata.lens.makernotes.CameraFormat];
_pCameraSettings->cropFactor = cropFactors[_pLibRaw->imgdata.lens.makernotes.CameraFormat];
Expand All @@ -90,6 +91,12 @@ void RawDecoder::Attach(const std::string& fileName)
_pCameraSettings->cameraModelName.push_back(' ');
_pCameraSettings->cameraModelName.append(_pLibRaw->imgdata.idata.model);

_pCameraSettings->maxChannel = _pLibRaw->imgdata.color.maximum;
for ( int i = 0; i < 4; ++i )
{
_pCameraSettings->channelPremultipiers[i] = _pLibRaw->imgdata.color.pre_mul[i];
}

if (lensMakers.find(_pLibRaw->imgdata.lens.makernotes.LensID) != std::end(lensMakers))
_pCameraSettings->lensMakerName = lensMakers.at(_pLibRaw->imgdata.lens.makernotes.LensID);

Expand Down Expand Up @@ -121,6 +128,7 @@ std::shared_ptr<IBitmap> RawDecoder::ReadBitmap()
{
throw std::runtime_error("raw processing error");
}
_pCameraSettings->blackLevel = _pLibRaw->imgdata.color.black;

if ( _pixelFormat == PixelFormat::Gray16 )
{
Expand All @@ -129,11 +137,14 @@ std::shared_ptr<IBitmap> RawDecoder::ReadBitmap()
const int leftOffset = _pLibRaw->imgdata.sizes.left_margin * BytesPerPixel( _pixelFormat );
const int stride = _width * BytesPerPixel( _pixelFormat );

for ( uint32_t i = 0; i < _height; ++i )
oneapi::tbb::parallel_for( oneapi::tbb::blocked_range<int>( 0, _height ), [&] (const oneapi::tbb::blocked_range<int>& range)
{
memcpy( pRes->GetPlanarScanline( i ), reinterpret_cast<char*>( _pLibRaw->imgdata.rawdata.raw_image ) + topOffset + i * rawStride + leftOffset, stride);
}

for ( int i = range.begin(); i < range.end(); ++i )
{
memcpy( pRes->GetPlanarScanline( i ), reinterpret_cast< char* >( _pLibRaw->imgdata.rawdata.raw_image ) + topOffset + i * rawStride + leftOffset, stride );
}
} );
pRes->SetCameraSettings( _pCameraSettings );
Reattach();
return pRes;
}
Expand Down Expand Up @@ -165,4 +176,14 @@ std::unordered_set<std::string> RawDecoder::GetExtensions()
return { ".ari", ".dpx", ".arw", ".srf", ".sr2", ".bay", ".cr3", ".crw", ".cr2", ".dng", ".dcr", ".kdc", ".erf", ".3fr", ".mef", ".mrw", ".nef", ".nrw", ".orf", ".ptx", ".pef", ".raf", ".raw", ".rw1", ".rw2", "r3d", "srw", ".x3f" };
}

const RawSettings& RawDecoder::GetRawSettings()
{
return _rawSettings;
}

void RawDecoder::SetRawSettings( const RawSettings& rawSettings )
{
_rawSettings = rawSettings;
}

ACMB_NAMESPACE_END
11 changes: 3 additions & 8 deletions Codecs/Raw/RawDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@
class LibRaw;

ACMB_NAMESPACE_BEGIN
/// Settings for RAW files reading
struct RawSettings
{
/// if true bitmap size will be two times smaller
bool halfSize = false;
/// if format is grayscale picture will not be debayered
PixelFormat outputFormat = PixelFormat::RGB48;
};

/// <summary>
/// Reads RAW files
Expand All @@ -37,6 +29,9 @@ class RawDecoder : public ImageDecoder
///returns supported extensions
static std::unordered_set <std::string> GetExtensions();

const RawSettings& GetRawSettings();
void SetRawSettings( const RawSettings& rawSettings );

ADD_EXTENSIONS
};

Expand Down
15 changes: 15 additions & 0 deletions Codecs/Raw/RawSettings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once
#include "../../Core/enums.h"

ACMB_NAMESPACE_BEGIN

/// Settings for RAW files reading
struct RawSettings
{
/// if true bitmap size will be two times smaller
bool halfSize = false;
/// if format is grayscale picture will not be debayered
PixelFormat outputFormat = PixelFormat::Gray16;
};

ACMB_NAMESPACE_END
16 changes: 8 additions & 8 deletions Codecs/imagedecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ IBitmapPtr ImageDecoder::ProcessBitmap( IBitmapPtr )
return ReadBitmap();
}

std::shared_ptr<ImageDecoder> ImageDecoder::Create(const std::string &fileName)
std::shared_ptr<ImageDecoder> ImageDecoder::Create(const std::string &fileName, const RawSettings& rawSettings )
{
auto path = std::filesystem::path(fileName);
auto extension = path.extension().string();
Expand All @@ -79,7 +79,7 @@ std::shared_ptr<ImageDecoder> ImageDecoder::Create(const std::string &fileName)
}
else if ( RawDecoder::GetExtensions().contains( extension ) )
{
pDecoder.reset(new RawDecoder());
pDecoder.reset(new RawDecoder( rawSettings ));
}
else if ( TiffDecoder::GetExtensions().contains( extension ) )
{
Expand All @@ -98,7 +98,7 @@ const std::string& ImageDecoder::GetLastFileName() const
return _lastFileName;
}

std::vector<Pipeline> ImageDecoder::GetPipelinesFromDir( std::string path )
std::vector<Pipeline> ImageDecoder::GetPipelinesFromDir( std::string path, const RawSettings& rawSettings )
{
if ( !std::filesystem::is_directory( path ) )
return {};
Expand All @@ -112,13 +112,13 @@ std::vector<Pipeline> ImageDecoder::GetPipelinesFromDir( std::string path )
auto extension = entry.path().extension().string();
std::transform( extension.begin(), extension.end(), extension.begin(), [] ( unsigned char c ) { return std::tolower( c ); } );
if ( GetAllExtensions().contains(extension) )
res.emplace_back( ImageDecoder::Create( entry.path().string() ) );
res.emplace_back( ImageDecoder::Create( entry.path().string(), rawSettings ) );
}

return res;
}

std::vector<Pipeline> ImageDecoder::GetPipelinesFromMask( std::string mask )
std::vector<Pipeline> ImageDecoder::GetPipelinesFromMask( std::string mask, const RawSettings& rawSettings )
{
size_t start = 0;
std::vector<Pipeline> res;
Expand All @@ -133,12 +133,12 @@ std::vector<Pipeline> ImageDecoder::GetPipelinesFromMask( std::string mask )
{
if ( std::filesystem::is_directory( fileName ) )
{
auto pipelines = ImageDecoder::GetPipelinesFromDir( fileName );
auto pipelines = ImageDecoder::GetPipelinesFromDir( fileName, rawSettings );
res.insert( res.end(), pipelines.begin(), pipelines.end() );
}
else
{
res.emplace_back( ImageDecoder::Create( fileName ) );
res.emplace_back( ImageDecoder::Create( fileName, rawSettings ) );
}
}
else if ( separatorPos != std::string::npos )
Expand All @@ -155,7 +155,7 @@ std::vector<Pipeline> ImageDecoder::GetPipelinesFromMask( std::string mask )
{
auto tempName = fileName.substr( 0, separatorPos - varDigitCount ) + IntToString( j, varDigitCount ) + fileName.substr( pointPos );
if ( std::filesystem::exists( tempName ) )
res.emplace_back( Create( tempName ) );
res.emplace_back( Create( tempName, rawSettings ) );
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions Codecs/imagedecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../Core/imageparams.h"
#include "../Core/camerasettings.h"
#include "../Core/pipeline.h"
#include "Raw/RawSettings.h"

#include <string>
#include <vector>
Expand Down Expand Up @@ -46,15 +47,17 @@ class ImageDecoder : public IPipelineFirstElement
virtual uint32_t GetCurrentScanline() const;
/// reads and returns bitmap, needed for the compatibility with pipelines
virtual IBitmapPtr ProcessBitmap( IBitmapPtr pBitmap = nullptr ) override;
/// needed for the compatibility with pipelines
static std::shared_ptr<ImageDecoder> Create(const std::string& fileName);
/// needed for the compatibility with pipelines, if opening file is RAW, rawSettings will be applied
static std::shared_ptr<ImageDecoder> Create( const std::string& fileName, const RawSettings& rawSettings = {} );
/// returns name of the last attached file, if no file was attached returns empty string
const std::string& GetLastFileName() const;

/// finds all files of supported formats in given directory, attaches decoders to them and creates pipelines
static std::vector<Pipeline> GetPipelinesFromDir( std::string path );
/// if opening file is RAW, rawSettings will be applied
static std::vector<Pipeline> GetPipelinesFromDir( std::string path, const RawSettings& rawSettings = {} );
/// finds all files of supported formats satisfying given mask, attaches decoders to them and creates pipelines
static std::vector<Pipeline> GetPipelinesFromMask( std::string mask );
/// if opening file is RAW, rawSettings will be applied
static std::vector<Pipeline> GetPipelinesFromMask( std::string mask, const RawSettings& rawSettings = {} );
/// returns all supported extensions by all decoders
static const std::unordered_set<std::string>& GetAllExtensions();

Expand Down
6 changes: 6 additions & 0 deletions Core/IPipelineElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

ACMB_NAMESPACE_BEGIN

IPipelineElement::IPipelineElement()
: _pCameraSettings( std::make_shared<CameraSettings>() )
{

}

void IPipelineElement::CalcParams( std::shared_ptr<ImageParams> pParams )
{
_width = pParams->GetWidth();
Expand Down
2 changes: 2 additions & 0 deletions Core/IPipelineElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class IPipelineElement : public ImageParams
std::shared_ptr<CameraSettings> _pCameraSettings;

public:
///
IPipelineElement();
/// override this if derived class changes size or pixel format of the image
virtual void CalcParams( std::shared_ptr<ImageParams> pParams );
/// abstract fuction where the given bitmap is processed
Expand Down
6 changes: 3 additions & 3 deletions Core/bitmap.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "bitmap.h"
#include <fstream>
#include <filesystem>
#include "../Codecs/imagedecoder.h"
#include "../Codecs/imageencoder.h"
#include "../Codecs/imagedecoder.h"

ACMB_NAMESPACE_BEGIN

Expand All @@ -12,9 +12,9 @@ std::string GetDirectory( const std::string& fileName )
return ( std::string::npos == pos ) ? "" : fileName.substr( 0, pos );
}

std::shared_ptr<IBitmap> IBitmap::Create(const std::string &fileName)
std::shared_ptr<IBitmap> IBitmap::Create(const std::string &fileName, const RawSettings& rawSettings)
{
auto pDecoder = ImageDecoder::Create(fileName);
auto pDecoder = ImageDecoder::Create( fileName, rawSettings );
pDecoder->Attach(fileName);
return pDecoder->ReadBitmap();
}
Expand Down
20 changes: 19 additions & 1 deletion Core/bitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
#include <algorithm>
#include "imageparams.h"
#include "../Tools/mathtools.h"
#include "camerasettings.h"
#include "../Codecs/Raw/RawSettings.h"

//#undef max

ACMB_NAMESPACE_BEGIN

/// <summary>
/// Abstract factory class for bitmap of any pixel format
/// </summary>
Expand All @@ -27,8 +31,11 @@ class IBitmap : public ImageParams
virtual void SetChannel(uint32_t i, uint32_t j, uint32_t k, uint32_t value) = 0;
/// returns count of allocated bytes
virtual uint32_t GetByteSize() const = 0;

virtual std::shared_ptr<CameraSettings> GetCameraSettings() const = 0;
virtual void SetCameraSettings( std::shared_ptr<CameraSettings> pCameraSettings ) = 0;
/// creates bitmap from a given file
static std::shared_ptr<IBitmap> Create(const std::string& fileName);
static std::shared_ptr<IBitmap> Create( const std::string& fileName, const RawSettings& rawSettings = RawSettings {} );
/// creates bitmap with given params
static std::shared_ptr<IBitmap> Create(uint32_t width, uint32_t height, PixelFormat pixelFormat);
/// saves given bitmap to a file
Expand All @@ -51,6 +58,7 @@ class Bitmap : public IBitmap
static constexpr auto channelCount = PixelFormatTraits<pixelFormat>::channelCount;

std::vector<ChannelType> _data;
std::shared_ptr<CameraSettings> _pCameraSettings;

void Fill(ColorType fillColor)
{
Expand Down Expand Up @@ -168,6 +176,16 @@ class Bitmap : public IBitmap
const ChannelType maxChannel = std::numeric_limits<ChannelType>::max();
return std::clamp<float>(QuadraticInterpolation(y - y0, yIn[0], yIn[1], yIn[2]), 0, maxChannel);
}

virtual std::shared_ptr<CameraSettings> GetCameraSettings() const override
{
return _pCameraSettings;
}

virtual void SetCameraSettings( std::shared_ptr<CameraSettings> pCameraSettings ) override
{
_pCameraSettings = pCameraSettings;
}
};

ACMB_NAMESPACE_END
5 changes: 5 additions & 0 deletions Core/camerasettings.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "./../Geometry/rect.h"
#include <array>

ACMB_NAMESPACE_BEGIN

Expand All @@ -18,6 +19,10 @@ struct CameraSettings
double distance = 1000.0;

int64_t timestamp;

uint16_t blackLevel = 0;
uint16_t maxChannel = 0xFFFF;
std::array<float, 4> channelPremultipiers = { 1.0f, 1.0f, 1.0f, 1.0f };
};

ACMB_NAMESPACE_END
6 changes: 0 additions & 6 deletions Core/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,3 @@
#define ACMB_NAMESPACE_END }
#define ACMB_TESTS_NAMESPACE_BEGIN namespace acmb { namespace tests {
#define ACMB_TESTS_NAMESPACE_END }}

#define MAJOR_VERSION "0"
#define MINOR_VERSION "0"
#define REVISION_VERSION "1"
#define BUILD_NUMBER "1"
#define FULL_VERSION MAJOR_VERSION "." MINOR_VERSION "." REVISION_VERSION "." BUILD_NUMBER
1 change: 1 addition & 0 deletions Core/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ IBitmapPtr Pipeline::RunAndGetBitmap()
auto pBitmap = _elements[0]->ProcessBitmap();
for ( size_t i = 1; i < _elements.size(); ++i )
{
_elements[i]->SetCameraSettings( _elements[i - 1]->GetCameraSettings() );
pBitmap = _elements[i]->ProcessBitmap( pBitmap );
}

Expand Down
5 changes: 5 additions & 0 deletions Core/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ class Pipeline
std::string GetFileName() const;
/// returns number of elements
size_t GetSize() const;

IPipelineElementPtr operator[]( size_t i )
{
return _elements[i];
}
};

ACMB_NAMESPACE_END
6 changes: 6 additions & 0 deletions Core/versioning.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once
#define MAJOR_VERSION "0"
#define MINOR_VERSION "0"
#define REVISION_VERSION "1"
#define BUILD_NUMBER "1"
#define FULL_VERSION MAJOR_VERSION "." MINOR_VERSION "." REVISION_VERSION "." BUILD_NUMBER
Loading

0 comments on commit 13cbf4f

Please sign in to comment.