Fixed crash and add suppress bad message in history and mip in cache
This commit is contained in:
commit
161a56eec5
@ -40,5 +40,5 @@ http://rawpedia.rawtherapee.com/Linux
|
||||
Windows:
|
||||
http://rawpedia.rawtherapee.com/Windows
|
||||
|
||||
OS X:
|
||||
macOS:
|
||||
http://rawpedia.rawtherapee.com/macOS
|
||||
|
BIN
rtdata/dcpprofiles/NIKON D300.dcp
Normal file
BIN
rtdata/dcpprofiles/NIKON D300.dcp
Normal file
Binary file not shown.
BIN
rtdata/dcpprofiles/NIKON D80.dcp
Normal file
BIN
rtdata/dcpprofiles/NIKON D80.dcp
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
rtdata/dcpprofiles/OLYMPUS E-M1MarkII.dcp
Normal file
BIN
rtdata/dcpprofiles/OLYMPUS E-M1MarkII.dcp
Normal file
Binary file not shown.
BIN
rtdata/dcpprofiles/Panasonic DMC-GX85.dcp
Normal file
BIN
rtdata/dcpprofiles/Panasonic DMC-GX85.dcp
Normal file
Binary file not shown.
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -69,7 +69,7 @@
|
||||
#define ALIGNED64
|
||||
#define ALIGNED16
|
||||
#endif
|
||||
#if !defined(__clang__) && defined _OPENMP
|
||||
#if defined _OPENMP
|
||||
#define _RT_NESTED_OPENMP
|
||||
#endif
|
||||
#endif
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
800
rtengine/xtranscompressed.cc
Normal file
800
rtengine/xtranscompressed.cc
Normal 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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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_ ()
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
});
|
||||
|
||||
|
@ -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_ ()
|
||||
|
@ -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
|
||||
|
@ -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_ ()
|
||||
|
@ -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
|
||||
|
113
rtgui/crop.cc
113
rtgui/crop.cc
@ -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 ()
|
||||
|
68
rtgui/crop.h
68
rtgui/crop.h
@ -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
|
||||
|
@ -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 ();
|
||||
|
@ -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
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
#include "dirbrowser.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -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_ ()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
161
rtgui/history.cc
161
rtgui/history.cc
@ -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], ¶msEdited);
|
||||
}
|
||||
@ -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], ¶msEdited);
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
118
rtgui/resize.cc
118
rtgui/resize.cc
@ -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()
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user