Пример #1
0
/* Call im_shrink via arg vector.
 */
static int
shrink_vec( im_object *argv )
{
	double xshrink = *((double *) argv[2]);
	double yshrink = *((double *) argv[3]);

	return( im_shrink( argv[0], argv[1], xshrink, yshrink ) );
}
Пример #2
0
int
main( int argc, char *argv[] )
{
	int enlar = 0;
	int center = 0;
	int rev = 0;

	IMAGE *vips;
	FILE *out;
	int n1, n2;
	int x, y;
	int xsize, ysize;
	int c;
	PEL *p;

	if( im_init_world( argv[0] ) )
	        error_exit( "unable to start VIPS" );

	while( --argc > 0 && (*++argv)[0] == '-' )
		while( (c = *++argv[0]) )
			switch( c ) {
			case 'e':
				enlar = 1;
				break;

			case 'c':
				center = 1;
				break;

			case 'r':
				rev = 1;
				break;

			default:
				error_exit( "mitsub: illegal option %c", c );
			}

	if( argc != 2 )
		error_exit( "usage: mitsub [-ecr] vipsfile mitfile\n"
			"where:\n"
			"\tvipsfile may be 1, 3 or 4 bands for mono, IM_TYPE_RGB or "
			"IM_TYPE_CMYK printing\n" 
			"\tmitfile may be '-', meaning send to stdout\n"
			"\t-e means enlarge to fill page\n"
			"\t-c means centre within page\n"
			"\t-r means reverse black/white\n"
			"\tNOTE: data is sent raw, with 0 == no ink - all correction is up to "
			"you\n"
			"example:\n"
			"\t%% mitsub -ec fred.v - > /dev/bpp0" );

	if( !(vips = im_open( argv[0], "r" )) )
		error_exit( "mitsub: unable to open \"%s\" for input", 
			argv[0] );

	if( strcmp( argv[1], "-" ) == 0 )
		out = stdout;
	else if( !(out = fopen( argv[1], "w" )) )
		error_exit( "mitsub: unable to open \"%s\" for output", 
			argv[1] );

	if( vips->Coding != IM_CODING_NONE || vips->BandFmt != IM_BANDFMT_UCHAR )
		error_exit( "mitsub: uncoded uchar only" );
	if( vips->Bands != 1 && vips->Bands != 3 && vips->Bands != 4 )
		error_exit( "mitsub: 1,3 and 4 band images only" );

	/* Set xsize and ysize.
	 */
	if( vips->Xsize <= vips->Ysize ) {
		xsize = vips->Xsize;
		ysize = vips->Ysize;
	}
	else {
		im_diagnostics( "mitsub: rotating ..." );
		xsize = vips->Ysize;
		ysize = vips->Xsize;
	}

	/* Shrink if image is too big.
	 */
	if( xsize > HMAX || ysize > VMAX ) {
		double x_factor = HMAX/xsize;
		double y_factor = VMAX/ysize;
		double factor = IM_MAX( x_factor, y_factor );
		IMAGE *sh = im_open( "shrink", "t" );

		im_diagnostics( "mitsub: shrinking by %g ...", factor );
		if( !sh || im_shrink( vips, sh, factor, factor ) )
			error_exit( "mitsub: shrink failed" );

		vips = sh;
		enlar = 0;
	}

	/* On line command and buffer clear.
	 */
 	putc( 0x11, out );
	putc( 0x1b, out );
	putc( 'Z', out );

	/* Memory clear.
	 */
	putc( 0x1b, out );
	putc( 'Z', out );

	/* Media size. (Size A4)
	 */
	putc( 0x1b, out );
	putc( '#', out );
	putc( 'P', out );
	putc( '0', out );

	/* Enlargement.
	 */
	if( enlar ) {
		double rh, rv;
		int n, m;

		/* Enlarge method: ('0'=simple enlargement, 
		 * '1'=linear enlargement)
		 */
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'O', out );
		putc( '1', out );	

		rh = HMAX/(double) xsize;
		rv = VMAX/(double) ysize;
		if( rh > 8 || rv > 8 ) {
			n = 8;
			m = 1;
		}
		else if( rh > rv ) {
			double fact = VMAX/255;

			n = 255;
			m = (int) ysize/fact + 1;
		}
		else {
			double fact = HMAX/255;

			n = 255;
			m = (int) xsize/fact + 1;
		}
		im_diagnostics( "mitsub: enlarging by %g ...", (double) n/m );

		/* Horizontal enlarge.
		 */	
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'P', out );
		putc( n, out );
		putc( m, out );

		/* Vertical enlarge.
		 */
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'Q', out );
		putc( n, out );
		putc( m, out );

	}
	else {
		/* No enlargement.
		 */
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'O', out );
		putc( '1', out );	
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'P', out );
		putc( 1, out );
		putc( 1, out );
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'Q', out );
		putc( 1, out );
		putc( 1, out );
	}

	if( rev ) {
		/* Colour reversing.
		 */
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'W', out );
		putc( '2', out  );
	}
	else {
		/* No reverse.
		 */
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'W', out );
		putc( '0', out  );
	}

	/* Number of copies.
	 */
	putc( 0x1b, out );
	putc( '#', out );
	putc( 'C', out );
	putc( NBPRINT, out  );

	/* Left margin.
	 */
	putc( 0x1b, out );
	putc( '&', out );
	putc( 'S', out );
	putc( 0, out  );

	/* Top margin.
	 */
	putc( 0x1b, out );
	putc( '&', out );
	putc( 'T', out );
	putc( 0, out  );

	/* Centering. ('1' = centering available, '0'= no centering).
	 */
	if( center ) {
		im_diagnostics( "mitsub: centering ..." );
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'C', out );
		putc( '1', out );	 
	}
	else {
		/* No centering.
		 */
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'C', out );
		putc( '0', out );
	}

	/* Transfer format = pixel order method for colour, = frame order 
	 * method for monochrome.
	 */	
	switch( vips->Bands ) {
	case 3:
	case 4:
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'A', out );
		putc( '2', out  );
		break;

	case 1:
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'A', out );
		putc( '0', out  );	
		break;

	default:
		error_exit( "internal error" );
		/*NOTREACHED*/
	}

	/* Colour specification.
	 */
	switch( vips->Bands ) {
	case 4:
	case 1:
		/* IM_TYPE_CMYK. For mono, send just K.
		 */
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'I', out );
		putc( '2', out );
		break;

	case 3:
		/* IM_TYPE_RGB.
		 */
		putc( 0x1b, out );
		putc( '&', out );
		putc( 'I', out );
		putc( '0', out );
		break;
	
	default:
		error_exit( "internal error" );
		/*NOTREACHED*/
	}

	/* Gray scale level.
	 */
	putc( 0x1b, out );
	putc( '#', out );
	putc( 'L', out );
	putc( 8, out );

	/* Rotation.
	 */
	if( vips->Xsize <= vips->Ysize ) {
		putc( 0x1b, out );
		putc( '#', out );
		putc( 'R', out );
		putc( '0', out );
	}
	else  {
		putc( 0x1b, out );
		putc( '#', out );
		putc( 'R', out );
		putc( '1', out );
	}
		
	/* Horizontal shift.
	 */ 
	putc( 0x1b, out );
	putc( '&', out );
	putc( 'J', out );
	putc( 0, out );
	putc( 0, out );

	/* Vertical shift.
	 */
	putc( 0x1b, out );
	putc( '&', out );
	putc( 'K', out );
	putc( 0, out );
	putc( 0, out );

	/* Number of horizontal pixels.
	 */
	n1 = vips->Xsize >> 8;
	n2 = vips->Xsize & 0xff;
	putc(  0x1b, out );
	putc( '&', out );
	putc( 'H', out );
	putc( n1, out );
	putc( n2, out );
	
	/* Number of vertical pixels.
	 */
	n1 = vips->Ysize >> 8;
	n2 = vips->Ysize & 0xff;
	putc( 0x1b, out );
	putc( '&', out );
	putc( 'V', out );
	putc( n1, out );
	putc( n2, out );

	/* Transfer colour (for monochrome image only).
	 */
	if( vips->Bands == 1 ) {
		putc( 0x1b, out );
		putc( 'C', out );
		putc( '4', out );
	}

	/* Image data transfer. Image must be sent as YMCK.
	 */
	putc( 0x1b, out );
	putc( 'O', out );
	if( im_incheck( vips ) )
		error_exit( "mitsub: unable to read image data" );
	p = (PEL *) vips->data;
	switch( vips->Bands ) {
	case 4:
		im_diagnostics( "mitsub: sending IM_TYPE_CMYK ..." );
		for( y = 0; y < vips->Ysize; y++ )
			for( x = 0; x < vips->Xsize; x++ ) {
 				putc( p[2], out );
				putc( p[1], out );
				putc( p[0], out );
				putc( p[3], out );
				p += 4;
			}
		break;

	case 3:
		im_diagnostics( "mitsub: sending IM_TYPE_RGB ..." );
		for( y = 0; y < vips->Ysize; y++ )
			for( x = 0; x < vips->Xsize; x++ ) {
 				putc( p[0], out );
				putc( p[1], out );
				putc( p[2], out );
				p += 3;
			}
		break;

	case 1:
		im_diagnostics( "mitsub: sending K ..." );
		for( y = 0; y < vips->Ysize; y++ )
			for( x = 0; x < vips->Xsize; x++ )
 				putc( *p++, out );
		break;
	}

	/* Form feed. Page end.
	 */
	putc( 0x0c, out  );

	/* Now try to reset printer to default settings. 
	 *
	 * No enlargement.
	 */
	putc( 0x1b, out );
	putc( '&', out );
	putc( 'O', out );
	putc( '1', out );	
	putc( 0x1b, out );
	putc( '&', out );
	putc( 'P', out );
	putc( 1, out );
	putc( 1, out );
	putc( 0x1b, out );
	putc( '&', out );
	putc( 'Q', out );
	putc( 1, out );
	putc( 1, out );

	/* No centering.
	 */
	putc( 0x1b, out );
	putc( '&', out );
	putc( 'C', out );
	putc( '0', out );

	/* No colour reverse.
	 */
	putc( 0x1b, out );
	putc( '&', out );
	putc( 'W', out );
	putc( '0', out  );

	return( 0 );
}
Пример #3
0
static int
shrink_factor( IMAGE *in, IMAGE *out, 
	int shrink, double residual, VipsInterpolate *interp )
{
	IMAGE *t[9];
	VipsImage **s = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( out ), 1 );
	IMAGE *x;
	int tile_width;
	int tile_height;
	int nlines;

	if( im_open_local_array( out, t, 9, "thumbnail", "p" ) )
		return( -1 );
	x = in;

	/* Unpack the two coded formats we support to float for processing.
	 */
	if( x->Coding == IM_CODING_LABQ ) {
		if( verbose ) 
			printf( "unpacking LAB to RGB\n" );

		if( im_LabQ2disp( x, t[1], im_col_displays( 7 ) ) )
			return( -1 );
		x = t[1];
	}
	else if( x->Coding == IM_CODING_RAD ) {
		if( verbose ) 
			printf( "unpacking Rad to float\n" );

		if( im_rad2float( x, t[1] ) )
			return( -1 );
		x = t[1];
	}

	if( im_shrink( x, t[2], shrink, shrink ) )
		return( -1 );

	/* We want to make sure we read the image sequentially.
	 * However, the convolution we may be doing later will force us 
	 * into SMALLTILE or maybe FATSTRIP mode and that will break
	 * sequentiality.
	 *
	 * So ... read into a cache where tiles are scanlines, and make sure
	 * we keep enough scanlines to be able to serve a line of tiles.
	 */
	vips_get_tile_size( t[2], 
		&tile_width, &tile_height, &nlines );
	if( vips_tilecache( t[2], &s[0], 
		"tile_width", t[2]->Xsize,
		"tile_height", 10,
		"max_tiles", (nlines * 2) / 10,
		"strategy", VIPS_CACHE_SEQUENTIAL,
		NULL ) ||
		im_affinei_all( s[0], t[4], 
			interp, residual, 0, 0, residual, 0, 0 ) )
		return( -1 );
	x = t[4];

	/* If we are upsampling, don't sharpen, since nearest looks dumb
	 * sharpened.
	 */
	if( shrink > 1 && residual <= 1.0 && !nosharpen ) {
		if( verbose ) 
			printf( "sharpening thumbnail\n" );

		if( im_conv( x, t[5], sharpen_filter() ) )
			return( -1 );
		x = t[5];
	}

	/* Colour management: we can transform the image if we have an output
	 * profile and an input profile. The input profile can be in the
	 * image, or if there is no profile there, supplied by the user.
	 */
	if( export_profile &&
		(im_header_get_typeof( x, IM_META_ICC_NAME ) || 
		 import_profile) ) {
		if( im_header_get_typeof( x, IM_META_ICC_NAME ) ) {
			if( verbose ) 
				printf( "importing with embedded profile\n" );

			if( im_icc_import_embedded( x, t[6], 
				IM_INTENT_RELATIVE_COLORIMETRIC ) )
				return( -1 );
		}
		else {
			if( verbose ) 
				printf( "importing with profile %s\n",
					import_profile );

			if( im_icc_import( x, t[6], 
				import_profile, 
				IM_INTENT_RELATIVE_COLORIMETRIC ) )
				return( -1 );
		}

		if( verbose ) 
			printf( "exporting with profile %s\n", export_profile );

		if( im_icc_export_depth( t[6], t[7], 
			8, export_profile, 
			IM_INTENT_RELATIVE_COLORIMETRIC ) )
			return( -1 );

		x = t[7];
	}

	if( delete_profile ) {
		if( verbose )
			printf( "deleting profile from output image\n" );

		if( im_meta_get_typeof( x, IM_META_ICC_NAME ) &&
			!im_meta_remove( x, IM_META_ICC_NAME ) )
			return( -1 );
	}

	if( im_copy( x, out ) )
		return( -1 );

	return( 0 );
}