Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 9 additions & 34 deletions libvips/resample/reducev.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
* - speed up the mask construction for uchar/ushort images
* 22/4/22 kleisauke
* - add @gap option
* 22/8/25 kleisauke
* - remove seq line cache
*/

/*
Expand Down Expand Up @@ -830,7 +832,7 @@ vips_reducev_build(VipsObject *object)
VipsResample *resample = VIPS_RESAMPLE(object);
VipsReducev *reducev = (VipsReducev *) object;
VipsImage **t = (VipsImage **)
vips_object_local_array(object, 5);
vips_object_local_array(object, 3);

VipsImage *in;
VipsGenerateFn generate;
Expand Down Expand Up @@ -983,8 +985,7 @@ vips_reducev_build(VipsObject *object)
*/
generate = vips_reducev_gen;

t[3] = vips_image_new();
if (vips_image_pipelinev(t[3],
if (vips_image_pipelinev(resample->out,
VIPS_DEMAND_STYLE_FATSTRIP, in, nullptr))
return -1;

Expand All @@ -995,8 +996,8 @@ vips_reducev_build(VipsObject *object)
* example, vipsthumbnail knows the true reduce factor (including the
* fractional part), we just see the integer part here.
*/
t[3]->Ysize = height;
if (t[3]->Ysize <= 0) {
resample->out->Ysize = height;
if (resample->out->Ysize <= 0) {
vips_error(object_class->nickname,
"%s", _("image has shrunk to nothing"));
return -1;
Expand All @@ -1005,41 +1006,15 @@ vips_reducev_build(VipsObject *object)
#ifdef DEBUG
printf("vips_reducev_build: reducing %d x %d image to %d x %d\n",
in->Xsize, in->Ysize,
t[3]->Xsize, t[3]->Ysize);
resample->out->Xsize, resample->out->Ysize);
#endif /*DEBUG*/

if (vips_image_generate(t[3],
if (vips_image_generate(resample->out,
vips_reducev_start, generate, vips_reducev_stop,
in, reducev))
return -1;

in = t[3];

vips_reorder_margin_hint(in, reducev->n_point);

/* Large reducev will throw off sequential mode. Suppose thread1 is
* generating tile (0, 0), but stalls. thread2 generates tile
* (0, 1), 128 lines further down the output. After it has done,
* thread1 tries to generate (0, 0), but by then the pixels it needs
* have gone from the input image line cache if the reducev is large.
*
* To fix this, put another seq on the output of reducev. Now we'll
* always have the previous XX lines of the shrunk image, and we won't
* fetch out of order.
*/
if (vips_image_is_sequential(in)) {
g_info("reducev sequential line cache");

if (vips_sequential(in, &t[4],
"tile_height", 10,
// "trace", TRUE,
nullptr))
return -1;
in = t[4];
}

if (vips_image_write(in, resample->out))
return -1;
vips_reorder_margin_hint(resample->out, reducev->n_point);

return 0;
}
Expand Down
40 changes: 8 additions & 32 deletions libvips/resample/shrinkv.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
* - use a double sum buffer for int32 types
* 22/4/22 kleisauke
* - add @ceil option
* 22/8/25 kleisauke
* - remove seq line cache
*/

/*
Expand Down Expand Up @@ -469,7 +471,7 @@ vips_shrinkv_build(VipsObject *object)
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object);
VipsResample *resample = VIPS_RESAMPLE(object);
VipsShrinkv *shrink = (VipsShrinkv *) object;
VipsImage **t = (VipsImage **) vips_object_local_array(object, 4);
VipsImage **t = (VipsImage **) vips_object_local_array(object, 2);

VipsImage *in;
VipsGenerateFn generate;
Expand Down Expand Up @@ -543,8 +545,7 @@ vips_shrinkv_build(VipsObject *object)
/* SMALLTILE or we'll need huge input areas for our output. In seq
* mode, the linecache above will keep us sequential.
*/
t[2] = vips_image_new();
if (vips_image_pipelinev(t[2],
if (vips_image_pipelinev(resample->out,
VIPS_DEMAND_STYLE_SMALLTILE, in, NULL))
return -1;

Expand All @@ -554,10 +555,10 @@ vips_shrinkv_build(VipsObject *object)
* example, vipsthumbnail knows the true shrink factor (including the
* fractional part), we just see the integer part here.
*/
t[2]->Ysize = shrink->ceil
resample->out->Ysize = shrink->ceil
? ceil((double) resample->in->Ysize / shrink->vshrink)
: VIPS_ROUND_UINT((double) resample->in->Ysize / shrink->vshrink);
if (t[2]->Ysize <= 0) {
if (resample->out->Ysize <= 0) {
vips_error(class->nickname,
"%s", _("image has shrunk to nothing"));
return -1;
Expand All @@ -567,39 +568,14 @@ vips_shrinkv_build(VipsObject *object)
printf("vips_shrinkv_build: vshrink = %d\n", shrink->vshrink);
printf("vips_shrinkv_build: shrinking %d x %d image to %d x %d\n",
in->Xsize, in->Ysize,
t[2]->Xsize, t[2]->Ysize);
resample->out->Xsize, resample->out->Ysize);
#endif /*DEBUG*/

if (vips_image_generate(t[2],
if (vips_image_generate(resample->out,
vips_shrinkv_start, generate, vips_shrinkv_stop,
in, shrink))
return -1;

in = t[2];

/* Large vshrinks will throw off sequential mode. Suppose thread1 is
* generating tile (0, 0), but stalls. thread2 generates tile
* (0, 1), 128 lines further down the output. After it has done,
* thread1 tries to generate (0, 0), but by then the pixels it needs
* have gone from the input image line cache if the vshrink is large.
*
* To fix this, put another seq on the output of vshrink. Now we'll
* always have the previous XX lines of the shrunk image, and we won't
* fetch out of order.
*/
if (vips_image_is_sequential(in)) {
g_info("shrinkv sequential line cache");

if (vips_sequential(in, &t[3],
"tile_height", 10,
NULL))
return -1;
in = t[3];
}

if (vips_image_write(in, resample->out))
return -1;

return 0;
}

Expand Down
Loading