initial commit
This commit is contained in:
@@ -0,0 +1,870 @@
|
||||
/*!
|
||||
\file cexif.h
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CEXIF_H
|
||||
#define CEXIF_H
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <QDateTime>
|
||||
#include <QImage>
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QList>
|
||||
|
||||
#include <QSqlDatabase>
|
||||
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cEXIFCompression cexif.h "cexif.h"
|
||||
*/
|
||||
class cEXIFCompression
|
||||
{
|
||||
public:
|
||||
cEXIFCompression(const qint32& iID, const QString& szCompression);
|
||||
|
||||
qint32 m_iID; /*!< TODO: describe */
|
||||
QString m_szCompression; /*!< TODO: describe */
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cEXIFCompression*)
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cEXIFCompressionList cexif.h "cexif.h"
|
||||
*/
|
||||
class cEXIFCompressionList : public QList<cEXIFCompression*>
|
||||
{
|
||||
public:
|
||||
cEXIFCompressionList();
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn add
|
||||
\param iID
|
||||
\param szCompression
|
||||
\return cEXIFCompression
|
||||
*/
|
||||
cEXIFCompression* add(const qint32& iID, const QString& szCompression);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param iID
|
||||
\return cEXIFCompression
|
||||
*/
|
||||
cEXIFCompression* find(const qint32& iID);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn compression
|
||||
\param iID
|
||||
\return QString
|
||||
*/
|
||||
QString compression(const qint32& iID);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cEXIFCompressionList)
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cEXIFLightSource cexif.h "cexif.h"
|
||||
*/
|
||||
class cEXIFLightSource
|
||||
{
|
||||
public:
|
||||
cEXIFLightSource(const qint32& iID, const QString& szLightSource);
|
||||
|
||||
qint32 m_iID; /*!< TODO: describe */
|
||||
QString m_szLightSource; /*!< TODO: describe */
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cEXIFLightSource*)
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cEXIFLightSourceList cexif.h "cexif.h"
|
||||
*/
|
||||
class cEXIFLightSourceList : public QList<cEXIFLightSource*>
|
||||
{
|
||||
public:
|
||||
cEXIFLightSourceList();
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn add
|
||||
\param iID
|
||||
\param szLightSource
|
||||
\return cEXIFLightSource
|
||||
*/
|
||||
cEXIFLightSource* add(const qint32& iID, const QString& szLightSource);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param iID
|
||||
\return cEXIFLightSource
|
||||
*/
|
||||
cEXIFLightSource* find(const qint32& iID);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn lightSource
|
||||
\param iID
|
||||
\return QString
|
||||
*/
|
||||
QString lightSource(const qint32& iID);
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cEXIFFlash cexif.h "cexif.h"
|
||||
*/
|
||||
class cEXIFFlash
|
||||
{
|
||||
public:
|
||||
cEXIFFlash(const qint32& iID, const QString& szFlash);
|
||||
|
||||
qint32 m_iID; /*!< TODO: describe */
|
||||
QString m_szFlash; /*!< TODO: describe */
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cEXIFFlash*)
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cEXIFFlashList cexif.h "cexif.h"
|
||||
*/
|
||||
class cEXIFFlashList : public QList<cEXIFFlash*>
|
||||
{
|
||||
public:
|
||||
cEXIFFlashList();
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn add
|
||||
\param iID
|
||||
\param szFlash
|
||||
\return cEXIFFlash
|
||||
*/
|
||||
cEXIFFlash* add(const qint32& iID, const QString& szFlash);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param iID
|
||||
\return cEXIFFlash
|
||||
*/
|
||||
cEXIFFlash* find(const qint32& iID);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn flash
|
||||
\param iID
|
||||
\return QString
|
||||
*/
|
||||
QString flash(const qint32& iID);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
class cEXIFTag
|
||||
{
|
||||
public:
|
||||
cEXIFTag(const qint32& iTAGID, const QString& szTAGName, const QString& szIFD, const QString& szKey, const QString& szType, const QString& szDescription);
|
||||
|
||||
qint32 m_iTAGID; /*!< TODO: describe */
|
||||
QString m_szTAGName; /*!< TODO: describe */
|
||||
QString m_szIFD; /*!< TODO: describe */
|
||||
QString m_szKey; /*!< TODO: describe */
|
||||
QString m_szType; /*!< TODO: describe */
|
||||
QString m_szDescription; /*!< TODO: describe */
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cEXIFTag*)
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cEXIFTagList cexif.h "cexif.h"
|
||||
*/
|
||||
class cEXIFTagList : public QList<cEXIFTag*>
|
||||
{
|
||||
public:
|
||||
cEXIFTagList();
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn add
|
||||
\param iTAGID
|
||||
\param szTAGName
|
||||
\param szIFD
|
||||
\param szType
|
||||
\param szDescription
|
||||
\return cEXIFTag
|
||||
*/
|
||||
cEXIFTag* add(const qint32& iTAGID, const QString& szTAGName, const QString& szIFD, const QString& szKey, const QString& szType, const QString& szDescription);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param szKey
|
||||
\return cEXIFTag
|
||||
*/
|
||||
cEXIFTag* find(const QString& szKey);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param iTAGID
|
||||
\param szIFD
|
||||
\return cEXIFTag
|
||||
*/
|
||||
cEXIFTag* find(const qint32& iTAGID, const QString& szIFD);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param szTAG
|
||||
\param szIFD
|
||||
\return cEXIFTag
|
||||
*/
|
||||
cEXIFTag* find(const QString& szTAG, const QString& szIFD);
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
*/
|
||||
class cEXIFValue
|
||||
{
|
||||
public:
|
||||
cEXIFValue(cEXIFTag* lpEXIFTag);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn exifTag
|
||||
\return cEXIFTag
|
||||
*/
|
||||
cEXIFTag* exifTag();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn setValue
|
||||
\param szValue
|
||||
\param iTypeId
|
||||
\param iCount
|
||||
*/
|
||||
void setValue(const QString& szValue, qint32 iTypeId, qint32 iCount = 1);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn value
|
||||
\return QVariant
|
||||
*/
|
||||
QVariant value();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn valueList
|
||||
\return QList<QVariant>
|
||||
*/
|
||||
QList<QVariant> valueList();
|
||||
|
||||
private:
|
||||
cEXIFTag* m_lpEXIFTag; /*!< TODO: describe */
|
||||
QList<QVariant> m_valueList; /*!< TODO: describe */
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn convertValue
|
||||
\param szValue
|
||||
\param iTypeId
|
||||
\return QVariant
|
||||
*/
|
||||
QVariant convertValue(const QString& szValue, qint32 iTypeId);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cEXIFValue*)
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cEXIFValueList cexif.h "cexif.h"
|
||||
*/
|
||||
class cEXIFValueList : public QList<cEXIFValue*>
|
||||
{
|
||||
public:
|
||||
cEXIFValueList();
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn add
|
||||
\param lpEXIFTag
|
||||
\return cEXIFValue
|
||||
*/
|
||||
cEXIFValue* add(cEXIFTag* lpEXIFTag);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param lpEXIFTag
|
||||
\return cEXIFValue
|
||||
*/
|
||||
cEXIFValue* find(cEXIFTag* lpEXIFTag);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
class cIPTCTag
|
||||
{
|
||||
public:
|
||||
cIPTCTag(const qint32& iTAGID, const QString& szTAGName, const qint32& iTypeID, const QString& szDescription);
|
||||
|
||||
qint32 m_iTAGID; /*!< TODO: describe */
|
||||
QString m_szTAGName; /*!< TODO: describe */
|
||||
qint32 m_iTypeID; /*!< TODO: describe */
|
||||
QString m_szDescription; /*!< TODO: describe */
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cIPTCTag*)
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cIPTCTagList cexif.h "cexif.h"
|
||||
*/
|
||||
class cIPTCTagList : public QList<cIPTCTag*>
|
||||
{
|
||||
public:
|
||||
cIPTCTagList();
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn add
|
||||
\param iTAGID
|
||||
\param szTAGName
|
||||
\param iTypeID
|
||||
\param szDescription
|
||||
\return cIPTCTag
|
||||
*/
|
||||
cIPTCTag* add(const qint32& iTAGID, const QString& szTAGName, const qint32& iTypeID, const QString& szDescription);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param iTAGID
|
||||
\return cIPTCTag
|
||||
*/
|
||||
cIPTCTag* find(const qint32& iTAGID);
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
*/
|
||||
class cIPTCValue
|
||||
{
|
||||
public:
|
||||
cIPTCValue(cIPTCTag* lpIPTCTag);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn iptcTag
|
||||
\return cIPTCTag
|
||||
*/
|
||||
cIPTCTag* iptcTag();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn setValue
|
||||
\param szValue
|
||||
\param iTypeId
|
||||
\param iCount
|
||||
*/
|
||||
void setValue(const QString& szValue, qint32 iTypeId, qint32 iCount = 1);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn value
|
||||
\return QVariant
|
||||
*/
|
||||
QVariant value();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn valueList
|
||||
\return QList<QVariant>
|
||||
*/
|
||||
QList<QVariant> valueList();
|
||||
|
||||
private:
|
||||
cIPTCTag* m_lpIPTCTag; /*!< TODO: describe */
|
||||
QList<QVariant> m_valueList; /*!< TODO: describe */
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn convertValue
|
||||
\param szValue
|
||||
\param iTypeId
|
||||
\return QVariant
|
||||
*/
|
||||
QVariant convertValue(const QString& szValue, qint32 iTypeId);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cIPTCValue*)
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cIPTCValueList cexif.h "cexif.h"
|
||||
*/
|
||||
class cIPTCValueList : public QList<cIPTCValue*>
|
||||
{
|
||||
public:
|
||||
cIPTCValueList();
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn add
|
||||
\param lpIPTCTag
|
||||
\return cIPTCValue
|
||||
*/
|
||||
cIPTCValue* add(cIPTCTag* lpIPTCTag);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param lpIPTCTag
|
||||
\return cIPTCValue
|
||||
*/
|
||||
cIPTCValue* find(cIPTCTag* lpIPTCTag);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
class cXMPTag
|
||||
{
|
||||
public:
|
||||
cXMPTag(const QString& szTAGName, const qint32& iTypeID, const QString& szDescription);
|
||||
|
||||
QString m_szTAGName; /*!< TODO: describe */
|
||||
qint32 m_iTypeID; /*!< TODO: describe */
|
||||
QString m_szDescription; /*!< TODO: describe */
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cXMPTag*)
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cXMPTagList cexif.h "cexif.h"
|
||||
*/
|
||||
class cXMPTagList : public QList<cXMPTag*>
|
||||
{
|
||||
public:
|
||||
cXMPTagList();
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn add
|
||||
\param szTAGName
|
||||
\param iTypeID
|
||||
\param szDescription
|
||||
\return cXMPTag
|
||||
*/
|
||||
cXMPTag* add(const QString& szTAGName, const qint32& iTypeID, const QString& szDescription);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param szTAGName
|
||||
\return cXMPTag
|
||||
*/
|
||||
cXMPTag* find(const QString& szTAGName);
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
*/
|
||||
class cXMPValue
|
||||
{
|
||||
public:
|
||||
cXMPValue(cXMPTag* lpXMPTag);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn exifTag
|
||||
\return cXMPTag
|
||||
*/
|
||||
cXMPTag* xmpTag();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn setValue
|
||||
\param szValue
|
||||
\param iTypeId
|
||||
\param iCount
|
||||
*/
|
||||
void setValue(const QString& szValue, qint32 iTypeId, qint32 iCount = 1);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn value
|
||||
\return QVariant
|
||||
*/
|
||||
QVariant value();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn valueList
|
||||
\return QList<QVariant>
|
||||
*/
|
||||
QList<QVariant> valueList();
|
||||
|
||||
private:
|
||||
cXMPTag* m_lpXMPTag; /*!< TODO: describe */
|
||||
QList<QVariant> m_valueList; /*!< TODO: describe */
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn convertValue
|
||||
\param szValue
|
||||
\param iTypeId
|
||||
\return QVariant
|
||||
*/
|
||||
QVariant convertValue(const QString& szValue, qint32 iTypeId);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cXMPValue*)
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cXMPValueList cexif.h "cexif.h"
|
||||
*/
|
||||
class cXMPValueList : public QList<cXMPValue*>
|
||||
{
|
||||
public:
|
||||
cXMPValueList();
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn add
|
||||
\param lpXMPTag
|
||||
\return cXMPValue
|
||||
*/
|
||||
cXMPValue* add(cXMPTag* lpXMPTag);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn find
|
||||
\param lpXMPTag
|
||||
\return cXMPValue
|
||||
*/
|
||||
cXMPValue* find(cXMPTag* lpXMPTag);
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cEXIF cexif.h "cexif.h"
|
||||
*/
|
||||
class cEXIF
|
||||
{
|
||||
public:
|
||||
cEXIF(cEXIFTagList* lpEXIFTagList, cEXIFCompressionList* lpEXIFCompressionList, cEXIFLightSourceList* lpEXIFLightSourceList, cEXIFFlashList* lpEXIFFlashList, cIPTCTagList* lpIPTCTagList, cXMPTagList* lpXMPTagList);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn fromFile
|
||||
\param szFileName
|
||||
\return bool
|
||||
*/
|
||||
bool fromFile(const QString& szFileName);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn mimeType
|
||||
\return QString
|
||||
*/
|
||||
QString mimeType();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn imageWidth
|
||||
\return qint32
|
||||
*/
|
||||
qint32 imageWidth();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn imageHeight
|
||||
\return qint32
|
||||
*/
|
||||
qint32 imageHeight();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn imageOrientation
|
||||
\return qint16
|
||||
*/
|
||||
qint16 imageOrientation();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cameraMake
|
||||
\return QString
|
||||
*/
|
||||
QString cameraMake();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cameraModel
|
||||
\return QString
|
||||
*/
|
||||
QString cameraModel();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn dateTime
|
||||
\return QDateTime
|
||||
*/
|
||||
QDateTime dateTime();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn fNumber
|
||||
\return QString
|
||||
*/
|
||||
QString fNumber();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn iso
|
||||
\return qint32
|
||||
*/
|
||||
qint32 iso();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn flash
|
||||
\return QString
|
||||
*/
|
||||
QString flash();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn flashID
|
||||
\return qint32
|
||||
*/
|
||||
qint32 flashID();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn focalLength
|
||||
\return qreal
|
||||
*/
|
||||
qreal focalLength();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn lensMake
|
||||
\return QString
|
||||
*/
|
||||
QString lensMake();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn lensModel
|
||||
\return QString
|
||||
*/
|
||||
QString lensModel();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn exposureTime
|
||||
\return QString
|
||||
*/
|
||||
QString exposureTime();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn exposureBias
|
||||
\return qint32
|
||||
*/
|
||||
qint32 exposureBias();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn exifVersion
|
||||
\return QString
|
||||
*/
|
||||
QString exifVersion();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn dateTimeOriginal
|
||||
\return QDateTime
|
||||
*/
|
||||
QDateTime dateTimeOriginal();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn dateTimeDigitized
|
||||
\return QDateTime
|
||||
*/
|
||||
QDateTime dateTimeDigitized();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn whiteBalance
|
||||
\return qint32
|
||||
*/
|
||||
qint32 whiteBalance();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn focalLength35
|
||||
\return qreal
|
||||
*/
|
||||
qreal focalLength35();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn gps
|
||||
\return QString
|
||||
*/
|
||||
QString gps();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn duration
|
||||
\return QString
|
||||
*/
|
||||
QString duration();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn fileName
|
||||
\return QString
|
||||
*/
|
||||
QString fileName();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn previewList
|
||||
\return QList<QImage>
|
||||
*/
|
||||
QList<QImage> previewList();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn thumbnail
|
||||
\return QImage
|
||||
*/
|
||||
QImage thumbnail();
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn copyTo
|
||||
\param fileName
|
||||
*/
|
||||
bool copyTo(const QString& fileName);
|
||||
|
||||
private:
|
||||
cEXIFValueList m_exifValueList; /*!< TODO: describe */
|
||||
cIPTCValueList m_iptcValueList; /*!< TODO: describe */
|
||||
cXMPValueList m_xmpValueList; /*!< TODO: describe */
|
||||
QString m_szMimeType; /*!< TODO: describe */
|
||||
qint32 m_iWidth; /*!< TODO: describe */
|
||||
qint32 m_iHeight; /*!< TODO: describe */
|
||||
QString m_szFileName; /*!< TODO: describe */
|
||||
QList<QImage> m_previewList; /*!< TODO: describe */
|
||||
QImage m_thumbnail; /*!< TODO: describe */
|
||||
|
||||
cEXIFTagList* m_lpEXIFTagList; /*!< TODO: describe */
|
||||
cEXIFCompressionList* m_lpEXIFCompressionList; /*!< TODO: describe */
|
||||
cEXIFLightSourceList* m_lpEXIFLightSourceList; /*!< TODO: describe */
|
||||
cEXIFFlashList* m_lpEXIFFlashList; /*!< TODO: describe */
|
||||
|
||||
cIPTCTagList* m_lpIPTCTagList; /*!< TODO: describe */
|
||||
|
||||
cXMPTagList* m_lpXMPTagList; /*!< TODO: describe */
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn getEXIFTag
|
||||
\param iTAGID
|
||||
\param szIFD
|
||||
\return QVariant
|
||||
*/
|
||||
QVariant getEXIFTag(qint32 iTAGID, const QString& szIFD);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn getIPTCTag
|
||||
\param iTAGID
|
||||
\return QVariant
|
||||
*/
|
||||
QVariant getIPTCTag(qint32 iTAGID);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn getXMPTag
|
||||
\param szTAGName
|
||||
\return QVariant
|
||||
*/
|
||||
QVariant getXMPTag(const QString& szTAGName);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn getTagList
|
||||
\param iTAGID
|
||||
\param iIFDID
|
||||
\return QList<QVariant>
|
||||
*/
|
||||
QList<QVariant> getTagList(qint32 iTAGID, const QString& szIFD);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(cEXIF*)
|
||||
|
||||
#endif // CEXIF_H
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "cfilebrowser.h"
|
||||
#include "ui_cfilebrowser.h"
|
||||
|
||||
cFileBrowser::cFileBrowser(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::cFileBrowser)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
cFileBrowser::~cFileBrowser()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef CFILEBROWSER_H
|
||||
#define CFILEBROWSER_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class cFileBrowser;
|
||||
}
|
||||
|
||||
class cFileBrowser : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit cFileBrowser(QWidget *parent = nullptr);
|
||||
~cFileBrowser();
|
||||
|
||||
private:
|
||||
Ui::cFileBrowser *ui;
|
||||
};
|
||||
|
||||
#endif // CFILEBROWSER_H
|
||||
@@ -0,0 +1,21 @@
|
||||
<ui version="4.0">
|
||||
<author/>
|
||||
<comment/>
|
||||
<exportmacro/>
|
||||
<class>cFileBrowser</class>
|
||||
<widget name="cFileBrowser" class="QWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
</widget>
|
||||
<pixmapfunction/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "cfileviewer.h"
|
||||
#include "ui_cfileviewer.h"
|
||||
|
||||
cFileViewer::cFileViewer(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::cFileViewer)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
cFileViewer::~cFileViewer()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef CFILEVIEWER_H
|
||||
#define CFILEVIEWER_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class cFileViewer;
|
||||
}
|
||||
|
||||
class cFileViewer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit cFileViewer(QWidget *parent = nullptr);
|
||||
~cFileViewer();
|
||||
|
||||
private:
|
||||
Ui::cFileViewer *ui;
|
||||
};
|
||||
|
||||
#endif // CFILEVIEWER_H
|
||||
@@ -0,0 +1,21 @@
|
||||
<ui version="4.0">
|
||||
<author/>
|
||||
<comment/>
|
||||
<exportmacro/>
|
||||
<class>cFileViewer</class>
|
||||
<widget name="cFileViewer" class="QWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
</widget>
|
||||
<pixmapfunction/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+428
@@ -0,0 +1,428 @@
|
||||
/*!
|
||||
\file cimage.cpp
|
||||
|
||||
*/
|
||||
|
||||
#include "cimage.h"
|
||||
|
||||
#include "opencv2/imgproc/types_c.h"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
|
||||
#include <QTransform>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
|
||||
cImage::cImage() :
|
||||
QImage(),
|
||||
m_isChromatic(true),
|
||||
m_camType(camera_unknown),
|
||||
m_raw(false)
|
||||
{
|
||||
}
|
||||
|
||||
cImage::cImage(const QSize &size, QImage::Format format) :
|
||||
QImage(size, format),
|
||||
m_isChromatic(true),
|
||||
m_camType(camera_unknown),
|
||||
m_raw(false)
|
||||
{
|
||||
}
|
||||
|
||||
cImage::cImage(int width, int height, QImage::Format format) :
|
||||
QImage(width, height, format),
|
||||
m_isChromatic(true),
|
||||
m_camType(camera_unknown),
|
||||
m_raw(false)
|
||||
{
|
||||
}
|
||||
|
||||
cImage::cImage(uchar *data, int width, int height, QImage::Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo) :
|
||||
QImage(data, width, height, format, cleanupFunction, cleanupInfo),
|
||||
m_isChromatic(true),
|
||||
m_camType(camera_unknown),
|
||||
m_raw(false)
|
||||
{
|
||||
}
|
||||
|
||||
cImage::cImage(const uchar *data, int width, int height, QImage::Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo) :
|
||||
QImage(data, width, height, format, cleanupFunction, cleanupInfo),
|
||||
m_isChromatic(true),
|
||||
m_camType(camera_unknown),
|
||||
m_raw(false)
|
||||
{
|
||||
}
|
||||
|
||||
cImage::cImage(uchar *data, int width, int height, int bytesPerLine, QImage::Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo) :
|
||||
QImage(data, width, height, bytesPerLine, format, cleanupFunction, cleanupInfo),
|
||||
m_isChromatic(true),
|
||||
m_camType(camera_unknown),
|
||||
m_raw(false)
|
||||
{
|
||||
}
|
||||
|
||||
cImage::cImage(const uchar *data, int width, int height, int bytesPerLine, QImage::Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo) :
|
||||
QImage(data, width, height, bytesPerLine, format, cleanupFunction, cleanupInfo),
|
||||
m_isChromatic(true),
|
||||
m_camType(camera_unknown),
|
||||
m_raw(false)
|
||||
{
|
||||
}
|
||||
|
||||
cImage::cImage(const QString &fileName, const char *format) :
|
||||
QImage(),
|
||||
m_isChromatic(true),
|
||||
m_camType(camera_unknown),
|
||||
m_raw(false)
|
||||
{
|
||||
load(fileName, format);
|
||||
}
|
||||
|
||||
cImage::cImage(const QImage &image) :
|
||||
QImage(image),
|
||||
m_isChromatic(true),
|
||||
m_camType(camera_unknown),
|
||||
m_raw(false)
|
||||
{
|
||||
}
|
||||
|
||||
cImage::cImage(QImage &&other) :
|
||||
QImage(other),
|
||||
m_isChromatic(true),
|
||||
m_camType(camera_unknown),
|
||||
m_raw(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool cImage::load(const QString &fileName, const char *format)
|
||||
{
|
||||
QFileInfo fileInfo(fileName);
|
||||
|
||||
if(!fileInfo.suffix().compare("NEF", Qt::CaseInsensitive))
|
||||
return(loadRAW(fileName));
|
||||
|
||||
if(QImage::load(fileName, format))
|
||||
return(true);
|
||||
|
||||
return(loadRAW(fileName));
|
||||
}
|
||||
|
||||
bool cImage::openBuffer(const QString &fileName, const QSharedPointer<QByteArray>& ba, LibRaw& iProcessor)
|
||||
{
|
||||
int error = LIBRAW_DATA_ERROR;
|
||||
QFileInfo fi(fileName);
|
||||
|
||||
if(fi.suffix().contains("iiq", Qt::CaseInsensitive) || !ba || ba->isEmpty())
|
||||
error = iProcessor.open_file(fileName.toStdString().c_str());
|
||||
else
|
||||
{
|
||||
if(ba->isEmpty() || ba->size() < 100)
|
||||
return(false);
|
||||
|
||||
error = iProcessor.open_buffer((void*)ba->constData(), static_cast<size_t>(ba->size()));
|
||||
}
|
||||
|
||||
return (error == LIBRAW_SUCCESS);
|
||||
}
|
||||
|
||||
void cImage::detectSpecialCamera(const LibRaw & iProcessor)
|
||||
{
|
||||
if(QString(iProcessor.imgdata.idata.model) == "IQ260 Achromatic")
|
||||
m_isChromatic = false;
|
||||
|
||||
if (QString(iProcessor.imgdata.idata.model).contains("IQ260"))
|
||||
m_camType = camera_iiq;
|
||||
else if (!QString(iProcessor.imgdata.idata.make).compare("Canon", Qt::CaseInsensitive))
|
||||
m_camType = camera_canon;
|
||||
}
|
||||
|
||||
cv::Mat cImage::demosaic(LibRaw & iProcessor)
|
||||
{
|
||||
cv::Mat rawMat = cv::Mat(iProcessor.imgdata.sizes.height, iProcessor.imgdata.sizes.width, CV_16UC1);
|
||||
double dynamicRange = static_cast<double>(iProcessor.imgdata.color.maximum - iProcessor.imgdata.color.black);
|
||||
|
||||
// normalize all image values
|
||||
for(int rIdx = 0; rIdx < rawMat.rows; rIdx++)
|
||||
{
|
||||
unsigned short *ptrRaw = rawMat.ptr<unsigned short>(rIdx);
|
||||
|
||||
for (int cIdx = 0; cIdx < rawMat.cols; cIdx++)
|
||||
{
|
||||
int colIdx = iProcessor.COLOR(rIdx, cIdx);
|
||||
double val = static_cast<double>(iProcessor.imgdata.image[(rawMat.cols*rIdx) + cIdx][colIdx]);
|
||||
|
||||
// normalize the value w.r.t the black point defined
|
||||
val = (val - iProcessor.imgdata.color.black) / dynamicRange;
|
||||
ptrRaw[cIdx] = clip<unsigned short>(val * USHRT_MAX); // for conversion to 16U
|
||||
}
|
||||
}
|
||||
|
||||
// no demosaicing
|
||||
if(m_isChromatic)
|
||||
{
|
||||
unsigned long type = static_cast<unsigned long>(iProcessor.imgdata.idata.filters);
|
||||
type = type & 255;
|
||||
|
||||
cv::Mat rgbImg;
|
||||
|
||||
//define bayer pattern
|
||||
if(type == 180)
|
||||
cvtColor(rawMat, rgbImg, CV_BayerBG2RGB); //bitmask 10 11 01 00 -> 3(G) 2(B) 1(G) 0(R) -> RG RG RG
|
||||
else if(type == 30)
|
||||
cvtColor(rawMat, rgbImg, CV_BayerRG2RGB); //bitmask 00 01 11 10 -> 0 1 3 2
|
||||
else if(type == 225)
|
||||
cvtColor(rawMat, rgbImg, CV_BayerGB2RGB); //bitmask 11 10 00 01
|
||||
else if(type == 75)
|
||||
cvtColor(rawMat, rgbImg, CV_BayerGR2RGB); //bitmask 01 00 10 11
|
||||
else
|
||||
{
|
||||
qWarning() << "Wrong Bayer Pattern (not BG, RG, GB, GR)\n";
|
||||
return cv::Mat();
|
||||
}
|
||||
|
||||
rawMat = rgbImg;
|
||||
}
|
||||
|
||||
// 16U (1 or 3 channeled) Mat
|
||||
return(rawMat);
|
||||
}
|
||||
|
||||
cv::Mat cImage::prepareImg(const LibRaw & iProcessor)
|
||||
{
|
||||
cv::Mat rawMat = cv::Mat(iProcessor.imgdata.sizes.height, iProcessor.imgdata.sizes.width, CV_16UC3, cv::Scalar(0));
|
||||
double dynamicRange = static_cast<double>(iProcessor.imgdata.color.maximum - iProcessor.imgdata.color.black);
|
||||
|
||||
// normalization function
|
||||
auto normalize = [&](double val)
|
||||
{
|
||||
val = (val - iProcessor.imgdata.color.black) / dynamicRange;
|
||||
return clip<unsigned short>(val * USHRT_MAX);
|
||||
};
|
||||
|
||||
for (int rIdx = 0; rIdx < rawMat.rows; rIdx++)
|
||||
{
|
||||
unsigned short *ptrI = rawMat.ptr<unsigned short>(rIdx);
|
||||
|
||||
for (int cIdx = 0; cIdx < rawMat.cols; cIdx++)
|
||||
{
|
||||
|
||||
*ptrI = normalize(iProcessor.imgdata.image[rawMat.cols*rIdx + cIdx][0]);
|
||||
ptrI++;
|
||||
*ptrI = normalize(iProcessor.imgdata.image[rawMat.cols*rIdx + cIdx][1]);
|
||||
ptrI++;
|
||||
*ptrI = normalize(iProcessor.imgdata.image[rawMat.cols*rIdx + cIdx][2]);
|
||||
ptrI++;
|
||||
}
|
||||
}
|
||||
|
||||
return rawMat;
|
||||
}
|
||||
|
||||
void cImage::whiteBalance(const LibRaw & iProcessor, cv::Mat & img)
|
||||
{
|
||||
// white balance must not be empty at this point
|
||||
cv::Mat wb = whiteMultipliers(iProcessor);
|
||||
const float* wbp = wb.ptr<float>();
|
||||
assert(wb.cols == 4);
|
||||
|
||||
for(int rIdx = 0; rIdx < img.rows; rIdx++)
|
||||
{
|
||||
unsigned short *ptr = img.ptr<unsigned short>(rIdx);
|
||||
|
||||
for (int cIdx = 0; cIdx < img.cols; cIdx++)
|
||||
{
|
||||
//apply white balance correction
|
||||
unsigned short r = clip<unsigned short>(*ptr * wbp[0]);
|
||||
unsigned short g = clip<unsigned short>(*(ptr+1) * wbp[1]);
|
||||
unsigned short b = clip<unsigned short>(*(ptr+2) * wbp[2]);
|
||||
|
||||
//apply color correction
|
||||
int cr = qRound(iProcessor.imgdata.color.rgb_cam[0][0] * r +
|
||||
iProcessor.imgdata.color.rgb_cam[0][1] * g +
|
||||
iProcessor.imgdata.color.rgb_cam[0][2] * b);
|
||||
int cg = qRound(iProcessor.imgdata.color.rgb_cam[1][0] * r +
|
||||
iProcessor.imgdata.color.rgb_cam[1][1] * g +
|
||||
iProcessor.imgdata.color.rgb_cam[1][2] * b);
|
||||
int cb = qRound(iProcessor.imgdata.color.rgb_cam[2][0] * r +
|
||||
iProcessor.imgdata.color.rgb_cam[2][1] * g +
|
||||
iProcessor.imgdata.color.rgb_cam[2][2] * b);
|
||||
|
||||
// clip & save color corrected values
|
||||
*ptr = clip<unsigned short>(cr);
|
||||
ptr++;
|
||||
*ptr = clip<unsigned short>(cg);
|
||||
ptr++;
|
||||
*ptr = clip<unsigned short>(cb);
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat cImage::whiteMultipliers(const LibRaw & iProcessor)
|
||||
{
|
||||
// get camera white balance multipliers
|
||||
cv::Mat wm(1, 4, CV_32FC1);
|
||||
|
||||
float* wmp = wm.ptr<float>();
|
||||
|
||||
for(int idx = 0; idx < wm.cols; idx++)
|
||||
wmp[idx] = iProcessor.imgdata.color.cam_mul[idx];
|
||||
|
||||
if(wmp[3] == 0.0f)
|
||||
wmp[3] = wmp[1]; // take green (usually its RGBG)
|
||||
|
||||
// normalize white balance multipliers
|
||||
float w = static_cast<float>(cv::sum(wm)[0] / 4.0f);
|
||||
float maxW = 1.0f;
|
||||
|
||||
//clipping according the camera model
|
||||
//if w > 2.0 maxW is 256, otherwise 512
|
||||
//tested empirically
|
||||
//check if it can be defined by some metadata settings?
|
||||
if(w > 2.0f)
|
||||
maxW = 255.0f;
|
||||
if(w > 2.0f && m_camType == camera_canon)
|
||||
maxW = 511.0f; // some cameras would even need ~800 - why?
|
||||
|
||||
//normalize white point
|
||||
wm /= maxW;
|
||||
|
||||
// 1 x 4 32FC1 white balance vector
|
||||
return wm;
|
||||
}
|
||||
|
||||
void cImage::gammaCorrection(const LibRaw & iProcessor, cv::Mat& img)
|
||||
{
|
||||
// white balance must not be empty at this point
|
||||
cv::Mat gt = gammaTable(iProcessor);
|
||||
const unsigned short* gammaLookup = gt.ptr<unsigned short>();
|
||||
assert(gt.cols == USHRT_MAX);
|
||||
|
||||
for(int rIdx = 0; rIdx < img.rows; rIdx++)
|
||||
{
|
||||
unsigned short *ptr = img.ptr<unsigned short>(rIdx);
|
||||
|
||||
for(int cIdx = 0; cIdx < img.cols * img.channels(); cIdx++)
|
||||
{
|
||||
// values close to 0 are treated linear
|
||||
if (ptr[cIdx] <= 5) // 0.018 * 255
|
||||
ptr[cIdx] = static_cast<unsigned short>(qRound(ptr[cIdx] * static_cast<double>(iProcessor.imgdata.params.gamm[1]) / 255.0));
|
||||
else
|
||||
ptr[cIdx] = gammaLookup[ptr[cIdx]];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cv::Mat cImage::gammaTable(const LibRaw & iProcessor)
|
||||
{
|
||||
// OK this is an instance of reverse engineering:
|
||||
// we found out that the values of (at least) the PhaseOne's achromatic back have to be doubled
|
||||
// our images are no close to what their software (Capture One does) - only the gamma correction
|
||||
// seems to be slightly different... -> now we can load compressed IIQs that are not supported by PS : )
|
||||
double cameraHackMlp = (QString(iProcessor.imgdata.idata.model) == "IQ260 Achromatic") ? 2.0 : 1.0;
|
||||
|
||||
//read gamma value and create gamma table
|
||||
double gamma = static_cast<double>(iProcessor.imgdata.params.gamm[0]);
|
||||
|
||||
cv::Mat gmt(1, USHRT_MAX, CV_16UC1);
|
||||
unsigned short* gmtp = gmt.ptr<unsigned short>();
|
||||
|
||||
for (int idx = 0; idx < gmt.cols; idx++) {
|
||||
gmtp[idx] = clip<unsigned short>(qRound((1.099*std::pow(static_cast<double>(idx) / USHRT_MAX, gamma) - 0.099) * 255 * cameraHackMlp));
|
||||
}
|
||||
|
||||
// a 1 x 65535 U16 gamma table
|
||||
return gmt;
|
||||
}
|
||||
|
||||
QImage cImage::raw2Img(const LibRaw & iProcessor, cv::Mat & img)
|
||||
{
|
||||
//check the pixel aspect ratio of the raw image
|
||||
if(iProcessor.imgdata.sizes.pixel_aspect != 1.0f)
|
||||
cv::resize(img, img, cv::Size(), static_cast<double>(iProcessor.imgdata.sizes.pixel_aspect), 1.0f);
|
||||
|
||||
// revert back to 8-bit image
|
||||
img.convertTo(img, CV_8U);
|
||||
|
||||
// TODO: for now - fix this!
|
||||
if(img.channels() == 1)
|
||||
cv::cvtColor(img, img, CV_GRAY2RGB);
|
||||
|
||||
return(mat2QImage(img));
|
||||
}
|
||||
|
||||
QImage cImage::mat2QImage(cv::Mat img)
|
||||
{
|
||||
QImage qImg;
|
||||
|
||||
// since Mat header is copied, a new buffer should be allocated (check this!)
|
||||
if(img.depth() == CV_32F)
|
||||
img.convertTo(img, CV_8U, 255);
|
||||
|
||||
if(img.type() == CV_8UC1)
|
||||
qImg = QImage(img.data, static_cast<int>(img.cols), static_cast<int>(img.rows), static_cast<int>(img.step), QImage::Format_Indexed8); // opencv uses size_t for scaling in x64 applications
|
||||
if(img.type() == CV_8UC3)
|
||||
qImg = QImage(img.data, static_cast<int>(img.cols), static_cast<int>(img.rows), static_cast<int>(img.step), QImage::Format_RGB888);
|
||||
if(img.type() == CV_8UC4)
|
||||
qImg = QImage(img.data, static_cast<int>(img.cols), static_cast<int>(img.rows), static_cast<int>(img.step), QImage::Format_ARGB32);
|
||||
|
||||
qImg = qImg.copy();
|
||||
|
||||
return qImg;
|
||||
}
|
||||
|
||||
bool cImage::loadRAW(const QString &fileName)
|
||||
{
|
||||
QSharedPointer<QByteArray> ba;
|
||||
LibRaw iProcessor;
|
||||
|
||||
if(!openBuffer(fileName, ba, iProcessor))
|
||||
{
|
||||
qDebug() << "could not open buffer";
|
||||
return(false);
|
||||
}
|
||||
|
||||
detectSpecialCamera(iProcessor);
|
||||
|
||||
int error = iProcessor.unpack();
|
||||
|
||||
if(strcmp(iProcessor.version(), "0.13.5") != 0) // fixes a bug specific to libraw 13 - version call is UNTESTED
|
||||
iProcessor.raw2image();
|
||||
|
||||
if(error != LIBRAW_SUCCESS)
|
||||
return(false);
|
||||
|
||||
cv::Mat rawMat;
|
||||
|
||||
if(iProcessor.imgdata.idata.filters)
|
||||
rawMat = demosaic(iProcessor);
|
||||
else
|
||||
rawMat = prepareImg(iProcessor);
|
||||
|
||||
// color correction + white balance
|
||||
if(m_isChromatic)
|
||||
whiteBalance(iProcessor, rawMat);
|
||||
|
||||
gammaCorrection(iProcessor, rawMat);
|
||||
|
||||
// reduce color noise
|
||||
// if (DkSettingsManager::param().resources().filterRawImages && mIsChromatic)
|
||||
// reduceColorNoise(iProcessor, rawMat);
|
||||
|
||||
*this = raw2Img(iProcessor, rawMat);
|
||||
|
||||
iProcessor.recycle();
|
||||
rawMat.release();
|
||||
|
||||
m_raw = true;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool cImage::isRaw()
|
||||
{
|
||||
return(m_raw);
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
/*!
|
||||
\file cimage.h
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CIMAGE_H
|
||||
#define CIMAGE_H
|
||||
|
||||
|
||||
#include "libraw/libraw.h"
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#include <QImage>
|
||||
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\class cImage cimage.h "cimage.h"
|
||||
*/
|
||||
class cImage : public QImage
|
||||
{
|
||||
public:
|
||||
cImage();
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cImage
|
||||
\param size
|
||||
\param format
|
||||
*/
|
||||
cImage(const QSize &size, QImage::Format format);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cImage
|
||||
\param width
|
||||
\param height
|
||||
\param format
|
||||
*/
|
||||
cImage(int width, int height, QImage::Format format);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cImage
|
||||
\param data
|
||||
\param width
|
||||
\param height
|
||||
\param format
|
||||
\param cleanupFunction
|
||||
\param cleanupInfo
|
||||
*/
|
||||
cImage(uchar *data, int width, int height, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cImage
|
||||
\param data
|
||||
\param width
|
||||
\param height
|
||||
\param format
|
||||
\param cleanupFunction
|
||||
\param cleanupInfo
|
||||
*/
|
||||
cImage(const uchar *data, int width, int height, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cImage
|
||||
\param data
|
||||
\param width
|
||||
\param height
|
||||
\param bytesPerLine
|
||||
\param format
|
||||
\param cleanupFunction
|
||||
\param cleanupInfo
|
||||
*/
|
||||
cImage(uchar *data, int width, int height, int bytesPerLine, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cImage
|
||||
\param data
|
||||
\param width
|
||||
\param height
|
||||
\param bytesPerLine
|
||||
\param format
|
||||
\param cleanupFunction
|
||||
\param cleanupInfo
|
||||
*/
|
||||
cImage(const uchar *data, int width, int height, int bytesPerLine, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cImage
|
||||
\param fileName
|
||||
\param format
|
||||
*/
|
||||
cImage(const QString &fileName, const char *format = nullptr);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cImage
|
||||
\param image
|
||||
*/
|
||||
cImage(const QImage &image);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn cImage
|
||||
\param other
|
||||
*/
|
||||
cImage(QImage &&other);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn load
|
||||
\param fileName
|
||||
\param format
|
||||
\return bool
|
||||
*/
|
||||
bool load(const QString &fileName, const char *format = nullptr);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn isRaw
|
||||
\return bool
|
||||
*/
|
||||
bool isRaw();
|
||||
|
||||
protected:
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\enum Cam
|
||||
*/
|
||||
enum Cam
|
||||
{
|
||||
camera_unknown = 0,
|
||||
camera_iiq,
|
||||
camera_canon,
|
||||
camera_end
|
||||
};
|
||||
|
||||
template <typename num>
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn clip
|
||||
\param val
|
||||
\return num
|
||||
*/
|
||||
num clip(float val) const
|
||||
{
|
||||
int vr = qRound(val);
|
||||
|
||||
// trust me I'm an engineer @ -2
|
||||
// with -2 we do not get pink in oversaturated areas
|
||||
if (vr > std::numeric_limits<num>::max())
|
||||
vr = std::numeric_limits<num>::max()-2;
|
||||
if (vr < 0)
|
||||
vr = 0;
|
||||
|
||||
return static_cast<num>(vr);
|
||||
}
|
||||
|
||||
template <typename num>
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn clip
|
||||
\param val
|
||||
\return num
|
||||
*/
|
||||
num clip(double val) const
|
||||
{
|
||||
int vr = qRound(val);
|
||||
|
||||
// trust me I'm an engineer @ -2
|
||||
// with -2 we do not get pink in oversaturated areas
|
||||
if (vr > std::numeric_limits<num>::max())
|
||||
vr = std::numeric_limits<num>::max()-2;
|
||||
if (vr < 0)
|
||||
vr = 0;
|
||||
|
||||
return static_cast<num>(vr);
|
||||
}
|
||||
|
||||
template <typename num>
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn clip
|
||||
\param val
|
||||
\return num
|
||||
*/
|
||||
num clip(int val) const
|
||||
{
|
||||
int vr = qRound(static_cast<double>(val));
|
||||
|
||||
// trust me I'm an engineer @ -2
|
||||
// with -2 we do not get pink in oversaturated areas
|
||||
if (vr > std::numeric_limits<num>::max())
|
||||
vr = std::numeric_limits<num>::max()-2;
|
||||
if (vr < 0)
|
||||
vr = 0;
|
||||
|
||||
return static_cast<num>(vr);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isChromatic; /*!< TODO: describe */
|
||||
Cam m_camType; /*!< TODO: describe */
|
||||
bool m_raw; /*!< TODO: describe */
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn loadRAW
|
||||
\param fileName
|
||||
\return bool
|
||||
*/
|
||||
bool loadRAW(const QString &fileName);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn openBuffer
|
||||
\param fileName
|
||||
\param ba
|
||||
\param iProcessor
|
||||
\return bool
|
||||
*/
|
||||
bool openBuffer(const QString &fileName, const QSharedPointer<QByteArray>& ba, LibRaw& iProcessor);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn detectSpecialCamera
|
||||
\param iProcessor
|
||||
*/
|
||||
void detectSpecialCamera(const LibRaw & iProcessor);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn demosaic
|
||||
\param iProcessor
|
||||
\return cv::Mat
|
||||
*/
|
||||
cv::Mat demosaic(LibRaw & iProcessor);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn prepareImg
|
||||
\param iProcessor
|
||||
\return cv::Mat
|
||||
*/
|
||||
cv::Mat prepareImg(const LibRaw & iProcessor);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn whiteBalance
|
||||
\param iProcessor
|
||||
\param img
|
||||
*/
|
||||
void whiteBalance(const LibRaw & iProcessor, cv::Mat & img);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn whiteMultipliers
|
||||
\param iProcessor
|
||||
\return cv::Mat
|
||||
*/
|
||||
cv::Mat whiteMultipliers(const LibRaw & iProcessor);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn gammaCorrection
|
||||
\param iProcessor
|
||||
\param img
|
||||
*/
|
||||
void gammaCorrection(const LibRaw & iProcessor, cv::Mat& img);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn gammaTable
|
||||
\param iProcessor
|
||||
\return cv::Mat
|
||||
*/
|
||||
cv::Mat gammaTable(const LibRaw & iProcessor);
|
||||
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn raw2Img
|
||||
\param iProcessor
|
||||
\param img
|
||||
\return QImage
|
||||
*/
|
||||
QImage raw2Img(const LibRaw & iProcessor, cv::Mat & img);
|
||||
/*!
|
||||
\brief
|
||||
|
||||
\fn mat2QImage
|
||||
\param img
|
||||
\return QImage
|
||||
*/
|
||||
QImage mat2QImage(cv::Mat img);
|
||||
};
|
||||
|
||||
#endif // CIMAGE_H
|
||||
Reference in New Issue
Block a user