Skip to content

Commit 62a8564

Browse files
committed
Merge branch '8.17'
2 parents e5e5c20 + 11e02da commit 62a8564

File tree

3 files changed

+37
-40
lines changed

3 files changed

+37
-40
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ master
88
file formats
99
- pdfload: control region to be rendered via `page_box` [lovell]
1010

11+
8.17.2
12+
13+
- rank: fix an off-by-one error [larsmaxfield]
14+
1115
7/7/25 8.17.1
1216

1317
- fix API docs build with meson < 0.60 [lovell]

libvips/morphology/morphology.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,16 @@ vips_morphology_class_init(VipsMorphologyClass *class)
5757
{
5858
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
5959
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS(class);
60+
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class);
6061

6162
gobject_class->set_property = vips_object_set_property;
6263
gobject_class->get_property = vips_object_get_property;
6364

6465
vobject_class->nickname = "morphology";
6566
vobject_class->description = _("morphological operations");
6667

68+
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
69+
6770
/* Inputs set by subclassess.
6871
*/
6972

libvips/morphology/rank.c

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,9 @@ vips_rank_stop(void *vseq, void *a, void *b)
115115
VIPS_FREE(seq->sort);
116116

117117
if (seq->hist &&
118-
in) {
119-
int i;
120-
121-
for (i = 0; i < in->Bands; i++)
118+
in)
119+
for (int i = 0; i < in->Bands; i++)
122120
VIPS_FREE(seq->hist[i]);
123-
}
124121
VIPS_FREE(seq->hist);
125122

126123
return 0;
@@ -147,17 +144,13 @@ vips_rank_start(VipsImage *out, void *a, void *b)
147144
}
148145

149146
if (rank->hist_path) {
150-
int i;
151-
152-
if (!(seq->hist =
153-
VIPS_ARRAY(NULL, in->Bands, unsigned int *))) {
147+
if (!(seq->hist = VIPS_ARRAY(NULL, in->Bands, unsigned int *))) {
154148
vips_rank_stop(seq, in, rank);
155149
return NULL;
156150
}
157151

158-
for (i = 0; i < in->Bands; i++)
159-
if (!(seq->hist[i] =
160-
VIPS_ARRAY(NULL, 256, unsigned int))) {
152+
for (int i = 0; i < in->Bands; i++)
153+
if (!(seq->hist[i] = VIPS_ARRAY(NULL, 256, unsigned int))) {
161154
vips_rank_stop(seq, in, rank);
162155
return NULL;
163156
}
@@ -175,62 +168,58 @@ vips_rank_generate_uchar(VipsRegion *out_region,
175168
VipsImage *in = seq->ir->im;
176169
VipsRect *r = &out_region->valid;
177170
const int bands = in->Bands;
178-
const int last = bands * (rank->width - 1);
171+
const int lsk = VIPS_REGION_LSKIP(seq->ir);
179172

180173
/* Get input and output pointers for this line.
181174
*/
182-
VipsPel *restrict p =
183-
VIPS_REGION_ADDR(seq->ir, r->left, r->top + y);
184-
VipsPel *restrict q =
185-
VIPS_REGION_ADDR(out_region, r->left, r->top + y);
175+
VipsPel *restrict p = VIPS_REGION_ADDR(seq->ir, r->left, r->top + y);
176+
VipsPel *restrict q = VIPS_REGION_ADDR(out_region, r->left, r->top + y);
186177

187178
VipsPel *restrict p1;
188-
int lsk;
189-
int x, i, j, b;
190-
191-
lsk = VIPS_REGION_LSKIP(seq->ir);
192179

193180
/* Find histogram for the first output pixel.
194181
*/
195-
for (b = 0; b < bands; b++)
182+
for (int b = 0; b < bands; b++)
196183
memset(seq->hist[b], 0, 256 * sizeof(unsigned int));
197184
p1 = p;
198-
for (j = 0; j < rank->height; j++) {
199-
for (i = 0, x = 0; x < rank->width; x++)
200-
for (b = 0; b < bands; b++, i++)
185+
for (int j = 0; j < rank->height; j++) {
186+
int i;
187+
188+
i = 0;
189+
for (int x = 0; x < rank->width; x++)
190+
for (int b = 0; b < bands; b++, i++)
201191
seq->hist[b][p1[i]] += 1;
202192

203193
p1 += lsk;
204194
}
205195

206196
/* Loop for output pels.
207197
*/
208-
for (x = 0; x < r->width; x++) {
209-
for (b = 0; b < bands; b++) {
198+
for (int x = 0; x < r->width; x++) {
199+
for (int b = 0; b < bands; b++) {
210200
/* Calculate cumulative histogram -- the value is the
211201
* index at which we pass the rank.
212202
*/
213203
unsigned int *restrict hist = seq->hist[b];
214204

215205
int sum;
216-
int i;
217-
206+
int value;
218207
sum = 0;
219-
for (i = 0; i < 256; i++) {
220-
sum += hist[i];
208+
for (value = 0; value < 256; value++) {
209+
sum += hist[value];
221210
if (sum > rank->index)
222211
break;
223212
}
224-
q[b] = i;
213+
q[b] = value;
225214

226-
/* Adapt histogram -- remove the pels from
227-
* the left hand column, add in pels for a
228-
* new right-hand column.
215+
/* Adapt histogram -- remove the pels from the left hand column,
216+
* add in pels for a new right-hand column.
229217
*/
218+
const int next = bands * rank->width;
230219
p1 = p + b;
231-
for (j = 0; j < rank->height; j++) {
220+
for (int j = 0; j < rank->height; j++) {
232221
hist[p1[0]] -= 1;
233-
hist[p1[last]] += 1;
222+
hist[p1[next]] += 1;
234223

235224
p1 += lsk;
236225
}
@@ -437,7 +426,7 @@ vips_rank_generate(VipsRegion *out_region,
437426
VipsRect s;
438427
int ls;
439428

440-
int x, y;
429+
int x;
441430
int i, j, k;
442431
int upper, lower, mid;
443432

@@ -451,7 +440,7 @@ vips_rank_generate(VipsRegion *out_region,
451440
return -1;
452441
ls = VIPS_REGION_LSKIP(ir) / VIPS_IMAGE_SIZEOF_ELEMENT(in);
453442

454-
for (y = 0; y < r->height; y++) {
443+
for (int y = 0; y < r->height; y++) {
455444
if (rank->hist_path)
456445
vips_rank_generate_uchar(out_region, seq, rank, y);
457446
else if (rank->index == 0)
@@ -492,7 +481,8 @@ vips_rank_build(VipsObject *object)
492481
return -1;
493482
}
494483
rank->n = rank->width * rank->height;
495-
if (rank->index < 0 || rank->index > rank->n - 1) {
484+
if (rank->index < 0 ||
485+
rank->index > rank->n - 1) {
496486
vips_error(class->nickname, "%s", _("index out of range"));
497487
return -1;
498488
}

0 commit comments

Comments
 (0)