Fixed crash and add suppress bad message in history and mip in cache

This commit is contained in:
Desmis 2017-02-14 08:09:42 +01:00
commit 161a56eec5
43 changed files with 1900 additions and 872 deletions

View File

@ -40,5 +40,5 @@ http://rawpedia.rawtherapee.com/Linux
Windows:
http://rawpedia.rawtherapee.com/Windows
OS X:
macOS:
http://rawpedia.rawtherapee.com/macOS

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -741,6 +741,7 @@ HISTORY_MSG_506;Local - Denoise
HISTORY_MSG_507;Local - LH Curve
HISTORY_MSG_508;Local - Enable super
HISTORY_MSG_509;Local - CC curve
HISTORY_MSG_510;Local - curve method
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
HISTORY_SNAPSHOT;Snapshot

View File

@ -11,6 +11,7 @@
/*RT*/#define DJGPP
#include "opthelper.h"
/*
dcraw.c -- Dave Coffin's raw photo decoder
Copyright 1997-2016 by Dave Coffin, dcoffin a cybercom o net
@ -6264,6 +6265,7 @@ void CLASS apply_tiff()
tile_width = tiff_ifd[i].tile_width;
tile_length = tiff_ifd[i].tile_length;
shutter = tiff_ifd[i].shutter;
raw_size = tiff_ifd[i].bytes;
raw = i;
}
}
@ -9016,6 +9018,9 @@ canon_a5:
if (filters == 9)
FORC(36) ((char *)xtrans)[c] =
xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6];
if(filters == 9 && raw_height * raw_width * 2 != raw_size) {
xtransCompressed = true;
}
} else if (!strcmp(model,"KD-400Z")) {
height = 1712;
width = 2312;
@ -9865,6 +9870,8 @@ struct tiff_hdr {
char desc[512], make[64], model[64], soft[32], date[20], artist[64];
};
#include "xtranscompressed.cc"
/* RT: Delete from here */
/*RT*/#undef SQR
/*RT*/#undef MAX

View File

@ -89,8 +89,51 @@ protected:
unsigned black, cblack[4102], maximum, mix_green, raw_color, zero_is_bad;
unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error;
unsigned tile_width, tile_length, gpsdata[32], load_flags;
bool xtransCompressed = false;
struct xtrans_params
{
char *q_table; /* quantization table */
int q_point[5]; /* quantization points */
int max_bits;
int min_value;
int raw_bits;
int total_values;
int maxDiff;
ushort line_width;
};
struct int_pair {
int value1;
int value2;
};
enum _xt_lines
{
_R0=0,_R1,_R2,_R3,_R4,
_G0,_G1,_G2,_G3,_G4,_G5,_G6,_G7,
_B0,_B1,_B2,_B3,_B4,
_ltotal
};
struct xtrans_block {
int cur_bit; // current bit being read (from left to right)
int cur_pos; // current position in a buffer
INT64 cur_buf_offset; // offset of this buffer in a file
unsigned max_read_size; // Amount of data to be read
int cur_buf_size; // buffer size
uchar *cur_buf; // currently read block
IMFILE *input;
struct int_pair grad_even[3][41]; // tables of gradients
struct int_pair grad_odd[3][41];
ushort *linealloc;
ushort *linebuf[_ltotal];
};
int fuji_total_lines, fuji_total_blocks, fuji_block_width, fuji_bits;
ushort raw_height, raw_width, height, width, top_margin, left_margin;
ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height;
unsigned raw_size;
ushort *raw_image;
float * float_raw_image;
ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4];
@ -226,6 +269,25 @@ void adobe_copy_pixel (unsigned row, unsigned col, ushort **rp);
void lossless_dng_load_raw();
void packed_dng_load_raw();
void deflate_dng_load_raw();
void init_xtrans(struct xtrans_params* info);
void fuji_fill_buffer(struct xtrans_block *info);
void init_xtrans_block(struct xtrans_block* info, const struct xtrans_params *params, INT64 raw_offset, unsigned dsize);
void copy_line_to_xtrans(struct xtrans_block* info, int cur_line, int cur_block, int cur_block_width);
void fuji_zerobits(struct xtrans_block* info, int *count);
void fuji_read_code(struct xtrans_block* info, int *data, int bits_to_read);
int bitDiff(int value1, int value2);
int fuji_decode_sample_even(struct xtrans_block* info, const struct xtrans_params * params, ushort* line_buf, int pos, struct int_pair* grads);
int fuji_decode_sample_odd(struct xtrans_block* info, const struct xtrans_params * params, ushort* line_buf, int pos, struct int_pair* grads);
void fuji_decode_interpolation_even(int line_width, ushort* line_buf, int pos);
void xtrans_extend_generic(ushort *linebuf[_ltotal], int line_width, int start, int end);
void xtrans_extend_red(ushort *linebuf[_ltotal], int line_width);
void xtrans_extend_green(ushort *linebuf[_ltotal], int line_width);
void xtrans_extend_blue(ushort *linebuf[_ltotal], int line_width);
void xtrans_decode_block(struct xtrans_block* info, const struct xtrans_params *params, int cur_line);
void xtrans_decode_strip(const struct xtrans_params* info_common, int cur_block, INT64 raw_offset, unsigned dsize);
void xtrans_compressed_load_raw();
void xtrans_decode_loop(const struct xtrans_params* common_info, int count, INT64* raw_block_offsets, unsigned *block_sizes);
void parse_xtrans_header();
void pentax_load_raw();
void nikon_load_raw();
int nikon_is_compressed();

View File

@ -28,7 +28,19 @@
#include <unistd.h>
//#include <chrono>
// "ceil" rounding
#define SKIPS(a,b) ((a) / (b) + ((a) % (b) > 0))
//#define SKIPS(a,b) ((a) / (b) + ((a) % (b) > 0))
namespace
{
// "ceil" rounding
template<typename T>
constexpr T skips (T a, T b)
{
return a / b + static_cast<bool> (a % b);
}
}
namespace rtengine
{
@ -37,8 +49,8 @@ extern const Settings* settings;
Crop::Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow)
: PipetteBuffer (editDataProvider), origCrop (nullptr), laboCrop (nullptr), labnCrop (nullptr),
cropImg (nullptr), cbuf_real (nullptr), shbuf_real (nullptr), cshmap (nullptr), transCrop (nullptr), cieCrop (nullptr), cbuffer (nullptr), shbuffer (nullptr),
updating (false), newUpdatePending (false), skip (10), padding (0),
cropImg (nullptr), cbuf_real (nullptr), shbuf_real (nullptr), cshmap (nullptr), transCrop (nullptr), cieCrop (nullptr), cbuffer (nullptr), shbuffer (nullptr),
updating (false), newUpdatePending (false), skip (10),
cropx (0), cropy (0), cropw (-1), croph (-1),
trafx (0), trafy (0), trafw (-1), trafh (-1),
rqcropx (0), rqcropy (0), rqcropw (-1), rqcroph (-1),
@ -116,6 +128,12 @@ void Crop::setEditSubscriber (EditSubscriber* newSubscriber)
// If oldSubscriber == NULL && newSubscriber != NULL && newSubscriber->getEditingType() == ET_PIPETTE-> the image will be allocated when necessary
}
bool Crop::hasListener()
{
MyMutex::MyLock cropLock (cropMutex);
return cropImageListener;
}
void Crop::update (int todo)
{
MyMutex::MyLock cropLock (cropMutex);
@ -690,7 +708,7 @@ void Crop::update (int todo)
}
if (needstransform)
parent->ipf.transform (baseCrop, transCrop, cropx / skip, cropy / skip, trafx / skip, trafy / skip, SKIPS (parent->fw, skip), SKIPS (parent->fh, skip), parent->getFullWidth(), parent->getFullHeight(),
parent->ipf.transform (baseCrop, transCrop, cropx / skip, cropy / skip, trafx / skip, trafy / skip, skips (parent->fw, skip), skips (parent->fh, skip), parent->getFullWidth(), parent->getFullHeight(),
parent->imgsrc->getMetaData()->getFocalLen(), parent->imgsrc->getMetaData()->getFocalLen35mm(),
parent->imgsrc->getMetaData()->getFocusDist(), parent->imgsrc->getRotateDegree(), false);
else {
@ -721,7 +739,7 @@ void Crop::update (int todo)
// blurmap for shadow & highlights
if ((todo & M_BLURMAP) && params.sh.enabled) {
double radius = sqrt (double (SKIPS (parent->fw, skip) * SKIPS (parent->fw, skip) + SKIPS (parent->fh, skip) * SKIPS (parent->fh, skip))) / 2.0;
double radius = sqrt (double (skips (parent->fw, skip) * skips (parent->fw, skip) + skips (parent->fh, skip) * skips (parent->fh, skip))) / 2.0;
double shradius = params.sh.radius;
if (!params.sh.hq) {
@ -817,7 +835,8 @@ void Crop::update (int todo)
if (needslocal ) {
// if (tyty ) {
//Glib::ustring datalab2 = parent->imgsrc->getFileName() + ".mip";
Glib::ustring pop = options.getUserProfilePath() + "/";
// Glib::ustring pop = options.getUserProfilePath() + "/";
Glib::ustring pop = options.cacheBaseDir + "/mip/";
Glib::ustring datalab;
@ -1011,7 +1030,7 @@ void Crop::update (int todo)
params.locallab.chromaref = parent->chromarefs[sp];
params.locallab.lumaref = parent->lumarefs[sp];
parent->ipf.Lab_Local (1, sp, (float**)shbuffer, labnCrop, labnCrop, trafx / skip, trafy / skip, cropx / skip, cropy / skip, SKIPS (parent->fw, skip), SKIPS (parent->fh, skip), parent->fw, parent->fh, locutili, skip, locRETgainCurve, locallutili, lllocalcurve2, loclhCurve, cclocalcurve2, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref);
parent->ipf.Lab_Local (1, sp, (float**)shbuffer, labnCrop, labnCrop, trafx / skip, trafy / skip, cropx / skip, cropy / skip, skips (parent->fw, skip), skips (parent->fh, skip), parent->fw, parent->fh, locutili, skip, locRETgainCurve, locallutili, lllocalcurve2, loclhCurve, cclocalcurve2, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref);
lllocalcurve2.clear();
cclocalcurve2.clear();
@ -1247,7 +1266,7 @@ void Crop::update (int todo)
params.locallab.chromaref = parent->chromarefs[sp];
params.locallab.lumaref = parent->lumarefs[sp];
parent->ipf.Lab_Local (1, sp, (float**)shbuffer, labnCrop, labnCrop, trafx / skip, trafy / skip, cropx / skip, cropy / skip, SKIPS (parent->fw, skip), SKIPS (parent->fh, skip), parent->getFullWidth(), parent->getFullHeight(), locutili2, skip, locRETgainCurve, locallutili, lllocalcurve2, loclhCurve, cclocalcurve2, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref);
parent->ipf.Lab_Local (1, sp, (float**)shbuffer, labnCrop, labnCrop, trafx / skip, trafy / skip, cropx / skip, cropy / skip, skips (parent->fw, skip), skips (parent->fh, skip), parent->getFullWidth(), parent->getFullHeight(), locutili2, skip, locRETgainCurve, locallutili, lllocalcurve2, loclhCurve, cclocalcurve2, params.locallab.hueref, params.locallab.chromaref, params.locallab.lumaref);
lllocalcurve2.clear();
cclocalcurve2.clear();
@ -1590,12 +1609,11 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte
PreviewProps cp (orx, ory, orw, orh, skip);
int orW, orH;
parent->imgsrc->getSize (cp, orW, orH);
int cw = skips (bw, skip);
int ch = skips (bh, skip);
int cw = SKIPS (bw, skip);
int ch = SKIPS (bh, skip);
leftBorder = SKIPS (rqx1 - bx1, skip);
upperBorder = SKIPS (rqy1 - by1, skip);
leftBorder = skips (rqx1 - bx1, skip);
upperBorder = skips (rqy1 - by1, skip);
if (settings->verbose) {
printf ("setsizes starts (%d, %d, %d, %d, %d, %d)\n", orW, orH, trafw, trafh, cw, ch);
@ -1787,5 +1805,22 @@ void Crop::fullUpdate ()
parent->updaterThreadStart.unlock ();
}
int Crop::get_skip()
{
MyMutex::MyLock lock (cropMutex);
return skip;
}
int Crop::getLeftBorder()
{
MyMutex::MyLock lock (cropMutex);
return leftBorder;
}
int Crop::getUpperBorder()
{
MyMutex::MyLock lock (cropMutex);
return upperBorder;
}
}

View File

@ -16,8 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CROP_H_
#define _CROP_H_
#pragma once
#include "improccoordinator.h"
#include "rtengine.h"
@ -59,19 +58,18 @@ protected:
bool updating; /// Flag telling if an updater thread is currently processing
bool newUpdatePending; /// Flag telling the updater thread that a new update is pending
int skip;
int padding; /// Minimum space allowed around image in the display area
int cropx, cropy, cropw, croph; /// size of the detail crop image ('skip' taken into account), with border
int trafx, trafy, trafw, trafh; /// the size and position to get from the imagesource that is transformed to the requested crop area
int rqcropx, rqcropy, rqcropw, rqcroph; /// size of the requested detail crop image (the image might be smaller) (without border)
int borderRequested; /// requested extra border size for image processing
const int borderRequested; /// requested extra border size for image processing
int upperBorder, leftBorder; /// extra border size really allocated for image processing
bool cropAllocated;
DetailedCropListener* cropImageListener;
MyMutex cropMutex;
ImProcCoordinator* parent;
bool isDetailWindow;
ImProcCoordinator* const parent;
const bool isDetailWindow;
EditUniqueID getCurrEditID();
bool setCropSizes (int cropX, int cropY, int cropW, int cropH, int skip, bool internal);
void freeAll ();
@ -80,20 +78,8 @@ public:
Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow);
virtual ~Crop ();
// MyMutex* locMutex;
void mLock ()
{
cropMutex.lock();
}
void mUnlock ()
{
cropMutex.lock();
}
void setEditSubscriber (EditSubscriber* newSubscriber);
bool hasListener ()
{
return cropImageListener;
}
bool hasListener();
void update (int todo);
void setWindow (int cropX, int cropY, int cropW, int cropH, int skip)
{
@ -109,22 +95,8 @@ public:
void setListener (DetailedCropListener* il);
void destroy ();
int get_skip ()
{
return skip;
}
int getPadding ()
{
return padding;
}
int getLeftBorder ()
{
return leftBorder;
}
int getUpperBorder ()
{
return upperBorder;
}
int get_skip();
int getLeftBorder();
int getUpperBorder();
};
}
#endif

View File

@ -739,7 +739,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall)
}
// printf("mip file=%s \n", datalab.c_str());
Glib::ustring pop = options.getUserProfilePath() + "/";
// Glib::ustring pop = options.getUserProfilePath() + "/";
Glib::ustring pop = options.cacheBaseDir + "/mip/";
Glib::ustring datal;

View File

@ -69,7 +69,7 @@
#define ALIGNED64
#define ALIGNED16
#endif
#if !defined(__clang__) && defined _OPENMP
#if defined _OPENMP
#define _RT_NESTED_OPENMP
#endif
#endif

View File

@ -435,6 +435,10 @@ int RawImage::loadRaw (bool loadData, bool closeFile, ProgressListener *plistene
return 2;
}
if(xtransCompressed) {
parse_xtrans_header();
}
if (flip == 5) {
this->rotate_deg = 270;
} else if (flip == 3) {

View File

@ -949,7 +949,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
//Glib::ustring datalab = imgsrc->getFileName() + ".mip";
Glib::ustring pop = options.getUserProfilePath() + "/";
// Glib::ustring pop = options.getUserProfilePath() + "/";
Glib::ustring pop = options.cacheBaseDir + "/mip/";
Glib::ustring datalab;
if (options.mip == MI_opt) {

View File

@ -0,0 +1,800 @@
/* -*- C++ -*-
* File: xtranscompressed.cpp
* Copyright (C) 2016 Alexey Danilchenko
*
* Adopted to LibRaw by Alex Tutubalin, lexa@lexa.ru
* LibRaw Fujifilm/compressed decoder
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of three licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
* Adopted to RawTherapee by Ingo Weyrich
*/
void CLASS init_xtrans (struct xtrans_params* info)
{
int cur_val, i;
char *qt;
if (fuji_block_width % 3) {
derror();
}
info->q_table = (char *) malloc (32768);
merror (info->q_table, "init_xtrans()");
info->line_width = (fuji_block_width * 2) / 3;
info->q_point[0] = 0;
info->q_point[1] = 0x12;
info->q_point[2] = 0x43;
info->q_point[3] = 0x114;
info->q_point[4] = (1 << fuji_bits) - 1;
info->min_value = 0x40;
cur_val = -info->q_point[4];
for (qt = info->q_table; cur_val <= info->q_point[4]; ++qt, ++cur_val) {
if (cur_val <= -info->q_point[3]) {
*qt = -4;
} else if (cur_val <= -info->q_point[2]) {
*qt = -3;
} else if (cur_val <= -info->q_point[1]) {
*qt = -2;
} else if (cur_val < 0) {
*qt = -1;
} else if (cur_val == 0) {
*qt = 0;
} else if (cur_val < info->q_point[1]) {
*qt = 1;
} else if (cur_val < info->q_point[2]) {
*qt = 2;
} else if (cur_val < info->q_point[3]) {
*qt = 3;
} else {
*qt = 4;
}
}
// populting gradients
if (info->q_point[4] == 0x3FFF) {
info->total_values = 0x4000;
info->raw_bits = 14;
info->max_bits = 56;
info->maxDiff = 256;
} else if (info->q_point[4] == 0xFFF) {
info->total_values = 4096;
info->raw_bits = 12;
info->max_bits = 48;
info->maxDiff = 64;
} else {
derror();
}
}
#define XTRANS_BUF_SIZE 0x10000u
void CLASS fuji_fill_buffer (struct xtrans_block *info)
{
if (info->cur_pos >= info->cur_buf_size) {
info->cur_pos = 0;
info->cur_buf_offset += info->cur_buf_size;
#ifdef _OPENMP
#pragma omp critical
#endif
{
fseek (info->input, info->cur_buf_offset, SEEK_SET);
info->cur_buf_size = fread (info->cur_buf, 1, std::min (info->max_read_size, XTRANS_BUF_SIZE), info->input);
}
if (info->cur_buf_size < 1) // nothing read
;//throw LIBRAW_EXCEPTION_IO_EOF;
info->max_read_size -= info->cur_buf_size;
}
}
void CLASS init_xtrans_block (struct xtrans_block* info, const struct xtrans_params *params, INT64 raw_offset, unsigned dsize)
{
info->linealloc = (ushort*)calloc (sizeof (ushort), _ltotal * (params->line_width + 2));
merror (info->linealloc, "init_xtrans_block()");
info->input = ifp;
INT64 fsize = info->input->size;
info->max_read_size = std::min (unsigned (fsize - raw_offset), dsize + 16); // Data size may be incorrect?
info->linebuf[_R0] = info->linealloc;
for (int i = _R1; i <= _B4; i++) {
info->linebuf[i] = info->linebuf[i - 1] + params->line_width + 2;
}
// init buffer
info->cur_buf = (uchar*)malloc (XTRANS_BUF_SIZE);
merror (info->cur_buf, "init_xtrans_block()");
info->cur_bit = 0;
info->cur_pos = 0;
info->cur_buf_offset = raw_offset;
for (int j = 0; j < 3; j++)
for (int i = 0; i < 41; i++) {
info->grad_even[j][i].value1 = params->maxDiff;
info->grad_even[j][i].value2 = 1;
info->grad_odd[j][i].value1 = params->maxDiff;
info->grad_odd[j][i].value2 = 1;
}
info->cur_buf_size = 0;
fuji_fill_buffer (info);
}
void CLASS copy_line_to_xtrans (struct xtrans_block* info, int cur_line, int cur_block, int cur_block_width)
{
ushort *lineBufB[3];
ushort *lineBufG[6];
ushort *lineBufR[3];
unsigned pixel_count;
ushort* line_buf;
int index;
int offset = fuji_block_width * cur_block + 6 * raw_width * cur_line;
ushort* raw_block_data = raw_image + offset;
int row_count = 0;
for (int i = 0; i < 3; i++) {
lineBufR[i] = info->linebuf[_R2 + i] + 1;
lineBufB[i] = info->linebuf[_B2 + i] + 1;
}
for (int i = 0; i < 6; i++) {
lineBufG[i] = info->linebuf[_G2 + i] + 1;
}
while (row_count < 6) {
pixel_count = 0;
while (pixel_count < cur_block_width) {
switch (xtrans_abs[row_count][ (pixel_count % 6)]) {
case 0: // red
line_buf = lineBufR[row_count >> 1];
break;
case 1: // green
line_buf = lineBufG[row_count];
break;
case 2: // blue
line_buf = lineBufB[row_count >> 1];
break;
}
index = (((pixel_count * 2 / 3) & 0x7FFFFFFE) | (pixel_count % 3) & 1) + ((pixel_count % 3) >> 1);
raw_block_data[pixel_count] = line_buf[index];
++pixel_count;
}
++row_count;
raw_block_data += raw_width;
}
}
#define fuji_quant_gradient(i,v1,v2) (9*i->q_table[i->q_point[4]+(v1)] + i->q_table[i->q_point[4]+(v2)])
void CLASS fuji_zerobits (struct xtrans_block* info, int *count)
{
uchar zero = 0;
*count = 0;
while (zero == 0) {
zero = (info->cur_buf[info->cur_pos] >> (7 - info->cur_bit)) & 1;
info->cur_bit++;
info->cur_bit &= 7;
if (!info->cur_bit) {
++info->cur_pos;
fuji_fill_buffer (info);
}
if (zero) {
break;
}
++*count;
}
}
void CLASS fuji_read_code (struct xtrans_block* info, int *data, int bits_to_read)
{
uchar bits_left = bits_to_read;
uchar bits_left_in_byte = 8 - (info->cur_bit & 7);
*data = 0;
if (!bits_to_read) {
return;
}
if (bits_to_read >= bits_left_in_byte) {
do {
*data <<= bits_left_in_byte;
bits_left -= bits_left_in_byte;
*data |= info->cur_buf[info->cur_pos] & ((1 << bits_left_in_byte) - 1);
++info->cur_pos;
fuji_fill_buffer (info);
bits_left_in_byte = 8;
} while (bits_left >= 8);
}
if (!bits_left) {
info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7;
return;
}
*data <<= bits_left;
bits_left_in_byte -= bits_left;
*data |= ((1 << bits_left) - 1) & ((unsigned)info->cur_buf[info->cur_pos] >> bits_left_in_byte);
info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7;
}
int CLASS bitDiff (int value1, int value2)
{
int decBits = 0;
if ( value2 < value1 )
while (decBits <= 12 && (value2 << ++decBits) < value1)
;
return decBits;
}
int CLASS fuji_decode_sample_even (struct xtrans_block* info, const struct xtrans_params * params, ushort* line_buf, int pos, struct int_pair* grads)
{
int interp_val = 0;
int errcnt = 0;
int sample = 0, code = 0;
ushort* line_buf_cur = line_buf + pos;
int Rb = line_buf_cur[-2 - params->line_width];
int Rc = line_buf_cur[-3 - params->line_width];
int Rd = line_buf_cur[-1 - params->line_width];
int Rf = line_buf_cur[-4 - 2 * params->line_width];
int grad, gradient, diffRcRb, diffRfRb, diffRdRb;
grad = fuji_quant_gradient (params, Rb - Rf, Rc - Rb);
gradient = std::abs (grad);
diffRcRb = std::abs (Rc - Rb);
diffRfRb = std::abs (Rf - Rb);
diffRdRb = std::abs (Rd - Rb);
if ( diffRcRb > diffRfRb && diffRcRb > diffRdRb ) {
interp_val = Rf + Rd + 2 * Rb;
} else if ( diffRdRb > diffRcRb && diffRdRb > diffRfRb ) {
interp_val = Rf + Rc + 2 * Rb;
} else {
interp_val = Rd + Rc + 2 * Rb;
}
fuji_zerobits (info, &sample);
if (sample < params->max_bits - params->raw_bits - 1) {
int decBits = bitDiff (grads[gradient].value1, grads[gradient].value2);
fuji_read_code (info, &code, decBits);
code += sample << decBits;
} else {
fuji_read_code (info, &code, params->raw_bits);
code++;
}
if (code < 0 || code >= params->total_values) {
errcnt++;
}
if (code & 1) {
code = -1 - code / 2;
} else {
code /= 2;
}
grads[gradient].value1 += std::abs (code);
if (grads[gradient].value2 == params->min_value ) {
grads[gradient].value1 >>= 1;
grads[gradient].value2 >>= 1;
}
grads[gradient].value2++;
if (grad < 0) {
interp_val = (interp_val >> 2) - code;
} else {
interp_val = (interp_val >> 2) + code;
}
if ( interp_val < 0 ) {
interp_val += params->total_values;
} else if (interp_val > params->q_point[4]) {
interp_val -= params->total_values;
}
if ( interp_val >= 0 ) {
line_buf_cur[0] = std::min (interp_val, params->q_point[4]);
} else {
line_buf_cur[0] = 0;
}
return errcnt;
}
int CLASS fuji_decode_sample_odd (struct xtrans_block* info, const struct xtrans_params * params, ushort* line_buf, int pos, struct int_pair* grads)
{
int interp_val = 0;
int errcnt = 0;
int sample = 0, code = 0;
ushort* line_buf_cur = line_buf + pos;
int Ra = line_buf_cur[-1];
int Rb = line_buf_cur[-2 - params->line_width];
int Rc = line_buf_cur[-3 - params->line_width];
int Rd = line_buf_cur[-1 - params->line_width];
int Rg = line_buf_cur[1];
int grad, gradient;
grad = fuji_quant_gradient (params, Rb - Rc, Rc - Ra);
gradient = std::abs (grad);
if ((Rb > Rc && Rb > Rd) || (Rb < Rc && Rb < Rd)) {
interp_val = (Rg + Ra + 2 * Rb) >> 2;
} else {
interp_val = (Ra + Rg) >> 1;
}
fuji_zerobits (info, &sample);
if (sample < params->max_bits - params->raw_bits - 1) {
int decBits = bitDiff (grads[gradient].value1, grads[gradient].value2);
fuji_read_code (info, &code, decBits);
code += sample << decBits;
} else {
fuji_read_code (info, &code, params->raw_bits);
code++;
}
if (code < 0 || code >= params->total_values) {
errcnt++;
}
if (code & 1) {
code = -1 - code / 2;
} else {
code /= 2;
}
grads[gradient].value1 += std::abs (code);
if (grads[gradient].value2 == params->min_value) {
grads[gradient].value1 >>= 1;
grads[gradient].value2 >>= 1;
}
grads[gradient].value2++;
if (grad < 0) {
interp_val -= code;
} else {
interp_val += code;
}
if ( interp_val < 0 ) {
interp_val += params->total_values;
} else if (interp_val > params->q_point[4]) {
interp_val -= params->total_values;
}
if ( interp_val >= 0 ) {
line_buf_cur[0] = std::min(interp_val, params->q_point[4]);
} else {
line_buf_cur[0] = 0;
}
return errcnt;
}
void CLASS fuji_decode_interpolation_even (int line_width, ushort* line_buf, int pos)
{
ushort* line_buf_cur = line_buf + pos;
int Rb = line_buf_cur[-2 - line_width];
int Rc = line_buf_cur[-3 - line_width];
int Rd = line_buf_cur[-1 - line_width];
int Rf = line_buf_cur[-4 - 2 * line_width];
int diffRcRb = std::abs (Rc - Rb);
int diffRfRb = std::abs (Rf - Rb);
int diffRdRb = std::abs (Rd - Rb);
if ( diffRcRb > diffRfRb && diffRcRb > diffRdRb ) {
*line_buf_cur = (Rf + Rd + 2 * Rb) >> 2;
} else if ( diffRdRb > diffRcRb && diffRdRb > diffRfRb ) {
*line_buf_cur = (Rf + Rc + 2 * Rb) >> 2;
} else {
*line_buf_cur = (Rd + Rc + 2 * Rb) >> 2;
}
}
void CLASS xtrans_extend_generic (ushort *linebuf[_ltotal], int line_width, int start, int end)
{
for (int i = start; i <= end; i++) {
linebuf[i][0] = linebuf[i - 1][1];
linebuf[i][line_width + 1] = linebuf[i - 1][line_width];
}
}
void CLASS xtrans_extend_red (ushort *linebuf[_ltotal], int line_width)
{
xtrans_extend_generic (linebuf, line_width, _R2, _R4);
}
void CLASS xtrans_extend_green (ushort *linebuf[_ltotal], int line_width)
{
xtrans_extend_generic (linebuf, line_width, _G2, _G7);
}
void CLASS xtrans_extend_blue (ushort *linebuf[_ltotal], int line_width)
{
xtrans_extend_generic (linebuf, line_width, _B2, _B4);
}
void CLASS xtrans_decode_block (struct xtrans_block* info, const struct xtrans_params *params, int cur_line)
{
int r_even_pos = 0, r_odd_pos = 1;
int g_even_pos = 0, g_odd_pos = 1;
int b_even_pos = 0, b_odd_pos = 1;
int errcnt = 0;
const int line_width = params->line_width;
while (g_even_pos < line_width || g_odd_pos < line_width) {
if (g_even_pos < line_width) {
fuji_decode_interpolation_even (line_width, info->linebuf[_R2] + 1, r_even_pos);
r_even_pos += 2;
errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G2] + 1, g_even_pos, info->grad_even[0]);
g_even_pos += 2;
}
if (g_even_pos > 8) {
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R2] + 1, r_odd_pos, info->grad_odd[0]);
r_odd_pos += 2;
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G2] + 1, g_odd_pos, info->grad_odd[0]);
g_odd_pos += 2;
}
}
xtrans_extend_red (info->linebuf, line_width);
xtrans_extend_green (info->linebuf, line_width);
g_even_pos = 0, g_odd_pos = 1;
while (g_even_pos < line_width || g_odd_pos < line_width) {
if (g_even_pos < line_width) {
errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G3] + 1, g_even_pos, info->grad_even[1]);
g_even_pos += 2;
fuji_decode_interpolation_even (line_width, info->linebuf[_B2] + 1, b_even_pos);
b_even_pos += 2;
}
if (g_even_pos > 8) {
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G3] + 1, g_odd_pos, info->grad_odd[1]);
g_odd_pos += 2;
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B2] + 1, b_odd_pos, info->grad_odd[1]);
b_odd_pos += 2;
}
}
xtrans_extend_green (info->linebuf, line_width);
xtrans_extend_blue (info->linebuf, line_width);
r_even_pos = 0, r_odd_pos = 1;
g_even_pos = 0, g_odd_pos = 1;
while (g_even_pos < line_width || g_odd_pos < line_width) {
if (g_even_pos < line_width) {
if (r_even_pos & 3) {
errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R3] + 1, r_even_pos, info->grad_even[2]);
} else {
fuji_decode_interpolation_even (line_width, info->linebuf[_R3] + 1, r_even_pos);
}
r_even_pos += 2;
fuji_decode_interpolation_even (line_width, info->linebuf[_G4] + 1, g_even_pos);
g_even_pos += 2;
}
if (g_even_pos > 8) {
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R3] + 1, r_odd_pos, info->grad_odd[2]);
r_odd_pos += 2;
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G4] + 1, g_odd_pos, info->grad_odd[2]);
g_odd_pos += 2;
}
}
xtrans_extend_red (info->linebuf, line_width);
xtrans_extend_green (info->linebuf, line_width);
g_even_pos = 0, g_odd_pos = 1;
b_even_pos = 0, b_odd_pos = 1;
while (g_even_pos < line_width || g_odd_pos < line_width) {
if (g_even_pos < line_width) {
errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G5] + 1, g_even_pos, info->grad_even[0]);
g_even_pos += 2;
if ((b_even_pos & 3) == 2) {
fuji_decode_interpolation_even (line_width, info->linebuf[_B3] + 1, b_even_pos);
} else {
errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B3] + 1, b_even_pos, info->grad_even[0]);
}
b_even_pos += 2;
}
if (g_even_pos > 8) {
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G5] + 1, g_odd_pos, info->grad_odd[0]);
g_odd_pos += 2;
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B3] + 1, b_odd_pos, info->grad_odd[0]);
b_odd_pos += 2;
}
}
xtrans_extend_green (info->linebuf, line_width);
xtrans_extend_blue (info->linebuf, line_width);
r_even_pos = 0, r_odd_pos = 1;
g_even_pos = 0, g_odd_pos = 1;
while (g_even_pos < line_width || g_odd_pos < line_width) {
if (g_even_pos < line_width) {
if ((r_even_pos & 3) == 2) {
fuji_decode_interpolation_even (line_width, info->linebuf[_R4] + 1, r_even_pos);
} else {
errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R4] + 1, r_even_pos, info->grad_even[1]);
}
r_even_pos += 2;
errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G6] + 1, g_even_pos, info->grad_even[1]);
g_even_pos += 2;
}
if (g_even_pos > 8) {
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R4] + 1, r_odd_pos, info->grad_odd[1]);
r_odd_pos += 2;
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G6] + 1, g_odd_pos, info->grad_odd[1]);
g_odd_pos += 2;
}
}
xtrans_extend_red (info->linebuf, line_width);
xtrans_extend_green (info->linebuf, line_width);
g_even_pos = 0, g_odd_pos = 1;
b_even_pos = 0, b_odd_pos = 1;
while (g_even_pos < line_width || g_odd_pos < line_width) {
if (g_even_pos < line_width) {
fuji_decode_interpolation_even (line_width, info->linebuf[_G7] + 1, g_even_pos);
g_even_pos += 2;
if (b_even_pos & 3) {
errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B4] + 1, b_even_pos, info->grad_even[2]);
} else {
fuji_decode_interpolation_even (line_width, info->linebuf[_B4] + 1, b_even_pos);
}
b_even_pos += 2;
}
if (g_even_pos > 8) {
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G7] + 1, g_odd_pos, info->grad_odd[2]);
g_odd_pos += 2;
errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B4] + 1, b_odd_pos, info->grad_odd[2]);
b_odd_pos += 2;
}
}
xtrans_extend_green (info->linebuf, line_width);
xtrans_extend_blue (info->linebuf, line_width);
if (errcnt) {
derror();
}
}
void CLASS xtrans_decode_strip (const struct xtrans_params* info_common, int cur_block, INT64 raw_offset, unsigned dsize)
{
int cur_block_width, cur_line;
unsigned line_size;
struct xtrans_block info;
init_xtrans_block (&info, info_common, raw_offset, dsize);
line_size = sizeof (ushort) * (info_common->line_width + 2);
cur_block_width = fuji_block_width;
if (cur_block + 1 == fuji_total_blocks) {
cur_block_width = raw_width % fuji_block_width;
}
struct i_pair {
int a, b;
};
const i_pair mtable[6] = { {_R0, _R3}, {_R1, _R4}, {_G0, _G6}, {_G1, _G7}, {_B0, _B3}, {_B1, _B4}},
ztable[3] = {{_R2, 3}, {_G2, 6}, {_B2, 3}};
for (cur_line = 0; cur_line < fuji_total_lines; cur_line++) {
xtrans_decode_block (&info, info_common, cur_line);
// copy data from line buffers and advance
for (int i = 0; i < 6; i++) {
memcpy (info.linebuf[mtable[i].a], info.linebuf[mtable[i].b], line_size);
}
copy_line_to_xtrans (&info, cur_line, cur_block, cur_block_width);
for (int i = 0; i < 3; i++) {
memset (info.linebuf[ztable[i].a], 0, ztable[i].b * line_size);
info.linebuf[ztable[i].a][0] = info.linebuf[ztable[i].a - 1][1];
info.linebuf[ztable[i].a][info_common->line_width + 1] = info.linebuf[ztable[i].a - 1][info_common->line_width];
}
}
// release data
free (info.linealloc);
free (info.cur_buf);
}
static unsigned sgetn (int n, uchar *s)
{
unsigned result = 0;
while (n-- > 0) {
result = (result << 8) | (*s++);
}
return result;
}
void CLASS xtrans_compressed_load_raw()
{
struct xtrans_params common_info;
int cur_block;
unsigned line_size, *block_sizes;
INT64 raw_offset, *raw_block_offsets;
//struct xtrans_block info;
init_xtrans (&common_info);
line_size = sizeof (ushort) * (common_info.line_width + 2);
// read block sizes
block_sizes = (unsigned*) malloc (sizeof (unsigned) * fuji_total_blocks);
merror (block_sizes, "xtrans_load_raw()");
raw_block_offsets = (INT64*) malloc (sizeof (INT64) * fuji_total_blocks);
merror (raw_block_offsets, "xtrans_load_raw()");
raw_offset = sizeof (unsigned) * fuji_total_blocks;
if (raw_offset & 0xC) {
raw_offset += 0x10 - (raw_offset & 0xC);
}
raw_offset += data_offset;
fseek (ifp, data_offset, SEEK_SET);
fread (block_sizes, 1, sizeof (unsigned)*fuji_total_blocks, ifp);
raw_block_offsets[0] = raw_offset;
// calculating raw block offsets
for (cur_block = 0; cur_block < fuji_total_blocks; cur_block++) {
unsigned bsize = sgetn (4, (uchar *) (block_sizes + cur_block));
block_sizes[cur_block] = bsize;
}
for (cur_block = 1; cur_block < fuji_total_blocks; cur_block++) {
raw_block_offsets[cur_block] = raw_block_offsets[cur_block - 1] + block_sizes[cur_block - 1] ;
}
xtrans_decode_loop (&common_info, fuji_total_blocks, raw_block_offsets, block_sizes);
free (block_sizes);
free (raw_block_offsets);
free (common_info.q_table);
}
void CLASS xtrans_decode_loop (const struct xtrans_params* common_info, int count, INT64* raw_block_offsets, unsigned *block_sizes)
{
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int cur_block = 0; cur_block < count ; cur_block++) {
xtrans_decode_strip (common_info, cur_block, raw_block_offsets[cur_block], block_sizes[cur_block]);
}
}
void CLASS parse_xtrans_header()
{
uchar header[16];
ushort signature;
uchar version;
uchar h_raw_type;
uchar h_raw_bits;
ushort h_raw_height;
ushort h_raw_rounded_width;
ushort h_raw_width;
ushort h_block_size;
uchar h_blocks_in_row;
ushort h_total_lines;
fseek (ifp, data_offset, SEEK_SET);
fread (header, 1, sizeof (header), ifp);
signature = sgetn (2, header);
version = header[2];
h_raw_type = header[3];
h_raw_bits = header[4];
h_raw_height = sgetn (2, header + 5);
h_raw_rounded_width = sgetn (2, header + 7);
h_raw_width = sgetn (2, header + 9);
h_block_size = sgetn (2, header + 11);
h_blocks_in_row = header[13];
h_total_lines = sgetn (2, header + 14);
// general validation
if (signature != 0x4953
|| version != 1
|| h_raw_height > 0x3000
|| h_raw_height < 6
|| h_raw_height % 6
|| h_raw_width > 0x3000
|| h_raw_width < 0x300
|| h_raw_width % 24
|| h_raw_rounded_width > 0x3000
|| h_raw_rounded_width < h_block_size
|| h_raw_rounded_width % h_block_size
|| h_raw_rounded_width - h_raw_width >= h_block_size
|| h_block_size != 0x300
|| h_blocks_in_row > 0x10
|| h_blocks_in_row == 0
|| h_blocks_in_row != h_raw_rounded_width / h_block_size
|| h_total_lines > 0x800
|| h_total_lines == 0
|| h_total_lines != h_raw_height / 6
|| (h_raw_bits != 12 && h_raw_bits != 14)
|| h_raw_type != 16) {
xtransCompressed = false;
return;
}
// modify data
fuji_total_lines = h_total_lines;
fuji_total_blocks = h_blocks_in_row;
fuji_block_width = h_block_size;
fuji_bits = h_raw_bits;
raw_width = h_raw_width;
raw_height = h_raw_height;
data_offset += 16;
load_raw = &CLASS xtrans_compressed_load_raw;
}

View File

@ -85,6 +85,8 @@ BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(nullptr), fileCa
BatchQueue::~BatchQueue ()
{
idle_register.destroy();
MYWRITERLOCK(l, entryRW);
// The listener merges parameters with old values, so delete afterwards
@ -937,7 +939,7 @@ void BatchQueue::notifyListener (bool queueEmptied)
}
params->queueEmptied = queueEmptied;
params->queueError = false;
add_idle (bqnotifylistenerUI, params);
idle_register.add(bqnotifylistenerUI, params);
}
}
@ -967,6 +969,6 @@ void BatchQueue::error (Glib::ustring msg)
params->queueEmptied = false;
params->queueError = true;
params->queueErrorMessage = msg;
add_idle (bqnotifylistenerUI, params);
idle_register.add(bqnotifylistenerUI, params);
}
}

View File

@ -36,37 +36,12 @@ public:
};
class FileCatalog;
class BatchQueue : public ThumbBrowserBase,
class BatchQueue final :
public ThumbBrowserBase,
public rtengine::BatchProcessingListener,
public LWButtonListener
{
protected:
int getMaxThumbnailHeight() const;
void saveThumbnailHeight (int height);
int getThumbnailHeight ();
BatchQueueEntry* processing; // holds the currently processed image
FileCatalog* fileCatalog;
int sequence; // holds the current sequence index
Glib::ustring nameTemplate;
MyImageMenuItem* cancel;
MyImageMenuItem* head;
MyImageMenuItem* tail;
Gtk::MenuItem* selall;
Gtk::MenuItem* open;
Glib::RefPtr<Gtk::AccelGroup> pmaccelgroup;
Gtk::Menu pmenu;
BatchQueueListener* listener;
Glib::ustring autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format);
Glib::ustring getTempFilenameForParams( const Glib::ustring &filename );
bool saveBatchQueue ();
void notifyListener (bool queueEmptied);
public:
explicit BatchQueue (FileCatalog* aFileCatalog);
~BatchQueue ();
@ -106,6 +81,34 @@ public:
static Glib::ustring calcAutoFileNameBase (const Glib::ustring& origFileName, int sequence = 0);
static int calcMaxThumbnailHeight();
protected:
int getMaxThumbnailHeight() const;
void saveThumbnailHeight (int height);
int getThumbnailHeight ();
Glib::ustring autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format);
Glib::ustring getTempFilenameForParams( const Glib::ustring &filename );
bool saveBatchQueue ();
void notifyListener (bool queueEmptied);
BatchQueueEntry* processing; // holds the currently processed image
FileCatalog* fileCatalog;
int sequence; // holds the current sequence index
Glib::ustring nameTemplate;
MyImageMenuItem* cancel;
MyImageMenuItem* head;
MyImageMenuItem* tail;
Gtk::MenuItem* selall;
Gtk::MenuItem* open;
Glib::RefPtr<Gtk::AccelGroup> pmaccelgroup;
Gtk::Menu pmenu;
BatchQueueListener* listener;
IdleRegister idle_register;
};
#endif

View File

@ -364,23 +364,25 @@ BlackWhite::BlackWhite (): FoldableToolPanel(this, "blackwhite", M("TP_BWMIX_LAB
}
BlackWhite::~BlackWhite ()
{
idle_register.destroy();
delete luminanceCEG;
delete beforeCurveCEG;
delete afterCurveCEG;
}
int BWChangedUI (void* data)
{
(static_cast<BlackWhite*>(data))->BWComputed_ ();
return 0;
}
void BlackWhite::BWChanged (double redbw, double greenbw, double bluebw)
{
nextredbw = redbw;
nextgreenbw = greenbw;
nextbluebw = bluebw;
add_idle (BWChangedUI, this);
const auto func = [](gpointer data) -> gboolean {
static_cast<BlackWhite*>(data)->BWComputed_();
return FALSE;
};
idle_register.add(func, this);
}
bool BlackWhite::BWComputed_ ()

View File

@ -28,10 +28,64 @@
#include "mycurve.h"
#include "colorprovider.h"
class BlackWhite : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoBWListener, public CurveListener, public ColorProvider
class BlackWhite final :
public ToolParamBlock,
public AdjusterListener,
public FoldableToolPanel,
public rtengine::AutoBWListener,
public CurveListener,
public ColorProvider
{
public:
BlackWhite ();
~BlackWhite ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void setBatchMode (bool batchMode);
void autoOpenCurve ();
void setEditProvider (EditDataProvider *provider);
void autoch_toggled ();
void neutral_pressed ();
void updateRGBLabel ();
void adjusterChanged (Adjuster* a, double newval);
void setAdjusterBehavior (bool bwadd, bool bwgadd);
void trimValues (rtengine::procparams::ProcParams* pp);
void enabledcc_toggled ();
void enabledChanged ();
void methodChanged ();
void filterChanged ();
void settingChanged ();
virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller);
void BWChanged (double redbw, double greenbw, double bluebw);
bool BWComputed_ ();
void curveChanged (CurveEditor* ce);
void curveMode1Changed ();
bool curveMode1Changed_ ();
void curveMode1Changed2 ();
bool curveMode1Changed2_ ();
void algoChanged ();
Glib::ustring getSettingString ();
Glib::ustring getFilterString ();
Glib::ustring getalgoString ();
private:
void showLuminance();
void hideLuminance();
void showFilter();
void hideFilter();
void showEnabledCC();
void hideEnabledCC();
void showMixer(int nChannels, bool RGBIsSensitive = true);
void hideMixer();
void showGamma();
void hideGamma();
protected:
FlatCurveEditor* luminanceCurve;
Gtk::HSeparator* luminanceSep;
CurveEditorGroup* luminanceCEG;
@ -85,55 +139,7 @@ protected:
double nextgreenbw;
double nextbluebw;
void showLuminance();
void hideLuminance();
void showFilter();
void hideFilter();
void showEnabledCC();
void hideEnabledCC();
void showMixer(int nChannels, bool RGBIsSensitive = true);
void hideMixer();
void showGamma();
void hideGamma();
public:
BlackWhite ();
~BlackWhite ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void setBatchMode (bool batchMode);
void autoOpenCurve ();
void setEditProvider (EditDataProvider *provider);
void autoch_toggled ();
void neutral_pressed ();
void updateRGBLabel ();
void adjusterChanged (Adjuster* a, double newval);
void setAdjusterBehavior (bool bwadd, bool bwgadd);
void trimValues (rtengine::procparams::ProcParams* pp);
void enabledcc_toggled ();
void enabledChanged ();
void methodChanged ();
void filterChanged ();
void settingChanged ();
virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller);
void BWChanged (double redbw, double greenbw, double bluebw);
bool BWComputed_ ();
void curveChanged (CurveEditor* ce);
void curveMode1Changed ();
bool curveMode1Changed_ ();
void curveMode1Changed2 ();
bool curveMode1Changed2_ ();
void algoChanged ();
Glib::ustring getSettingString ();
Glib::ustring getFilterString ();
Glib::ustring getalgoString ();
IdleRegister idle_register;
};
#endif

View File

@ -19,6 +19,7 @@
#include "cachemanager.h"
#include <memory>
#include <iostream>
#include <glib/gstdio.h>
#include <giomm.h>
@ -35,8 +36,8 @@
namespace
{
constexpr auto cacheDirMode = 511;
constexpr auto cacheDirs = { "profiles", "images", "aehistograms", "embprofiles", "data" };
constexpr int cacheDirMode = 0777;
constexpr const char* cacheDirs[] = { "profiles", "images", "aehistograms", "embprofiles", "data", "mip" };
}
@ -60,7 +61,7 @@ void CacheManager::init ()
}
if (error != 0 && options.rtSettings.verbose) {
std::cerr << "Failed to create all cache directories: " << g_strerror(errno) << std::endl;
std::cerr << "Failed to create all cache directories: " << g_strerror (errno) << std::endl;
}
}
@ -76,6 +77,7 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname)
// if it is open, return it
const auto iterator = openEntries.find (fname);
if (iterator != openEntries.end ()) {
auto cachedThumbnail = iterator->second;
@ -99,9 +101,11 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname)
CacheImageData imageData;
const auto error = imageData.load (cacheName);
if (error == 0 && imageData.supported) {
thumbnail.reset (new Thumbnail (this, fname, &imageData));
if (!thumbnail->isSupported ()) {
thumbnail.reset ();
}
@ -112,6 +116,7 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname)
if (!thumbnail) {
thumbnail.reset (new Thumbnail (this, fname, md5));
if (!thumbnail->isSupported ()) {
thumbnail.reset ();
}
@ -123,6 +128,7 @@ Thumbnail* CacheManager::getEntry (const Glib::ustring& fname)
MyMutex::MyLock lock (mutex);
const auto iterator = openEntries.find (fname);
if (iterator != openEntries.end ()) {
auto cachedThumbnail = iterator->second;
@ -145,6 +151,7 @@ void CacheManager::deleteEntry (const Glib::ustring& fname)
// check if it is opened
auto iterator = openEntries.find (fname);
if (iterator == openEntries.end ()) {
deleteFiles (fname, getMD5 (fname), true, true);
return;
@ -190,12 +197,13 @@ void CacheManager::renameEntry (const std::string& oldfilename, const std::strin
error |= g_rename (getCacheFileName ("data", oldfilename, ".txt", oldmd5).c_str (), getCacheFileName ("data", newfilename, ".txt", newmd5).c_str ());
if (error != 0 && options.rtSettings.verbose) {
std::cerr << "Failed to rename all files for cache entry '" << oldfilename << "': " << g_strerror(errno) << std::endl;
std::cerr << "Failed to rename all files for cache entry '" << oldfilename << "': " << g_strerror (errno) << std::endl;
}
// check if it is opened
// if it is open, update md5
const auto iterator = openEntries.find (oldfilename);
if (iterator == openEntries.end ()) {
return;
}
@ -256,12 +264,13 @@ void CacheManager::deleteDir (const Glib::ustring& dirName) const
Glib::Dir dir (Glib::build_filename (baseDir, dirName));
auto error = 0;
for (auto entry = dir.begin (); entry != dir.end (); ++entry) {
error |= g_remove (Glib::build_filename (baseDir, dirName, *entry).c_str ());
}
if (error != 0 && options.rtSettings.verbose) {
std::cerr << "Failed to delete all entries in cache directory '" << dirName << "': " << g_strerror(errno) << std::endl;
std::cerr << "Failed to delete all entries in cache directory '" << dirName << "': " << g_strerror (errno) << std::endl;
}
} catch (Glib::Error&) {}
@ -289,7 +298,7 @@ void CacheManager::deleteFiles (const Glib::ustring& fname, const std::string& m
}
if (error != 0 && options.rtSettings.verbose) {
std::cerr << "Failed to delete all files for cache entry '" << fname << "': " << g_strerror(errno) << std::endl;
std::cerr << "Failed to delete all files for cache entry '" << fname << "': " << g_strerror (errno) << std::endl;
}
}
@ -302,9 +311,10 @@ std::string CacheManager::getMD5 (const Glib::ustring& fname)
#ifdef WIN32
std::unique_ptr<wchar_t, GFreeFunc> wfname (reinterpret_cast<wchar_t*>(g_utf8_to_utf16 (fname.c_str (), -1, NULL, NULL, NULL)), g_free);
std::unique_ptr<wchar_t, GFreeFunc> wfname (reinterpret_cast<wchar_t*> (g_utf8_to_utf16 (fname.c_str (), -1, NULL, NULL, NULL)), g_free);
WIN32_FILE_ATTRIBUTE_DATA fileAttr;
if (GetFileAttributesExW (wfname.get (), GetFileExInfoStandard, &fileAttr)) {
// We use name, size and creation time to identify a file.
const auto identifier = Glib::ustring::compose ("%1-%2-%3-%4", fileAttr.nFileSizeLow, fileAttr.ftCreationTime.dwHighDateTime, fileAttr.ftCreationTime.dwLowDateTime, fname);
@ -313,8 +323,7 @@ std::string CacheManager::getMD5 (const Glib::ustring& fname)
#else
try
{
try {
if (auto info = file->query_info ()) {
// We only use name and size to identify a file.
@ -322,7 +331,7 @@ std::string CacheManager::getMD5 (const Glib::ustring& fname)
return Glib::Checksum::compute_checksum (Glib::Checksum::CHECKSUM_MD5, identifier);
}
} catch(Gio::Error&) {}
} catch (Gio::Error&) {}
#endif
@ -332,9 +341,9 @@ std::string CacheManager::getMD5 (const Glib::ustring& fname)
}
Glib::ustring CacheManager::getCacheFileName (const Glib::ustring& subDir,
const Glib::ustring& fname,
const Glib::ustring& fext,
const Glib::ustring& md5) const
const Glib::ustring& fname,
const Glib::ustring& fext,
const Glib::ustring& md5) const
{
const auto dirName = Glib::build_filename (baseDir, subDir);
const auto baseName = Glib::path_get_basename (fname) + "." + md5;
@ -363,8 +372,7 @@ void CacheManager::applyCacheSizeLimitation () const
return;
}
std::sort (files.begin (), files.end (), [] (const FNameMTime& lhs, const FNameMTime& rhs)
{
std::sort (files.begin (), files.end (), [] (const FNameMTime & lhs, const FNameMTime & rhs) {
return lhs.second < rhs.second;
});

View File

@ -424,6 +424,8 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel(this, "colorappearance",
ColorAppearance::~ColorAppearance ()
{
idle_register.destroy();
delete curveEditorG;
delete curveEditorG2;
delete curveEditorG3;
@ -1002,15 +1004,17 @@ void ColorAppearance::setDefaults (const ProcParams* defParams, const ParamsEdit
}
}
int autoCamChangedUI (void* data)
{
(static_cast<ColorAppearance*>(data))->autoCamComputed_ ();
return 0;
}
void ColorAppearance::autoCamChanged (double ccam)
{
nextCcam = ccam;
add_idle (autoCamChangedUI, this);
const auto func = [](gpointer data) -> gboolean {
static_cast<ColorAppearance*>(data)->autoCamComputed_();
return FALSE;
};
idle_register.add(func, this);
}
bool ColorAppearance::autoCamComputed_ ()
@ -1023,15 +1027,17 @@ bool ColorAppearance::autoCamComputed_ ()
return false;
}
int adapCamChangedUI (void* data)
{
(static_cast<ColorAppearance*>(data))->adapCamComputed_ ();
return 0;
}
void ColorAppearance::adapCamChanged (double cadap)
{
nextCadap = cadap;
add_idle (adapCamChangedUI, this);
const auto func = [](gpointer data) -> gboolean {
static_cast<ColorAppearance*>(data)->adapCamComputed_();
return FALSE;
};
idle_register.add(func, this);
}
bool ColorAppearance::adapCamComputed_ ()

View File

@ -28,10 +28,61 @@
#include "guiutils.h"
#include "colorprovider.h"
class ColorAppearance : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoCamListener, public CurveListener, public ColorProvider
class ColorAppearance final :
public ToolParamBlock,
public AdjusterListener,
public FoldableToolPanel,
public rtengine::AutoCamListener,
public CurveListener,
public ColorProvider
{
public:
ColorAppearance ();
~ColorAppearance ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled (Adjuster* a, bool newval);
// void adjusterAdapToggled (Adjuster* a, bool newval);
void enabledChanged ();
void surroundChanged ();
void wbmodelChanged ();
void algoChanged ();
void surrsource_toggled ();
void gamut_toggled ();
// void badpix_toggled ();
void datacie_toggled ();
void tonecie_toggled ();
// void sharpcie_toggled ();
void autoCamChanged (double ccam);
bool autoCamComputed_ ();
void adapCamChanged (double cadap);
bool adapCamComputed_ ();
void curveChanged (CurveEditor* ce);
void curveMode1Changed ();
bool curveMode1Changed_ ();
void curveMode2Changed ();
bool curveMode2Changed_ ();
void curveMode3Changed ();
bool curveMode3Changed_ ();
void expandCurve (bool isExpanded);
bool isCurveExpanded ();
void autoOpenCurve ();
void setAdjusterBehavior (bool degreeadd, bool adapscenadd, bool adaplumadd, bool badpixsladd, bool jlightadd, bool chromaadd, bool contrastadd, bool rstprotectionadd, bool qbrightadd, bool qcontrastadd, bool schromaadd, bool mchromaadd, bool colorhadd);
void trimValues (rtengine::procparams::ProcParams* pp);
void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histLRETI);
virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller);
private:
bool bgTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip);
bool srTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip);
protected:
Glib::RefPtr<Gtk::Tooltip> bgTTips;
Glib::RefPtr<Gtk::Tooltip> srTTips;
Glib::RefPtr<Gdk::Pixbuf> bgPixbuf;
@ -83,56 +134,10 @@ protected:
bool lastAutoAdapscen;
bool lastsurr;
bool lastgamut;
// bool lastbadpix;
bool lastdatacie;
bool lasttonecie;
// bool lastsharpcie;
bool bgTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip);
bool srTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip);
public:
ColorAppearance ();
~ColorAppearance ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void adjusterAutoToggled (Adjuster* a, bool newval);
// void adjusterAdapToggled (Adjuster* a, bool newval);
void enabledChanged ();
void surroundChanged ();
void wbmodelChanged ();
void algoChanged ();
void surrsource_toggled ();
void gamut_toggled ();
// void badpix_toggled ();
void datacie_toggled ();
void tonecie_toggled ();
// void sharpcie_toggled ();
void autoCamChanged (double ccam);
bool autoCamComputed_ ();
void adapCamChanged (double cadap);
bool adapCamComputed_ ();
void curveChanged (CurveEditor* ce);
void curveMode1Changed ();
bool curveMode1Changed_ ();
void curveMode2Changed ();
bool curveMode2Changed_ ();
void curveMode3Changed ();
bool curveMode3Changed_ ();
void expandCurve (bool isExpanded);
bool isCurveExpanded ();
void autoOpenCurve ();
void setAdjusterBehavior (bool degreeadd, bool adapscenadd, bool adaplumadd, bool badpixsladd, bool jlightadd, bool chromaadd, bool contrastadd, bool rstprotectionadd, bool qbrightadd, bool qcontrastadd, bool schromaadd, bool mchromaadd, bool colorhadd);
void trimValues (rtengine::procparams::ProcParams* pp);
void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histLRETI);
virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller);
IdleRegister idle_register;
};
#endif

View File

@ -324,6 +324,8 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR
ColorToning::~ColorToning()
{
idle_register.destroy();
delete colorCurveEditorG;
delete opacityCurveEditorG;
delete clCurveEditorG;
@ -650,19 +652,18 @@ void ColorToning::adjusterChanged (ThresholdAdjuster* a, double newBottom, doubl
Glib::ustring::compose(Glib::ustring(M("TP_COLORTONING_HUE") + ": %1" + "\n" + M("TP_COLORTONING_STRENGTH") + ": %2"), int(newTop), int(newBottom)));
}
int CTChanged_UI (void* data)
{
(static_cast<ColorToning*>(data))->CTComp_ ();
return 0;
}
void ColorToning::autoColorTonChanged(int bwct, int satthres, int satprot)
{
nextbw = bwct;
nextsatth = satthres;
nextsatpr = satprot;
add_idle (CTChanged_UI, this);
const auto func = [](gpointer data) -> gboolean {
static_cast<ColorToning*>(data)->CTComp_();
return FALSE;
};
idle_register.add(func, this);
}
bool ColorToning::CTComp_ ()

View File

@ -13,12 +13,43 @@
#include "thresholdadjuster.h"
#include "colorprovider.h"
class ColorToning : public ToolParamBlock, public FoldableToolPanel, public rtengine::AutoColorTonListener, public CurveListener, public ColorProvider,
public ThresholdAdjusterListener, public AdjusterListener
class ColorToning final :
public ToolParamBlock,
public FoldableToolPanel,
public rtengine::AutoColorTonListener,
public CurveListener,
public ColorProvider,
public ThresholdAdjusterListener,
public AdjusterListener
{
public:
ColorToning ();
~ColorToning();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
void setBatchMode (bool batchMode);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void trimValues (rtengine::procparams::ProcParams* pp);
void adjusterChanged (Adjuster* a, double newval);
void adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop);
void setAdjusterBehavior (bool splitAdd, bool satThresholdAdd, bool satOpacityAdd, bool strprotectAdd, bool balanceAdd);
void neutral_pressed ();
//void neutralCurves_pressed ();
void autoColorTonChanged (int bwct, int satthres, int satprot);
bool CTComp_ ();
protected:
//Gtk::HSeparator* splitSep;
void enabledChanged ();
void curveChanged (CurveEditor* ce);
void autosatChanged ();
void autoOpenCurve ();
void methodChanged ();
void twocolorChanged (bool changedbymethod);
void twoColorChangedByGui ();
void lumamodeChanged ();
void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller);
private:
Gtk::HSeparator* satLimiterSep;
Gtk::HSeparator* colorSep;
CurveEditorGroup* colorCurveEditorG;
@ -57,7 +88,6 @@ protected:
Gtk::Image* irg;
Gtk::Button* neutral;
//Gtk::Button* neutralCurves;
Gtk::HBox* neutrHBox;
Gtk::HBox* chromaHbox;
Gtk::Label* chroLabel;
@ -75,32 +105,7 @@ protected:
bool lastLumamode;
sigc::connection lumamodeConn;
public:
ColorToning ();
~ColorToning();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
void setBatchMode (bool batchMode);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void trimValues (rtengine::procparams::ProcParams* pp);
void adjusterChanged (Adjuster* a, double newval);
void adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop);
void setAdjusterBehavior (bool splitAdd, bool satThresholdAdd, bool satOpacityAdd, bool strprotectAdd, bool balanceAdd);
void neutral_pressed ();
//void neutralCurves_pressed ();
void autoColorTonChanged (int bwct, int satthres, int satprot);
bool CTComp_ ();
void enabledChanged ();
void curveChanged (CurveEditor* ce);
void autosatChanged ();
void autoOpenCurve ();
void methodChanged ();
void twocolorChanged (bool changedbymethod);
void twoColorChangedByGui ();
void lumamodeChanged ();
void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller);
IdleRegister idle_register;
};
#endif

View File

@ -25,6 +25,9 @@ using namespace rtengine::procparams;
extern Options options;
namespace
{
class RefreshSpinHelper
{
@ -35,6 +38,22 @@ public:
: crop(_crop), notify(_notify) {}
};
int refreshSpinsUI (void* data)
{
RefreshSpinHelper* rsh = static_cast<RefreshSpinHelper*>(data);
rsh->crop->refreshSpins (rsh->notify);
delete rsh;
return 0;
}
int notifyListenerUI (void* data)
{
static_cast<Crop*>(data)->notifyListener();
return 0;
}
}
Crop::Crop (): FoldableToolPanel(this, "crop", M("TP_CROP_LABEL"), false, true)
{
@ -252,6 +271,11 @@ Crop::Crop (): FoldableToolPanel(this, "crop", M("TP_CROP_LABEL"), false, true)
show_all ();
}
Crop::~Crop()
{
idle_register.destroy();
}
void Crop::writeOptions ()
{
@ -508,32 +532,18 @@ void Crop::enabledChanged ()
}
}
int notifyListenerUI (void* data)
{
(static_cast<Crop*>(data))->notifyListener ();
return 0;
}
int refreshSpinsUI (void* data)
{
RefreshSpinHelper* rsh = static_cast<RefreshSpinHelper*>(data);
rsh->crop->refreshSpins (rsh->notify);
delete rsh;
return 0;
}
void Crop::hFlipCrop ()
{
nx = maxw - nx - nw;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::vFlipCrop ()
{
ny = maxh - ny - nh;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::rotateCrop (int deg, bool hflip, bool vflip)
@ -573,7 +583,7 @@ void Crop::rotateCrop (int deg, bool hflip, bool vflip)
}
lastRotationDeg = deg;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::positionChanged ()
@ -587,7 +597,7 @@ void Crop::positionChanged ()
int W = nw;
int H = nh;
cropMoved (X, Y, W, H);
add_idle (notifyListenerUI, this);
idle_register.add(notifyListenerUI, this);
}
void Crop::widthChanged ()
@ -600,7 +610,7 @@ void Crop::widthChanged ()
int W = (int)w->get_value ();
int H = nh;
cropWidth2Resized (X, Y, W, H);
add_idle (notifyListenerUI, this);
idle_register.add(notifyListenerUI, this);
}
void Crop::heightChanged ()
@ -613,7 +623,7 @@ void Crop::heightChanged ()
int W = nw;
int H = (int)h->get_value ();
cropHeight2Resized (X, Y, W, H);
add_idle (notifyListenerUI, this);
idle_register.add(notifyListenerUI, this);
}
// Fixed ratio toggle button
@ -665,7 +675,7 @@ void Crop::adjustCropToRatio()
}
// This will save the options
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, true));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, true));
}
void Crop::refreshSize ()
@ -737,28 +747,28 @@ void Crop::setDimensions (int mw, int mh)
refreshSize ();
}
struct setdimparams {
Crop* crop;
int x;
int y;
};
int sizeChangedUI (void* data)
{
setdimparams* params = static_cast<setdimparams*>(data);
params->crop->setDimensions (params->x, params->y);
delete params;
return 0;
}
void Crop::sizeChanged (int x, int y, int ow, int oh)
{
struct Params {
Crop* crop;
int x;
int y;
};
setdimparams* params = new setdimparams;
params->x = x;
params->y = y;
params->crop = this;
add_idle (sizeChangedUI, params);
Params* const params = new Params{
this,
x,
y
};
const auto func = [](gpointer data) -> gboolean {
Params* const params = static_cast<Params*>(data);
params->crop->setDimensions(params->x, params->y);
delete params;
return FALSE;
};
idle_register.add(func, params);
}
bool Crop::refreshSpins (bool notify)
@ -822,7 +832,7 @@ void Crop::cropMoved (int &X, int &Y, int &W, int &H)
nw = W;
nh = H;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
}
@ -866,7 +876,7 @@ void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H)
nw = W;
nh = H;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H)
@ -906,7 +916,7 @@ void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H)
nw = W;
nh = H;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H)
@ -949,7 +959,7 @@ void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H)
nw = W;
nh = H;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H)
@ -989,7 +999,7 @@ void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H)
nw = W;
nh = H;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H)
@ -1031,7 +1041,7 @@ void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H)
nw = W;
nh = H;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H)
@ -1071,7 +1081,7 @@ void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H)
nw = W;
nh = H;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H)
@ -1111,7 +1121,7 @@ void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H)
nw = W;
nh = H;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::cropBottomRightResized (int &X, int &Y, int &W, int &H)
@ -1148,7 +1158,7 @@ void Crop::cropBottomRightResized (int &X, int &Y, int &W, int &H)
nw = W;
nh = H;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::cropInit (int &x, int &y, int &w, int &h)
@ -1266,13 +1276,12 @@ void Crop::cropResized (int &x, int &y, int& x2, int& y2)
nw = W;
nh = H;
add_idle (refreshSpinsUI, new RefreshSpinHelper (this, false));
idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false));
}
void Crop::cropManipReady ()
{
add_idle (notifyListenerUI, this);
idle_register.add(notifyListenerUI, this);
}
double Crop::getRatio ()

View File

@ -33,44 +33,20 @@ public:
virtual void cropSelectRequested() = 0;
};
class CropRatio
{
public:
struct CropRatio {
Glib::ustring label;
double value;
};
class Crop : public ToolParamBlock, public CropGUIListener, public FoldableToolPanel, public rtengine::SizeListener
class Crop final :
public ToolParamBlock,
public CropGUIListener,
public FoldableToolPanel,
public rtengine::SizeListener
{
protected:
Gtk::CheckButton* fixr;
MyComboBoxText* ratio;
MyComboBoxText* orientation;
MyComboBoxText* guide;
Gtk::Button* selectCrop;
CropPanelListener* clistener;
int opt;
MySpinButton* x;
MySpinButton* y;
MySpinButton* w;
MySpinButton* h;
MySpinButton* ppi;
Gtk::Label* sizecm;
Gtk::Label* sizein;
Gtk::VBox* ppibox;
Gtk::VBox* sizebox;
int maxw, maxh;
double nx, ny;
int nw, nh;
int lastRotationDeg;
sigc::connection xconn, yconn, wconn, hconn, fconn, rconn, oconn, gconn;
bool wDirty, hDirty, xDirty, yDirty, lastFixRatio;
void adjustCropToRatio();
std::vector<CropRatio> cropratio;
public:
Crop ();
Crop();
~Crop();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
@ -116,6 +92,34 @@ public:
void hFlipCrop ();
void vFlipCrop ();
void rotateCrop (int deg, bool hflip, bool vflip);
private:
Gtk::CheckButton* fixr;
MyComboBoxText* ratio;
MyComboBoxText* orientation;
MyComboBoxText* guide;
Gtk::Button* selectCrop;
CropPanelListener* clistener;
int opt;
MySpinButton* x;
MySpinButton* y;
MySpinButton* w;
MySpinButton* h;
MySpinButton* ppi;
Gtk::Label* sizecm;
Gtk::Label* sizein;
Gtk::VBox* ppibox;
Gtk::VBox* sizebox;
int maxw, maxh;
double nx, ny;
int nw, nh;
int lastRotationDeg;
sigc::connection xconn, yconn, wconn, hconn, fconn, rconn, oconn, gconn;
bool wDirty, hDirty, xDirty, yDirty, lastFixRatio;
void adjustCropToRatio();
std::vector<CropRatio> cropratio;
IdleRegister idle_register;
};
#endif

View File

@ -38,14 +38,15 @@ CropHandler::CropHandler ()
displayHandler(nullptr)
{
chi = new CropHandlerIdleHelper;
chi->destroyed = false;
chi->pending = 0;
chi->cropHandler = this;
idle_helper = new IdleHelper;
idle_helper->destroyed = false;
idle_helper->pending = 0;
idle_helper->cropHandler = this;
}
CropHandler::~CropHandler ()
{
idle_register.destroy();
if (ipc) {
ipc->delSizeListener (this);
@ -61,10 +62,10 @@ CropHandler::~CropHandler ()
cimg.lock ();
if (chi->pending) {
chi->destroyed = true;
if (idle_helper->pending) {
idle_helper->destroyed = true;
} else {
delete chi;
delete idle_helper;
}
cimg.unlock ();
@ -292,83 +293,6 @@ void CropHandler::getPosition (int& x, int& y)
}
int createpixbufs (void* data)
{
CropHandlerIdleHelper* chi = static_cast<CropHandlerIdleHelper*>(data);
if (chi->destroyed) {
if (chi->pending == 1) {
delete chi;
} else {
chi->pending--;
}
return 0;
}
CropHandler* ch = chi->cropHandler;
ch->cimg.lock ();
ch->cropPixbuf.clear ();
if (!ch->enabled) {
delete [] ch->cropimg;
ch->cropimg = nullptr;
delete [] ch->cropimgtrue;
ch->cropimgtrue = nullptr;
ch->cimg.unlock ();
return 0;
}
if (ch->cropimg) {
if (ch->cix == ch->cropX && ch->ciy == ch->cropY && ch->ciw == ch->cropW && ch->cih == ch->cropH && ch->cis == (ch->zoom >= 1000 ? 1 : ch->zoom)) {
// calculate final image size
int czoom = ch->zoom < 1000 ? 1000 : ch->zoom;
int imw = ch->cropimg_width * czoom / 1000;
int imh = ch->cropimg_height * czoom / 1000;
if (imw > ch->ww) {
imw = ch->ww;
}
if (imh > ch->wh) {
imh = ch->wh;
}
Glib::RefPtr<Gdk::Pixbuf> tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width);
ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh);
tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom / 1000.0, czoom / 1000.0, Gdk::INTERP_NEAREST);
tmpPixbuf.clear ();
Glib::RefPtr<Gdk::Pixbuf> tmpPixbuftrue = Gdk::Pixbuf::create_from_data (ch->cropimgtrue, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width);
ch->cropPixbuftrue = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh);
tmpPixbuftrue->scale (ch->cropPixbuftrue, 0, 0, imw, imh, 0, 0, czoom / 1000.0, czoom / 1000.0, Gdk::INTERP_NEAREST);
tmpPixbuftrue.clear ();
}
delete [] ch->cropimg;
ch->cropimg = nullptr;
delete [] ch->cropimgtrue;
ch->cropimgtrue = nullptr;
}
ch->cimg.unlock ();
if (ch->displayHandler) {
ch->displayHandler->cropImageUpdated ();
if (ch->initial) {
ch->displayHandler->initialImageArrived ();
ch->initial = false;
}
}
chi->pending--;
return 0;
}
void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procparams::ColorManagementParams cmp,
rtengine::procparams::CropParams cp, int ax, int ay, int aw, int ah, int askip)
{
@ -408,8 +332,84 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp
ciw = aw;
cih = ah;
cis = askip;
chi->pending++;
add_idle (createpixbufs, chi);
idle_helper->pending++;
const auto func = [](gpointer data) -> gboolean {
IdleHelper* const idle_helper = static_cast<IdleHelper*>(data);
if (idle_helper->destroyed) {
if (idle_helper->pending == 1) {
delete idle_helper;
} else {
idle_helper->pending--;
}
return FALSE;
}
CropHandler* ch = idle_helper->cropHandler;
ch->cimg.lock ();
ch->cropPixbuf.clear ();
if (!ch->enabled) {
delete [] ch->cropimg;
ch->cropimg = nullptr;
delete [] ch->cropimgtrue;
ch->cropimgtrue = nullptr;
ch->cimg.unlock ();
return FALSE;
}
if (ch->cropimg) {
if (ch->cix == ch->cropX && ch->ciy == ch->cropY && ch->ciw == ch->cropW && ch->cih == ch->cropH && ch->cis == (ch->zoom >= 1000 ? 1 : ch->zoom)) {
// calculate final image size
int czoom = ch->zoom < 1000 ? 1000 : ch->zoom;
int imw = ch->cropimg_width * czoom / 1000;
int imh = ch->cropimg_height * czoom / 1000;
if (imw > ch->ww) {
imw = ch->ww;
}
if (imh > ch->wh) {
imh = ch->wh;
}
Glib::RefPtr<Gdk::Pixbuf> tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width);
ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh);
tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom / 1000.0, czoom / 1000.0, Gdk::INTERP_NEAREST);
tmpPixbuf.clear ();
Glib::RefPtr<Gdk::Pixbuf> tmpPixbuftrue = Gdk::Pixbuf::create_from_data (ch->cropimgtrue, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width);
ch->cropPixbuftrue = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh);
tmpPixbuftrue->scale (ch->cropPixbuftrue, 0, 0, imw, imh, 0, 0, czoom / 1000.0, czoom / 1000.0, Gdk::INTERP_NEAREST);
tmpPixbuftrue.clear ();
}
delete [] ch->cropimg;
ch->cropimg = nullptr;
delete [] ch->cropimgtrue;
ch->cropimgtrue = nullptr;
}
ch->cimg.unlock ();
if (ch->displayHandler) {
ch->displayHandler->cropImageUpdated ();
if (ch->initial) {
ch->displayHandler->initialImageArrived ();
ch->initial = false;
}
}
idle_helper->pending--;
return FALSE;
};
idle_register.add(func, idle_helper);
}
cimg.unlock ();

View File

@ -36,56 +36,15 @@ public:
virtual void setDisplayPosition (int x, int y) {}
};
class CropHandler;
struct CropHandlerIdleHelper {
CropHandler* cropHandler;
bool destroyed;
int pending;
};
/**
* This class handle the displayed part of the image, ask for the initial data and process it so it can display it.
* Its position on the preview is handled not set by this class but by the CropHandlerListener (i.e. CropWindow) with which it works closely.
*/
class CropHandler : public rtengine::DetailedCropListener, public rtengine::SizeListener
class CropHandler final :
public rtengine::DetailedCropListener,
public rtengine::SizeListener
{
friend int createpixbufs (void* data);
protected:
int zoom; // scale factor (e.g. 5 if 1:5 scale) ; if 1:1 scale and bigger, factor is multiplied by 1000 (i.e. 1000 for 1:1 scale, 2000 for 2:1, etc...)
int ww, wh; // size of the crop's canvas on the screen ; might be bigger than the displayed image, but not smaller
int imx, imy, imw, imh; // this is a copy of the cropwindow's parameters
int cax, cay; // clamped crop anchor's coordinate, i.e. point of the image that coincide to the center of the display area, expressed in image coordinates; cannot be outside the image's bounds; but if cax==cay==-1, designate the center of the image
int cx, cy, cw, ch; // position and size of the requested crop ; position expressed in image coordinates, so cx and cy might be negative and cw and ch higher than the image's 1:1 size
int cropX, cropY, cropW, cropH; // cropPixbuf's displayed area (position and size), i.e. coordinates in 1:1 scale, i.e. cx, cy, cw & ch trimmed to the image's bounds
bool enabled;
unsigned char* cropimg;
unsigned char* cropimgtrue;
int cropimg_width, cropimg_height, cix, ciy, ciw, cih, cis;
bool initial;
bool isLowUpdatePriority;
rtengine::StagedImageProcessor* ipc;
rtengine::DetailedCrop* crop;
CropDisplayHandler* displayHandler;
CropHandlerIdleHelper* chi;
void compDim ();
public:
void update ();
rtengine::procparams::CropParams cropParams;
rtengine::procparams::ColorManagementParams colorParams;
Glib::RefPtr<Gdk::Pixbuf> cropPixbuf;
Glib::RefPtr<Gdk::Pixbuf> cropPixbuftrue;
MyMutex cimg;
CropHandler ();
~CropHandler ();
@ -127,6 +86,46 @@ public:
bool getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip);
// SizeListener interface
void sizeChanged (int w, int h, int ow, int oh);
void update ();
rtengine::procparams::CropParams cropParams;
rtengine::procparams::ColorManagementParams colorParams;
Glib::RefPtr<Gdk::Pixbuf> cropPixbuf;
Glib::RefPtr<Gdk::Pixbuf> cropPixbuftrue;
MyMutex cimg;
private:
struct IdleHelper {
CropHandler* cropHandler;
bool destroyed;
int pending;
};
void compDim ();
int zoom; // scale factor (e.g. 5 if 1:5 scale) ; if 1:1 scale and bigger, factor is multiplied by 1000 (i.e. 1000 for 1:1 scale, 2000 for 2:1, etc...)
int ww, wh; // size of the crop's canvas on the screen ; might be bigger than the displayed image, but not smaller
int imx, imy, imw, imh; // this is a copy of the cropwindow's parameters
int cax, cay; // clamped crop anchor's coordinate, i.e. point of the image that coincide to the center of the display area, expressed in image coordinates; cannot be outside the image's bounds; but if cax==cay==-1, designate the center of the image
int cx, cy, cw, ch; // position and size of the requested crop ; position expressed in image coordinates, so cx and cy might be negative and cw and ch higher than the image's 1:1 size
int cropX, cropY, cropW, cropH; // cropPixbuf's displayed area (position and size), i.e. coordinates in 1:1 scale, i.e. cx, cy, cw & ch trimmed to the image's bounds
bool enabled;
unsigned char* cropimg;
unsigned char* cropimgtrue;
int cropimg_width, cropimg_height, cix, ciy, ciw, cih, cis;
bool initial;
bool isLowUpdatePriority;
rtengine::StagedImageProcessor* ipc;
rtengine::DetailedCrop* crop;
CropDisplayHandler* displayHandler;
IdleHelper* idle_helper;
IdleRegister idle_register;
};
#endif

View File

@ -18,6 +18,7 @@
*/
#include "dirbrowser.h"
#include <iostream>
#include <cstring>
#ifdef WIN32

View File

@ -327,22 +327,24 @@ DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, "dirpyrdenoise", M("TP
DirPyrDenoise::~DirPyrDenoise ()
{
idle_register.destroy();
delete NoiscurveEditorG;
delete CCcurveEditorG;
}
}
int chromaChangedUI (void* data)
{
(static_cast<DirPyrDenoise*>(data))->chromaComputed_ ();
return 0;
}
void DirPyrDenoise::chromaChanged (double autchroma, double autred, double autblue)
{
nextchroma = autchroma;
// printf("CHROM=%f\n",nextchroma);
nextred = autred;
nextblue = autblue;
add_idle(chromaChangedUI, this);
const auto func = [](gpointer data) -> gboolean {
static_cast<DirPyrDenoise*>(data)->chromaComputed_();
return false;
};
idle_register.add(func, this);
}
bool DirPyrDenoise::chromaComputed_ ()
@ -356,12 +358,6 @@ bool DirPyrDenoise::chromaComputed_ ()
updateNoiseLabel ();
return false;
}
int TilePrevChangedUI (void* data)
{
(static_cast<DirPyrDenoise*>(data))->TilePrevComputed_ ();
return 0;
}
void DirPyrDenoise::noiseTilePrev (int tileX, int tileY, int prevX, int prevY, int sizeT, int sizeP)
{
@ -372,10 +368,14 @@ void DirPyrDenoise::noiseTilePrev (int tileX, int tileY, int prevX, int prevY, i
nextsizeT = sizeT;
nextsizeP = sizeP;
add_idle(TilePrevChangedUI, this);
const auto func = [](gpointer data) -> gboolean {
static_cast<DirPyrDenoise*>(data)->TilePrevComputed_();
return false;
};
idle_register.add(func, this);
}
bool DirPyrDenoise::TilePrevComputed_ ()
{
@ -385,6 +385,7 @@ bool DirPyrDenoise::TilePrevComputed_ ()
updatePrevLabel ();
return false;
}
void DirPyrDenoise::updateTileLabel ()
{
if (!batchMode) {
@ -422,19 +423,17 @@ void DirPyrDenoise::updatePrevLabel ()
}
}
int noiseChangedUI (void* data)
{
(static_cast<DirPyrDenoise*>(data))->noiseComputed_ ();
return 0;
}
void DirPyrDenoise::noiseChanged (double nresid, double highresid)
{
nextnresid = nresid;
nexthighresid = highresid;
add_idle(noiseChangedUI, this);
const auto func = [](gpointer data) -> gboolean {
static_cast<DirPyrDenoise*>(data)->noiseComputed_();
return false;
};
idle_register.add(func, this);
}
bool DirPyrDenoise::noiseComputed_ ()

View File

@ -28,10 +28,58 @@
#include "guiutils.h"
#include "options.h"
class DirPyrDenoise : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoChromaListener, public CurveListener, public ColorProvider
class DirPyrDenoise final :
public ToolParamBlock,
public AdjusterListener,
public FoldableToolPanel,
public rtengine::AutoChromaListener,
public CurveListener,
public ColorProvider
{
public:
DirPyrDenoise ();
~DirPyrDenoise ();
protected:
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void setBatchMode (bool batchMode);
void curveChanged (CurveEditor* ce);
void setEditProvider (EditDataProvider *provider);
void autoOpenCurve ();
void adjusterChanged (Adjuster* a, double newval);
void enabledChanged ();
void enhanceChanged ();
void medianChanged ();
void autochromaChanged ();
void chromaChanged (double autchroma, double autred, double autblue);
bool chromaComputed_ ();
void noiseChanged (double nresid, double highresid);
bool noiseComputed_ ();
void noiseTilePrev (int tileX, int tileY, int prevX, int prevY, int sizeT, int sizeP);
bool TilePrevComputed_ ();
// void perform_toggled ();
void updateNoiseLabel ();
void LmethodChanged ();
void CmethodChanged ();
void C2methodChanged ();
void updateTileLabel ();
void updatePrevLabel ();
void dmethodChanged ();
void medmethodChanged ();
void methodmedChanged ();
void rgbmethodChanged ();
void smethodChanged ();
virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller);
void setAdjusterBehavior (bool lumaadd, bool lumdetadd, bool chromaadd, bool chromaredadd, bool chromablueadd, bool gammaadd, bool passesadd);
void trimValues (rtengine::procparams::ProcParams* pp);
Glib::ustring getSettingString ();
private:
CurveEditorGroup* NoiscurveEditorG;
CurveEditorGroup* CCcurveEditorG;
Adjuster* luma;
@ -92,50 +140,7 @@ protected:
int nextsizeT;
int nextsizeP;
public:
DirPyrDenoise ();
~DirPyrDenoise ();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr);
void setBatchMode (bool batchMode);
void curveChanged (CurveEditor* ce);
void setEditProvider (EditDataProvider *provider);
void autoOpenCurve ();
void adjusterChanged (Adjuster* a, double newval);
void enabledChanged ();
void enhanceChanged ();
void medianChanged ();
void autochromaChanged ();
void chromaChanged (double autchroma, double autred, double autblue);
bool chromaComputed_ ();
void noiseChanged (double nresid, double highresid);
bool noiseComputed_ ();
void noiseTilePrev (int tileX, int tileY, int prevX, int prevY, int sizeT, int sizeP);
bool TilePrevComputed_ ();
// void perform_toggled ();
void updateNoiseLabel ();
void LmethodChanged ();
void CmethodChanged ();
void C2methodChanged ();
void updateTileLabel ();
void updatePrevLabel ();
void dmethodChanged ();
void medmethodChanged ();
void methodmedChanged ();
void rgbmethodChanged ();
void smethodChanged ();
virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller);
void setAdjusterBehavior (bool lumaadd, bool lumdetadd, bool chromaadd, bool chromaredadd, bool chromablueadd, bool gammaadd, bool passesadd);
void trimValues (rtengine::procparams::ProcParams* pp);
Glib::ustring getSettingString ();
IdleRegister idle_register;
};
#endif

View File

@ -35,6 +35,44 @@
using namespace rtengine::procparams;
namespace
{
struct spparams {
double val;
Glib::ustring str;
MyProgressBar *pProgress;
Glib::RefPtr<Gtk::CssProvider> cssProvider;
};
int setprogressStrUI ( void *p )
{
spparams *s = static_cast<spparams*> (p);
if ( ! s->str.empty() ) {
s->pProgress->set_text ( M (s->str) );
}
if ( s->val >= 0 ) {
s->pProgress->set_fraction ( s->val );
if (s->cssProvider) {
if ( s->val < 1.0 ) {
s->cssProvider->load_from_data ("ProgressBar { background-color: red }");
} else {
s->cssProvider->load_from_data ("ProgressBar { background-color: grey }");
}
s->pProgress->get_style_context()->set_background (s->pProgress->get_window());
}
}
delete s;
return FALSE;
}
}
class EditorPanel::ColorManagementToolbar
{
private:
@ -683,6 +721,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel)
EditorPanel::~EditorPanel ()
{
idle_register.destroy();
history->setHistoryBeforeLineListener (nullptr);
// the order is important!
@ -1017,46 +1056,12 @@ void EditorPanel::setProgressState (bool inProcessing)
g_idle_add (setProgressStateUIThread, p);
}
struct spparams {
double val;
Glib::ustring str;
MyProgressBar *pProgress;
Glib::RefPtr<Gtk::CssProvider> cssProvider;
};
int setprogressStrUI ( void *p )
{
spparams *s = static_cast<spparams*> (p);
if ( ! s->str.empty() ) {
s->pProgress->set_text ( M (s->str) );
}
if ( s->val >= 0 ) {
s->pProgress->set_fraction ( s->val );
if (s->cssProvider) {
if ( s->val < 1.0 ) {
s->cssProvider->load_from_data ("ProgressBar { background-color: red }");
} else {
s->cssProvider->load_from_data ("ProgressBar { background-color: grey }");
}
s->pProgress->get_style_context()->set_background (s->pProgress->get_window());
}
}
delete s;
return 0;
}
void EditorPanel::setProgress (double p)
{
spparams *s = new spparams;
s->val = p;
s->pProgress = progressLabel;
add_idle (setprogressStrUI, s);
idle_register.add(setprogressStrUI, s);
}
void EditorPanel::setProgressStr (Glib::ustring str)
@ -1065,7 +1070,7 @@ void EditorPanel::setProgressStr (Glib::ustring str)
s->str = str;
s->val = -1;
s->pProgress = progressLabel;
add_idle (setprogressStrUI, s);
idle_register.add(setprogressStrUI, s);
}
// This is only called from the ThreadUI, so within the gtk thread

View File

@ -45,102 +45,17 @@ struct EditorPanelIdleHelper {
};
class RTWindow;
class EditorPanel : public Gtk::VBox,
class EditorPanel final :
public Gtk::VBox,
public PParamsChangeListener,
public rtengine::ProgressListener,
public ThumbnailListener,
public HistoryBeforeLineListener,
public rtengine::HistogramListener
{
private:
Glib::ustring lastSaveAsFileName;
bool realized;
protected:
MyProgressBar *progressLabel;
Gtk::ToggleButton* info;
Gtk::ToggleButton* hidehp;
Gtk::ToggleButton* tbShowHideSidePanels;
Gtk::ToggleButton* tbTopPanel_1;
Gtk::ToggleButton* tbRightPanel_1;
Gtk::ToggleButton* tbBeforeLock;
//bool bAllSidePanelsVisible;
Gtk::ToggleButton* beforeAfter;
Gtk::Paned* hpanedl;
Gtk::Paned* hpanedr;
Gtk::Image *iHistoryShow, *iHistoryHide;
Gtk::Image *iTopPanel_1_Show, *iTopPanel_1_Hide;
Gtk::Image *iRightPanel_1_Show, *iRightPanel_1_Hide;
Gtk::Image *iShowHideSidePanels;
Gtk::Image *iShowHideSidePanels_exit;
Gtk::Image *iBeforeLockON, *iBeforeLockOFF;
Gtk::VBox *leftbox;
Gtk::VBox *vboxright;
Gtk::Button* queueimg;
Gtk::Button* saveimgas;
Gtk::Button* sendtogimp;
Gtk::Button* navSync;
Gtk::Button* navNext;
Gtk::Button* navPrev;
class ColorManagementToolbar;
std::unique_ptr<ColorManagementToolbar> colorMgmtToolBar;
ImageAreaPanel* iareapanel;
PreviewHandler* previewHandler;
PreviewHandler* beforePreviewHandler; // for the before-after view
Navigator* navigator;
ImageAreaPanel* beforeIarea; // for the before-after view
Gtk::VBox* beforeBox;
Gtk::VBox* afterBox;
Gtk::Label* beforeLabel;
Gtk::Label* afterLabel;
Gtk::HBox* beforeAfterBox;
Gtk::HBox* beforeHeaderBox;
Gtk::HBox* afterHeaderBox;
Gtk::Frame* ppframe;
ProfilePanel* profilep;
History* history;
HistogramPanel* histogramPanel;
ToolPanelCoordinator* tpc;
RTWindow* parent;
//SaveAsDialog* saveAsDialog;
BatchToolPanelCoordinator* btpCoordinator;
FilePanel* fPanel;
bool firstProcessingDone;
Thumbnail* openThm; // may get invalid on external delete event
Glib::ustring fname; // must be saved separately
rtengine::InitialImage* isrc;
rtengine::StagedImageProcessor* ipc;
rtengine::StagedImageProcessor* beforeIpc; // for the before-after view
EditorPanelIdleHelper* epih;
void close ();
BatchQueueEntry* createBatchQueueEntry ();
bool idle_imageSaved (ProgressConnector<int> *pc, rtengine::IImage16* img, Glib::ustring fname, SaveFormat sf);
bool idle_saveImage (ProgressConnector<rtengine::IImage16*> *pc, Glib::ustring fname, SaveFormat sf);
bool idle_sendToGimp ( ProgressConnector<rtengine::IImage16*> *pc, Glib::ustring fname);
bool idle_sentToGimp (ProgressConnector<int> *pc, rtengine::IImage16* img, Glib::ustring filename);
int err;
time_t processingStartedTime;
sigc::connection ShowHideSidePanelsconn;
bool isProcessing;
public:
explicit EditorPanel (FilePanel* filePanel = nullptr);
virtual ~EditorPanel ();
~EditorPanel ();
void open (Thumbnail* tmb, rtengine::InitialImage* isrc);
void setAspect ();
@ -214,7 +129,93 @@ public:
void updateTabsUsesIcons (bool useIcons);
void updateHistogramPosition (int oldPosition, int newPosition);
Gtk::Paned *catalogPane;
Gtk::Paned* catalogPane;
private:
void close ();
BatchQueueEntry* createBatchQueueEntry ();
bool idle_imageSaved (ProgressConnector<int> *pc, rtengine::IImage16* img, Glib::ustring fname, SaveFormat sf);
bool idle_saveImage (ProgressConnector<rtengine::IImage16*> *pc, Glib::ustring fname, SaveFormat sf);
bool idle_sendToGimp ( ProgressConnector<rtengine::IImage16*> *pc, Glib::ustring fname);
bool idle_sentToGimp (ProgressConnector<int> *pc, rtengine::IImage16* img, Glib::ustring filename);
Glib::ustring lastSaveAsFileName;
bool realized;
MyProgressBar *progressLabel;
Gtk::ToggleButton* info;
Gtk::ToggleButton* hidehp;
Gtk::ToggleButton* tbShowHideSidePanels;
Gtk::ToggleButton* tbTopPanel_1;
Gtk::ToggleButton* tbRightPanel_1;
Gtk::ToggleButton* tbBeforeLock;
//bool bAllSidePanelsVisible;
Gtk::ToggleButton* beforeAfter;
Gtk::Paned* hpanedl;
Gtk::Paned* hpanedr;
Gtk::Image *iHistoryShow, *iHistoryHide;
Gtk::Image *iTopPanel_1_Show, *iTopPanel_1_Hide;
Gtk::Image *iRightPanel_1_Show, *iRightPanel_1_Hide;
Gtk::Image *iShowHideSidePanels;
Gtk::Image *iShowHideSidePanels_exit;
Gtk::Image *iBeforeLockON, *iBeforeLockOFF;
Gtk::VBox *leftbox;
Gtk::VBox *vboxright;
Gtk::Button* queueimg;
Gtk::Button* saveimgas;
Gtk::Button* sendtogimp;
Gtk::Button* navSync;
Gtk::Button* navNext;
Gtk::Button* navPrev;
class ColorManagementToolbar;
std::unique_ptr<ColorManagementToolbar> colorMgmtToolBar;
ImageAreaPanel* iareapanel;
PreviewHandler* previewHandler;
PreviewHandler* beforePreviewHandler; // for the before-after view
Navigator* navigator;
ImageAreaPanel* beforeIarea; // for the before-after view
Gtk::VBox* beforeBox;
Gtk::VBox* afterBox;
Gtk::Label* beforeLabel;
Gtk::Label* afterLabel;
Gtk::HBox* beforeAfterBox;
Gtk::HBox* beforeHeaderBox;
Gtk::HBox* afterHeaderBox;
Gtk::Frame* ppframe;
ProfilePanel* profilep;
History* history;
HistogramPanel* histogramPanel;
ToolPanelCoordinator* tpc;
RTWindow* parent;
//SaveAsDialog* saveAsDialog;
BatchToolPanelCoordinator* btpCoordinator;
FilePanel* fPanel;
bool firstProcessingDone;
Thumbnail* openThm; // may get invalid on external delete event
Glib::ustring fname; // must be saved separately
rtengine::InitialImage* isrc;
rtengine::StagedImageProcessor* ipc;
rtengine::StagedImageProcessor* beforeIpc; // for the before-after view
EditorPanelIdleHelper* epih;
int err;
time_t processingStartedTime;
sigc::connection ShowHideSidePanelsconn;
bool isProcessing;
IdleRegister idle_register;
};
#endif

View File

@ -22,12 +22,6 @@
#include "inspector.h"
#include "placesbrowser.h"
int FilePanelInitUI (void* data)
{
(static_cast<FilePanel*>(data))->init ();
return 0;
}
FilePanel::FilePanel () : parent(nullptr)
{
@ -143,13 +137,21 @@ FilePanel::FilePanel () : parent(nullptr)
fileCatalog->setFileSelectionChangeListener (tpc);
fileCatalog->setFileSelectionListener (this);
add_idle (FilePanelInitUI, this);
const auto func = [](gpointer data) -> gboolean {
static_cast<FilePanel*>(data)->init();
return FALSE;
};
idle_register.add(func, this);
show_all ();
}
FilePanel::~FilePanel ()
{
idle_register.destroy();
rightNotebookSwitchConn.disconnect();
if (inspectorPanel) {

View File

@ -33,38 +33,12 @@
#include "progressconnector.h"
class RTWindow;
class FilePanel : public Gtk::HPaned,
class FilePanel final :
public Gtk::HPaned,
public FileSelectionListener,
public PParamsChangeListener
{
protected:
//DirBrowser* dirBrowser;
PlacesBrowser* placesBrowser;
RecentBrowser* recentBrowser;
// FileCatalog* fileCatalog; // filecatalog is the file browser with the button bar above it
Inspector* inspectorPanel;
Gtk::VPaned* tpcPaned;
BatchToolPanelCoordinator* tpc;
History* history;
//FilterPanel* filterPanel;
RTWindow* parent;
Gtk::Notebook* rightNotebook;
sigc::connection rightNotebookSwitchConn;
struct pendingLoad {
bool complete;
ProgressConnector<rtengine::InitialImage*> *pc;
Thumbnail *thm;
};
MyMutex pendingLoadMutex;
std::vector<struct pendingLoad*> pendingLoads;
int error;
void on_NB_switch_page(Gtk::Widget* page, guint page_num);
public:
FilePanel ();
~FilePanel ();
@ -107,6 +81,32 @@ public:
bool handleShortcutKey (GdkEventKey* event);
void updateTPVScrollbar (bool hide);
void updateTabsUsesIcons (bool useIcons);
private:
void on_NB_switch_page(Gtk::Widget* page, guint page_num);
PlacesBrowser* placesBrowser;
RecentBrowser* recentBrowser;
Inspector* inspectorPanel;
Gtk::VPaned* tpcPaned;
BatchToolPanelCoordinator* tpc;
History* history;
RTWindow* parent;
Gtk::Notebook* rightNotebook;
sigc::connection rightNotebookSwitchConn;
struct pendingLoad {
bool complete;
ProgressConnector<rtengine::InitialImage*> *pc;
Thumbnail *thm;
};
MyMutex pendingLoadMutex;
std::vector<struct pendingLoad*> pendingLoads;
int error;
IdleRegister idle_register;
};
#endif

View File

@ -43,6 +43,53 @@ guint add_idle (GSourceFunc function, gpointer data)
//gtk_main_iteration_do(false);
}
IdleRegister::~IdleRegister()
{
destroy();
}
void IdleRegister::add(GSourceFunc function, gpointer data)
{
struct DataWrapper {
IdleRegister* const self;
GSourceFunc function;
gpointer data;
};
const auto dispatch = [](gpointer data) -> gboolean {
DataWrapper* const data_wrapper = static_cast<DataWrapper*>(data);
if (!data_wrapper->function(data_wrapper->data)) {
data_wrapper->self->mutex.lock();
data_wrapper->self->ids.erase(data_wrapper);
data_wrapper->self->mutex.unlock();
delete data_wrapper;
return FALSE;
}
return TRUE;
};
DataWrapper* const data_wrapper = new DataWrapper{
this,
function,
data
};
mutex.lock();
ids[data_wrapper] = add_idle(dispatch, data_wrapper);
mutex.unlock();
}
void IdleRegister::destroy()
{
mutex.lock();
for (const auto id : ids) {
g_source_remove(id.second);
}
mutex.unlock();
}
/*
gboolean giveMeAGo(void* data) {

View File

@ -19,13 +19,17 @@
#ifndef __GUI_UTILS_
#define __GUI_UTILS_
#include <map>
#include <gtkmm.h>
#include <cairomm/cairomm.h>
#include "../rtengine/rtengine.h"
#include "../rtengine/coord.h"
#include "../rtengine/noncopyable.h"
#include "../rtengine/rtengine.h"
#include "rtimage.h"
#include <sstream>
#include <iostream>
Glib::ustring escapeHtmlChars(const Glib::ustring &src);
bool removeIfThere (Gtk::Container* cont, Gtk::Widget* w, bool increference = true);
@ -40,6 +44,20 @@ void setExpandAlignProperties(Gtk::Widget *widget, bool hExpand, bool vExpand, e
guint add_idle (GSourceFunc function, gpointer data);
class IdleRegister final :
public rtengine::NonCopyable
{
public:
~IdleRegister();
void add(GSourceFunc function, gpointer data);
void destroy();
private:
std::map<void*, guint> ids;
MyMutex mutex;
};
// TODO: The documentation says gdk_threads_enter and gdk_threads_leave should be replaced
// by g_main_context_invoke(), g_idle_add() and related functions, but this will require more extensive changes.
// We silence those warnings until then so that we notice the others.

View File

@ -26,14 +26,14 @@ using namespace rtengine::procparams;
Glib::ustring eventDescrArray[NUMOFEVENTS];
History::History (bool bookmarkSupport) : blistener(nullptr), tpc (nullptr), bmnum (1)
History::History (bool bookmarkSupport) : blistener (nullptr), tpc (nullptr), bmnum (1)
{
blistenerLock = false; // sets default that the Before preview will not be locked
// fill history event message array
for (int i = 0; i < NUMOFEVENTS; i++) {
eventDescrArray[i] = M(Glib::ustring::compose("HISTORY_MSG_%1", i + 1));
eventDescrArray[i] = M (Glib::ustring::compose ("HISTORY_MSG_%1", i + 1));
}
// History List
@ -41,7 +41,7 @@ History::History (bool bookmarkSupport) : blistener(nullptr), tpc (nullptr), bmn
Gtk::ScrolledWindow* hscrollw = Gtk::manage (new Gtk::ScrolledWindow ());
hscrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
Gtk::Frame* histFrame = Gtk::manage (new Gtk::Frame (M("HISTORY_LABEL")));
Gtk::Frame* histFrame = Gtk::manage (new Gtk::Frame (M ("HISTORY_LABEL")));
histFrame->set_name ("HistoryPanel");
histFrame->add (*hscrollw);
@ -51,10 +51,10 @@ History::History (bool bookmarkSupport) : blistener(nullptr), tpc (nullptr), bmn
historyModel = Gtk::ListStore::create (historyColumns);
hTreeView->set_model (historyModel);
hTreeView->set_headers_visible (false);
hTreeView->set_hscroll_policy(Gtk::SCROLL_MINIMUM);
hTreeView->set_vscroll_policy(Gtk::SCROLL_NATURAL);
hTreeView->set_size_request(80, -1);
hTreeView->set_resize_mode(Gtk::RESIZE_QUEUE);
hTreeView->set_hscroll_policy (Gtk::SCROLL_MINIMUM);
hTreeView->set_vscroll_policy (Gtk::SCROLL_NATURAL);
hTreeView->set_size_request (80, -1);
hTreeView->set_resize_mode (Gtk::RESIZE_QUEUE);
Gtk::CellRendererText *changecrt = Gtk::manage (new Gtk::CellRendererText());
changecrt->property_ellipsize() = Pango::ELLIPSIZE_END;
@ -63,46 +63,46 @@ History::History (bool bookmarkSupport) : blistener(nullptr), tpc (nullptr), bmn
Gtk::TreeView::Column *hviewcol = Gtk::manage (new Gtk::TreeView::Column (""));
hviewcol->pack_start (*changecrt, true);
hviewcol->add_attribute (changecrt->property_markup (), historyColumns.text);
hviewcol->set_expand(true);
hviewcol->set_expand (true);
hviewcol->set_resizable (true);
hviewcol->set_fixed_width(35);
hviewcol->set_min_width(35);
hviewcol->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
hviewcol->set_fixed_width (35);
hviewcol->set_min_width (35);
hviewcol->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
Gtk::TreeView::Column *hviewcol2 = Gtk::manage (new Gtk::TreeView::Column (""));
hviewcol2->pack_start (*valuecrt, true);
hviewcol2->add_attribute (valuecrt->property_markup (), historyColumns.value);
hviewcol2->set_expand(true);
hviewcol2->set_resizable(true);
hviewcol2->set_fixed_width(35);
hviewcol2->set_min_width(35);
hviewcol2->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
valuecrt->set_alignment(1.f, 0.f);
hviewcol2->set_expand (true);
hviewcol2->set_resizable (true);
hviewcol2->set_fixed_width (35);
hviewcol2->set_min_width (35);
hviewcol2->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
valuecrt->set_alignment (1.f, 0.f);
hTreeView->set_has_tooltip(true);
hTreeView->signal_query_tooltip().connect( sigc::mem_fun(*this, &History::on_query_tooltip) );
hTreeView->set_has_tooltip (true);
hTreeView->signal_query_tooltip().connect ( sigc::mem_fun (*this, &History::on_query_tooltip) );
hTreeView->append_column (*hviewcol);
hTreeView->append_column (*hviewcol2);
selchangehist = hTreeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &History::historySelectionChanged));
selchangehist = hTreeView->get_selection()->signal_changed().connect (sigc::mem_fun (*this, &History::historySelectionChanged));
// Bookmark List
// ~~~~~~~~~~~~~
Gtk::HBox* ahbox = Gtk::manage (new Gtk::HBox ());
addBookmark = Gtk::manage (new Gtk::Button ()); // M("HISTORY_NEWSNAPSHOT")
setExpandAlignProperties(addBookmark, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
setExpandAlignProperties (addBookmark, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
//addBookmark->get_style_context()->set_junction_sides(Gtk::JUNCTION_RIGHT);
addBookmark->get_style_context()->add_class("Left");
addBookmark->set_tooltip_markup (M("HISTORY_NEWSNAPSHOT_TOOLTIP"));
addBookmark->get_style_context()->add_class ("Left");
addBookmark->set_tooltip_markup (M ("HISTORY_NEWSNAPSHOT_TOOLTIP"));
Gtk::Image* addimg = Gtk::manage (new RTImage ("gtk-add.png"));
addBookmark->set_image (*addimg);
ahbox->pack_start (*addBookmark);
delBookmark = Gtk::manage (new Gtk::Button ()); // M("HISTORY_DELSNAPSHOT")
setExpandAlignProperties(delBookmark, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
setExpandAlignProperties (delBookmark, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START);
//delBookmark->get_style_context()->set_junction_sides(Gtk::JUNCTION_LEFT);
delBookmark->get_style_context()->add_class("Right");
delBookmark->get_style_context()->add_class ("Right");
Gtk::Image* delimg = Gtk::manage (new RTImage ("list-remove.png"));
delBookmark->set_image (*delimg);
ahbox->pack_start (*delBookmark);
@ -112,19 +112,19 @@ History::History (bool bookmarkSupport) : blistener(nullptr), tpc (nullptr), bmn
bscrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
bscrollw->set_size_request (-1, 45);
Gtk::Frame* bmFrame = Gtk::manage (new Gtk::Frame (M("HISTORY_SNAPSHOTS")));
bmFrame->set_name("Snapshots");
Gtk::Frame* bmFrame = Gtk::manage (new Gtk::Frame (M ("HISTORY_SNAPSHOTS")));
bmFrame->set_name ("Snapshots");
Gtk::VBox* bmBox = Gtk::manage (new Gtk::VBox ());
bmFrame->add (*bmBox);
bmBox->pack_start (*bscrollw, Gtk::PACK_EXPAND_WIDGET, 4);
bmBox->pack_end (*ahbox, Gtk::PACK_SHRINK, 4);
bmBox->set_size_request(-1,60);
bmBox->set_size_request (-1, 60);
if (bookmarkSupport) {
historyVPaned = Gtk::manage ( new Gtk::VPaned () );
historyVPaned->pack1 (*histFrame, true, true);
historyVPaned->pack2 (*bmFrame, false, false);
pack_start(*historyVPaned);
pack_start (*historyVPaned);
} else {
pack_start (*histFrame);
}
@ -136,19 +136,19 @@ History::History (bool bookmarkSupport) : blistener(nullptr), tpc (nullptr), bmn
bookmarkModel = Gtk::ListStore::create (bookmarkColumns);
bTreeView->set_model (bookmarkModel);
bTreeView->set_headers_visible (false);
bTreeView->append_column_editable (M("HISTORY_SNAPSHOTS"), bookmarkColumns.text);
bTreeView->append_column_editable (M ("HISTORY_SNAPSHOTS"), bookmarkColumns.text);
selchangebm = bTreeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &History::bookmarkSelectionChanged));
selchangebm = bTreeView->get_selection()->signal_changed().connect (sigc::mem_fun (*this, &History::bookmarkSelectionChanged));
addBookmark->signal_clicked().connect( sigc::mem_fun(*this, &History::addBookmarkPressed) );
delBookmark->signal_clicked().connect( sigc::mem_fun(*this, &History::delBookmarkPressed) );
addBookmark->signal_clicked().connect ( sigc::mem_fun (*this, &History::addBookmarkPressed) );
delBookmark->signal_clicked().connect ( sigc::mem_fun (*this, &History::delBookmarkPressed) );
//hTreeView->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_HORIZONTAL);
hTreeView->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_BOTH);
//hTreeView->signal_size_allocate().connect( sigc::mem_fun(*this, &History::resized) );
hTreeView->set_enable_search(false);
bTreeView->set_enable_search(false);
hTreeView->set_enable_search (false);
bTreeView->set_enable_search (false);
show_all_children ();
}
@ -156,7 +156,7 @@ History::History (bool bookmarkSupport) : blistener(nullptr), tpc (nullptr), bmn
void History::initHistory ()
{
ConnectionBlocker selBlocker(selchangehist);
ConnectionBlocker selBlocker (selchangehist);
historyModel->clear ();
bookmarkModel->clear ();
}
@ -182,8 +182,8 @@ void History::historySelectionChanged ()
if (row && tpc) {
ProcParams pparams = row[historyColumns.params];
ParamsEdited pe(true);
PartialProfile pp(&pparams, &pe);
ParamsEdited pe (true);
PartialProfile pp (&pparams, &pe);
ParamsEdited paramsEdited = row[historyColumns.paramsEdited];
tpc->profileChange (&pp, EvHistoryBrowsed, row[historyColumns.text], &paramsEdited);
}
@ -215,8 +215,8 @@ void History::bookmarkSelectionChanged ()
if (row && tpc) {
ProcParams pparams = row[bookmarkColumns.params];
ParamsEdited pe(true);
PartialProfile pp(&pparams, &pe);
ParamsEdited pe (true);
PartialProfile pp (&pparams, &pe);
ParamsEdited paramsEdited = row[bookmarkColumns.paramsEdited];
tpc->profileChange (&pp, EvBookmarkSelected, row[bookmarkColumns.text], &paramsEdited);
}
@ -262,36 +262,38 @@ void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring
}
// if there is no last item or its chev!=ev, create a new one
if (size == 0 || !row || row[historyColumns.chev] != ev || ev == EvProfileChanged) {
Gtk::TreeModel::Row newrow = *(historyModel->append());
newrow[historyColumns.realText] = eventDescrArray[ev];
newrow[historyColumns.text] = text;
newrow[historyColumns.value] = descr;
newrow[historyColumns.chev] = ev;
newrow[historyColumns.params] = *params;
newrow[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited;
if (descr != "") {
if (size == 0 || !row || row[historyColumns.chev] != ev || ev == EvProfileChanged) {
Gtk::TreeModel::Row newrow = * (historyModel->append());
newrow[historyColumns.realText] = eventDescrArray[ev];
newrow[historyColumns.text] = text;
newrow[historyColumns.value] = descr;
newrow[historyColumns.chev] = ev;
newrow[historyColumns.params] = *params;
newrow[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited;
if (ev != EvBookmarkSelected) {
selection->select (newrow);
if (ev != EvBookmarkSelected) {
selection->select (newrow);
}
if (blistener && row && !blistenerLock) {
blistener->historyBeforeLineChanged (row[historyColumns.params]);
} else if (blistener && size == 0 && !blistenerLock) {
blistener->historyBeforeLineChanged (newrow[historyColumns.params]);
}
}
// else just update it
else {
row[historyColumns.realText] = eventDescrArray[ev];
row[historyColumns.text] = text;
row[historyColumns.value] = descr;
row[historyColumns.chev] = ev;
row[historyColumns.params] = *params;
row[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited;
if (blistener && row && !blistenerLock) {
blistener->historyBeforeLineChanged (row[historyColumns.params]);
} else if (blistener && size == 0 && !blistenerLock) {
blistener->historyBeforeLineChanged (newrow[historyColumns.params]);
}
}
// else just update it
else {
row[historyColumns.realText] = eventDescrArray[ev];
row[historyColumns.text] = text;
row[historyColumns.value] = descr;
row[historyColumns.chev] = ev;
row[historyColumns.params] = *params;
row[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited;
if (ev != EvBookmarkSelected) {
selection->select (row);
if (ev != EvBookmarkSelected) {
selection->select (row);
}
}
}
@ -322,7 +324,7 @@ void History::addBookmarkWithText (Glib::ustring text)
}
// append new row to bookmarks
Gtk::TreeModel::Row newrow = *(bookmarkModel->append());
Gtk::TreeModel::Row newrow = * (bookmarkModel->append());
newrow[bookmarkColumns.text] = text;
ProcParams params = row[historyColumns.params];
newrow[bookmarkColumns.params] = params;
@ -334,7 +336,7 @@ void History::addBookmarkPressed ()
{
if (hTreeView->get_selection()->get_selected()) {
addBookmarkWithText (Glib::ustring::compose ("%1 %2", M("HISTORY_SNAPSHOT"), bmnum++));
addBookmarkWithText (Glib::ustring::compose ("%1 %2", M ("HISTORY_SNAPSHOT"), bmnum++));
}
}
@ -369,7 +371,7 @@ void History::undo ()
int size = historyModel->children().size ();
if (size > 1) {
selection->select (historyModel->children().operator [](size - 2));
selection->select (historyModel->children().operator [] (size - 2));
}
}
}
@ -390,7 +392,7 @@ void History::redo ()
int size = historyModel->children().size ();
if (size > 1) {
selection->select (historyModel->children().operator [](size - 2));
selection->select (historyModel->children().operator [] (size - 2));
}
}
}
@ -416,22 +418,24 @@ bool History::getBeforeLineParams (rtengine::procparams::ProcParams& params)
return true;
}
bool History::on_query_tooltip(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip) {
bool History::on_query_tooltip (int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip)
{
bool displayTooltip = false;
Gtk::TreeModel::Path path;
int x2 = -1;
int y2 = -1;
hTreeView->convert_widget_to_bin_window_coords(x, y, x2, y2);
bool hasPath = hTreeView->get_path_at_pos(x2, y2, path);
hTreeView->convert_widget_to_bin_window_coords (x, y, x2, y2);
bool hasPath = hTreeView->get_path_at_pos (x2, y2, path);
if (hasPath) {
if (path && !path.empty()) {
Gtk::TreeModel::iterator iter = historyModel->get_iter(path);
Gtk::TreeModel::iterator iter = historyModel->get_iter (path);
if (iter) {
Glib::ustring param, val;
iter->get_value<Glib::ustring>(1, param);
iter->get_value<Glib::ustring>(2, val);
iter->get_value<Glib::ustring> (1, param);
iter->get_value<Glib::ustring> (2, val);
/*
*
@ -450,10 +454,11 @@ bool History::on_query_tooltip(int x, int y, bool keyboard_tooltip, const Glib::
tooltip->set_custom(*hbox);
*/
tooltip->set_text(param+" : "+val);
tooltip->set_text (param + " : " + val);
displayTooltip = true;
}
}
}
return displayTooltip;
}

View File

@ -1037,27 +1037,27 @@ bool Locallab::localretComputed_ ()
// printf("G2 anbspot=%i\n", anbspot->getValue());
if (listener) { //for all sliders
listener->panelChanged (Evlocallabanbspot, anbspot->getTextValue());
listener->panelChanged (Evlocallabanbspot, "");//anbspot->getTextValue());
}
if (listener) {//for curve
listener->panelChanged (EvlocallabCTgainCurverab, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (EvlocallabCTgainCurverab, M (""));
}
if (listener) {//for curve
listener->panelChanged (EvlocallabCTgainCurve, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (EvlocallabCTgainCurve, M (""));
}
if (listener) {//for curve
listener->panelChanged (Evlocallabllshape, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (Evlocallabllshape, M (""));
}
if (listener) {//for curve
listener->panelChanged (Evlocallabccshape, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (Evlocallabccshape, M (""));
}
if (listener) {//for curve
listener->panelChanged (EvlocallabLHshape, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (EvlocallabLHshape, M (""));
}
@ -1331,11 +1331,11 @@ bool Locallab::localComputed_ ()
//add events for each cases
if (listener) { //for all sliders
listener->panelChanged (Evlocallabanbspot, anbspot->getTextValue());
listener->panelChanged (Evlocallabanbspot, "");//anbspot->getTextValue());
}
if (listener) {//for curve
listener->panelChanged (EvlocallabCTgainCurverab, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (EvlocallabCTgainCurverab, M (""));
}
if (listener) {//for inverse color
@ -1375,19 +1375,19 @@ bool Locallab::localComputed_ ()
}
if (listener) {//for curve reti
listener->panelChanged (EvlocallabCTgainCurve, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (EvlocallabCTgainCurve, M (""));
}
if (listener) {//for curve LL
listener->panelChanged (Evlocallabllshape, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (Evlocallabllshape, M (""));
}
if (listener) {//for curve LH
listener->panelChanged (EvlocallabLHshape, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (EvlocallabLHshape, M (""));
}
if (listener) {//for curve LH
listener->panelChanged (Evlocallabccshape, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (Evlocallabccshape, M (""));
}
return false;
@ -2000,7 +2000,7 @@ void Locallab::curveChanged (CurveEditor* ce)
if (listener && getEnabled()) {
if (ce == cTgainshape) {
listener->panelChanged (EvlocallabCTgainCurve, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (EvlocallabCTgainCurve, M ("HISTORY_CUSTOMCURVE"));//HISTORY_CUSTOMCURVE
int strval = retrab->getValue();
//update MIP
retrab->setValue (strval + 1);
@ -2012,9 +2012,9 @@ void Locallab::curveChanged (CurveEditor* ce)
}
else if (ce == cTgainshaperab) {
listener->panelChanged (EvlocallabCTgainCurverab, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (EvlocallabCTgainCurverab, M (""));
} else if (ce == LHshape) {
listener->panelChanged (EvlocallabLHshape, M ("HISTORY_CUSTOMCURVE"));
listener->panelChanged (EvlocallabLHshape, M (""));
int strval = retrab->getValue();
//update MIP
retrab->setValue (strval + 1);
@ -2612,7 +2612,7 @@ void Locallab::adjusterChanged (Adjuster * a, double newval)
} else if (a == sensih) {
listener->panelChanged (Evlocallabsensih, sensih->getTextValue());
} else if (a == retrab) {
listener->panelChanged (Evlocallabretrab, retrab->getTextValue());
listener->panelChanged (Evlocallabretrab, "");//retrab->getTextValue());
} else if (a == radius) {
listener->panelChanged (Evlocallabradius, radius->getTextValue());
} else if (a == strength) {
@ -2638,7 +2638,7 @@ void Locallab::adjusterChanged (Adjuster * a, double newval)
} else if (a == nbspot) {
listener->panelChanged (Evlocallabnbspot, nbspot->getTextValue());
} else if (a == anbspot) {
listener->panelChanged (Evlocallabanbspot, anbspot->getTextValue());
listener->panelChanged (Evlocallabanbspot, "");//anbspot->getTextValue());
} else if (a == vart) {
listener->panelChanged (Evlocallabvart, vart->getTextValue());
} else if (a == chrrt) {

View File

@ -118,7 +118,7 @@ Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), fals
Resize::~Resize ()
{
idle_register.destroy();
delete scale;
delete sizeBox;
}
@ -352,68 +352,76 @@ void Resize::sizeChanged (int mw, int mh, int ow, int oh)
void Resize::setDimensions ()
{
const auto func = [](gpointer data) -> gboolean {
Resize* const self = static_cast<Resize*>(data);
int refw, refh;
self->wconn.block(true);
self->hconn.block(true);
self->scale->block(true);
wconn.block (true);
hconn.block (true);
scale->block(true);
int refw, refh;
if (appliesTo->get_active_row_number() == 0 && cropw) {
// Applies to Cropped area
refw = cropw;
refh = croph;
} else {
// Applies to Full image or crop is disabled
refw = maxw;
refh = maxh;
}
GThreadLock lock;
w->set_range (32, 4 * refw);
h->set_range (32, 4 * refh);
double tmpScale;
switch (spec->get_active_row_number()) {
case (0): // Scale mode
w->set_value((double)((int)( (double)(refw) * scale->getValue() + 0.5) ));
h->set_value((double)((int)( (double)(refh) * scale->getValue() + 0.5) ));
break;
case (1): // Width mode
tmpScale = w->get_value() / (double)refw;
scale->setValue (tmpScale);
h->set_value((double)((int)( (double)(refh) * tmpScale + 0.5) ));
break;
case (2): // Height mode
tmpScale = h->get_value() / (double)refh;
scale->setValue (tmpScale);
w->set_value((double)((int)( (double)(refw) * tmpScale + 0.5) ));
break;
case (3): { // Bounding box mode
double wSliderValue = w->get_value();
double hSliderValue = h->get_value();
if ( (wSliderValue / hSliderValue) < ((double)refw / (double)refh)) {
tmpScale = wSliderValue / (double)refw;
if (self->appliesTo->get_active_row_number() == 0 && self->cropw) {
// Applies to Cropped area
refw = self->cropw;
refh = self->croph;
} else {
tmpScale = hSliderValue / (double)refh;
// Applies to Full image or crop is disabled
refw = self->maxw;
refh = self->maxh;
}
scale->setValue (tmpScale);
break;
}
self->w->set_range(32, 4 * refw);
self->h->set_range(32, 4 * refh);
default:
break;
}
switch (self->spec->get_active_row_number()) {
case 0: {
// Scale mode
self->w->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refw) * self->scale->getValue() + 0.5)));
self->h->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refh) * self->scale->getValue() + 0.5)));
break;
}
scale->block(false);
wconn.block (false);
hconn.block (false);
case 1: {
// Width mode
const double tmp_scale = self->w->get_value() / static_cast<double>(refw);
self->scale->setValue(tmp_scale);
self->h->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refh) * tmp_scale + 0.5)));
break;
}
case 2: {
// Height mode
const double tmp_scale = self->h->get_value() / static_cast<double>(refh);
self->scale->setValue(tmp_scale);
self->w->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refw) * tmp_scale + 0.5)));
break;
}
case 3: {
// Bounding box mode
const double tmp_scale =
self->w->get_value() / self->h->get_value() < static_cast<double>(refw) / static_cast<double>(refh)
? self->w->get_value() / static_cast<double>(refw)
: self->h->get_value() / static_cast<double>(refh);
self->scale->setValue(tmp_scale);
break;
}
default: {
break;
}
}
self->scale->block(false);
self->wconn.block(false);
self->hconn.block(false);
return FALSE;
};
idle_register.add(func, this);
}
void Resize::fitBoxScale()

View File

@ -25,25 +25,13 @@
#include "toolpanel.h"
#include "guiutils.h"
class Resize : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::SizeListener
class Resize final :
public ToolParamBlock,
public AdjusterListener,
public FoldableToolPanel,
public rtengine::SizeListener
{
protected:
Adjuster* scale;
Gtk::VBox* sizeBox;
MyComboBoxText* appliesTo;
MyComboBoxText* method;
MyComboBoxText* spec;
MySpinButton* w;
MySpinButton* h;
int maxw, maxh;
int cropw, croph;
sigc::connection sconn, aconn, wconn, hconn;
bool wDirty, hDirty;
ToolParamBlock* packBox;
public:
Resize ();
~Resize ();
@ -75,6 +63,20 @@ private:
int getComputedHeight ();
void notifyBBox ();
void updateGUI ();
Adjuster* scale;
Gtk::VBox* sizeBox;
MyComboBoxText* appliesTo;
MyComboBoxText* method;
MyComboBoxText* spec;
MySpinButton* w;
MySpinButton* h;
int maxw, maxh;
int cropw, croph;
sigc::connection sconn, aconn, wconn, hconn;
bool wDirty, hDirty;
ToolParamBlock* packBox;
IdleRegister idle_register;
};
#endif