📄 lj250of.c
字号:
#ifndef lintstatic char *sccsid = "@(#)lj250of.c 4.2 ULTRIX 10/16/90";#endif/************************************************************************ * * * Copyright (c) 1987, 1990 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * lj250of.c * * Modification history * * 16-Oct-90 - Adrian Thoms (thoms@wessex) * Fixed the colour sixel generation algorithm: * Reduced amount of data generated for typical file by a factor of 14 * Reduced cpu utilisation by factor of over 5 * Can now generate all colours, (a few were missing due to IFMAC bug) * * 01-Oct-90 - Adrian Thoms (thoms@wessex) * Exit with failure status if the data is unprintable * This is to match behaviour of other filters * * 26-Sep-90 - Adrian Thoms (thoms@wessex) * Fixed to match new file guesser types * * 24-Sep-90 - Adrian Thoms (thoms@wessex) * Removed determinefile() and associated functions and definitions * to use library guesser module * * 30-Nov-89 - Daren Seymour * * Fixed last 2 lines of file missing when printing * from a VAXstation 2000. * * 9-Nov-89 - Daren Seymour * * Fixed UWS sixel screen dump problem. * * 23-Nov-88 - Dave Gray (gray) * * Fixed bad pointer reference in strncmp * * LJ250 Colorwriter/Companion Color Printer filter * * 9-Sep-87 - Ricky Palmer (rsp) * * Added some additional comments. * * 16-Jun-87 - Ricky Palmer (rsp) * * Added a couple lines to subtract one from lastcol and tmpcol * variables due to a firmware change in the LJ250 (rev. 6.0). * * 3-Mar-87 - Ricky Palmer (rsp) * * Created original file and filter program contents. * This filter supports all normal text output as well * as color sixels for output of sixel graphics. * */#include <stdio.h>#include <signal.h>#include <errno.h>#include <syslog.h>#include <ctype.h>#include <a.out.h>#include <imghdr.h>#include <strings.h>#include "guesser.h"#define MAXWIDTH 80 /* width char. count */#define MAXLENGTH 66 /* length char. count */#define MAXP_PIX_WIDTH 720 /* portrait pixel width */#define MAXP_PIX_HEIGHT 925 /* portrait pix. height */#define MAXL_PIX_WIDTH 925 /* landscape p. width */#define MAXL_PIX_HEIGHT 720 /* landscape p. length */#define MAXCOPIES 1 /* default # of copies */#define ITS 77#define SOFF '\077' /* sixel element offset */#define MAX(a,b) (a < b ? b : a) /* useful macros */#define MAXIMUM(a,b,c) (MAX(MAX(a,b),c))#define MIN(a,b) (a > b ? b : a)#define MINIMUM(a,b,c) (MIN(MIN(a,b),c))/* * These macros are used to select a colour number if parameter (a) is * in the range (b) to (c). * Parameter may be hue which wraps around fom 359 to 0 * In this case we may have a range which straddles 0 so this * case is catered for. * Note that this is not a runtime hit because the extra comparisons will * be done at compile time. * This part of the algorithm is speeded up by factor 2 by using else if */#define IFMAC if (0) {}#define ELSEIFMAC(a,b,c,d) else if(((b)<(c)&&(a)>=(b)&&(a)<=(c)) || \ ((b)>(c)&&((a)>=(b)||(a)<=(c)))) {\ if (lastcol != d) tmpcol = d; \ }FILE *input = stdin, *output = stdout; /* input and output */int width = MAXWIDTH; /* default line length */int length = MAXLENGTH; /* page length */int indent; /* indentation length */int npages = MAXCOPIES; /* number of copies */int literal; /* print control chars. */int error; /* error return status */char *name; /* user's login name */char *host; /* user's machine name */char *acctfile; /* accounting info. file*/int kindofile = EMPTY_FILE; /* initial kind of file */char *imgptr; /* image data pointers */short *cmpptr; /* color map pointer */struct imghdr im; /* image file header */char *rotptr; /* image rotate buffer */char *malloc(); /* malloc pointer */unsigned size; /* the usual */int rotated = 0; /* rotated image */void exit(), bcopy(), free(), syslog();unsigned sleep();/* The general strategy here is to process the command line arguments, open the syslog file for log information, determine the input stream "file type", call the filter code, and then optionally process accounting information upon completion. Informational and failure conditions are logged to syslog.*/main(argc, argv) int argc; char *argv[];{ register char *cp; register int i; while (--argc) { if (*(cp = *++argv) == '-') { switch (cp[1]) { case 'n': /* collect login name */ argc--; name = *++argv; break; case 'h': /* collect host name */ argc--; host = *++argv; break; case 'w': /* collect page width */ if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH) width = i; break; case 'l': /* collect page length */ length = atoi(&cp[2]); break; case 'i': /* collect indent */ indent = atoi(&cp[2]); break; case 'c': /* print control chars */ literal++; break; } } else acctfile = cp; } openlog("lj250of",LOG_PID); kindofile = determinefile(fileno(input)); error = lj250of(); if(error) { syslog(LOG_INFO,"Failed to output data"); exit(2); } if (name && acctfile && access(acctfile, 02) >= 0 && freopen(acctfile, "a", output) != NULL) { printf("%7.2f\t%s:%s\n", (float)npages, host, name); } exit(0);}/* Here is where all the real output work begins. The printer is issued a "warm reset" to clear any faulty conditions. We sleep for five seconds to allow for stability and then switch to the appropriate code for the determined file type stream.*/lj250of(){ register int i = 0; register int ch; register int counter = 0; register short *tmpptr; unsigned short sr,sg,sb; fprintf(output, "\033c"); sleep(5); counter = 0; switch(kindofile) { case EMPTY_FILE: break; case EXECUTABLE_FILE: case ARCHIVE_FILE: case DATA_FILE: case CAT_FILE: case POSTSCRIPT_FILE: syslog(LOG_INFO,"Unprintable data"); return(1); break; case XIMAGE_FILE: error = readXimghdr(); if(error) { syslog(LOG_INFO,"Failed to use image header"); return(1); } error = readXimgcmp(); if(error) { syslog(LOG_INFO,"Failed to use image colormap"); return(1); } if(im.format != ITS) { /* do RGB to HLS conversion */ tmpptr=cmpptr; for(i=0;i!=256;i++) { sr = *tmpptr; sg = *(tmpptr+1); sb = *(tmpptr+2); rgbtohls(sr,sg,sb,tmpptr,(tmpptr+1),(tmpptr+2)); tmpptr+=3; } } error = readXimgdat(); if(error) { syslog(LOG_INFO,"Failed to use image data"); return(1); } if(im.spbxnm > MAXP_PIX_WIDTH) { error = rotateXimgdat(); if(error) { syslog(LOG_INFO,"Failed to rotate image data"); return(1); } rotated++; } error = docsixel(); if(error) { syslog(LOG_INFO,"Failed to 'sixelize' data"); fprintf(output, "\033\\"); fprintf(output, "\033c"); sleep(5); return(1); } break; case TEXT_FILE: case CTEXT_FILE: case ATEXT_FILE: case RTEXT_FILE: case FTEXT_FILE: default: for(globi=0;globi<in;globi++) { putc(filestorage[globi],output); if(filestorage[globi] == '\012') { putc('\015',output); counter++; } if((counter%MAXWIDTH) == 0) fflush(output); counter++; } while((ch = getc(input)) != EOF) { putc(ch,output); if(ch == '\012') { putc('\015',output); counter++; } if((counter%MAXWIDTH) == 0) fflush(output); counter++; } break; } fprintf(output,"\014"); fflush(output); sleep(5); return(0);}/* If the file stream is of the XIMAGE_FILE type this routine is called from lj250of. The routine creates a color sixel output stream to send the printer based on the input data from an image file. Currently, only a frame buffer image of raw red, green, blue points or a GPX workstation "savimg" image are valid data streams. Color sixel output is initialized and then the processing begins. The current design of the algorithm does not attempt to dither the image data but rather matches indices to valid LJ250 hardware map colors. There are only 256 of these colors available as documented in the LJ250 Programmer's Guide. The algorithm used here employs the Hue, Lightness, and Saturation color model in determining the correct sixels to send to the printer.*/docsixel(){ register int i; int xcnt,ycnt,n = 1,ij=0,tmpycnt = 0; unsigned char *srcptr; unsigned char *nxtptr; short sh,sl,ss; unsigned short sr,sg,sb; char *base_band,*pb; int lastcol = -1; int tmpcol = 0; int count = 1; char lastc = 0; register char *cp; struct { char colour_number[4]; short colour_len; } didload[256]; fprintf(output,"\033P0;0;8q\"1;1"); srcptr=(unsigned char *)imgptr; ycnt=im.spbynm; if(im.format != ITS) nxtptr=srcptr+im.spbxnm * n; else nxtptr=srcptr+(im.spbxnm * n * 3); pb = base_band = (char *)malloc((unsigned) 12 * im.spbxnm); for(i=0;i<256;i++) didload[i].colour_len = 0; while(ycnt/n) { xcnt=im.spbxnm; base_band = pb; while(xcnt > 0) { if(MAXP_PIX_WIDTH - xcnt < 0) { if(im.format != ITS) srcptr+=n; else srcptr+=n*3; xcnt-=n; continue; } if(im.format != ITS) { sh = *((cmpptr + 3*(*srcptr))+0); sl = *((cmpptr + 3*(*srcptr))+1); ss = *((cmpptr + 3*(*srcptr))+2); } else { sr = (unsigned short)*srcptr++; sg = (unsigned short)*srcptr++; sb = (unsigned short)*srcptr; rgbtohls(sr,sg,sb,&sh,&sl,&ss); } for(i=0;i<2;i++) { *(base_band+i) = SOFF; } tmpcol = 0; if(ss == 0) { IFMAC ELSEIFMAC(sl,0,19,1) ELSEIFMAC(sl,20,39,221) ELSEIFMAC(sl,40,59,254) ELSEIFMAC(sl,60,79,255) ELSEIFMAC(sl,80,100,256) goto done; } if(sl >= 0 && sl <= 14 && lastcol != 1) { lastcol = 1; tmpcol = 1; goto done; } if(sl >= 86 && sl <= 100 && lastcol != 256) { tmpcol = 256; goto done; } if(sl >= 15 && sl <= 28 && ss >= 1 && ss <= 49) { IFMAC ELSEIFMAC(sh,330,29,239) ELSEIFMAC(sh,30,59,24) ELSEIFMAC(sh,60,89,50) ELSEIFMAC(sh,90,149,97) ELSEIFMAC(sh,150,179,146) ELSEIFMAC(sh,180,209,127) ELSEIFMAC(sh,210,269,159) ELSEIFMAC(sh,270,299,208) ELSEIFMAC(sh,300,329,196) goto done; } if(sl >= 15 && sl <= 28 && ss >= 50 && ss <= 100) { IFMAC ELSEIFMAC(sh,345,14,2) ELSEIFMAC(sh,15,29,3) ELSEIFMAC(sh,30,44,25) ELSEIFMAC(sh,45,54,26) ELSEIFMAC(sh,55,64,71) ELSEIFMAC(sh,65,74,37) ELSEIFMAC(sh,75,89,51) ELSEIFMAC(sh,90,104,81) ELSEIFMAC(sh,105,134,90) ELSEIFMAC(sh,135,149,43) ELSEIFMAC(sh,150,164,108) ELSEIFMAC(sh,165,174,175) ELSEIFMAC(sh,175,184,120) ELSEIFMAC(sh,185,194,128) ELSEIFMAC(sh,195,209,161) ELSEIFMAC(sh,210,224,137) ELSEIFMAC(sh,225,254,150) ELSEIFMAC(sh,255,269,187) ELSEIFMAC(sh,270,284,174) ELSEIFMAC(sh,285,294,211) ELSEIFMAC(sh,295,304,200) ELSEIFMAC(sh,305,314,210) ELSEIFMAC(sh,315,329,223) ELSEIFMAC(sh,330,344,222) goto done; } if(sl >= 29 && sl <= 42 && ss >= 1 && ss <= 49) { IFMAC ELSEIFMAC(sh,345,359,241) ELSEIFMAC(sh,0,14,240) ELSEIFMAC(sh,15,29,13) ELSEIFMAC(sh,30,44,35) ELSEIFMAC(sh,45,59,34) ELSEIFMAC(sh,60,74,52) ELSEIFMAC(sh,75,89,36) ELSEIFMAC(sh,90,104,44) ELSEIFMAC(sh,105,119,42) ELSEIFMAC(sh,120,134,98) ELSEIFMAC(sh,135,149,99) ELSEIFMAC(sh,150,164,148) ELSEIFMAC(sh,165,179,147) ELSEIFMAC(sh,180,194,129) ELSEIFMAC(sh,195,209,149)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -