Commit 5e0596f5 authored by Laurent Claustre's avatar Laurent Claustre

Added support for Mono12Packed compressed format with a decoding task managed

in the reconstruction.
parent 2f37a45e
......@@ -61,7 +61,6 @@ namespace lima
// In the same order/index as "PreAmpGainControl"
enum A3_Gain { Gain1 = 0, Gain2 = 1, Gain3 = 2, Gain4 = 3, Gain1_Gain3 = 4, Gain1_Gain4 = 5, Gain2_Gain3 = 6, Gain2_Gain4 = 7 };
// The "simple" version :
#warning Should verify the order of these on a camera which implements it :
enum A3_SimpleGain { b11_hi_gain=0, b11_low_gain=1, b16_lh_gain=2, none=31};
// In the same order/index as "ElectronicShutteringMode"
enum A3_ShutterMode { Rolling = 0, Global = 1 };
......@@ -75,6 +74,7 @@ namespace lima
enum A3_Binning { B1x1=0, B2x2=1, B3x3=2, B4x4=3, B8x8=4};
// The fan speed
enum A3_FanSpeed { Off=0, Low=1, On=2};
enum A3_PixelEncoding {Mono12=0, Mono12Packed = 1, Mono16=2, Mono32=3};
/*
// In the order of the menu, the status of the cooling unit :
......@@ -199,6 +199,8 @@ namespace lima
void getReadoutTime(double &o_time) const;
void getSerialNumber(std::string &o_sn) const;
int getPixelStride() const;
bool isDestrideNeeded() const {return m_destride_active;};
bool isDecodeNeeded() const {return m_decode_active;};
protected:
virtual void setMaxImageSizeCallbackActive(bool cb_active);
......@@ -300,8 +302,9 @@ namespace lima
static bool sAndorSDK3Initted;
bool m_destride_active;
bool m_maximage_size_cb_active;
bool m_destride_active;
bool m_decode_active;
};
// Some inline utility functions; used all-over in Andor3 plugin :
......
......@@ -51,7 +51,7 @@ namespace lima
DEB_CLASS_NAMESPC(DebModCamera, "Andor3Interface", "Andor3");
public:
Interface(Camera& cam, bool destride_active = true);
Interface(Camera& cam);
virtual ~Interface();
//- From HwInterface
......@@ -86,21 +86,16 @@ namespace lima
virtual void setSyncTriggering(bool i_sync);
virtual void getSyncTriggering(bool &o_sync) const;
void setDestrideActive(bool active);
void getDestrideActive(bool& active);
#warning Later should also have overlap and synctriggering ?
// Giving the possibility to get directly the camera object :
Camera& getCamera()
{ return m_cam; }
private:
Camera& m_cam;
Camera& m_cam;
CapList m_cap_list;
DetInfoCtrlObj *m_det_info;
SyncCtrlObj *m_sync;
DetInfoCtrlObj *m_det_info;
SyncCtrlObj *m_sync;
RoiCtrlObj *m_roi;
BinCtrlObj *m_bin;
ReconstructionCtrlObj *m_reconstruction;
......
......@@ -24,10 +24,8 @@
#include "lima/HwReconstructionCtrlObj.h"
namespace Tasks
{
class SoftRoi;
}
class _ReconstructionTask;
namespace lima
{
......@@ -40,17 +38,16 @@ namespace lima
DEB_CLASS_NAMESPC(DebModCamera, "Andor3ReconstructionCtrlObj", "Andor3");
public:
ReconstructionCtrlObj(Camera& cam, bool active);
ReconstructionCtrlObj(Camera& cam);
~ReconstructionCtrlObj();
virtual LinkTask* getReconstructionTask();
void setActive(bool active);
void getActive(bool& active) const;
void prepareAcq();
private:
Camera& m_cam;
bool m_active;
Tasks::SoftRoi* m_task;
Camera& m_cam;
_ReconstructionTask* m_task;
bool m_active;
};
}
}
......
......@@ -37,8 +37,9 @@ namespace Andor3
enum A3_ReadOutRate { MHz10 = 0, MHz100 = 1, MHz200 = 2, MHz280 = 3 };
enum A3_BitDepth { b11 = 0, b16= 1 };
enum A3_TriggerMode { Internal = 0, ExternalLevelTransition = 1, ExternalStart = 2, ExternalExposure = 3, Software = 4, Advanced = 5, External = 6 };
enum A3_Binning { B1x1=0, B2x2=1, B4x4=2, B8x8=3};
enum A3_Binning { B1x1=0, B2x2=1, B3x3=2, B4x4=3, B8x8=4};
enum A3_FanSpeed { Off=0, Low=1, On=2};
enum A3_PixelEncoding {Mono12=0, Mono12Packed = 1, Mono16=2, Mono32=3};
Camera(const std::string& bitflow_path, int camera_number=0);
~Camera();
......@@ -143,6 +144,9 @@ namespace Andor3
void getReadoutTime(double &o_time /Out/ ) const;
void getSerialNumber(std::string &o_sn /Out/ ) const;
int getPixelStride() const;
bool isDestrideNeeded() const;
bool isDecodeNeeded() const;
};
};
......
......@@ -29,13 +29,11 @@ namespace Andor3
protected:
public:
Interface(Andor3::Camera& cam /In,KeepReference/, bool destride_active = true );
Interface(Andor3::Camera& cam /In,KeepReference/);
virtual ~Interface();
//- From HwInterface
// SIP is not knowing what is CapList ... We have to use the native type rather than the typedef :
// virtual void getCapList(CapList& /Out/ ) const;
virtual void getCapList(std::vector<HwCap> &cap_list /Out/) const;
virtual void reset(ResetLevel reset_level /In/ );
virtual void prepareAcq();
......@@ -66,9 +64,5 @@ namespace Andor3
virtual void getOverlap(bool &o_overlap /Out/ ) const;
virtual void setSyncTriggering(bool i_sync /In/ );
virtual void getSyncTriggering(bool &o_sync /Out/ ) const;
void setDestrideActive(bool active /In/);
void getDestrideActive(bool& active /Out/);
};
};
This diff is collapsed.
......@@ -38,7 +38,7 @@
//---------------------------
//- @brief constructor
//---------------------------
lima::Andor3::Interface::Interface(lima::Andor3::Camera& cam, bool destride_active) :
lima::Andor3::Interface::Interface(lima::Andor3::Camera& cam) :
m_cam(cam),
m_cap_list()
{
......@@ -48,7 +48,7 @@ m_cap_list()
m_sync = new SyncCtrlObj(m_cam);
m_roi = new RoiCtrlObj(m_cam, this);
m_bin = new BinCtrlObj(m_cam, this);
m_reconstruction = new ReconstructionCtrlObj(m_cam, destride_active);
m_reconstruction = new ReconstructionCtrlObj(m_cam);
// Taking care of the content of the CapList, once for all :
m_cap_list.push_back(HwCap(m_det_info));
......@@ -90,7 +90,7 @@ lima::Andor3::Interface::reset(ResetLevel reset_level)
DEB_PARAM() << DEB_VAR1(reset_level);
stopAcq();
#warning Should make sure that within finite time the camera returns to status Ready !!!
//#warning Should make sure that within finite time the camera returns to status Ready !!!
// Should be done now...
}
......@@ -287,21 +287,6 @@ lima::Andor3::Interface::getSyncTriggering(bool &o_sync) const
m_cam.getSyncTriggering(o_sync);
}
void lima::Andor3::Interface::setDestrideActive(bool active)
{
DEB_MEMBER_FUNCT();
m_reconstruction->setActive(active);
m_cam.setDestrideActive(active);
}
void lima::Andor3::Interface::getDestrideActive(bool& active)
{
DEB_MEMBER_FUNCT();
m_reconstruction->getActive(active);
}
/*
Local Variables:
c-file-style: "gnu"
......
......@@ -23,20 +23,106 @@
#include "Andor3ReconstructionCtrlObj.h"
#include "Andor3Camera.h"
#include "processlib/LinkTask.h"
#include "processlib/SoftRoi.h"
#include "processlib/ProcessExceptions.h"
using namespace lima;
using namespace lima::Andor3;
class _ReconstructionTask : public LinkTask
{
DEB_CLASS_NAMESPC(DebModCameraCom, "_ReconstructionTask", "Andor3");
public:
_ReconstructionTask(): m_decode_active(false), m_destride_active(false) {}
virtual Data process(Data&);
void setDecodeActive(bool flag) {m_decode_active = flag;};
void setDestrideActive(bool flag){m_destride_active = flag;};
void setRoi(Roi& roi) {m_roi=roi;};
private:
bool m_decode_active;
bool m_destride_active;
Roi m_roi;
};
Data _ReconstructionTask::process(Data& src)
{
DEB_MEMBER_FUNCT();
if (m_decode_active)
{
if (src.depth() != 2)
{
char ErrorBuff[1024];
snprintf(ErrorBuff,sizeof(ErrorBuff),
"_ReconstructionTask: can't decode data only for 12bit packed, 2 bytes and data depth is %d",
src.depth());
throw ProcessException(ErrorBuff);
}
// Mono12Packed encoding: 3 bytes for 2 pixels
// ----------------------------------------------------------------------------------
// |Bits 11:4 = Most Significant Bits (MSB) | Bits 3:0 = Least Significant Bits (LSB) |
// ----------------------------------------------------------------------------------
// In buffer memory (ImageBuffer)
// -----------------------------------------------
// | ImageBuffer+0 | Pixel A (MSB) |
// -----------------------------------------------
// | ImageBuffer+1 | Pixel B (LSB) | Pixel A (LSB) |
// -----------------------------------------------
// | ImageBuffer+2 | Pixel B (MSB) |
// -----------------------------------------------
// | ImageBuffer+3 | Pixel C (MSB) |
// -----------------------------------------------
// | ImageBuffer+4 | Pixel D (LSB) | Pixel C (LSB) |
// -----------------------------------------------
// | ImageBuffer+5 | Pixel D (MSB) |
// -----------------------------------------------
//
int nb_pixels = src.size()/src.depth();
// for this unpacking algorithm we seek memory from bottom to top address
// this is not super efficient but a choice to not use 2 buffer systems for memory copies.
// move to the latest pixel memory position
unsigned short* dst_data = (unsigned short*)src.data()+nb_pixels-1;
// move the packed ptr to the last byte as well
int coded_size = (int) (nb_pixels * 1.5);
unsigned char* coded_ptr = (unsigned char*) src.data() + coded_size;
unsigned short msb_byte1, msb_byte2, lsb_byte;
while (nb_pixels)
{
msb_byte2 = *(--coded_ptr); lsb_byte= *(--coded_ptr); msb_byte1 = *(--coded_ptr);
*dst_data = (msb_byte2 << 4) + (lsb_byte >> 4);
*(--dst_data) = (msb_byte1 << 4) + (lsb_byte & 0xF);
nb_pixels-=2;
--dst_data;
}
} // if (m_decode_active)
if (m_destride_active)
{
Tasks::SoftRoi roi_task;
Point top_left = m_roi.getTopLeft();
Point bottom_right = m_roi.getBottomRight();
roi_task.setRoi(top_left.x, bottom_right.x,top_left.y, bottom_right.y);
return roi_task.process(src);
}
else
return src;
}
//-----------------------------------------------------
// @brief Ctor
//-----------------------------------------------------
ReconstructionCtrlObj::ReconstructionCtrlObj(Camera& cam, bool active):
m_cam(cam), m_active(active)
ReconstructionCtrlObj::ReconstructionCtrlObj(Camera& cam):
m_cam(cam), m_active(false)
{
DEB_CONSTRUCTOR();
m_task = new Tasks::SoftRoi();
m_task = new _ReconstructionTask();
m_task->setProcessingInPlace(true);
}
......@@ -53,28 +139,27 @@ void ReconstructionCtrlObj::prepareAcq()
{
DEB_MEMBER_FUNCT();
Roi roi;
Size detectorSize;
if (m_active) {
m_cam.getRoi(roi);
m_cam.getDetectorImageSize(detectorSize);
DEB_TRACE() << DEB_VAR1(roi);
DEB_TRACE() << DEB_VAR1(detectorSize);
// do nothing if a roi is set, checkRoi return the hw_roi with stride to get a SoftRoi to be applied.
if (roi.getSize().getWidth() == detectorSize.getWidth() && roi.getSize().getHeight() == detectorSize.getHeight()) {
if (m_cam.getPixelStride() != roi.getSize().getWidth()) {
const Point& topLeft = roi.getTopLeft();
const Point& bottomRight = roi.getBottomRight();
m_task->setRoi(topLeft.x, bottomRight.x, topLeft.y, bottomRight.y);
reconstructionChange(m_task);
} else {
reconstructionChange(NULL);
}
} else {
reconstructionChange(NULL);
bool destride_needed = m_cam.isDestrideNeeded();
bool decode_needed = m_cam.isDecodeNeeded();
if (!destride_needed && ! decode_needed)
{
m_active = false;
reconstructionChange(NULL);
}
else
{
m_active = true;
m_task->setDestrideActive(destride_needed);
if (destride_needed)
{
Size detector_size;
m_cam.getDetectorImageSize(detector_size);
Roi roi(0,0,detector_size.getWidth(),detector_size.getHeight());
m_task->setRoi(roi);
}
m_task->setDecodeActive(decode_needed);
reconstructionChange(m_task);
}
}
}
//-----------------------------------------------------
......@@ -88,13 +173,6 @@ LinkTask* ReconstructionCtrlObj::getReconstructionTask()
else return NULL;
}
void ReconstructionCtrlObj::setActive(bool active)
{
DEB_MEMBER_FUNCT();
m_active = active;
if (!active) reconstructionChange(NULL);
}
void ReconstructionCtrlObj::getActive(bool& active) const
{
DEB_MEMBER_FUNCT();
......
......@@ -23,7 +23,7 @@ SRCS = $(andor3-objs:.o=.cpp)
CXXFLAGS += -I../include -I../../../hardware/include -I../../../common/include \
-I/usr/local/include -I../../../third-party/Processlib/core/include -I../../../third-party/Processlib/tasks/include \
-Wall -pthread -fPIC -g
-Wall -pthread -fPIC -g -O2
all: Andor3.o
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment