Skip to content

Commit 2832bad

Browse files
committed
improve display of computed multipage images
1 parent b0045f1 commit 2832bad

File tree

4 files changed

+34
-72
lines changed

4 files changed

+34
-72
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- add `vips8_xxxxx` builtins, remove `vips_call9`
88
- improve search and display of builtins
99
- add `vips_image_guess_interpretation` builtin
10+
- improve display of computed multipage images
1011

1112
## 9.0.13 2025/09/20
1213

TODO

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
- try < > in the image titlebar
2+
3+
seems to get stuck on eg. mp3 files
14

25
- toolkitgroupview could have a non-scrolling version as the default
36

src/tilesource.c

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ typedef struct _TilesourceUpdate {
136136
int z;
137137
} TilesourceUpdate;
138138

139-
/* Open a specified level. Take page (if relevant) from the tilesource.
139+
/* Open a specified level. Take page (if relevant) from the tilesource. Try to
140+
* open all pages if pages_same_size is set.
140141
*/
141142
static VipsImage *
142143
tilesource_open(Tilesource *tilesource, int level)
@@ -145,7 +146,7 @@ tilesource_open(Tilesource *tilesource, int level)
145146
* images, since pages can vary in size (eg. PDF or TIFF) and we can't
146147
* open everything.
147148
*/
148-
gboolean all_pages = tilesource->type == TILESOURCE_TYPE_TOILET_ROLL;
149+
gboolean all_pages = tilesource->pages_same_size;
149150
int n = all_pages ? -1 : 1;
150151
int page = all_pages ? 0 : tilesource->page;
151152

@@ -310,7 +311,7 @@ tilesource_image(Tilesource *tilesource, VipsImage **mask_out, int current_z)
310311

311312
/* Open the image with any shrink-on-load tricks.
312313
*/
313-
if (tilesource->type == TILESOURCE_TYPE_IMAGE) {
314+
if (!tilesource->filename) {
314315
/* We are displaying a VipsImage* and there's no reopen possible.
315316
*/
316317
image = tilesource->base;
@@ -369,13 +370,13 @@ tilesource_image(Tilesource *tilesource, VipsImage **mask_out, int current_z)
369370
printf("\timage_height = %d\n", tilesource->image_height);
370371
#endif /*DEBUG*/
371372

372-
/* If we have a toilet roll source and we are displaying multipage or
373+
/* If we have a pages-same-size source and we are displaying multipage or
373374
* animated, crop out the page we want.
374375
*
375376
* We need to crop using the page size on image, since it might have
376377
* been shrunk by shrink-on-load above ^^
377378
*/
378-
if (tilesource->type == TILESOURCE_TYPE_TOILET_ROLL &&
379+
if (tilesource->pages_same_size &&
379380
(tilesource->mode == TILESOURCE_MODE_MULTIPAGE ||
380381
tilesource->mode == TILESOURCE_MODE_ANIMATED)) {
381382
// loaders will adjust page_height for shrink-on-load, so we can just
@@ -385,8 +386,7 @@ tilesource_image(Tilesource *tilesource, VipsImage **mask_out, int current_z)
385386
VipsImage *x;
386387

387388
if (vips_crop(image, &x,
388-
0, tilesource->page * page_height,
389-
image->Xsize, page_height, NULL))
389+
0, tilesource->page * page_height, image->Xsize, page_height, NULL))
390390
return NULL;
391391
VIPS_UNREF(image);
392392
image = x;
@@ -403,7 +403,7 @@ tilesource_image(Tilesource *tilesource, VipsImage **mask_out, int current_z)
403403

404404
/* In pages-as-bands mode, crop out all pages and join band-wise.
405405
*/
406-
if (tilesource->type == TILESOURCE_TYPE_TOILET_ROLL &&
406+
if (tilesource->pages_same_size &&
407407
tilesource->mode == TILESOURCE_MODE_PAGES_AS_BANDS) {
408408
// loaders will adjust page_height for shrink-on-load, so we can just
409409
// use that
@@ -504,7 +504,7 @@ tilesource_image(Tilesource *tilesource, VipsImage **mask_out, int current_z)
504504
*mask_out = NULL;
505505
}
506506
else {
507-
/* Need something to track the z at which we made this sink_screen.
507+
/* Need to track the z at which we made this sink_screen.
508508
*/
509509
TilesourceUpdate *update = VIPS_NEW(image, TilesourceUpdate);
510510
update->tilesource = tilesource;
@@ -1425,8 +1425,6 @@ tilesource_print(Tilesource *tilesource)
14251425
int i;
14261426

14271427
printf("tilesource: %p\n", tilesource);
1428-
printf("\ttype = %s\n",
1429-
vips_enum_nick(TILESOURCE_TYPE_TYPE, tilesource->type));
14301428
printf("\tloader = %s\n", tilesource->loader);
14311429
printf("\tn_pages = %d\n", tilesource->n_pages);
14321430
printf("\tpage_height = %d\n", tilesource->page_height);
@@ -1490,8 +1488,7 @@ tilesource_default_mode(Tilesource *tilesource)
14901488
{
14911489
TilesourceMode mode;
14921490

1493-
if (tilesource->type == TILESOURCE_TYPE_TOILET_ROLL &&
1494-
tilesource->n_pages > 1) {
1491+
if (tilesource->n_pages > 1) {
14951492
if (tilesource->delay)
14961493
mode = TILESOURCE_MODE_ANIMATED;
14971494
else if (tilesource->all_mono)
@@ -1517,8 +1514,6 @@ tilesource_new_from_image(VipsImage *image)
15171514
if (tilesource_set_base(tilesource, image))
15181515
return NULL;
15191516

1520-
tilesource->type = TILESOURCE_TYPE_IMAGE;
1521-
15221517
tilesource->level_count = 1;
15231518
tilesource->level_width[0] = image->Xsize;;
15241519
tilesource->level_height[0] = image->Ysize;;
@@ -1530,13 +1525,17 @@ tilesource_new_from_image(VipsImage *image)
15301525
/* Sanity-check and set up the page geometry.
15311526
*/
15321527
tilesource->page_height = vips_image_get_page_height(image);
1533-
if (image->Ysize % tilesource->page_height == 0)
1528+
if (image->Ysize % tilesource->page_height == 0) {
15341529
tilesource->n_pages = image->Ysize / tilesource->page_height;
1530+
tilesource->pages_same_size = TRUE;
1531+
}
15351532
else {
15361533
tilesource->page_height = image->Ysize;
15371534
tilesource->n_pages = 1;
15381535
}
15391536

1537+
tilesource->all_mono = image->Bands == 1;
1538+
15401539
tilesource_default_mode(tilesource);
15411540

15421541
if (tilesource->mode == TILESOURCE_MODE_TOILET_ROLL)
@@ -1871,18 +1870,16 @@ tilesource_new_from_file(const char *filename)
18711870
/* Block error messages from eg. page-pyramidal TIFFs where pages
18721871
* are not all the same size.
18731872
*/
1874-
tilesource->type = TILESOURCE_TYPE_TOILET_ROLL;
1873+
tilesource->pages_same_size = TRUE;
18751874
vips_error_freeze();
18761875
g_autoptr(VipsImage) x = tilesource_open(tilesource, 0);
18771876
vips_error_thaw();
18781877
if (x) {
1879-
/* Toilet-roll mode worked. We can update n_pages.
1878+
/* All pages worked. We can update n_pages.
18801879
*/
18811880
tilesource->page_height = vips_image_get_page_height(x);
1882-
if (x->Ysize % tilesource->page_height == 0) {
1881+
if (x->Ysize % tilesource->page_height == 0)
18831882
tilesource->n_pages = x->Ysize / tilesource->page_height;
1884-
tilesource->pages_same_size = TRUE;
1885-
}
18861883
else {
18871884
#ifdef DEBUG
18881885
printf("tilesource_new_from_file: bad page layout\n");
@@ -1891,8 +1888,11 @@ tilesource_new_from_file(const char *filename)
18911888
tilesource->n_pages = 1;
18921889
VIPS_FREE(tilesource->delay);
18931890
tilesource->n_delay = 0;
1891+
tilesource->pages_same_size = FALSE;
18941892
}
18951893
}
1894+
else
1895+
tilesource->pages_same_size = FALSE;
18961896

18971897
/* Are all pages the same size and format, and also all mono (one
18981898
* band)? We can display pages-as-bands.
@@ -1920,17 +1920,6 @@ tilesource_new_from_file(const char *filename)
19201920
tilesource->page_pyramid = FALSE;
19211921
}
19221922

1923-
/* Sniffing is done ... set the image type.
1924-
*/
1925-
if (tilesource->pages_same_size)
1926-
tilesource->type = TILESOURCE_TYPE_TOILET_ROLL;
1927-
else {
1928-
if (tilesource->page_pyramid)
1929-
tilesource->type = TILESOURCE_TYPE_PAGE_PYRAMID;
1930-
else
1931-
tilesource->type = TILESOURCE_TYPE_MULTIPAGE;
1932-
}
1933-
19341923
/* And now we can reopen in the correct mode.
19351924
*/
19361925
g_autoptr(VipsImage) base = tilesource_open(tilesource, 0);

src/tilesource.h

Lines changed: 9 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -42,38 +42,6 @@
4242
#define TILESOURCE_GET_CLASS(obj) \
4343
(G_TYPE_INSTANCE_GET_CLASS((obj), TILESOURCE_TYPE, TilesourceClass))
4444

45-
/* The three basic types of image we support.
46-
*
47-
* MULTIPAGE
48-
*
49-
* Pages differ in size or perhaps format, so must be loaded as separate
50-
* images. Pages can have subifd pyramids. Includes single-page images.
51-
* Reload on page change.
52-
*
53-
* PAGE_PYRAMID
54-
*
55-
* "page" param is pyr levels. We load a single page and reload on
56-
* magnification change.
57-
*
58-
* TOILET_ROLL
59-
*
60-
* All pages are the identical, so we open as a single, tall, thin strip
61-
* and the viewer does any presenting as pages / animation / etc. during
62-
* conversion to image image.
63-
*
64-
* These images can have subifd pyramids.
65-
*
66-
* IMAGE
67-
*
68-
* We've been given a VipsImage* to display, held in @base.
69-
*/
70-
typedef enum _TilesourceType {
71-
TILESOURCE_TYPE_MULTIPAGE,
72-
TILESOURCE_TYPE_PAGE_PYRAMID,
73-
TILESOURCE_TYPE_TOILET_ROLL,
74-
TILESOURCE_TYPE_IMAGE,
75-
} TilesourceType;
76-
7745
/* The modes of image display we support.
7846
*
7947
* UNSET
@@ -87,18 +55,18 @@ typedef enum _TilesourceType {
8755
*
8856
* MULTIPAGE
8957
*
90-
* Behaviour depends on TilesourceType:
58+
* Behaviour depends on Tilesource details:
9159
*
92-
* TILESOURCE_TYPE_PAGE_PYRAMID
60+
* ->page_pyramid
9361
*
9462
* Disable page controls. No crop. Reload on mag change.
9563
*
96-
* TILESOURCE_TYPE_TOILET_ROLL
64+
* ->pages_same_size && ->delay && ->n_pages > 1
9765
*
98-
* Enable page control iff > 1 page. Crop in display conversion
66+
* Enable page controls, crop in display conversion
9967
* to select page.
10068
*
101-
* TILESOURCE_TYPE_MULTIPAGE
69+
* ->n_pages > 1
10270
*
10371
* Enable page control iff > 1 page.
10472
*
@@ -149,6 +117,8 @@ typedef struct _Tilesource {
149117
/* The loader and the file we have loaded from. We may need to reload
150118
* on a zoom or page change. We can't use a VipsSource since they are not
151119
* cached and we'd get repeated decode on page change.
120+
*
121+
* filename is NULL for a computed image.
152122
*/
153123
const char *loader;
154124
char *filename;
@@ -159,7 +129,6 @@ typedef struct _Tilesource {
159129
* Some properties of this base image
160130
*/
161131
VipsImage *base;
162-
TilesourceType type; // what general type of image we have
163132
int n_pages;
164133
int page_height;
165134
int n_subifds;
@@ -174,8 +143,8 @@ typedef struct _Tilesource {
174143
*/
175144
gboolean page_pyramid;
176145

177-
/* If all the pages are the same size and format, we can load as a
178-
* toilet roll.
146+
/* If all the pages are the same size and format, we can display as a
147+
* toilet roll or animated.
179148
*/
180149
gboolean pages_same_size;
181150

0 commit comments

Comments
 (0)