Skip to content

Commit b025242

Browse files
committed
fix a possible infobar race
1 parent a4b94dc commit b025242

File tree

7 files changed

+76
-56
lines changed

7 files changed

+76
-56
lines changed

TODO

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,35 @@
1-
- nip4 ~/pics/nipguide.pdf, set "toilet roll", then set "multipage", height is
2-
wrong
1+
- try:
2+
3+
nip4 k2.jpg
4+
alt-R
5+
segv in infobar_status_update()
6+
7+
8+
- try:
9+
10+
nip4 ~/pics/S000_t000002_V000_R0000_X000_Y000_C02_I1_D0_P00101.tif
11+
12+
incredibly slow, in fact does not draw at all, and it's not clear why
13+
14+
this takes under 2s to draw the image:
15+
16+
image = pyvips.Image.new_from_file(sys.argv[1], n=-1);
17+
18+
page_width = image.width
19+
page_height = image.get("page-height")
20+
21+
pages = [image.crop(0, y * page_height, page_width, page_height)
22+
for y in range(3)]
23+
24+
rgb = pages[0].bandjoin(pages[1:])
25+
26+
rgb = rgb.copy(interpretation="rgb16")
27+
28+
rgb.write_to_file(sys.argv[2])
29+
30+
31+
332

4-
- nip4 ~/pics/S000_t000002_V000_R0000_X000_Y000_C02_I1_D0_P00101.tif, set
5-
"multipage", does not display correctly
633

734
- alt-L and R for a while, coredump
835

src/gtk/nip4.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,4 @@
8888
margin-left: 4px;
8989
margin-right: 4px;
9090
}
91+

src/imagedisplay.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
#include "nip4.h"
3131

3232
/*
33-
*/
3433
#define DEBUG_VERBOSE
3534
#define DEBUG
35+
*/
3636

3737
// the focus colour we paint
3838
// FIXME ... we should somehow get this from the theme, I'm not sure how
@@ -649,6 +649,8 @@ imagedisplay_snapshot(GtkWidget *widget, GtkSnapshot *snapshot)
649649
printf("imagedisplay_snapshot:\n");
650650
#endif /*DEBUG*/
651651

652+
GTK_WIDGET_CLASS(imagedisplay_parent_class)->snapshot(widget, snapshot);
653+
652654
/* Clip to the widget area, or we may paint over the display control
653655
* bar.
654656
*/
@@ -670,7 +672,6 @@ imagedisplay_snapshot(GtkWidget *widget, GtkSnapshot *snapshot)
670672

671673
/* It's unclear how to do this :( maybe we're supposed to get the base
672674
* widget class to do it? Draw it ourselves for now.
673-
*/
674675
if (gtk_widget_has_focus(widget)) {
675676
GskRoundedRect outline;
676677
@@ -687,6 +688,7 @@ imagedisplay_snapshot(GtkWidget *widget, GtkSnapshot *snapshot)
687688
(float[4]){ 2, 2, 2, 2 },
688689
(GdkRGBA[4]){ BORDER, BORDER, BORDER, BORDER });
689690
}
691+
*/
690692
}
691693

692694
static void

src/infobar.c

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ infobar_status_value_set_array(Infobar *infobar, double *d)
180180
typedef struct _PixelUpdate {
181181
// what we update, where we get the pixel data
182182
Infobar *infobar;
183-
Tilesource *tilesource;
183+
VipsImage *image;
184184

185185
// fetch params
186186
int image_x;
@@ -196,7 +196,7 @@ infobar_update_free(PixelUpdate *update)
196196
update->infobar->updating = FALSE;
197197

198198
VIPS_UNREF(update->infobar);
199-
VIPS_UNREF(update->tilesource);
199+
VIPS_UNREF(update->image);
200200
VIPS_FREE(update->vector);
201201
VIPS_FREE(update);
202202
}
@@ -220,9 +220,22 @@ static void
220220
infobar_get_pixel(void *a, void *b)
221221
{
222222
PixelUpdate *update = (PixelUpdate *) a;
223+
VipsImage *image = update->image;
223224

224-
update->result = tilesource_get_pixel(update->tilesource,
225-
update->image_x, update->image_y, &update->vector, &update->n);
225+
/* Block outside the image.
226+
*/
227+
if (update->image_x >= 0 &&
228+
update->image_y >= 0 &&
229+
update->image_x < image->Xsize &&
230+
update->image_y < image->Ysize)
231+
/* Fetch from image, even though this can be very slow.
232+
* This is run in a bg thread, so speed should not matter too much.
233+
*/
234+
update->result = !vips_getpoint(image,
235+
&update->vector, &update->n,
236+
update->image_x, update->image_y,
237+
"unpack_complex", TRUE,
238+
NULL);
226239

227240
g_idle_add(infobar_update_pixel_idle, update);
228241
}
@@ -232,18 +245,24 @@ static void
232245
infobar_update_pixel(Infobar *infobar,
233246
Tilesource *tilesource, double image_x, double image_y)
234247
{
235-
if (!infobar->updating) {
236-
PixelUpdate *update = g_new0(PixelUpdate, 1);
248+
if (!infobar->updating &&
249+
tilesource->image) {
250+
infobar->updating = TRUE;
237251

252+
PixelUpdate *update = g_new0(PixelUpdate, 1);
238253
update->infobar = infobar;
239-
update->tilesource = tilesource;
240-
update->image_x = image_x;
241-
update->image_y = image_y;
242-
infobar->updating = TRUE;
254+
update->image = tilesource->image;
255+
256+
/* Currently in level0 image coordinates ... we will fetch from
257+
* tilesource->image, the current pyr layer.
258+
*/
259+
int factor = tilesource->image_width / tilesource->image->Xsize;
260+
update->image_x = image_x / factor;
261+
update->image_y = image_y / factor;
243262

244263
// must stay valid until we are done
245264
g_object_ref(update->infobar);
246-
g_object_ref(update->tilesource);
265+
g_object_ref(update->image);
247266

248267
if (vips_thread_execute("pixel", infobar_get_pixel, update))
249268
// if we can't run a bg task, we must free the update
@@ -266,16 +285,16 @@ infobar_status_update(Infobar *infobar)
266285

267286
Tilesource *tilesource = imagewindow_get_tilesource(infobar->win);
268287
imagewindow_get_mouse_position(infobar->win, &image_x, &image_y);
269-
image_x = VIPS_CLIP(0, (int) image_x, tilesource->image->Xsize - 1);
270-
image_y = VIPS_CLIP(0, (int) image_y, tilesource->image->Ysize - 1);
271288

272-
vips_buf_appendf(&buf, "%d", (int) image_x);
273-
gtk_label_set_text(GTK_LABEL(infobar->x), vips_buf_all(&buf));
274-
vips_buf_rewind(&buf);
289+
if (tilesource->image) {
290+
vips_buf_appendf(&buf, "%d", (int) image_x);
291+
gtk_label_set_text(GTK_LABEL(infobar->x), vips_buf_all(&buf));
292+
vips_buf_rewind(&buf);
275293

276-
vips_buf_appendf(&buf, "%d", (int) image_y);
277-
gtk_label_set_text(GTK_LABEL(infobar->y), vips_buf_all(&buf));
278-
vips_buf_rewind(&buf);
294+
vips_buf_appendf(&buf, "%d", (int) image_y);
295+
gtk_label_set_text(GTK_LABEL(infobar->y), vips_buf_all(&buf));
296+
vips_buf_rewind(&buf);
297+
}
279298

280299
double zoom = imagewindow_get_zoom(infobar->win);
281300
vips_buf_appendf(&buf, "Magnification %d%%", (int) rint(zoom * 100));

src/tilecache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030
#include "nip4.h"
3131

3232
/*
33-
*/
3433
#define DEBUG_RENDER_TIME
3534
#define DEBUG_VERBOSE
3635
#define DEBUG
36+
*/
3737

3838
enum {
3939
/* Properties.

src/tilesource.c

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@
2828
*/
2929

3030
/*
31-
*/
3231
#define DEBUG_VERBOSE
3332
#define DEBUG
3433
#define DEBUG_MAKE
34+
*/
3535

3636
#include "nip4.h"
3737

@@ -2073,33 +2073,6 @@ tilesource_get_base_image(Tilesource *tilesource)
20732073
return tilesource->base;
20742074
}
20752075

2076-
gboolean
2077-
tilesource_get_pixel(Tilesource *tilesource, int image_x, int image_y,
2078-
double **vector, int *n)
2079-
{
2080-
if (!tilesource->loaded ||
2081-
!tilesource->image)
2082-
return FALSE;
2083-
2084-
/* Block outside the image.
2085-
*/
2086-
if (image_x < 0 ||
2087-
image_y < 0 ||
2088-
image_x >= tilesource->image->Xsize ||
2089-
image_y >= tilesource->image->Ysize)
2090-
return FALSE;
2091-
2092-
/* Fetch from image (not ->display), even though this can be very slow.
2093-
* This is run in a bg thread, so speed should not matter too much.
2094-
*/
2095-
if (vips_getpoint(tilesource->image, vector, n, image_x, image_y,
2096-
"unpack_complex", TRUE,
2097-
NULL))
2098-
return FALSE;
2099-
2100-
return TRUE;
2101-
}
2102-
21032076
void
21042077
tilesource_set_synchronous(Tilesource *tilesource, gboolean synchronous)
21052078
{

src/tilesource.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,6 @@ GFile *tilesource_get_file(Tilesource *tilesource);
319319

320320
VipsImage *tilesource_get_image(Tilesource *tilesource);
321321
VipsImage *tilesource_get_base_image(Tilesource *tilesource);
322-
gboolean tilesource_get_pixel(Tilesource *tilesource,
323-
int image_x, int image_y, double **vector, int *n);
324322
Tilesource *tilesource_duplicate(Tilesource *tilesource);
325323
void tilesource_changed(Tilesource *tilesource);
326324

0 commit comments

Comments
 (0)