diff --git a/vips/conversion.c b/vips/conversion.c index 49f82be8..00fc1b08 100644 --- a/vips/conversion.c +++ b/vips/conversion.c @@ -229,8 +229,40 @@ int smartcrop(VipsImage *in, VipsImage **out, int width, int height, int crop(VipsImage *in, VipsImage **out, int left, int top, int width, int height) { - return vips_crop(in, out, left, top, width, height, - NULL); + // resolve image pages + int page_height = vips_image_get_page_height(in); + int n_pages = in->Ysize / page_height; + if (n_pages <= 1) { + return vips_crop(in, out, left, top, width, height, NULL); + } + + int in_width = in->Xsize; + VipsObject *base = VIPS_OBJECT(vips_image_new()); + VipsImage **page = (VipsImage **) vips_object_local_array(base, n_pages); + VipsImage **copy = (VipsImage **) vips_object_local_array(base, 1); + // split image into cropped frames + for (int i = 0; i < n_pages; i++) { + if ( + vips_extract_area(in, &page[i], 0, page_height * i, in_width, page_height, NULL) || + vips_crop(page[i], &page[i], left, top, width, height, NULL) + ) { + g_object_unref(base); + return -1; + } + } + + // reassemble frames and set page height + // copy before modifying metadata + if( + vips_arrayjoin(page, ©[0], n_pages, "across", 1, NULL) || + vips_copy(copy[0], out, NULL) + ) { + g_object_unref(base); + return -1; + } + vips_image_set_int(*out, VIPS_META_PAGE_HEIGHT, height); + g_object_unref(base); + return 0; } int flatten_image(VipsImage *in, VipsImage **out, double r, double g, diff --git a/vips/image_gif_test.go b/vips/image_gif_test.go index 169103d2..252404f2 100644 --- a/vips/image_gif_test.go +++ b/vips/image_gif_test.go @@ -115,6 +115,18 @@ func TestImage_GIF_Animated_ExtractArea(t *testing.T) { nil) } +func TestImage_GIF_Animated_Crop(t *testing.T) { + goldenAnimatedTest(t, resources+"gif-animated.gif", + -1, + func(img *ImageRef) error { + return img.Crop(10, 20, 20, 20) + }, + func(img *ImageRef) { + assert.Equal(t, img.GetPageHeight(), 20) + }, + nil) +} + func TestImage_GIF_Animated_PageDelay(t *testing.T) { goldenAnimatedTest(t, resources+"gif-animated.gif", -1,