📄 foo2oak.c
字号:
/*GENERALThis program converts pbm (B/W) images, 2-bit pgm (grayscale), and1-bit- or 2-bit-per-pixel cmyk images (all produced by ghostscript)to Oak Technolgies JBIG format.With this utility, you can print to some HP printers, such as these: - HP LaserJet 1500BUGS AND DEFICIENCIES - Needs to do color correction - Needs to support a better input color file format which includes explicit page boundary indications.EXAMPLESAUTHORSRick Richardson. It also uses Markus Kuhn's jbig-kit compressionlibrary (included, but also available athttp://www.cl.cam.ac.uk/~mgk25/jbigkit/).You can contact the current author at mailto:rick.richardson@comcast.netLICENSEThis program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or (atyour 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.If you want to use this program under different license conditions,then contact the author for an arrangement.It is possible that certain products which can be built using the jbigsoftware module might form inventions protected by patent rights insome countries (e.g., by patents about arithmetic coding algorithmsowned by IBM and AT&T in the USA). Provision of this software by theauthor does NOT include any licenses for any patents. In thosecountries where a patent license is required for certain applicationsof this software module, you will have to obtain such a licenseyourself.# ./usb_printerid /dev/usb/lp0GET_DEVICE_ID string:MFG:Hewlett-Packard;CMD:OAKRAS,DW-PCL;MDL:hp color LaserJet 1500;CLS:PRINTER;DES:Hewlett-Packard color LaserJet 1500;MEM:16MB;1284.4DL:4d,4e,1;MSZ:10000000;FDT:0;CAL:00020811213C568F02060C1825446BA800030914203F5B9901040C151E3E60AD;Status: 0x18*//* * TODO: Handle 2 bit mono and color output */static char Version[] = "$Id: foo2oak.c,v 1.48 2007/07/15 14:31:56 rick Exp $";#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <stdarg.h>#include <time.h>#include "jbig.h"#include "oak.h"/* * Command line options */int Debug = 0;int ZeroTime = 0;int ResX = 600;int ResY = 600;int Bpp = 1;int PaperCode = OAK_PAPER_LETTER;int PageWidth = 600 * 8.5;int PageHeight = 600 * 11;int UpperLeftX = 0;int UpperLeftY = 0;int LowerRightX = 0;int LowerRightY = 0;int Copies = 1;int Duplex = 1;int SourceCode = OAK_SOURCE_AUTO;int MediaCode = OAK_MEDIA_AUTO;char *Username = NULL;char *Filename = NULL;int Mode = 0; #define MODE_MONO 1 #define MODE_COLOR 2int Color2Mono = 0;int BlackClears = 1;int AllIsBlack = 1;int LogicalOffsetX = 0;int LogicalOffsetY = 0;#define LOGICAL_CLIP_X 2#define LOGICAL_CLIP_Y 1int LogicalClip = LOGICAL_CLIP_X | LOGICAL_CLIP_Y;int IsCUPS = 0;/* * I now believe this is a YMCK printer as far as plane output ordering goes. */#define PL_C 2#define PL_M 1#define PL_Y 0#define PL_K 3voidusage(void){ fprintf(stderr,"Usage:\n"" foo2oak [options] <pbmraw-file >OAKT-file\n""\n"" Convert Ghostscript pbm format to a 1-bpp monochrome OAKT stream,\n"" for driving the HP LaserJet 1500 color laser printer\n"" and other OAKT-based black and white printers.\n""\n"" gs -q -dBATCH -dSAFER -dQUIET -dNOPAUSE \\ \n"" -sPAPERSIZE=letter -r600x600 -sDEVICE=pbmraw \\ \n"" -sOutputFile=- - < testpage.ps \\ \n"" | foo2oak -r600x600 -g5100x6600 -p1 >testpage.oak\n""\n"" foo2oak [options] <pgmraw-file >OAKT-file\n""\n"" Convert Ghostscript pgm format to a 2-bpp monochrome OAKT stream,\n"" for driving the HP LaserJet 1500 color laser printer\n"" and other OAKT-based black and white printers.\n""\n"" gs -q -dBATCH -dSAFER -dQUIET -dNOPAUSE \\ \n"" -sPAPERSIZE=letter -r600x600 -sDEVICE=pgmraw \\ \n"" -sOutputFile=- - < testpage.ps \\ \n"" | foo2oak -r600x600 -g5100x6600 -p1 >testpage.oak\n""\n"" foo2oak [options] <bitcmyk-file >OAKT-file\n""\n"" Convert Ghostscript bitcmyk format to a 1-bpp color OAKT stream,\n"" for driving the HP LaserJet 1500 color laser printer.\n"" N.B. Color correction is expected to be performed by ghostscript.\n""\n"" gs -q -dBATCH -dSAFER -dQUIET -dNOPAUSE \\ \n"" -sPAPERSIZE=letter -g5100x6600 -r600x600 -sDEVICE=bitcmyk \\ \n"" -sOutputFile=- - < testpage.ps \\ \n"" | foo2oak -r600x600 -g5100x6600 -p1 >testpage.oak\n""\n""Normal Options:\n""-b bits Bits per plane if autodetect doesn't work (1 or 2) [%d]\n""-c Force color mode if autodetect doesn't work\n"//"-d duplex Duplex code to send to printer [%d]\n"//" 1=off, 2=longedge, 3=shortedge\n""-g <xpix>x<ypix> Set page dimensions in pixels [%dx%d]\n""-m media Media code to send to printer [%d]\n"" 0=auto 1=plain 2=preprinted 3=letterhead 4=graytrans\n"" 5=prepunched 6=labels 7=bond 8=recycled 9=color\n"" 10=cardstock 11=heavy 12=envelope 13=light 14=tough\n""-p paper Paper code to send to printer [%d]\n"" 1=letter, 5=legal 7=executive 9=A4 11=A5 13=B5jis\n""-n copies Number of copies [%d]\n""-r <xres>x<yres> Set device resolution in pixels/inch [%dx%d]\n""-s source Source code to send to printer [%d]\n"" 1=tray1 4=manual 7=auto\n"" Code numbers may vary with printer model\n""-J filename Filename string to send to printer [%s]\n""-U username Username string to send to printer [%s]\n""\n""Printer Tweaking Options:\n""-u <xoff>x<yoff> Set offset of upper left printable in pixels [%dx%d]\n""-l <xoff>x<yoff> Set offset of lower right printable in pixels [%dx%d]\n""-L mask Send logical clipping values from -u/-l in ZjStream [%d]\n"" 0=no, 1=Y, 2=X, 3=XY\n""-A Turn off: conversion of C=1,M=1,Y=1 to pure black\n""-B Turn off: K=1 forces C,M,Y to 0\n""\n""Debugging Options:\n""-S plane Output just a single color plane from a color print [all]\n"" %d=Cyan, %d=Magenta, %d=Yellow, %d=Black\n""-D lvl Set Debug level [%d]\n""-V Version %s\n" // , Duplex , Bpp , PageWidth , PageHeight , MediaCode , PaperCode , Copies , ResX , ResY , SourceCode , Filename ? Filename : "" , Username ? Username : "" , UpperLeftX , UpperLeftY , LowerRightX , LowerRightY , LogicalClip , PL_C, PL_M, PL_Y, PL_K , Debug , Version ); exit(1);}voiddebug(int level, char *fmt, ...){ va_list ap; if (Debug < level) return; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap);}voiderror(int fatal, char *fmt, ...){ va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); if (fatal) exit(fatal);}intparse_xy(char *str, int *xp, int *yp){ char *p; if (!str || str[0] == 0) return -1; *xp = strtoul(str, &p, 0); if (str == p) return -2; while (*p && (*p < '0' || *p > '9')) ++p; str = p; if (str[0] == 0) return -3; *yp = strtoul(str, &p, 0); if (str == p) return -4; return (0);}/* * bit mirroring arrays */unsigned char Mirror1[256] ={ 0,128, 64,192, 32,160, 96,224, 16,144, 80,208, 48,176,112,240, 8,136, 72,200, 40,168,104,232, 24,152, 88,216, 56,184,120,248, 4,132, 68,196, 36,164,100,228, 20,148, 84,212, 52,180,116,244, 12,140, 76,204, 44,172,108,236, 28,156, 92,220, 60,188,124,252, 2,130, 66,194, 34,162, 98,226, 18,146, 82,210, 50,178,114,242, 10,138, 74,202, 42,170,106,234, 26,154, 90,218, 58,186,122,250, 6,134, 70,198, 38,166,102,230, 22,150, 86,214, 54,182,118,246, 14,142, 78,206, 46,174,110,238, 30,158, 94,222, 62,190,126,254, 1,129, 65,193, 33,161, 97,225, 17,145, 81,209, 49,177,113,241, 9,137, 73,201, 41,169,105,233, 25,153, 89,217, 57,185,121,249, 5,133, 69,197, 37,165,101,229, 21,149, 85,213, 53,181,117,245, 13,141, 77,205, 45,173,109,237, 29,157, 93,221, 61,189,125,253, 3,131, 67,195, 35,163, 99,227, 19,147, 83,211, 51,179,115,243, 11,139, 75,203, 43,171,107,235, 27,155, 91,219, 59,187,123,251, 7,135, 71,199, 39,167,103,231, 23,151, 87,215, 55,183,119,247, 15,143, 79,207, 47,175,111,239, 31,159, 95,223, 63,191,127,255,};unsigned char Mirror2[256] ={ 0, 64,128,192, 16, 80,144,208, 32, 96,160,224, 48,112,176,240, 4, 68,132,196, 20, 84,148,212, 36,100,164,228, 52,116,180,244, 8, 72,136,200, 24, 88,152,216, 40,104,168,232, 56,120,184,248, 12, 76,140,204, 28, 92,156,220, 44,108,172,236, 60,124,188,252, 1, 65,129,193, 17, 81,145,209, 33, 97,161,225, 49,113,177,241, 5, 69,133,197, 21, 85,149,213, 37,101,165,229, 53,117,181,245, 9, 73,137,201, 25, 89,153,217, 41,105,169,233, 57,121,185,249, 13, 77,141,205, 29, 93,157,221, 45,109,173,237, 61,125,189,253, 2, 66,130,194, 18, 82,146,210, 34, 98,162,226, 50,114,178,242, 6, 70,134,198, 22, 86,150,214, 38,102,166,230, 54,118,182,246, 10, 74,138,202, 26, 90,154,218, 42,106,170,234, 58,122,186,250, 14, 78,142,206, 30, 94,158,222, 46,110,174,238, 62,126,190,254, 3, 67,131,195, 19, 83,147,211, 35, 99,163,227, 51,115,179,243, 7, 71,135,199, 23, 87,151,215, 39,103,167,231, 55,119,183,247, 11, 75,139,203, 27, 91,155,219, 43,107,171,235, 59,123,187,251, 15, 79,143,207, 31, 95,159,223, 47,111,175,239, 63,127,191,255,};unsigned char Mirror4[256] ={ 0, 16, 32, 48, 64, 80, 96,112,128,144,160,176,192,208,224,240, 1, 17, 33, 49, 65, 81, 97,113,129,145,161,177,193,209,225,241, 2, 18, 34, 50, 66, 82, 98,114,130,146,162,178,194,210,226,242, 3, 19, 35, 51, 67, 83, 99,115,131,147,163,179,195,211,227,243, 4, 20, 36, 52, 68, 84,100,116,132,148,164,180,196,212,228,244, 5, 21, 37, 53, 69, 85,101,117,133,149,165,181,197,213,229,245, 6, 22, 38, 54, 70, 86,102,118,134,150,166,182,198,214,230,246, 7, 23, 39, 55, 71, 87,103,119,135,151,167,183,199,215,231,247, 8, 24, 40, 56, 72, 88,104,120,136,152,168,184,200,216,232,248, 9, 25, 41, 57, 73, 89,105,121,137,153,169,185,201,217,233,249, 10, 26, 42, 58, 74, 90,106,122,138,154,170,186,202,218,234,250, 11, 27, 43, 59, 75, 91,107,123,139,155,171,187,203,219,235,251, 12, 28, 44, 60, 76, 92,108,124,140,156,172,188,204,220,236,252, 13, 29, 45, 61, 77, 93,109,125,141,157,173,189,205,221,237,253, 14, 30, 46, 62, 78, 94,110,126,142,158,174,190,206,222,238,254, 15, 31, 47, 63, 79, 95,111,127,143,159,175,191,207,223,239,255,};voidmirror_bytes(unsigned char *sp, int bpl, unsigned char *mirror){ unsigned char *ep = sp + bpl - 1; unsigned char tmp; while (sp < ep) { tmp = mirror[*sp]; *sp = mirror[*ep]; *ep = tmp; ++sp; --ep; } if (sp == ep) *sp = mirror[*sp];}/* * This creates a linked list of compressed data. The first item * in the list is the BIH and is always 20 bytes in size. Each following * item is 65536 bytes in length. The last item length is whatever remains. */typedef struct _BIE_CHAIN{ unsigned char *data; size_t len; struct _BIE_CHAIN *next;} BIE_CHAIN;voidfree_chain(BIE_CHAIN *chain){ BIE_CHAIN *next; next = chain; while ((chain = next)) { next = chain->next; if (chain->data) free(chain->data); free(chain); }}voidoutput_jbig(unsigned char *start, size_t len, void *cbarg){ BIE_CHAIN *current, **root = (BIE_CHAIN **) cbarg; int size = 65536; // Printer does strange things otherwise. if ( (*root) == NULL) { (*root) = malloc(sizeof(BIE_CHAIN)); if (!(*root)) error(1, "Can't allocate space for chain\n"); (*root)->data = NULL; (*root)->next = NULL; (*root)->len = 0; size = 20; if (len != 20) error(1, "First chunk must be BIH and 20 bytes long\n"); } current = *root; while (current->next) current = current->next; while (len > 0) { int amt, left; if (!current->data) { current->data = malloc(size); if (!current->data) error(1, "Can't allocate space for compressed data\n"); } left = size - current->len; amt = (len > left) ? left : len; memcpy(current->data + current->len, start, amt); current->len += amt; len -= amt; start += amt; if (current->len == size) { current->next = malloc(sizeof(BIE_CHAIN)); if (!current->next) error(1, "Can't allocate space for chain\n"); current = current->next; current->data = NULL; current->next = NULL; current->len = 0; } }}intoak_record(FILE *fp, int type, void *payload, int paylen){ OAK_HDR hdr; static char pad[] = "PAD_PAD_PAD_PAD_"; static int pageno = 0; memcpy(hdr.magic, OAK_HDR_MAGIC, sizeof(hdr.magic)); hdr.type = type; hdr.len = (sizeof(hdr) + paylen + 15) & ~0x0f; fwrite(&hdr, 1, sizeof(hdr), fp); if (payload && paylen) fwrite(payload, 1, paylen, fp); fwrite(pad, 1, hdr.len - (sizeof(hdr) + paylen), fp); if (type == OAK_TYPE_START_PAGE) { ++pageno; if (IsCUPS) fprintf(stderr, "PAGE: %d %d\n", pageno, Copies); } return 0;}voidstart_doc(FILE *fp){ OAK_OTHER recother; OAK_TIME rectime; OAK_FILENAME recfile; time_t now; struct tm *tm; memset(&recother, 0, sizeof(recother)); recother.unk = 1; // TODO strcpy(recother.string, "OTHER"); // TODO: Username???? oak_record(fp, OAK_TYPE_OTHER, &recother, sizeof(recother)); memset(&rectime, 0, sizeof(rectime)); time(&now); if (ZeroTime) now = 0; strcpy(rectime.datetime, ctime(&now)); rectime.time_t = now; tm = localtime(&now); rectime.year = tm->tm_year + 1900; rectime.tm_mon = tm->tm_mon; rectime.tm_mday = tm->tm_mday; rectime.tm_hour = tm->tm_hour;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -