fix non-animated webp read
This commit is contained in:
parent
1d64321649
commit
4e182440ef
@ -44,8 +44,8 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
#define DEBUG_VERBOSE
|
#define DEBUG_VERBOSE
|
||||||
*/
|
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@ -134,10 +134,20 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
VipsImage *frame;
|
VipsImage *frame;
|
||||||
|
|
||||||
|
/* The frame number currently in @frame. Numbered from 1, so 0 means
|
||||||
|
* before the first frame.
|
||||||
|
*/
|
||||||
|
int frame_no;
|
||||||
|
|
||||||
/* Iterate through the frames with this. iter.frame_num is the number
|
/* Iterate through the frames with this. iter.frame_num is the number
|
||||||
* of the current loaded frame.
|
* of the currently loaded frame.
|
||||||
*/
|
*/
|
||||||
WebPIterator iter;
|
WebPIterator iter;
|
||||||
|
|
||||||
|
/* How to junk the current frame when we move on.
|
||||||
|
*/
|
||||||
|
WebPMuxAnimDispose dispose_method;
|
||||||
|
VipsRect dispose_rect;
|
||||||
} Read;
|
} Read;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -332,6 +342,8 @@ read_new( const char *filename, const void *data, size_t length,
|
|||||||
read->fd = 0;
|
read->fd = 0;
|
||||||
read->demux = NULL;
|
read->demux = NULL;
|
||||||
read->frame = NULL;
|
read->frame = NULL;
|
||||||
|
read->dispose_method = WEBP_MUX_DISPOSE_NONE;
|
||||||
|
read->frame_no = 0;
|
||||||
|
|
||||||
if( read->filename ) {
|
if( read->filename ) {
|
||||||
/* libwebp makes streaming from a file source very hard. We
|
/* libwebp makes streaming from a file source very hard. We
|
||||||
@ -592,31 +604,22 @@ read_next_frame( Read *read )
|
|||||||
{
|
{
|
||||||
VipsImage *frame;
|
VipsImage *frame;
|
||||||
|
|
||||||
/* Any dispose action.
|
/* Dispose from the previous frame.
|
||||||
*/
|
*/
|
||||||
|
if( read->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND )
|
||||||
if( read->iter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND ) {
|
|
||||||
/* We must clear the pixels occupied by this webp frame (not
|
/* We must clear the pixels occupied by this webp frame (not
|
||||||
* the whole of the read frame) to the background colour.
|
* the whole of the read frame) to the background colour.
|
||||||
*/
|
*/
|
||||||
VipsRect area = {
|
|
||||||
read->iter.x_offset,
|
|
||||||
read->iter.y_offset,
|
|
||||||
read->iter.width,
|
|
||||||
read->iter.height
|
|
||||||
};
|
|
||||||
|
|
||||||
vips_image_paint_pel( read->frame,
|
vips_image_paint_pel( read->frame,
|
||||||
&area, (VipsPel *) &read->background );
|
&read->dispose_rect, (VipsPel *) &read->background );
|
||||||
}
|
|
||||||
|
|
||||||
/* Fetch the next frame.
|
/* Note this frame's dispose for next time.
|
||||||
*/
|
*/
|
||||||
|
read->dispose_method = read->iter.dispose_method;
|
||||||
if( !WebPDemuxNextFrame( &read->iter ) ) {
|
read->dispose_rect.left = read->iter.x_offset;
|
||||||
vips_error( "webp2vips", "%s", _( "not enough frames" ) );
|
read->dispose_rect.top = read->iter.y_offset;
|
||||||
return( -1 );
|
read->dispose_rect.width = read->iter.width;
|
||||||
}
|
read->dispose_rect.height = read->iter.height;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "webp2vips: frame_num = %d\n", read->iter.frame_num );
|
printf( "webp2vips: frame_num = %d\n", read->iter.frame_num );
|
||||||
@ -649,13 +652,22 @@ read_next_frame( Read *read )
|
|||||||
|
|
||||||
/* Now blend or copy the new pixels into our accumulator.
|
/* Now blend or copy the new pixels into our accumulator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vips_image_paint_image( read->frame, frame,
|
vips_image_paint_image( read->frame, frame,
|
||||||
read->iter.x_offset, read->iter.y_offset,
|
read->iter.x_offset, read->iter.y_offset,
|
||||||
read->iter.blend_method == WEBP_MUX_BLEND );
|
read->iter.blend_method == WEBP_MUX_BLEND );
|
||||||
|
|
||||||
g_object_unref( frame );
|
g_object_unref( frame );
|
||||||
|
|
||||||
|
/* If there's another frame, move on.
|
||||||
|
*/
|
||||||
|
if( read->iter.frame_num < read->frame_count ) {
|
||||||
|
if( !WebPDemuxNextFrame( &read->iter ) ) {
|
||||||
|
vips_error( "webp2vips",
|
||||||
|
"%s", _( "not enough frames" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,7 +678,9 @@ read_webp_generate( VipsRegion *or,
|
|||||||
VipsRect *r = &or->valid;
|
VipsRect *r = &or->valid;
|
||||||
Read *read = (Read *) a;
|
Read *read = (Read *) a;
|
||||||
|
|
||||||
int frame = r->top / read->frame_height + read->page;
|
/* iter.frame_num numbers from 1.
|
||||||
|
*/
|
||||||
|
int frame = 1 + r->top / read->frame_height + read->page;
|
||||||
int line = r->top % read->frame_height;
|
int line = r->top % read->frame_height;
|
||||||
|
|
||||||
#ifdef DEBUG_VERBOSE
|
#ifdef DEBUG_VERBOSE
|
||||||
@ -675,10 +689,13 @@ read_webp_generate( VipsRegion *or,
|
|||||||
|
|
||||||
g_assert( r->height == 1 );
|
g_assert( r->height == 1 );
|
||||||
|
|
||||||
while( read->iter.frame_num < frame )
|
while( read->frame_no <= frame ) {
|
||||||
if( read_next_frame( read ) )
|
if( read_next_frame( read ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
read->frame_no += 1;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy( VIPS_REGION_ADDR( or, 0, r->top ),
|
memcpy( VIPS_REGION_ADDR( or, 0, r->top ),
|
||||||
VIPS_IMAGE_ADDR( read->frame, 0, line ),
|
VIPS_IMAGE_ADDR( read->frame, 0, line ),
|
||||||
VIPS_IMAGE_SIZEOF_LINE( read->frame ) );
|
VIPS_IMAGE_SIZEOF_LINE( read->frame ) );
|
||||||
|
Loading…
Reference in New Issue
Block a user