libvips/contrib/mitsub/mitsub.c
2007-08-29 16:23:50 +00:00

492 lines
9.4 KiB
C

/*
* Version which sents raw data to the printer, which enlarges and centers.
* Works for monochrome and four band IM_TYPE_CMYK images. Uses putc instead of
* fprintf. Sents data straight to the printer. If enlargement, it is full and
* x and y ratios are the same (aspect ratio is not changed)
*
* Helene Chahine, July 95
*
* JC 4/8/95
* - small tidies and bug fixes
* - now does 1, 3 and 4 band
* - resets printer after use
* JC 1/9/95
* - colour reverse mode added
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <stdio.h>
#include <string.h>
#include <vips/vips.h>
#include <vips/util.h>
#define NBPRINT 1 /* Maximun 15 copies */
#define VMAX 2904 /* Number of horizontal pixels */
#define HMAX 2368 /* Number of vertical pixels */
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 );
}