add rgba -> rgb stage for webp output

This commit is contained in:
John Cupitt 2019-06-30 16:53:11 +01:00
parent aac01126af
commit 25af46a189
2 changed files with 35 additions and 18 deletions

View File

@ -287,11 +287,6 @@ vips_image_paint_image( VipsImage *frame,
g_assert( VIPS_IMAGE_SIZEOF_PEL( sub ) == ps ); g_assert( VIPS_IMAGE_SIZEOF_PEL( sub ) == ps );
/* Disable blend if we are not RGBA.
*/
if( frame->Bands != 4 )
blend = FALSE;
vips_rect_intersectrect( &frame_rect, &sub_rect, &ovl ); vips_rect_intersectrect( &frame_rect, &sub_rect, &ovl );
if( !vips_rect_isempty( &ovl ) ) { if( !vips_rect_isempty( &ovl ) ) {
VipsPel *p, *q; VipsPel *p, *q;
@ -455,10 +450,11 @@ read_header( Read *read, VipsImage *out )
flags = WebPDemuxGetI( read->demux, WEBP_FF_FORMAT_FLAGS ); flags = WebPDemuxGetI( read->demux, WEBP_FF_FORMAT_FLAGS );
read->alpha = flags & ALPHA_FLAG; read->alpha = flags & ALPHA_FLAG;
if( read->alpha )
read->config.output.colorspace = MODE_RGBA; /* We do everything as RGBA and then, if we can, drop the alpha on
else * save.
read->config.output.colorspace = MODE_RGB; */
read->config.output.colorspace = MODE_RGBA;
if( flags & ANIMATION_FLAG ) { if( flags & ANIMATION_FLAG ) {
int loop_count; int loop_count;
@ -553,10 +549,12 @@ read_header( Read *read, VipsImage *out )
} }
} }
/* The canvas is always RGBA, we drop alpha to RGB on output if we
* can.
*/
read->frame = vips_image_new_memory(); read->frame = vips_image_new_memory();
vips_image_init_fields( read->frame, vips_image_init_fields( read->frame,
read->frame_width, read->frame_height, read->frame_width, read->frame_height, 4,
read->alpha ? 4 : 3,
VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_FORMAT_UCHAR, VIPS_CODING_NONE,
VIPS_INTERPRETATION_sRGB, VIPS_INTERPRETATION_sRGB,
1.0, 1.0 ); 1.0, 1.0 );
@ -619,8 +617,7 @@ read_frame( Read *read,
frame = vips_image_new_memory(); frame = vips_image_new_memory();
vips_image_init_fields( frame, vips_image_init_fields( frame,
width, height, width, height, 4,
read->alpha ? 4 : 3,
VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_FORMAT_UCHAR, VIPS_CODING_NONE,
VIPS_INTERPRETATION_sRGB, VIPS_INTERPRETATION_sRGB,
1.0, 1.0 ); 1.0, 1.0 );
@ -765,9 +762,29 @@ read_webp_generate( VipsRegion *or,
read->frame_no += 1; read->frame_no += 1;
} }
memcpy( VIPS_REGION_ADDR( or, 0, r->top ), if( or->im->Bands == 4 )
VIPS_IMAGE_ADDR( read->frame, 0, line ), memcpy( VIPS_REGION_ADDR( or, 0, r->top ),
VIPS_IMAGE_SIZEOF_LINE( read->frame ) ); VIPS_IMAGE_ADDR( read->frame, 0, line ),
VIPS_IMAGE_SIZEOF_LINE( read->frame ) );
else {
int x;
VipsPel *p;
VipsPel *q;
/* We know that alpha is solid, so we can just drop the 4th
* band.
*/
p = VIPS_IMAGE_ADDR( read->frame, 0, line );
q = VIPS_REGION_ADDR( or, 0, r->top );
for( x = 0; x < r->width; x++ ) {
q[0] = p[0];
q[1] = p[1];
q[2] = p[2];
q += 3;
p += 4;
}
}
return( 0 ); return( 0 );
} }

View File

@ -463,7 +463,7 @@ class TestForeign:
def test_webp(self): def test_webp(self):
def webp_valid(im): def webp_valid(im):
a = im(10, 10) a = im(10, 10)
assert_almost_equal_objects(a, [71, 166, 236]) assert_almost_equal_objects(a, [70, 165, 235])
assert im.width == 550 assert im.width == 550
assert im.height == 368 assert im.height == 368
assert im.bands == 3 assert im.bands == 3
@ -478,7 +478,7 @@ class TestForeign:
im = pyvips.Image.new_from_file(WEBP_FILE) im = pyvips.Image.new_from_file(WEBP_FILE)
buf = im.webpsave_buffer(lossless=True) buf = im.webpsave_buffer(lossless=True)
im2 = pyvips.Image.new_from_buffer(buf, "") im2 = pyvips.Image.new_from_buffer(buf, "")
assert im.avg() == im2.avg() assert abs(im.avg() - im2.avg()) < 1
# higher Q should mean a bigger buffer # higher Q should mean a bigger buffer
b1 = im.webpsave_buffer(Q=10) b1 = im.webpsave_buffer(Q=10)