Sychronization of crop image processing; see issue #549
This commit is contained in:
@@ -25,11 +25,6 @@ CropHandler::CropHandler ()
|
||||
: zoom(10), cx(0), cy(0), cw(0), ch(0),
|
||||
cropX(0), cropY(0), cropW(0), cropH(0), enabled(false),
|
||||
cropimg(NULL), ipc(NULL), crop(NULL), listener(NULL) {
|
||||
|
||||
chi = new CropHandlerIdleHelper;
|
||||
chi->destroyed = false;
|
||||
chi->pending = 0;
|
||||
chi->cropHandler = this;
|
||||
}
|
||||
|
||||
CropHandler::~CropHandler () {
|
||||
@@ -40,12 +35,6 @@ CropHandler::~CropHandler () {
|
||||
setEnabled (false);
|
||||
if (crop)
|
||||
crop->destroy ();
|
||||
cimg.lock ();
|
||||
if (chi->pending)
|
||||
chi->destroyed = true;
|
||||
else
|
||||
delete chi;
|
||||
cimg.unlock ();
|
||||
}
|
||||
|
||||
void CropHandler::newImage (StagedImageProcessor* ipc_) {
|
||||
@@ -64,13 +53,7 @@ void CropHandler::newImage (StagedImageProcessor* ipc_) {
|
||||
}
|
||||
|
||||
void CropHandler::sizeChanged (int x, int y, int ow, int oh) { // the ipc notifies it to keep track size changes like rotation
|
||||
|
||||
compDim ();
|
||||
|
||||
// this should be put into an idle source!!!
|
||||
/* if (listener)
|
||||
listener->cropWindowChanged ();
|
||||
*/
|
||||
}
|
||||
|
||||
double CropHandler::getFitZoom () {
|
||||
@@ -80,12 +63,12 @@ double CropHandler::getFitZoom () {
|
||||
double z2 = (double) ww / ipc->getFullWidth ();
|
||||
return z1<z2 ? z1 : z2;
|
||||
}
|
||||
else
|
||||
else {
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
void CropHandler::setZoom (int z, int centerx, int centery) {
|
||||
|
||||
int x = cx + cw / 2;
|
||||
int y = cy + ch / 2;
|
||||
|
||||
@@ -116,6 +99,7 @@ void CropHandler::setWSize (int w, int h) {
|
||||
|
||||
ww = w;
|
||||
wh = h;
|
||||
|
||||
if (zoom>=1000) {
|
||||
cw = ww * 1000 / zoom;
|
||||
ch = wh * 1000 / zoom;
|
||||
@@ -152,88 +136,20 @@ void CropHandler::getPosition (int& x, int& y) {
|
||||
y = cropY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create the piece of preview image that will be integrally copied in the preview area
|
||||
*/
|
||||
int createpixbufs (void* data) {
|
||||
|
||||
gdk_threads_enter ();
|
||||
|
||||
CropHandlerIdleHelper* chi = (CropHandlerIdleHelper*) data;
|
||||
if (chi->destroyed) {
|
||||
if (chi->pending == 1)
|
||||
delete chi;
|
||||
else
|
||||
chi->pending--;
|
||||
gdk_threads_leave ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CropHandler* ch = chi->cropHandler;
|
||||
|
||||
ch->cimg.lock ();
|
||||
ch->cropPixbuf.clear ();
|
||||
|
||||
if (!ch->enabled) {
|
||||
delete [] ch->cropimg;
|
||||
ch->cropimg = NULL;
|
||||
ch->cimg.unlock ();
|
||||
gdk_threads_leave ();
|
||||
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;
|
||||
|
||||
// Create a temporary pixbuf to copy the piece of the full size image
|
||||
Glib::RefPtr<Gdk::Pixbuf> tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, ch->cropimg_height, 3*ch->cropimg_width);
|
||||
// Create the real preview image
|
||||
ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh);
|
||||
// Rescale the piece of the full size image and put it in the preview image
|
||||
tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom/1000.0, czoom/1000.0, Gdk::INTERP_NEAREST);
|
||||
// Delete the temporary pixbuf
|
||||
tmpPixbuf.clear ();
|
||||
}
|
||||
delete [] ch->cropimg;
|
||||
ch->cropimg = NULL;
|
||||
}
|
||||
ch->cimg.unlock ();
|
||||
if (ch->listener) {
|
||||
ch->listener->cropImageUpdated ();
|
||||
if (ch->initial) {
|
||||
ch->listener->initialImageArrived ();
|
||||
ch->initial = false;
|
||||
}
|
||||
}
|
||||
|
||||
chi->pending--;
|
||||
|
||||
gdk_threads_leave ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CropHandler::setDetailedCrop (IImage8* im, rtengine::procparams::CropParams cp, int ax, int ay, int aw, int ah, int askip) {
|
||||
|
||||
if (!enabled)
|
||||
return;
|
||||
cimg.lock ();
|
||||
|
||||
cimg.lock ();
|
||||
cropPixbuf.clear ();
|
||||
if (cropimg) delete [] cropimg;
|
||||
cropimg = NULL;
|
||||
|
||||
if (!enabled) {
|
||||
cimg.unlock ();
|
||||
return;
|
||||
}
|
||||
|
||||
cropParams = cp;
|
||||
|
||||
cropPixbuf.clear ();
|
||||
if (cropimg)
|
||||
delete [] cropimg;
|
||||
cropimg = NULL;
|
||||
|
||||
if (ax==cropX && ay==cropY && aw==cropW && ah==cropH && askip==(zoom>=1000?1:zoom)) {
|
||||
cropimg_width = im->getWidth ();
|
||||
@@ -245,10 +161,41 @@ void CropHandler::setDetailedCrop (IImage8* im, rtengine::procparams::CropParams
|
||||
ciw = aw;
|
||||
cih = ah;
|
||||
cis = askip;
|
||||
chi->pending++;
|
||||
g_idle_add (createpixbufs, chi);
|
||||
}
|
||||
cimg.unlock ();
|
||||
|
||||
// Create the piece of preview image that will be integrally copied in the preview area
|
||||
if (cix==cropX && ciy==cropY && ciw==cropW && cih==cropH && cis==(zoom>=1000?1:zoom)) {
|
||||
// calculate final image size
|
||||
int czoom = zoom<1000 ? 1000 : zoom;
|
||||
int imw = cropimg_width * czoom / 1000;
|
||||
int imh = cropimg_height * czoom / 1000;
|
||||
if (imw>ww)
|
||||
imw = ww;
|
||||
if (imh>wh)
|
||||
imh = wh;
|
||||
|
||||
// Create a temporary pixbuf to copy the piece of the full size image
|
||||
Glib::RefPtr<Gdk::Pixbuf> tmpPixbuf = Gdk::Pixbuf::create_from_data (cropimg, Gdk::COLORSPACE_RGB, false, 8, cropimg_width, cropimg_height, 3*cropimg_width);
|
||||
// Create the real preview image
|
||||
cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh);
|
||||
// Rescale the piece of the full size image and put it in the preview image
|
||||
tmpPixbuf->scale (cropPixbuf, 0, 0, imw, imh, 0, 0, czoom/1000.0, czoom/1000.0, Gdk::INTERP_NEAREST);
|
||||
// Delete the temporary pixbuf
|
||||
tmpPixbuf.clear ();
|
||||
}
|
||||
delete [] cropimg;
|
||||
cropimg = NULL;
|
||||
|
||||
cimg.unlock ();
|
||||
|
||||
if (listener) {
|
||||
listener->cropImageUpdated ();
|
||||
if (initial) {
|
||||
listener->initialImageArrived (); // sets zoomToFit, so it should be the right size image!
|
||||
initial = false;
|
||||
}
|
||||
}
|
||||
} else cimg.unlock ();
|
||||
|
||||
}
|
||||
|
||||
bool CropHandler::getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip) {
|
||||
|
@@ -30,12 +30,6 @@ class CropHandlerListener {
|
||||
virtual void initialImageArrived () {}
|
||||
};
|
||||
|
||||
class CropHandler;
|
||||
struct CropHandlerIdleHelper {
|
||||
CropHandler* cropHandler;
|
||||
bool destroyed;
|
||||
int pending;
|
||||
};
|
||||
|
||||
class CropHandler : public rtengine::DetailedCropListener, public rtengine::SizeListener {
|
||||
|
||||
@@ -55,7 +49,6 @@ class CropHandler : public rtengine::DetailedCropListener, public rtengine::Size
|
||||
rtengine::DetailedCrop* crop;
|
||||
|
||||
CropHandlerListener* listener;
|
||||
CropHandlerIdleHelper* chi;
|
||||
|
||||
void update ();
|
||||
void compDim ();
|
||||
|
@@ -92,9 +92,8 @@ CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_)
|
||||
|
||||
minWidth = bsw + iw + 2*sideBorderWidth;
|
||||
|
||||
setSize (100, 100);
|
||||
cropHandler.newImage (ipc_);
|
||||
cropHandler.setPosition (0,0);
|
||||
|
||||
cropHandler.setEnabled (true);
|
||||
cropHandler.setCropHandlerListener (this);
|
||||
|
||||
@@ -195,6 +194,7 @@ void CropWindow::setSize (int w, int h, bool norefresh) {
|
||||
|
||||
if (!norefresh)
|
||||
cropHandler.setWSize (imgAreaW, imgAreaH);
|
||||
|
||||
iarea->redraw ();
|
||||
}
|
||||
|
||||
@@ -746,7 +746,6 @@ double CropWindow::getZoom () {
|
||||
}
|
||||
|
||||
void CropWindow::setZoom (double zoom) {
|
||||
|
||||
int cz = MAXZOOMSTEPS;
|
||||
if (zoom < zoomSteps[0].zoom)
|
||||
cz = 0;
|
||||
|
@@ -59,20 +59,21 @@ void ImageArea::on_realize()
|
||||
}
|
||||
|
||||
void ImageArea::on_resized (Gtk::Allocation& req) {
|
||||
|
||||
if (ipc && !mainCropWindow) {
|
||||
mainCropWindow = new CropWindow (this, ipc);
|
||||
mainCropWindow->setDecorated (false);
|
||||
mainCropWindow->setFitZoomEnabled (true);
|
||||
mainCropWindow->setPosition (0, 0);
|
||||
mainCropWindow->setSize (get_width(), get_height());
|
||||
mainCropWindow->addCropWindowListener (this);
|
||||
mainCropWindow->setCropGUIListener (cropgl);
|
||||
mainCropWindow->setPointerMotionListener (pmlistener);
|
||||
}
|
||||
else if (ipc) {
|
||||
mainCropWindow->setSize (get_width(), get_height());
|
||||
}
|
||||
if (ipc && get_width()>1) { // sometimes on_resize is called in some init state, causing wrong sizes
|
||||
if (!mainCropWindow) {
|
||||
mainCropWindow = new CropWindow (this, ipc);
|
||||
mainCropWindow->setDecorated (false);
|
||||
mainCropWindow->setFitZoomEnabled (true);
|
||||
mainCropWindow->setPosition (0, 0);
|
||||
mainCropWindow->setSize (get_width(), get_height());
|
||||
mainCropWindow->addCropWindowListener (this);
|
||||
mainCropWindow->setCropGUIListener (cropgl);
|
||||
mainCropWindow->setPointerMotionListener (pmlistener);
|
||||
}
|
||||
else {
|
||||
mainCropWindow->setSize (get_width(), get_height());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImageArea::setImProcCoordinator (rtengine::StagedImageProcessor* ipc_) {
|
||||
|
Reference in New Issue
Block a user