Пример #1
0
/* Out is a huge "t" buffer we decompress to.
 */
static int
png2vips_interlace( Read *read, VipsImage *out )
{
	int y;

#ifdef DEBUG
	printf( "png2vips_interlace: reading whole image\n" ); 
#endif /*DEBUG*/

	if( vips_image_write_prepare( out ) )
		return( -1 );

	if( setjmp( png_jmpbuf( read->pPng ) ) ) 
		return( -1 );
 
	if( !(read->row_pointer = VIPS_ARRAY( NULL, out->Ysize, png_bytep )) )
		return( -1 );
	for( y = 0; y < out->Ysize; y++ )
		read->row_pointer[y] = VIPS_IMAGE_ADDR( out, 0, y );

	/* Some libpng warn you to call png_set_interlace_handling(); here, but
	 * that can actually break interlace. We have to live with the warning,
	 * unfortunately.
	 */

	png_read_image( read->pPng, read->row_pointer );

	png_read_end( read->pPng, NULL ); 

	read_destroy( read );

	return( 0 );
}
Пример #2
0
/* Out is a huge "t" buffer we decompress to.
 */
static int
png2vips_interlace( Read *read, VipsImage *out )
{
	int y;

#ifdef DEBUG
	printf( "png2vips_interlace: reading whole image\n" ); 
#endif /*DEBUG*/

	if( vips_image_write_prepare( out ) )
		return( -1 );

	if( setjmp( png_jmpbuf( read->pPng ) ) ) 
		return( -1 );

	if( !(read->row_pointer = VIPS_ARRAY( NULL, out->Ysize, png_bytep )) )
		return( -1 );
	for( y = 0; y < out->Ysize; y++ )
		read->row_pointer[y] = VIPS_IMAGE_ADDR( out, 0, y );

	png_read_image( read->pPng, read->row_pointer );

	png_read_end( read->pPng, NULL ); 

	read_destroy( read );

	return( 0 );
}
Пример #3
0
static Read *
read_new( IMAGE *in, IMAGE *out, 
	int tile_width, int tile_height, int max_tiles )
{
	Read *read;

	if( !(read = IM_NEW( NULL, Read )) )
		return( NULL );
	read->in = in;
	read->out = out;
	read->tile_width = tile_width;
	read->tile_height = tile_height;
	read->max_tiles = max_tiles;
	read->time = 0;
	read->ntiles = 0;
	read->lock = g_mutex_new();
	read->cache = NULL;

	if( im_add_close_callback( out, 
		(im_callback_fn) read_destroy, read, NULL ) ) {
		read_destroy( read );
		return( NULL );
	}

	return( read );
}
Пример #4
0
static Read *
read_new( const char *filename, VipsImage *out )
{
	Read *read;

	if( !(read = VIPS_NEW( NULL, Read )) )
		return( NULL );

	read->filename = vips_strdup( NULL, filename );
	read->out = out;
	read->mat = NULL;
	read->var = NULL;

	if( !(read->mat = Mat_Open( filename, MAT_ACC_RDONLY )) ) {
		vips_error( "mat2vips", 
			_( "unable to open \"%s\"" ), filename );
		read_destroy( read );
		return( NULL );
	}

	for(;;) {
		if( !(read->var = Mat_VarReadNextInfo( read->mat )) ) {
			vips_error( "mat2vips", 
				_( "no matrix variables in \"%s\"" ), 
				filename );
			read_destroy( read );
			return( NULL );
		}

#ifdef DEBUG
		printf( "mat2vips: seen:\n" );
		printf( "var->name == %s\n", read->var->name );
		printf( "var->class_type == %d\n", read->var->class_type );
		printf( "var->rank == %d\n", read->var->rank );
#endif /*DEBUG*/

		/* Vector to colour image is OK for us.
		 */
		if( read->var->rank >= 1 && read->var->rank <= 3 )
			break;

		VIPS_FREEF( Mat_VarFree, read->var );
	}

	return( read );
}
Пример #5
0
/* Read a PNG file header into a VIPS header.
 */
static int
png2vips_header( const char *name, IMAGE *out )
{
	Read *read;

	if( !(read = read_new( name, out )) )
		return( -1 );

	if( png2vips( read, 1 ) ) {
		read_destroy( read );
		return( -1 );
	}

	read_destroy( read );

	return( 0 );
}
Пример #6
0
int
vips__mat_header( const char *filename, VipsImage *out )
{
	Read *read;

#ifdef DEBUG
	printf( "mat2vips_header: reading \"%s\"\n", filename );
#endif /*DEBUG*/

	if( !(read = read_new( filename, out )) ) 
		return( -1 );
	if( mat2vips_get_header( read->var, read->out ) ) {
		read_destroy( read );
		return( -1 );
	}
	read_destroy( read );

	return( 0 );
}
Пример #7
0
static Read *
read_new( const char *name, IMAGE *out )
{
	Read *read;

	if( !(read = IM_NEW( NULL, Read )) )
		return( NULL );

	read->name = im_strdup( NULL, name );
	read->out = out;
	read->fp = NULL;
	read->pPng = NULL;
	read->pInfo = NULL;
	read->row_pointer = NULL;
	read->data = NULL;

        if( !(read->fp = im__file_open_read( name, NULL )) ) {
		read_destroy( read );
		return( NULL );
	}

	if( !(read->pPng = png_create_read_struct( 
		PNG_LIBPNG_VER_STRING, NULL,
		user_error_function, user_warning_function )) ) {
		read_destroy( read );
		return( NULL );
	}

	/* Catch PNG errors from png_create_info_struct().
	 */
	if( setjmp( read->pPng->jmpbuf ) ) {
		read_destroy( read );
		return( NULL );
	}

	if( !(read->pInfo = png_create_info_struct( read->pPng )) ) {
		read_destroy( read );
		return( NULL );
	}

	return( read );
}
Пример #8
0
/**
 * im_mat2vips:
 * @filename: file to load
 * @out: image to write to
 *
 * Read a Matlab save file into a VIPS image. 
 *
 * This operation searches the save
 * file for the first array variable with between 1 and 3 dimensions and loads
 * it as an image. It will not handle complex images. It does not handle
 * sparse matrices. 
 *
 * See also: #VipsFormat.
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_mat2vips( const char *filename, IMAGE *out )
{
	Read *read;

#ifdef DEBUG
	printf( "mat2vips: reading \"%s\"\n", filename );
#endif /*DEBUG*/

	if( !(read = read_new( filename, out )) ) 
		return( -1 );
	if( mat2vips_get_header( read->var, read->out ) ||
		mat2vips_get_data( read->mat, read->var, read->out ) ) {
		read_destroy( read );
		return( -1 );
	}
	read_destroy( read );

	return( 0 );
}
Пример #9
0
/**
 * im_png2vips:
 * @filename: file to load
 * @out: image to write to
 *
 * Read a PNG file into a VIPS image. It can read all png images, including 8-
 * and 16-bit images, 1 and 3 channel, with and without an alpha channel.
 *
 * There is no support for embedded ICC profiles.
 *
 * See also: #VipsFormat, im_vips2png().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_png2vips( const char *name, IMAGE *out )
{
	Read *read;

#ifdef DEBUG
	printf( "im_png2vips: reading \"%s\"\n", name );
#endif /*DEBUG*/

	if( !(read = read_new( name, out )) )
		return( -1 );

	if( png2vips( read, 0 ) ) {
		read_destroy( read );
		return( -1 );
	}

	read_destroy( read );

	return( 0 );
}
Пример #10
0
/* Read a PNG file header into a VIPS header.
 */
int
vips__png_header( const char *name, VipsImage *out )
{
	Read *read;

	if( !(read = read_new_filename( out, name, FALSE )) ||
		png2vips_header( read, out ) ) 
		return( -1 );

	/* Just a header read: we can free the read early and save an fd.
	 */
	read_destroy( read );

	return( 0 );
}
Пример #11
0
static Read *
read_new( const char *filename, IMAGE *im )
{
	Read *read;
	static int inited = 0;

	if( !inited ) {
#ifdef HAVE_MAGICKCOREGENESIS
		MagickCoreGenesis( im_get_argv0(), MagickFalse );
#else /*!HAVE_MAGICKCOREGENESIS*/
		InitializeMagick( "" );
#endif /*HAVE_MAGICKCOREGENESIS*/
		inited = 1;
	}

	if( !(read = IM_NEW( NULL, Read )) )
		return( NULL );
	read->filename = im_strdup( NULL, filename );
	read->im = im;
	read->image = NULL;
	read->image_info = CloneImageInfo( NULL );
	GetExceptionInfo( &read->exception );
	read->n_frames = 0;
	read->frames = NULL;
	read->frame_height = 0;
	read->lock = g_mutex_new();

	if( im_add_close_callback( im,
		(im_callback_fn) read_destroy, read, NULL ) ) {
		read_destroy( read );
		return( NULL );
	}

	if( !read->filename || !read->image_info ) 
		return( NULL );

	im_strncpy( read->image_info->filename, filename, MaxTextExtent );

#ifdef DEBUG
	printf( "im_magick2vips: read_new: %s\n", read->filename );
#endif /*DEBUG*/

	return( read );
}
Пример #12
0
static int
png2vips_generate( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
        VipsRect *r = &or->valid;
	Read *read = (Read *) a;

	int y;

#ifdef DEBUG
	printf( "png2vips_generate: line %d, %d rows\n", r->top, r->height );
	printf( "png2vips_generate: y_top = %d\n", read->y_pos );
#endif /*DEBUG*/

	/* We're inside a tilecache where tiles are the full image width, so
	 * this should always be true.
	 */
	g_assert( r->left == 0 );
	g_assert( r->width == or->im->Xsize );
	g_assert( VIPS_RECT_BOTTOM( r ) <= or->im->Ysize );

	/* Tiles should always be a strip in height, unless it's the final
	 * strip.
	 */
	g_assert( r->height == VIPS_MIN( 8, or->im->Ysize - r->top ) ); 

	/* And check that y_pos is correct. It should be, since we are inside
	 * a vips_sequential().
	 */
	if( r->top != read->y_pos ) {
		vips_error( "vipspng", 
			_( "out of order read at line %d" ), read->y_pos );
		return( -1 );
	}

	for( y = 0; y < r->height; y++ ) {
		png_bytep q = (png_bytep) VIPS_REGION_ADDR( or, 0, r->top + y );

		/* We need to catch and ignore errors from read_row().
		 */
		if( !setjmp( png_jmpbuf( read->pPng ) ) ) 
			png_read_row( read->pPng, q, NULL );
		else { 
#ifdef DEBUG
			printf( "png2vips_generate: png_read_row() failed, "
				"line %d\n", r->top + y ); 
			printf( "png2vips_generate: file %s\n", read->name );
			printf( "png2vips_generate: thread %p\n", 
				g_thread_self() );
#endif /*DEBUG*/
		}

		read->y_pos += 1;
	}

	/* Turn errors back on. png_read_end() can trigger them too.
	 */
	if( setjmp( png_jmpbuf( read->pPng ) ) ) 
		return( -1 );

	/* We need to shut down the reader immediately at the end of read or
	 * we won't detach ready for the next image.
	 */
	if( read->y_pos >= read->out->Ysize ) {
		png_read_end( read->pPng, NULL ); 
		read_destroy( read );
	}

	return( 0 );
}
Пример #13
0
static void
read_close_cb( VipsImage *out, Read *read )
{
	read_destroy( read ); 
}
Пример #14
0
static int
png2vips_generate( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
        VipsRect *r = &or->valid;
	Read *read = (Read *) a;

	int y;

#ifdef DEBUG
	printf( "png2vips_generate: line %d, %d rows\n", r->top, r->height );
	printf( "png2vips_generate: y_top = %d\n", read->y_pos );
#endif /*DEBUG*/

	/* We're inside a tilecache where tiles are the full image width, so
	 * this should always be true.
	 */
	g_assert( r->left == 0 );
	g_assert( r->width == or->im->Xsize );
	g_assert( VIPS_RECT_BOTTOM( r ) <= or->im->Ysize );

	/* Tiles should always be a strip in height, unless it's the final
	 * strip.
	 */
	g_assert( r->height == VIPS_MIN( 8, or->im->Ysize - r->top ) ); 

	/* And check that y_pos is correct. It should be, since we are inside
	 * a vips_sequential().
	 */
	if( r->top != read->y_pos ) {
		vips_error( "vipspng", 
			_( "out of order read at line %d" ), read->y_pos );
		return( -1 );
	}

	for( y = 0; y < r->height; y++ ) {
		png_bytep q = (png_bytep) VIPS_REGION_ADDR( or, 0, r->top + y );

		/* We need to catch errors from read_row().
		 */
		if( !setjmp( png_jmpbuf( read->pPng ) ) ) 
			png_read_row( read->pPng, q, NULL );
		else { 
			/* We've failed to read some pixels. Knock this 
			 * operation out of cache. 
			 */
			vips_foreign_load_invalidate( read->out );

#ifdef DEBUG
			printf( "png2vips_generate: png_read_row() failed, "
				"line %d\n", r->top + y ); 
			printf( "png2vips_generate: file %s\n", read->name );
			printf( "png2vips_generate: thread %p\n", 
				g_thread_self() );
#endif /*DEBUG*/

			/* And bail if fail is on. We have to add an error
			 * message, since the handler we install just does
			 * g_warning().
			 */
			if( read->fail ) {
				vips_error( "vipspng", 
					"%s", _( "libpng read error" ) ); 
				return( -1 );
			}
		}

		read->y_pos += 1;
	}

	/* Catch errors from png_read_end(). This can fail on a truncated
	 * file. 
	 */
	if( setjmp( png_jmpbuf( read->pPng ) ) ) {
		if( read->fail ) {
			vips_error( "vipspng", "%s", _( "libpng read error" ) ); 
			return( -1 );
		}

		return( 0 );
	}

	/* We need to shut down the reader immediately at the end of read or
	 * we won't detach ready for the next image.
	 */
	if( read->y_pos >= read->out->Ysize ) {
		png_read_end( read->pPng, NULL ); 
		read_destroy( read );
	}

	return( 0 );
}