Ejemplo n.º 1
0
static int
png2vips_image( Read *read, VipsImage *out )
{
	int interlace_type = png_get_interlace_type( read->pPng, read->pInfo );
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( out ), 3 );

	if( interlace_type != PNG_INTERLACE_NONE ) { 
		/* Arg awful interlaced image. We have to load to a huge mem 
		 * buffer, then copy to out.
		 */
		t[0] = vips_image_new_memory();
		if( png2vips_header( read, t[0] ) ||
			png2vips_interlace( read, t[0] ) ||
			vips_image_write( t[0], out ) )
			return( -1 );
	}
	else {
		t[0] = vips_image_new();
		if( png2vips_header( read, t[0] ) ||
			vips_image_generate( t[0], 
				NULL, png2vips_generate, NULL, 
				read, NULL ) ||
			vips_sequential( t[0], &t[1], 
				"tile_height", 8,
				"access", read->readbehind ? 
					VIPS_ACCESS_SEQUENTIAL : 
					VIPS_ACCESS_SEQUENTIAL_UNBUFFERED,
				NULL ) ||
			vips_image_write( t[1], out ) )
			return( -1 );
	}

	return( 0 );
}
Ejemplo n.º 2
0
/* Read a PNG file (header) into a VIPS (header).
 */
static int
png2vips( Read *read, int header_only )
{
	int bands, bpp, type;

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

	png_init_io( read->pPng, read->fp );
	png_read_info( read->pPng, read->pInfo );

	/* png_get_channels() gives us 1 band for palette images ... so look
	 * at colour_type for output bands.
	 */
	switch( read->pInfo->color_type ) {
	case PNG_COLOR_TYPE_PALETTE: 
		bands = 3; 

		/* Don't know if this is really correct. If there are
		 * transparent pixels, assume we're going to output RGBA.
		 */
		if( read->pInfo->num_trans )
			bands = 4; 

		break;

	case PNG_COLOR_TYPE_GRAY: bands = 1; break;
	case PNG_COLOR_TYPE_GRAY_ALPHA: bands = 2; break;
	case PNG_COLOR_TYPE_RGB: bands = 3; break;
	case PNG_COLOR_TYPE_RGB_ALPHA: bands = 4; break;

	default:
		im_error( "im_png2vips", "%s", _( "unsupported color type" ) );
		return( -1 );
	}

	/* 8 or 16 bit.
	 */
	bpp = read->pInfo->bit_depth > 8 ? 2 : 1;

	if( bpp > 1 ) {
		if( bands < 3 )
			type = IM_TYPE_GREY16;
		else
			type = IM_TYPE_RGB16;
	}
	else {
		if( bands < 3 )
			type = IM_TYPE_B_W;
		else
			type = IM_TYPE_sRGB;
	}

	/* Expand palette images.
	 */
	if( read->pInfo->color_type == PNG_COLOR_TYPE_PALETTE )
	        png_set_expand( read->pPng );

	/* Expand <8 bit images to full bytes.
	 */
	if( read->pInfo->bit_depth < 8 ) {
		png_set_packing( read->pPng );
	        png_set_shift( read->pPng, &(read->pInfo->sig_bit) );
	}

	/* If we're an INTEL byte order machine and this is 16bits, we need
	 * to swap bytes.
	 */
	if( read->pInfo->bit_depth > 8 && !im_amiMSBfirst() )
		png_set_swap( read->pPng );

	/* Set VIPS header.
	 */
	im_initdesc( read->out,
		 read->pInfo->width, read->pInfo->height, bands,
		 bpp == 1 ? IM_BBITS_BYTE : IM_BBITS_SHORT, 
		 bpp == 1 ? IM_BANDFMT_UCHAR : IM_BANDFMT_USHORT,
		 IM_CODING_NONE, type, 1.0, 1.0, 0, 0 );

	if( !header_only ) {
		if( png_set_interlace_handling( read->pPng ) > 1 ) {
			if( png2vips_interlace( read ) )
				return( -1 );
		}
		else {
			if( png2vips_noninterlace( read ) )
				return( -1 );
		}
	}

	return( 0 );
}