30 bit display feature
This commit is contained in:
parent
795c8cae04
commit
a55f60e466
14 changed files with 747 additions and 73 deletions
|
@ -942,6 +942,454 @@ void doQuickPutNoFilter(const TRaster32P &dn, const TRasterGR8P &up,
|
|||
up->unlock();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
|
||||
void doQuickPutNoFilter(const TRaster64P &dn, const TRaster64P &up,
|
||||
const TAffine &aff, bool doPremultiply,
|
||||
bool firstColumn) {
|
||||
// se aff := TAffine(sx, 0, tx, 0, sy, ty) e' degenere la controimmagine
|
||||
// di up e' un segmento (o un punto)
|
||||
if ((aff.a11 * aff.a22 - aff.a12 * aff.a21) == 0) return;
|
||||
|
||||
// contatore bit di shift
|
||||
const int PADN = 16;
|
||||
|
||||
// max dimensioni di up gestibili (limite imposto dal numero di bit
|
||||
// disponibili per la parte intera di xL, yL)
|
||||
assert(std::max(up->getLx(), up->getLy()) <
|
||||
(1 << (8 * sizeof(int) - PADN - 1)));
|
||||
|
||||
TRectD boundingBoxD =
|
||||
TRectD(convert(dn->getBounds())) *
|
||||
(aff * TRectD(-0.5, -0.5, up->getLx() - 0.5, up->getLy() - 0.5));
|
||||
|
||||
// clipping
|
||||
if (boundingBoxD.x0 >= boundingBoxD.x1 || boundingBoxD.y0 >= boundingBoxD.y1)
|
||||
return;
|
||||
|
||||
// clipping y su dn
|
||||
int yMin = std::max(tfloor(boundingBoxD.y0), 0);
|
||||
|
||||
// clipping y su dn
|
||||
int yMax = std::min(tceil(boundingBoxD.y1), dn->getLy() - 1);
|
||||
|
||||
// clipping x su dn
|
||||
int xMin = std::max(tfloor(boundingBoxD.x0), 0);
|
||||
|
||||
// clipping x su dn
|
||||
int xMax = std::min(tceil(boundingBoxD.x1), dn->getLx() - 1);
|
||||
|
||||
// inversa di aff
|
||||
TAffine invAff = inv(aff);
|
||||
|
||||
// nel disegnare la y-esima scanline di dn, il passaggio al pixel
|
||||
// successivo comporta l'incremento (deltaXD, deltaYD) delle coordinate del
|
||||
// pixel corrispondente di up
|
||||
double deltaXD = invAff.a11;
|
||||
double deltaYD = invAff.a21;
|
||||
|
||||
// deltaXD "TLonghizzato" (round)
|
||||
int deltaXL = tround(deltaXD * (1 << PADN));
|
||||
|
||||
// deltaYD "TLonghizzato" (round)
|
||||
int deltaYL = tround(deltaYD * (1 << PADN));
|
||||
|
||||
// se aff "TLonghizzata" (round) e' degenere la controimmagine di up e' un
|
||||
// segmento (o un punto)
|
||||
if ((deltaXL == 0) && (deltaYL == 0)) return;
|
||||
|
||||
// TINT32 predecessore di up->getLx()
|
||||
int lxPred = up->getLx() * (1 << PADN) - 1;
|
||||
|
||||
// TINT32 predecessore di up->getLy()
|
||||
int lyPred = up->getLy() * (1 << PADN) - 1;
|
||||
|
||||
int dnWrap = dn->getWrap();
|
||||
int upWrap = up->getWrap();
|
||||
dn->lock();
|
||||
up->lock();
|
||||
|
||||
TPixel64 *dnRow = dn->pixels(yMin);
|
||||
TPixel64 *upBasePix = up->pixels();
|
||||
|
||||
// scorre le scanline di boundingBoxD
|
||||
for (int y = yMin; y <= yMax; y++, dnRow += dnWrap) {
|
||||
// (1) equazione k-parametrica della y-esima scanline di boundingBoxD:
|
||||
// (xMin, y) + k*(1, 0), k = 0, ..., (xMax - xMin)
|
||||
|
||||
// (2) equazione k-parametrica dell'immagine mediante invAff di (1):
|
||||
// invAff*(xMin, y) + k*(deltaXD, deltaYD),
|
||||
// k = kMin, ..., kMax con 0 <= kMin <= kMax <= (xMax - xMin)
|
||||
|
||||
// calcola kMin, kMax per la scanline corrente
|
||||
// intersecando la (2) con i lati di up
|
||||
|
||||
// il segmento [a, b] di up e' la controimmagine mediante aff della
|
||||
// porzione di scanline [ (xMin, y), (xMax, y) ] di dn
|
||||
|
||||
// TPointD b = invAff*TPointD(xMax, y);
|
||||
TPointD a = invAff * TPointD(xMin, y);
|
||||
|
||||
// (xL0, yL0) sono le coordinate di a (inizializzate per il round)
|
||||
// in versione "TLonghizzata"
|
||||
// 0 <= xL0 + k*deltaXL
|
||||
// < up->getLx()*(1<<PADN)
|
||||
//
|
||||
// 0 <= kMinX
|
||||
// <= kMin
|
||||
// <= k
|
||||
// <= kMax
|
||||
// <= kMaxX
|
||||
// <= (xMax - xMin)
|
||||
//
|
||||
// 0 <= yL0 + k*deltaYL
|
||||
// < up->getLy()*(1<<PADN)
|
||||
|
||||
// 0 <= kMinY
|
||||
// <= kMin
|
||||
// <= k
|
||||
// <= kMax
|
||||
// <= kMaxY
|
||||
// <= (xMax - xMin)
|
||||
|
||||
// xL0 inizializzato per il round
|
||||
int xL0 = tround((a.x + 0.5) * (1 << PADN));
|
||||
|
||||
// yL0 inizializzato per il round
|
||||
int yL0 = tround((a.y + 0.5) * (1 << PADN));
|
||||
|
||||
// calcola kMinX, kMaxX, kMinY, kMaxY
|
||||
int kMinX = 0, kMaxX = xMax - xMin; // clipping su dn
|
||||
int kMinY = 0, kMaxY = xMax - xMin; // clipping su dn
|
||||
|
||||
// 0 <= xL0 + k*deltaXL
|
||||
// < up->getLx()*(1<<PADN)
|
||||
// <=>
|
||||
// 0 <= xL0 + k*deltaXL
|
||||
// <= lxPred
|
||||
//
|
||||
// 0 <= yL0 + k*deltaYL
|
||||
// < up->getLy()*(1<<PADN)
|
||||
// <=>
|
||||
// 0 <= yL0 + k*deltaYL
|
||||
// <= lyPred
|
||||
|
||||
// calcola kMinX, kMaxX
|
||||
if (deltaXL == 0) {
|
||||
// [a, b] verticale esterno ad up+(bordo destro/basso)
|
||||
if ((xL0 < 0) || (lxPred < xL0)) continue;
|
||||
// altrimenti usa solo
|
||||
// kMinY, kMaxY ((deltaXL != 0) || (deltaYL != 0))
|
||||
} else if (deltaXL > 0) {
|
||||
// [a, b] esterno ad up+(bordo destro/basso)
|
||||
if (lxPred < xL0) continue;
|
||||
|
||||
kMaxX = (lxPred - xL0) / deltaXL; // floor
|
||||
if (xL0 < 0) {
|
||||
kMinX = ((-xL0) + deltaXL - 1) / deltaXL; // ceil
|
||||
}
|
||||
} else // (deltaXL < 0)
|
||||
{
|
||||
// [a, b] esterno ad up+(bordo destro/basso)
|
||||
if (xL0 < 0) continue;
|
||||
|
||||
kMaxX = xL0 / (-deltaXL); // floor
|
||||
if (lxPred < xL0) {
|
||||
kMinX = (xL0 - lxPred - deltaXL - 1) / (-deltaXL); // ceil
|
||||
}
|
||||
}
|
||||
|
||||
// calcola kMinY, kMaxY
|
||||
if (deltaYL == 0) {
|
||||
// [a, b] orizzontale esterno ad up+(bordo destro/basso)
|
||||
if ((yL0 < 0) || (lyPred < yL0)) continue;
|
||||
// altrimenti usa solo
|
||||
// kMinX, kMaxX ((deltaXL != 0) || (deltaYL != 0))
|
||||
} else if (deltaYL > 0) {
|
||||
// [a, b] esterno ad up+(bordo destro/basso)
|
||||
if (lyPred < yL0) continue;
|
||||
|
||||
kMaxY = (lyPred - yL0) / deltaYL; // floor
|
||||
if (yL0 < 0) {
|
||||
kMinY = ((-yL0) + deltaYL - 1) / deltaYL; // ceil
|
||||
}
|
||||
} else // (deltaYL < 0)
|
||||
{
|
||||
// [a, b] esterno ad up+(bordo destro/basso)
|
||||
if (yL0 < 0) continue;
|
||||
|
||||
kMaxY = yL0 / (-deltaYL); // floor
|
||||
if (lyPred < yL0) {
|
||||
kMinY = (yL0 - lyPred - deltaYL - 1) / (-deltaYL); // ceil
|
||||
}
|
||||
}
|
||||
|
||||
// calcola kMin, kMax effettuando anche il clippind su dn
|
||||
int kMin = std::max({kMinX, kMinY, (int)0});
|
||||
int kMax = std::min({kMaxX, kMaxY, xMax - xMin});
|
||||
|
||||
TPixel64 *dnPix = dnRow + xMin + kMin;
|
||||
TPixel64 *dnEndPix = dnRow + xMin + kMax + 1;
|
||||
|
||||
// (xL, yL) sono le coordinate (inizializzate per il round)
|
||||
// in versione "TLonghizzata" del pixel corrente di up
|
||||
int xL = xL0 + (kMin - 1) * deltaXL; // inizializza xL
|
||||
int yL = yL0 + (kMin - 1) * deltaYL; // inizializza yL
|
||||
|
||||
// scorre i pixel sulla y-esima scanline di boundingBoxD
|
||||
for (; dnPix < dnEndPix; ++dnPix) {
|
||||
xL += deltaXL;
|
||||
yL += deltaYL;
|
||||
|
||||
// il punto di up TPointD(xL/(1<<PADN), yL/(1<<PADN)) e'
|
||||
// approssimato con (xI, yI)
|
||||
int xI = xL >> PADN; // round
|
||||
int yI = yL >> PADN; // round
|
||||
|
||||
assert((0 <= xI) && (xI <= up->getLx() - 1) && (0 <= yI) &&
|
||||
(yI <= up->getLy() - 1));
|
||||
|
||||
TPixel64 upPix = *(upBasePix + (yI * upWrap + xI));
|
||||
|
||||
if (firstColumn) upPix.m = 65535;
|
||||
if (upPix.m == 0) continue;
|
||||
|
||||
if (upPix.m == 65535)
|
||||
*dnPix = upPix;
|
||||
else if (doPremultiply)
|
||||
*dnPix = quickOverPixPremult(*dnPix, upPix);
|
||||
else
|
||||
*dnPix = quickOverPix(*dnPix, upPix);
|
||||
}
|
||||
}
|
||||
dn->unlock();
|
||||
up->unlock();
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
void doQuickPutNoFilter(const TRaster64P &dn, const TRaster32P &up,
|
||||
const TAffine &aff, bool doPremultiply,
|
||||
bool firstColumn) {
|
||||
// se aff := TAffine(sx, 0, tx, 0, sy, ty) e' degenere la controimmagine
|
||||
// di up e' un segmento (o un punto)
|
||||
if ((aff.a11 * aff.a22 - aff.a12 * aff.a21) == 0) return;
|
||||
|
||||
// contatore bit di shift
|
||||
const int PADN = 16;
|
||||
|
||||
// max dimensioni di up gestibili (limite imposto dal numero di bit
|
||||
// disponibili per la parte intera di xL, yL)
|
||||
assert(std::max(up->getLx(), up->getLy()) <
|
||||
(1 << (8 * sizeof(int) - PADN - 1)));
|
||||
|
||||
TRectD boundingBoxD =
|
||||
TRectD(convert(dn->getBounds())) *
|
||||
(aff * TRectD(-0.5, -0.5, up->getLx() - 0.5, up->getLy() - 0.5));
|
||||
|
||||
// clipping
|
||||
if (boundingBoxD.x0 >= boundingBoxD.x1 || boundingBoxD.y0 >= boundingBoxD.y1)
|
||||
return;
|
||||
|
||||
// clipping y su dn
|
||||
int yMin = std::max(tfloor(boundingBoxD.y0), 0);
|
||||
|
||||
// clipping y su dn
|
||||
int yMax = std::min(tceil(boundingBoxD.y1), dn->getLy() - 1);
|
||||
|
||||
// clipping x su dn
|
||||
int xMin = std::max(tfloor(boundingBoxD.x0), 0);
|
||||
|
||||
// clipping x su dn
|
||||
int xMax = std::min(tceil(boundingBoxD.x1), dn->getLx() - 1);
|
||||
|
||||
// inversa di aff
|
||||
TAffine invAff = inv(aff);
|
||||
|
||||
// nel disegnare la y-esima scanline di dn, il passaggio al pixel
|
||||
// successivo comporta l'incremento (deltaXD, deltaYD) delle coordinate del
|
||||
// pixel corrispondente di up
|
||||
double deltaXD = invAff.a11;
|
||||
double deltaYD = invAff.a21;
|
||||
|
||||
// deltaXD "TLonghizzato" (round)
|
||||
int deltaXL = tround(deltaXD * (1 << PADN));
|
||||
|
||||
// deltaYD "TLonghizzato" (round)
|
||||
int deltaYL = tround(deltaYD * (1 << PADN));
|
||||
|
||||
// se aff "TLonghizzata" (round) e' degenere la controimmagine di up e' un
|
||||
// segmento (o un punto)
|
||||
if ((deltaXL == 0) && (deltaYL == 0)) return;
|
||||
|
||||
// TINT32 predecessore di up->getLx()
|
||||
int lxPred = up->getLx() * (1 << PADN) - 1;
|
||||
|
||||
// TINT32 predecessore di up->getLy()
|
||||
int lyPred = up->getLy() * (1 << PADN) - 1;
|
||||
|
||||
int dnWrap = dn->getWrap();
|
||||
int upWrap = up->getWrap();
|
||||
dn->lock();
|
||||
up->lock();
|
||||
|
||||
TPixel64 *dnRow = dn->pixels(yMin);
|
||||
TPixel32 *upBasePix = up->pixels();
|
||||
|
||||
// scorre le scanline di boundingBoxD
|
||||
for (int y = yMin; y <= yMax; y++, dnRow += dnWrap) {
|
||||
// (1) equazione k-parametrica della y-esima scanline di boundingBoxD:
|
||||
// (xMin, y) + k*(1, 0), k = 0, ..., (xMax - xMin)
|
||||
|
||||
// (2) equazione k-parametrica dell'immagine mediante invAff di (1):
|
||||
// invAff*(xMin, y) + k*(deltaXD, deltaYD),
|
||||
// k = kMin, ..., kMax con 0 <= kMin <= kMax <= (xMax - xMin)
|
||||
|
||||
// calcola kMin, kMax per la scanline corrente
|
||||
// intersecando la (2) con i lati di up
|
||||
|
||||
// il segmento [a, b] di up e' la controimmagine mediante aff della
|
||||
// porzione di scanline [ (xMin, y), (xMax, y) ] di dn
|
||||
|
||||
// TPointD b = invAff*TPointD(xMax, y);
|
||||
TPointD a = invAff * TPointD(xMin, y);
|
||||
|
||||
// (xL0, yL0) sono le coordinate di a (inizializzate per il round)
|
||||
// in versione "TLonghizzata"
|
||||
// 0 <= xL0 + k*deltaXL
|
||||
// < up->getLx()*(1<<PADN)
|
||||
//
|
||||
// 0 <= kMinX
|
||||
// <= kMin
|
||||
// <= k
|
||||
// <= kMax
|
||||
// <= kMaxX
|
||||
// <= (xMax - xMin)
|
||||
//
|
||||
// 0 <= yL0 + k*deltaYL
|
||||
// < up->getLy()*(1<<PADN)
|
||||
|
||||
// 0 <= kMinY
|
||||
// <= kMin
|
||||
// <= k
|
||||
// <= kMax
|
||||
// <= kMaxY
|
||||
// <= (xMax - xMin)
|
||||
|
||||
// xL0 inizializzato per il round
|
||||
int xL0 = tround((a.x + 0.5) * (1 << PADN));
|
||||
|
||||
// yL0 inizializzato per il round
|
||||
int yL0 = tround((a.y + 0.5) * (1 << PADN));
|
||||
|
||||
// calcola kMinX, kMaxX, kMinY, kMaxY
|
||||
int kMinX = 0, kMaxX = xMax - xMin; // clipping su dn
|
||||
int kMinY = 0, kMaxY = xMax - xMin; // clipping su dn
|
||||
|
||||
// 0 <= xL0 + k*deltaXL
|
||||
// < up->getLx()*(1<<PADN)
|
||||
// <=>
|
||||
// 0 <= xL0 + k*deltaXL
|
||||
// <= lxPred
|
||||
//
|
||||
// 0 <= yL0 + k*deltaYL
|
||||
// < up->getLy()*(1<<PADN)
|
||||
// <=>
|
||||
// 0 <= yL0 + k*deltaYL
|
||||
// <= lyPred
|
||||
|
||||
// calcola kMinX, kMaxX
|
||||
if (deltaXL == 0) {
|
||||
// [a, b] verticale esterno ad up+(bordo destro/basso)
|
||||
if ((xL0 < 0) || (lxPred < xL0)) continue;
|
||||
// altrimenti usa solo
|
||||
// kMinY, kMaxY ((deltaXL != 0) || (deltaYL != 0))
|
||||
} else if (deltaXL > 0) {
|
||||
// [a, b] esterno ad up+(bordo destro/basso)
|
||||
if (lxPred < xL0) continue;
|
||||
|
||||
kMaxX = (lxPred - xL0) / deltaXL; // floor
|
||||
if (xL0 < 0) {
|
||||
kMinX = ((-xL0) + deltaXL - 1) / deltaXL; // ceil
|
||||
}
|
||||
} else // (deltaXL < 0)
|
||||
{
|
||||
// [a, b] esterno ad up+(bordo destro/basso)
|
||||
if (xL0 < 0) continue;
|
||||
|
||||
kMaxX = xL0 / (-deltaXL); // floor
|
||||
if (lxPred < xL0) {
|
||||
kMinX = (xL0 - lxPred - deltaXL - 1) / (-deltaXL); // ceil
|
||||
}
|
||||
}
|
||||
|
||||
// calcola kMinY, kMaxY
|
||||
if (deltaYL == 0) {
|
||||
// [a, b] orizzontale esterno ad up+(bordo destro/basso)
|
||||
if ((yL0 < 0) || (lyPred < yL0)) continue;
|
||||
// altrimenti usa solo
|
||||
// kMinX, kMaxX ((deltaXL != 0) || (deltaYL != 0))
|
||||
} else if (deltaYL > 0) {
|
||||
// [a, b] esterno ad up+(bordo destro/basso)
|
||||
if (lyPred < yL0) continue;
|
||||
|
||||
kMaxY = (lyPred - yL0) / deltaYL; // floor
|
||||
if (yL0 < 0) {
|
||||
kMinY = ((-yL0) + deltaYL - 1) / deltaYL; // ceil
|
||||
}
|
||||
} else // (deltaYL < 0)
|
||||
{
|
||||
// [a, b] esterno ad up+(bordo destro/basso)
|
||||
if (yL0 < 0) continue;
|
||||
|
||||
kMaxY = yL0 / (-deltaYL); // floor
|
||||
if (lyPred < yL0) {
|
||||
kMinY = (yL0 - lyPred - deltaYL - 1) / (-deltaYL); // ceil
|
||||
}
|
||||
}
|
||||
|
||||
// calcola kMin, kMax effettuando anche il clippind su dn
|
||||
int kMin = std::max({kMinX, kMinY, (int)0});
|
||||
int kMax = std::min({kMaxX, kMaxY, xMax - xMin});
|
||||
|
||||
TPixel64 *dnPix = dnRow + xMin + kMin;
|
||||
TPixel64 *dnEndPix = dnRow + xMin + kMax + 1;
|
||||
|
||||
// (xL, yL) sono le coordinate (inizializzate per il round)
|
||||
// in versione "TLonghizzata" del pixel corrente di up
|
||||
int xL = xL0 + (kMin - 1) * deltaXL; // inizializza xL
|
||||
int yL = yL0 + (kMin - 1) * deltaYL; // inizializza yL
|
||||
|
||||
// scorre i pixel sulla y-esima scanline di boundingBoxD
|
||||
for (; dnPix < dnEndPix; ++dnPix) {
|
||||
xL += deltaXL;
|
||||
yL += deltaYL;
|
||||
|
||||
// il punto di up TPointD(xL/(1<<PADN), yL/(1<<PADN)) e'
|
||||
// approssimato con (xI, yI)
|
||||
int xI = xL >> PADN; // round
|
||||
int yI = yL >> PADN; // round
|
||||
|
||||
assert((0 <= xI) && (xI <= up->getLx() - 1) && (0 <= yI) &&
|
||||
(yI <= up->getLy() - 1));
|
||||
|
||||
TPixel32 upPix = *(upBasePix + (yI * upWrap + xI));
|
||||
|
||||
if (firstColumn) upPix.m = 255;
|
||||
if (upPix.m == 0) continue;
|
||||
|
||||
TPixel64 upPix64 = toPixel64(upPix);
|
||||
if (upPix.m == 255)
|
||||
*dnPix = upPix64;
|
||||
else if (doPremultiply)
|
||||
*dnPix = quickOverPixPremult(*dnPix, upPix64);
|
||||
else
|
||||
*dnPix = quickOverPix(*dnPix, upPix64);
|
||||
}
|
||||
}
|
||||
dn->unlock();
|
||||
up->unlock();
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
void doQuickPutFilter(const TRaster32P &dn, const TRaster32P &up, double sx,
|
||||
|
@ -4268,6 +4716,7 @@ void quickPut(const TRasterP &dn, const TRasterP &up, const TAffine &aff,
|
|||
TRaster32P up32 = up;
|
||||
TRasterGR8P dn8 = dn;
|
||||
TRasterGR8P up8 = up;
|
||||
TRaster64P dn64 = dn;
|
||||
TRaster64P up64 = up;
|
||||
|
||||
if (up8 && dn32) {
|
||||
|
@ -4294,6 +4743,10 @@ void quickPut(const TRasterP &dn, const TRasterP &up, const TAffine &aff,
|
|||
}
|
||||
} else if (dn32 && up64)
|
||||
doQuickPutNoFilter(dn32, up64, aff, doPremultiply, firstColumn);
|
||||
else if (dn64 && up64)
|
||||
doQuickPutNoFilter(dn64, up64, aff, doPremultiply, firstColumn);
|
||||
else if (dn64 && up32)
|
||||
doQuickPutNoFilter(dn64, up32, aff, doPremultiply, firstColumn);
|
||||
else
|
||||
throw TRopException("raster type mismatch");
|
||||
}
|
||||
|
|
|
@ -68,6 +68,12 @@ class TCubic;
|
|||
#define TGL_TYPE GL_UNSIGNED_BYTE
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// settings for 30bit display
|
||||
|
||||
#define TGL_TexFmt10 GL_RGB10_A2
|
||||
#define TGL_TYPE16 GL_UNSIGNED_SHORT
|
||||
|
||||
//=============================================================================
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
|
|
@ -234,6 +234,7 @@ public:
|
|||
}
|
||||
void setColorCalibrationLutPath(QString monitorName, QString path);
|
||||
QString getColorCalibrationLutPath(QString &monitorName) const;
|
||||
bool is30bitDisplayEnabled() const { return getBoolValue(displayIn30bit); }
|
||||
|
||||
bool isViewerIndicatorEnabled() const {
|
||||
return getBoolValue(viewerIndicatorEnabled);
|
||||
|
|
|
@ -45,6 +45,7 @@ enum PreferencesItemId {
|
|||
colorCalibrationEnabled,
|
||||
colorCalibrationLutPaths,
|
||||
showIconsInMenu,
|
||||
displayIn30bit,
|
||||
viewerIndicatorEnabled,
|
||||
|
||||
//----------
|
||||
|
|
|
@ -236,6 +236,12 @@ inline TPixel32 quickOverPixPremult(const TPixel32 &bot, const TPixel32 &top) {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline TPixel64 quickOverPixPremult(const TPixel64 &bot, const TPixel64 &top) {
|
||||
return quickOverPixPremultT<TPixel64, USHORT>(bot, top);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline TPixel64 quickOverPix(const TPixel64 &bot, const TPixel64 &top) {
|
||||
return quickOverPixT<TPixel64, USHORT>(bot, top);
|
||||
}
|
||||
|
@ -532,20 +538,24 @@ void mult(T &pixout, const T &pixin, double v) {
|
|||
g = pixin.g + v;
|
||||
b = pixin.b + v;
|
||||
m = pixin.m + v;
|
||||
pixout.r =
|
||||
(r < 0) ? 0 : ((r < T::maxChannelValue)
|
||||
pixout.r = (r < 0)
|
||||
? 0
|
||||
: ((r < T::maxChannelValue)
|
||||
? troundp(r * (pixout.r / (double)T::maxChannelValue))
|
||||
: pixout.r);
|
||||
pixout.g =
|
||||
(g < 0) ? 0 : ((g < T::maxChannelValue)
|
||||
pixout.g = (g < 0)
|
||||
? 0
|
||||
: ((g < T::maxChannelValue)
|
||||
? troundp(g * (pixout.g / (double)T::maxChannelValue))
|
||||
: pixout.g);
|
||||
pixout.b =
|
||||
(b < 0) ? 0 : ((b < T::maxChannelValue)
|
||||
pixout.b = (b < 0)
|
||||
? 0
|
||||
: ((b < T::maxChannelValue)
|
||||
? troundp(b * (pixout.b / (double)T::maxChannelValue))
|
||||
: pixout.b);
|
||||
pixout.m =
|
||||
(m < 0) ? 0 : ((m < T::maxChannelValue)
|
||||
pixout.m = (m < 0)
|
||||
? 0
|
||||
: ((m < T::maxChannelValue)
|
||||
? troundp(m * (pixout.m / (double)T::maxChannelValue))
|
||||
: pixout.m);
|
||||
}
|
||||
|
|
|
@ -163,34 +163,33 @@ inline TRectD getImageBoundsD(const TImageP &img) {
|
|||
FlipBook::FlipBook(QWidget *parent, QString viewerTitle,
|
||||
std::vector<int> flipConsoleButtonMask, UCHAR flags,
|
||||
bool isColorModel) //, bool showOnlyPlayBackgroundButton)
|
||||
: QWidget(parent),
|
||||
m_viewerTitle(viewerTitle),
|
||||
m_levelNames(),
|
||||
m_levels(),
|
||||
m_playSound(false),
|
||||
m_snd(0),
|
||||
m_player(0)
|
||||
: QWidget(parent)
|
||||
, m_viewerTitle(viewerTitle)
|
||||
, m_levelNames()
|
||||
, m_levels()
|
||||
, m_playSound(false)
|
||||
, m_snd(0)
|
||||
, m_player(0)
|
||||
//, m_doCompare(false)
|
||||
,
|
||||
m_currentFrameToSave(0),
|
||||
m_lw(),
|
||||
m_lr(),
|
||||
m_loadPopup(0),
|
||||
m_savePopup(0),
|
||||
m_shrink(1),
|
||||
m_isPreviewFx(false),
|
||||
m_previewedFx(0),
|
||||
m_previewXsh(0),
|
||||
m_previewUpdateTimer(this),
|
||||
m_xl(0),
|
||||
m_title1(),
|
||||
m_poolIndex(-1),
|
||||
m_freezed(false),
|
||||
m_loadbox(),
|
||||
m_dim(),
|
||||
m_loadboxes(),
|
||||
m_freezeButton(0),
|
||||
m_flags(flags) {
|
||||
, m_currentFrameToSave(0)
|
||||
, m_lw()
|
||||
, m_lr()
|
||||
, m_loadPopup(0)
|
||||
, m_savePopup(0)
|
||||
, m_shrink(1)
|
||||
, m_isPreviewFx(false)
|
||||
, m_previewedFx(0)
|
||||
, m_previewXsh(0)
|
||||
, m_previewUpdateTimer(this)
|
||||
, m_xl(0)
|
||||
, m_title1()
|
||||
, m_poolIndex(-1)
|
||||
, m_freezed(false)
|
||||
, m_loadbox()
|
||||
, m_dim()
|
||||
, m_loadboxes()
|
||||
, m_freezeButton(0)
|
||||
, m_flags(flags) {
|
||||
setAcceptDrops(true);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
|
@ -1141,8 +1140,7 @@ void FlipBook::setLevel(const TFilePath &fp, TPalette *palette, int from,
|
|||
levelToPush.m_incrementalIndexing = incrementalIndexing;
|
||||
|
||||
int formatIdx = Preferences::instance()->matchLevelFormat(fp);
|
||||
if (formatIdx >= 0 &&
|
||||
Preferences::instance()
|
||||
if (formatIdx >= 0 && Preferences::instance()
|
||||
->levelFormat(formatIdx)
|
||||
.m_options.m_premultiply) {
|
||||
levelToPush.m_premultiply = true;
|
||||
|
@ -1595,6 +1593,9 @@ TImageP FlipBook::getCurrentImage(int frame) {
|
|||
lx = m_loadbox.getLx();
|
||||
}
|
||||
|
||||
if (Preferences::instance()->is30bitDisplayEnabled())
|
||||
ir->enable16BitRead(true);
|
||||
|
||||
TImageP img = ir->load();
|
||||
|
||||
if (img) {
|
||||
|
|
|
@ -244,6 +244,11 @@ ImageViewer::ImageViewer(QWidget *parent, FlipBook *flipbook,
|
|||
|
||||
if (Preferences::instance()->isColorCalibrationEnabled())
|
||||
m_lutCalibrator = new LutCalibrator();
|
||||
|
||||
#if QT_VERSION >= 0x051000
|
||||
if (Preferences::instance()->is30bitDisplayEnabled())
|
||||
setTextureFormat(TGL_TexFmt10);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -488,6 +493,11 @@ void ImageViewer::resizeGL(int w, int h) {
|
|||
// remake fbo with new size
|
||||
if (m_lutCalibrator && m_lutCalibrator->isValid()) {
|
||||
if (m_fbo) delete m_fbo;
|
||||
if (Preferences::instance()->is30bitDisplayEnabled()) {
|
||||
QOpenGLFramebufferObjectFormat format;
|
||||
format.setInternalTextureFormat(TGL_TexFmt10);
|
||||
m_fbo = new QOpenGLFramebufferObject(w, h, format);
|
||||
} else // normally, initialize with GL_RGBA8 format
|
||||
m_fbo = new QOpenGLFramebufferObject(w, h);
|
||||
}
|
||||
}
|
||||
|
@ -495,6 +505,7 @@ void ImageViewer::resizeGL(int w, int h) {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ImageViewer::paintGL() {
|
||||
initializeOpenGLFunctions();
|
||||
if (m_lutCalibrator && m_lutCalibrator->isValid()) m_fbo->bind();
|
||||
|
||||
TDimension viewerSize(width(), height());
|
||||
|
@ -1422,8 +1433,14 @@ void ImageViewer::onPreferenceChanged(const QString& prefName) {
|
|||
m_lutCalibrator->initialize();
|
||||
connect(context(), SIGNAL(aboutToBeDestroyed()), this,
|
||||
SLOT(onContextAboutToBeDestroyed()));
|
||||
if (m_lutCalibrator->isValid() && !m_fbo)
|
||||
if (m_lutCalibrator->isValid() && !m_fbo) {
|
||||
if (Preferences::instance()->is30bitDisplayEnabled()) {
|
||||
QOpenGLFramebufferObjectFormat format;
|
||||
format.setInternalTextureFormat(TGL_TexFmt10);
|
||||
m_fbo = new QOpenGLFramebufferObject(width(), height(), format);
|
||||
} else // normally, initialize with GL_RGBA8 format
|
||||
m_fbo = new QOpenGLFramebufferObject(width(), height());
|
||||
}
|
||||
doneCurrent();
|
||||
}
|
||||
update();
|
||||
|
|
|
@ -528,6 +528,16 @@ int main(int argc, char *argv[]) {
|
|||
crInstall(&pInfo);
|
||||
#endif
|
||||
|
||||
// prepare for 30bit display
|
||||
if (Preferences::instance()->is30bitDisplayEnabled()) {
|
||||
QSurfaceFormat sFmt = QSurfaceFormat::defaultFormat();
|
||||
sFmt.setRedBufferSize(10);
|
||||
sFmt.setGreenBufferSize(10);
|
||||
sFmt.setBlueBufferSize(10);
|
||||
sFmt.setAlphaBufferSize(2);
|
||||
QSurfaceFormat::setDefaultFormat(sFmt);
|
||||
}
|
||||
|
||||
// Initialize thread components
|
||||
TThread::init();
|
||||
|
||||
|
|
|
@ -270,6 +270,89 @@ Preferences::LevelFormat PreferencesPopup::FormatProperties::levelFormat()
|
|||
return lf;
|
||||
}
|
||||
|
||||
//**********************************************************************************
|
||||
// PreferencesPopup::Display30bitCheckerView implementation
|
||||
//**********************************************************************************
|
||||
|
||||
PreferencesPopup::Display30bitChecker::GLView::GLView(QWidget* parent,
|
||||
bool is30bit)
|
||||
: QOpenGLWidget(parent), m_is30bit(is30bit) {
|
||||
setFixedSize(500, 100);
|
||||
#if QT_VERSION >= 0x051000
|
||||
if (m_is30bit) setTextureFormat(TGL_TexFmt10);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PreferencesPopup::Display30bitChecker::GLView::initializeGL() {
|
||||
initializeOpenGLFunctions();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
void PreferencesPopup::Display30bitChecker::GLView::resizeGL(int width,
|
||||
int height) {
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, 1, 0, 1, -1, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
void PreferencesPopup::Display30bitChecker::GLView::paintGL() {
|
||||
initializeOpenGLFunctions();
|
||||
glPushMatrix();
|
||||
glBegin(GL_QUADS);
|
||||
glColor3d(0.071, 0.153, 0.0);
|
||||
glVertex3d(0, 0, 0);
|
||||
glVertex3d(0, 1, 0);
|
||||
glColor3d(0.141, 0.239, 0.0);
|
||||
glVertex3d(1, 1, 0);
|
||||
glVertex3d(1, 0, 0);
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
|
||||
PreferencesPopup::Display30bitChecker::Display30bitChecker(
|
||||
PreferencesPopup* parent)
|
||||
: QDialog(parent) {
|
||||
setModal(true);
|
||||
m_currentDefaultFormat = QSurfaceFormat::defaultFormat();
|
||||
|
||||
setWindowTitle(tr("Check 30bit display availability"));
|
||||
|
||||
QSurfaceFormat sFmt = m_currentDefaultFormat;
|
||||
sFmt.setRedBufferSize(10);
|
||||
sFmt.setGreenBufferSize(10);
|
||||
sFmt.setBlueBufferSize(10);
|
||||
sFmt.setAlphaBufferSize(2);
|
||||
QSurfaceFormat::setDefaultFormat(sFmt);
|
||||
|
||||
GLView* view8bit = new GLView(this, false);
|
||||
GLView* view10bit = new GLView(this, true);
|
||||
QPushButton* closeBtn = new QPushButton(tr("Close"), this);
|
||||
QString infoLabel = tr(
|
||||
"If the lower gradient looks smooth and has no banding compared to the upper gradient,\n\
|
||||
30bit display is available in the current configuration.");
|
||||
|
||||
QVBoxLayout* lay = new QVBoxLayout();
|
||||
lay->setMargin(10);
|
||||
lay->setSpacing(10);
|
||||
{
|
||||
lay->addWidget(view8bit);
|
||||
lay->addWidget(view10bit);
|
||||
lay->addWidget(new QLabel(infoLabel, this));
|
||||
lay->addWidget(closeBtn, 0, Qt::AlignCenter);
|
||||
}
|
||||
setLayout(lay);
|
||||
lay->setSizeConstraint(QLayout::SetFixedSize);
|
||||
|
||||
connect(closeBtn, SIGNAL(clicked()), this, SLOT(accept()));
|
||||
}
|
||||
|
||||
PreferencesPopup::Display30bitChecker::~Display30bitChecker() {
|
||||
QSurfaceFormat::setDefaultFormat(m_currentDefaultFormat);
|
||||
}
|
||||
|
||||
//**********************************************************************************
|
||||
// PreferencesPopup implementation
|
||||
//**********************************************************************************
|
||||
|
@ -691,6 +774,13 @@ void PreferencesPopup::onLutPathChanged() {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void PreferencesPopup::onCheck30bitDisplay() {
|
||||
Display30bitChecker checker(this);
|
||||
checker.exec();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void PreferencesPopup::onAddLevelFormat() {
|
||||
bool ok = true;
|
||||
QString formatName = DVGui::getText(tr("New Level Format"),
|
||||
|
@ -1016,6 +1106,7 @@ QString PreferencesPopup::getUIString(PreferencesItemId id) {
|
|||
{colorCalibrationLutPaths,
|
||||
tr("3DLUT File for [%1]:")
|
||||
.arg(LutManager::instance()->getMonitorName())},
|
||||
{displayIn30bit, tr("30bit Display*")},
|
||||
{showIconsInMenu, tr("Show Icons In Menu*")},
|
||||
{viewerIndicatorEnabled, tr("Show Viewer Indicators")},
|
||||
|
||||
|
@ -1456,11 +1547,14 @@ QWidget* PreferencesPopup::createInterfacePage() {
|
|||
for (const QString& name : m_pref->getLanguageList())
|
||||
languageItemList.push_back(ComboBoxItem(name, name));
|
||||
|
||||
QPushButton* check30bitBtn = new QPushButton(tr("Check Availability"));
|
||||
|
||||
QWidget* widget = new QWidget(this);
|
||||
QGridLayout* lay = new QGridLayout();
|
||||
setupLayout(lay);
|
||||
|
||||
insertUI(CurrentStyleSheetName, lay, styleSheetItemList);
|
||||
int row = lay->rowCount();
|
||||
|
||||
// lay->addWidget(new QLabel(tr("Icon Theme*:"), this), 2, 0,
|
||||
// Qt::AlignRight | Qt::AlignVCenter);
|
||||
|
@ -1488,6 +1582,11 @@ QWidget* PreferencesPopup::createInterfacePage() {
|
|||
// insertUI(interfaceFontStyle, lay, buildFontStyleList());
|
||||
QGridLayout* colorCalibLay = insertGroupBoxUI(colorCalibrationEnabled, lay);
|
||||
{ insertUI(colorCalibrationLutPaths, colorCalibLay); }
|
||||
#if QT_VERSION >= 0x051000
|
||||
insertUI(displayIn30bit, lay);
|
||||
row = lay->rowCount();
|
||||
lay->addWidget(check30bitBtn, row - 1, 3);
|
||||
#endif
|
||||
// insertUI(showIconsInMenu, lay);
|
||||
|
||||
lay->setRowStretch(lay->rowCount(), 1);
|
||||
|
@ -1504,6 +1603,8 @@ QWidget* PreferencesPopup::createInterfacePage() {
|
|||
ret = ret && connect(TApp::instance()->getCurrentScene(),
|
||||
SIGNAL(pixelUnitSelected(bool)), this,
|
||||
SLOT(onPixelUnitExternallySelected(bool)));
|
||||
ret = ret && connect(check30bitBtn, SIGNAL(clicked()), this,
|
||||
SLOT(onCheck30bitDisplay()));
|
||||
assert(ret);
|
||||
|
||||
m_onEditedFuncMap.insert(CurrentStyleSheetName,
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
// Qt includes
|
||||
#include <QComboBox>
|
||||
#include <QFontComboBox>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QSurfaceFormat>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
//==============================================================
|
||||
|
||||
|
@ -65,6 +68,7 @@ public:
|
|||
|
||||
private:
|
||||
class FormatProperties;
|
||||
class Display30bitChecker;
|
||||
|
||||
private:
|
||||
Preferences* m_pref;
|
||||
|
@ -173,6 +177,7 @@ private slots:
|
|||
void onPixelUnitExternallySelected(bool on);
|
||||
void onInterfaceFontChanged(const QString& text);
|
||||
void onLutPathChanged();
|
||||
void onCheck30bitDisplay();
|
||||
|
||||
void onAddLevelFormat();
|
||||
void onRemoveLevelFormat();
|
||||
|
@ -212,4 +217,36 @@ private slots:
|
|||
void updateEnabledStatus();
|
||||
};
|
||||
|
||||
//**********************************************************************************
|
||||
// PreferencesPopup::Display30bitCheckerView definition
|
||||
//**********************************************************************************
|
||||
|
||||
class PreferencesPopup::Display30bitChecker final : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
QSurfaceFormat m_currentDefaultFormat;
|
||||
|
||||
private:
|
||||
class GLView;
|
||||
|
||||
public:
|
||||
Display30bitChecker(PreferencesPopup* parent);
|
||||
~Display30bitChecker();
|
||||
};
|
||||
|
||||
class PreferencesPopup::Display30bitChecker::GLView final
|
||||
: public QOpenGLWidget,
|
||||
protected QOpenGLFunctions {
|
||||
Q_OBJECT
|
||||
bool m_is30bit;
|
||||
|
||||
public:
|
||||
GLView(QWidget* parent, bool is30bit);
|
||||
|
||||
protected:
|
||||
void initializeGL() override;
|
||||
void resizeGL(int width, int height) override;
|
||||
void paintGL() override;
|
||||
};
|
||||
|
||||
#endif // PREFERENCESPOPUP_H
|
||||
|
|
|
@ -1070,7 +1070,9 @@ void PreviewFxInstance::doOnRenderRasterCompleted(
|
|||
/*-- 16bpcで計算された場合、結果をDitheringする --*/
|
||||
TRasterP rasA = renderData.m_rasA;
|
||||
TRasterP rasB = renderData.m_rasB;
|
||||
if (rasA->getPixelSize() == 8) // render in 64 bits
|
||||
// dither the 16bpc image IF the "30bit display" prefernce option is OFF
|
||||
if (rasA->getPixelSize() == 8 &&
|
||||
!Preferences::instance()->is30bitDisplayEnabled()) // render in 64 bits
|
||||
{
|
||||
TRaster32P auxA(rasA->getLx(), rasA->getLy());
|
||||
TRop::convert(auxA, rasA); // dithering
|
||||
|
|
|
@ -835,6 +835,10 @@ SceneViewer::SceneViewer(ImageUtils::FullScreenWidget *parent)
|
|||
|
||||
if (Preferences::instance()->isColorCalibrationEnabled())
|
||||
m_lutCalibrator = new LutCalibrator();
|
||||
#if QT_VERSION >= 0x051000
|
||||
if (Preferences::instance()->is30bitDisplayEnabled())
|
||||
setTextureFormat(TGL_TexFmt10);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1220,8 +1224,14 @@ void SceneViewer::onPreferenceChanged(const QString &prefName) {
|
|||
m_lutCalibrator->initialize();
|
||||
connect(context(), SIGNAL(aboutToBeDestroyed()), this,
|
||||
SLOT(onContextAboutToBeDestroyed()));
|
||||
if (m_lutCalibrator->isValid() && !m_fbo)
|
||||
if (m_lutCalibrator->isValid() && !m_fbo) {
|
||||
if (Preferences::instance()->is30bitDisplayEnabled()) {
|
||||
QOpenGLFramebufferObjectFormat format;
|
||||
format.setInternalTextureFormat(TGL_TexFmt10);
|
||||
m_fbo = new QOpenGLFramebufferObject(width(), height(), format);
|
||||
} else // normally, initialize with GL_RGBA8 format
|
||||
m_fbo = new QOpenGLFramebufferObject(width(), height());
|
||||
}
|
||||
doneCurrent();
|
||||
}
|
||||
update();
|
||||
|
@ -1279,6 +1289,11 @@ void SceneViewer::resizeGL(int w, int h) {
|
|||
// remake fbo with new size
|
||||
if (m_lutCalibrator && m_lutCalibrator->isValid()) {
|
||||
if (m_fbo) delete m_fbo;
|
||||
if (Preferences::instance()->is30bitDisplayEnabled()) {
|
||||
QOpenGLFramebufferObjectFormat format;
|
||||
format.setInternalTextureFormat(TGL_TexFmt10);
|
||||
m_fbo = new QOpenGLFramebufferObject(w, h, format);
|
||||
} else // normally, initialize with GL_RGBA8 format
|
||||
m_fbo = new QOpenGLFramebufferObject(w, h);
|
||||
}
|
||||
|
||||
|
|
|
@ -363,7 +363,8 @@ void Painter::doFlushRasterImages(const TRasterP &rin, int bg,
|
|||
TRect rect(tfloor(bbox.x0), tfloor(bbox.y0), tceil(bbox.x1), tceil(bbox.y1));
|
||||
if (rect.isEmpty()) return;
|
||||
|
||||
TRaster32P ras;
|
||||
TRasterP ras;
|
||||
// TRaster32P ras;
|
||||
TRasterP _rin = rin;
|
||||
TAffine aff;
|
||||
if (m_vSettings.m_useTexture) {
|
||||
|
@ -398,6 +399,17 @@ void Painter::doFlushRasterImages(const TRasterP &rin, int bg,
|
|||
// a quickput approximation?
|
||||
}
|
||||
|
||||
// when the "30bit display" preference option is enabled,
|
||||
// image previewed in 16bpc is not dithered & converted to 8bpc,
|
||||
// but is kept the channel depth as 16bpc.
|
||||
bool is16bpc = false;
|
||||
if (_rin->getPixelSize() == 8) {
|
||||
TRaster64P rasAux(ras->getLx(), ras->getLy());
|
||||
TRop::convert(rasAux, ras);
|
||||
ras = rasAux;
|
||||
is16bpc = true;
|
||||
}
|
||||
|
||||
ras->lock();
|
||||
|
||||
bool showChannelsOnMatte =
|
||||
|
@ -433,9 +445,14 @@ void Painter::doFlushRasterImages(const TRasterP &rin, int bg,
|
|||
// Image size is a 0 point. Do nothing
|
||||
if (rect.x0 == rect.x1 && rect.y0 == rect.y1) return;
|
||||
|
||||
if (is16bpc) {
|
||||
TRaster64P raux = ras->extract(rect);
|
||||
raux->fill(bg == 0x40000 ? TPixel64::Black : TPixel64::White);
|
||||
} else {
|
||||
TRaster32P raux = ras->extract(rect);
|
||||
raux->fill(bg == 0x40000 ? TPixel::Black : TPixel::White);
|
||||
}
|
||||
}
|
||||
|
||||
if (showChannelsOnMatte)
|
||||
quickput(ras, keepChannels(_rin, m_palette, chan), m_palette,
|
||||
|
@ -463,8 +480,9 @@ void Painter::doFlushRasterImages(const TRasterP &rin, int bg,
|
|||
glRasterPos2d(rect.x0, rect.y0);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
|
||||
glDrawPixels(ras->getWrap(), ras->getLy(), TGL_FMT, TGL_TYPE,
|
||||
ras->getRawData());
|
||||
glDrawPixels(ras->getWrap(), ras->getLy(), TGL_FMT,
|
||||
(is16bpc) ? TGL_TYPE16 : TGL_TYPE,
|
||||
(GLvoid *)ras->getRawData());
|
||||
|
||||
CHECK_ERRORS_BY_GL
|
||||
|
||||
|
@ -657,7 +675,8 @@ void ImagePainter::paintImage(const TImageP &image, const TDimension &imageSize,
|
|||
// be done on black bg!
|
||||
if (!vimg)
|
||||
painter.flushRasterImages(
|
||||
loadbox, visualSettings.m_doCompare ? compareSettings.m_compareX
|
||||
loadbox,
|
||||
visualSettings.m_doCompare ? compareSettings.m_compareX
|
||||
: DefaultCompareValue,
|
||||
visualSettings.m_doCompare ? compareSettings.m_compareY
|
||||
: DefaultCompareValue,
|
||||
|
|
|
@ -439,6 +439,7 @@ void Preferences::definePreferenceItems() {
|
|||
false);
|
||||
define(colorCalibrationLutPaths, "colorCalibrationLutPaths",
|
||||
QMetaType::QVariantMap, QVariantMap());
|
||||
define(displayIn30bit, "displayIn30bit", QMetaType::Bool, false);
|
||||
|
||||
// hide menu icons by default in macOS since the icon color may not match with
|
||||
// the system color theme
|
||||
|
|
Loading…
Reference in a new issue