Fix crash while rotating several thumbnails in File Browser
Fix issue #4858 and possibly #5310
This commit is contained in:
parent
bb97a30058
commit
ce04447c7a
@ -1483,6 +1483,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT
|
|||||||
delete labView;
|
delete labView;
|
||||||
delete baseImg;
|
delete baseImg;
|
||||||
|
|
||||||
|
/*
|
||||||
// calculate scale
|
// calculate scale
|
||||||
if (params.coarse.rotate == 90 || params.coarse.rotate == 270) {
|
if (params.coarse.rotate == 90 || params.coarse.rotate == 270) {
|
||||||
myscale = scale * thumbImg->getWidth() / fh;
|
myscale = scale * thumbImg->getWidth() / fh;
|
||||||
@ -1491,19 +1492,20 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT
|
|||||||
}
|
}
|
||||||
|
|
||||||
myscale = 1.0 / myscale;
|
myscale = 1.0 / myscale;
|
||||||
/* // apply crop
|
// apply crop
|
||||||
if (params.crop.enabled) {
|
if (params.crop.enabled) {
|
||||||
int ix = 0;
|
int ix = 0;
|
||||||
for (int i=0; i<fh; i++)
|
for (int i=0; i<fh; i++)
|
||||||
for (int j=0; j<fw; j++)
|
for (int j=0; j<fw; j++)
|
||||||
if (i<params.crop.y/myscale || i>(params.crop.y+params.crop.h)/myscale || j<params.crop.x/myscale || j>(params.crop.x+params.crop.w)/myscale) {
|
if (i<params.crop.y/myscale || i>(params.crop.y+params.crop.h)/myscale || j<params.crop.x/myscale || j>(params.crop.x+params.crop.w)/myscale) {
|
||||||
readyImg->data[ix++] /= 3;
|
readyImg->data[ix++] /= 3;
|
||||||
readyImg->data[ix++] /= 3;
|
readyImg->data[ix++] /= 3;
|
||||||
readyImg->data[ix++] /= 3;
|
readyImg->data[ix++] /= 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ix += 3;
|
ix += 3;
|
||||||
}*/
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return readyImg;
|
return readyImg;
|
||||||
}
|
}
|
||||||
|
@ -255,17 +255,20 @@ void FileBrowserEntry::_updateImage(rtengine::IImage8* img, double s, const rten
|
|||||||
const bool resize = !preview || prew != img->getWidth();
|
const bool resize = !preview || prew != img->getWidth();
|
||||||
prew = img->getWidth ();
|
prew = img->getWidth ();
|
||||||
|
|
||||||
GThreadLock lock;
|
|
||||||
|
|
||||||
// Check if image has been rotated since last time
|
// Check if image has been rotated since last time
|
||||||
rotated = preview && newLandscape != landscape;
|
rotated = preview && newLandscape != landscape;
|
||||||
|
|
||||||
if (resize) {
|
if (resize) {
|
||||||
delete [] preview;
|
if (preview) {
|
||||||
|
delete [] preview;
|
||||||
|
}
|
||||||
preview = new guint8 [prew * preh * 3];
|
preview = new guint8 [prew * preh * 3];
|
||||||
}
|
}
|
||||||
memcpy(preview, img->getData(), prew * preh * 3);
|
memcpy(preview, img->getData(), prew * preh * 3);
|
||||||
|
{
|
||||||
|
GThreadLock lock;
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
landscape = newLandscape;
|
landscape = newLandscape;
|
||||||
@ -318,24 +321,36 @@ bool FileBrowserEntry::motionNotify (int x, int y)
|
|||||||
cropParams->y = action_y + (y - press_y) / scale;
|
cropParams->y = action_y + (y - press_y) / scale;
|
||||||
cropParams->h += oy - cropParams->y;
|
cropParams->h += oy - cropParams->y;
|
||||||
cropgl->cropHeight1Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
cropgl->cropHeight1Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
parent->redrawNeeded (this);
|
parent->redrawNeeded (this);
|
||||||
} else if (state == SResizeH2 && cropgl) {
|
} else if (state == SResizeH2 && cropgl) {
|
||||||
cropParams->h = action_y + (y - press_y) / scale;
|
cropParams->h = action_y + (y - press_y) / scale;
|
||||||
cropgl->cropHeight2Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
cropgl->cropHeight2Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
parent->redrawNeeded (this);
|
parent->redrawNeeded (this);
|
||||||
} else if (state == SResizeW1 && cropgl) {
|
} else if (state == SResizeW1 && cropgl) {
|
||||||
int ox = cropParams->x;
|
int ox = cropParams->x;
|
||||||
cropParams->x = action_x + (x - press_x) / scale;
|
cropParams->x = action_x + (x - press_x) / scale;
|
||||||
cropParams->w += ox - cropParams->x;
|
cropParams->w += ox - cropParams->x;
|
||||||
cropgl->cropWidth1Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
cropgl->cropWidth1Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
parent->redrawNeeded (this);
|
parent->redrawNeeded (this);
|
||||||
} else if (state == SResizeW2 && cropgl) {
|
} else if (state == SResizeW2 && cropgl) {
|
||||||
cropParams->w = action_x + (x - press_x) / scale;
|
cropParams->w = action_x + (x - press_x) / scale;
|
||||||
cropgl->cropWidth2Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
cropgl->cropWidth2Resized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
parent->redrawNeeded (this);
|
parent->redrawNeeded (this);
|
||||||
} else if (state == SResizeTL && cropgl) {
|
} else if (state == SResizeTL && cropgl) {
|
||||||
int ox = cropParams->x;
|
int ox = cropParams->x;
|
||||||
@ -345,7 +360,10 @@ bool FileBrowserEntry::motionNotify (int x, int y)
|
|||||||
cropParams->y = action_y + (y - press_y) / scale;
|
cropParams->y = action_y + (y - press_y) / scale;
|
||||||
cropParams->h += oy - cropParams->y;
|
cropParams->h += oy - cropParams->y;
|
||||||
cropgl->cropTopLeftResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
cropgl->cropTopLeftResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
parent->redrawNeeded (this);
|
parent->redrawNeeded (this);
|
||||||
} else if (state == SResizeTR && cropgl) {
|
} else if (state == SResizeTR && cropgl) {
|
||||||
cropParams->w = action_x + (x - press_x) / scale;
|
cropParams->w = action_x + (x - press_x) / scale;
|
||||||
@ -353,7 +371,10 @@ bool FileBrowserEntry::motionNotify (int x, int y)
|
|||||||
cropParams->y = action_y + (y - press_y) / scale;
|
cropParams->y = action_y + (y - press_y) / scale;
|
||||||
cropParams->h += oy - cropParams->y;
|
cropParams->h += oy - cropParams->y;
|
||||||
cropgl->cropTopRightResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
cropgl->cropTopRightResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
parent->redrawNeeded (this);
|
parent->redrawNeeded (this);
|
||||||
} else if (state == SResizeBL && cropgl) {
|
} else if (state == SResizeBL && cropgl) {
|
||||||
int ox = cropParams->x;
|
int ox = cropParams->x;
|
||||||
@ -361,19 +382,28 @@ bool FileBrowserEntry::motionNotify (int x, int y)
|
|||||||
cropParams->w += ox - cropParams->x;
|
cropParams->w += ox - cropParams->x;
|
||||||
cropParams->h = action_y + (y - press_y) / scale;
|
cropParams->h = action_y + (y - press_y) / scale;
|
||||||
cropgl->cropBottomLeftResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
cropgl->cropBottomLeftResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
parent->redrawNeeded (this);
|
parent->redrawNeeded (this);
|
||||||
} else if (state == SResizeBR && cropgl) {
|
} else if (state == SResizeBR && cropgl) {
|
||||||
cropParams->w = action_x + (x - press_x) / scale;
|
cropParams->w = action_x + (x - press_x) / scale;
|
||||||
cropParams->h = action_y + (y - press_y) / scale;
|
cropParams->h = action_y + (y - press_y) / scale;
|
||||||
cropgl->cropBottomRightResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
cropgl->cropBottomRightResized (cropParams->x, cropParams->y, cropParams->w, cropParams->h, crop_custom_ratio);
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
parent->redrawNeeded (this);
|
parent->redrawNeeded (this);
|
||||||
} else if (state == SCropMove && cropgl) {
|
} else if (state == SCropMove && cropgl) {
|
||||||
cropParams->x = action_x + (x - press_x) / scale;
|
cropParams->x = action_x + (x - press_x) / scale;
|
||||||
cropParams->y = action_y + (y - press_y) / scale;
|
cropParams->y = action_y + (y - press_y) / scale;
|
||||||
cropgl->cropMoved (cropParams->x, cropParams->y, cropParams->w, cropParams->h);
|
cropgl->cropMoved (cropParams->x, cropParams->y, cropParams->w, cropParams->h);
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
parent->redrawNeeded (this);
|
parent->redrawNeeded (this);
|
||||||
} else if (state == SCropSelecting && cropgl) {
|
} else if (state == SCropSelecting && cropgl) {
|
||||||
int cx1 = press_x, cy1 = press_y;
|
int cx1 = press_x, cy1 = press_y;
|
||||||
@ -396,7 +426,10 @@ bool FileBrowserEntry::motionNotify (int x, int y)
|
|||||||
cropParams->h = cy1 - cy2 + 1;
|
cropParams->h = cy1 - cy2 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
|
}
|
||||||
parent->redrawNeeded (this);
|
parent->redrawNeeded (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,6 +597,7 @@ bool FileBrowserEntry::releaseNotify (int button, int type, int bstate, int x, i
|
|||||||
bool FileBrowserEntry::onArea (CursorArea a, int x, int y)
|
bool FileBrowserEntry::onArea (CursorArea a, int x, int y)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
if (!drawable || !preview) {
|
if (!drawable || !preview) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -764,6 +798,8 @@ void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr<Cairo::Context> cr)
|
|||||||
int y2 = action_y;
|
int y2 = action_y;
|
||||||
int x2 = action_x;
|
int x2 = action_x;
|
||||||
|
|
||||||
|
{
|
||||||
|
MYREADERLOCK(l, lockRW);
|
||||||
if (x2 < prex + ofsX + startx) {
|
if (x2 < prex + ofsX + startx) {
|
||||||
y2 = y1 - (double)(y1 - y2) * (x1 - (prex + ofsX + startx)) / (x1 - x2);
|
y2 = y1 - (double)(y1 - y2) * (x1 - (prex + ofsX + startx)) / (x1 - x2);
|
||||||
x2 = prex + ofsX + startx;
|
x2 = prex + ofsX + startx;
|
||||||
@ -779,6 +815,7 @@ void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr<Cairo::Context> cr)
|
|||||||
x2 = x1 - (double)(x1 - x2) * (y1 - (preh + prey + ofsY + starty - 1)) / (y1 - y2);
|
x2 = x1 - (double)(x1 - x2) * (y1 - (preh + prey + ofsY + starty - 1)) / (y1 - y2);
|
||||||
y2 = preh + prey + ofsY + starty - 1;
|
y2 = preh + prey + ofsY + starty - 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cr->set_line_width (1.5);
|
cr->set_line_width (1.5);
|
||||||
cr->set_source_rgb (1.0, 1.0, 1.0);
|
cr->set_source_rgb (1.0, 1.0, 1.0);
|
||||||
|
@ -494,6 +494,7 @@ void ThumbBrowserEntryBase::resize (int h)
|
|||||||
|
|
||||||
height = h;
|
height = h;
|
||||||
int old_preh = preh;
|
int old_preh = preh;
|
||||||
|
int old_prew = prew;
|
||||||
|
|
||||||
// dimensions of the button set
|
// dimensions of the button set
|
||||||
int bsw = 0, bsh = 0;
|
int bsw = 0, bsh = 0;
|
||||||
@ -555,9 +556,11 @@ void ThumbBrowserEntryBase::resize (int h)
|
|||||||
width = bsw + 2 * sideMargin + 2 * borderWidth;
|
width = bsw + 2 * sideMargin + 2 * borderWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preh != old_preh) {
|
if (preh != old_preh || prew != old_prew) { // if new thumbnail height or new orientation
|
||||||
delete [] preview;
|
if (preview) {
|
||||||
preview = nullptr;
|
delete [] preview;
|
||||||
|
preview = nullptr;
|
||||||
|
}
|
||||||
refreshThumbnailImage ();
|
refreshThumbnailImage ();
|
||||||
} else if (backBuffer) {
|
} else if (backBuffer) {
|
||||||
backBuffer->setDirty(true); // This will force a backBuffer update on queue_draw
|
backBuffer->setDirty(true); // This will force a backBuffer update on queue_draw
|
||||||
|
@ -49,17 +49,17 @@ class Thumbnail
|
|||||||
rtengine::Thumbnail* tpp;
|
rtengine::Thumbnail* tpp;
|
||||||
int tw, th; // dimensions of timgdata (it stores tpp->width and tpp->height in processed mode for simplicity)
|
int tw, th; // dimensions of timgdata (it stores tpp->width and tpp->height in processed mode for simplicity)
|
||||||
float imgRatio; // hack to avoid rounding error
|
float imgRatio; // hack to avoid rounding error
|
||||||
// double scale; // portion of the sizes of the processed thumbnail image and the full scale image
|
// double scale; // portion of the sizes of the processed thumbnail image and the full scale image
|
||||||
|
|
||||||
const std::unique_ptr<rtengine::procparams::ProcParams> pparams;
|
const std::unique_ptr<rtengine::procparams::ProcParams> pparams;
|
||||||
bool pparamsValid;
|
bool pparamsValid;
|
||||||
bool imageLoading;
|
bool imageLoading;
|
||||||
|
|
||||||
// these are the data of the result image of the last getthumbnailimage call (for caching purposes)
|
// these are the data of the result image of the last getthumbnailimage call (for caching purposes)
|
||||||
unsigned char* lastImg;
|
unsigned char* lastImg; // pointer to the processed and scaled base ImageIO image
|
||||||
int lastW;
|
int lastW; // non rotated width of the cached ImageIO image
|
||||||
int lastH;
|
int lastH; // non rotated height of the cached ImageIO image
|
||||||
double lastScale;
|
double lastScale; // scale of the cached ImageIO image
|
||||||
|
|
||||||
// exif & date/time strings
|
// exif & date/time strings
|
||||||
Glib::ustring exifString;
|
Glib::ustring exifString;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user