Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!rochester!rit!cci632!djh From: djh@cci632.UUCP (Daniel J. Hazekamp) Newsgroups: comp.graphics Subject: Re: "Sixels" and the Xerox 3700 laser printer Summary: Xerox Sixel encoding, code enclosed Message-ID: <29117@cci632.UUCP> Date: 9 Jun 89 14:19:22 GMT References: <4581@ucdavis.ucdavis.edu> <29536@ucbvax.BERKELEY.EDU> Organization: CCI, Communications Systems Division, Rochester, NY Lines: 485 Sixels are just what the name implies, six bit packets. They are generated by taking six bits at a time from the graphic image, adding hex 3F, and sending the resultant byte (8 bits) to the printer. Each scan line in the image has to be padded with zeros such that the number of bits is evenly divisible by 24. Note: Xerox font files are sixel encoded. Enclosed are 2 source files, sixel.c, which can be used to 'unsixel' data, such as Xerox font files, and 'giftoxp.c', which will print GIF images on a model 3700, 4045, or anuything else that supports 2700 mode with graphics. Note: giftoxp will not work on a model 2700. Since I do not have a 3700 or 4045, I'm not sure if it works poroperly, or at all. : to unbundle, "sh" this file -- DO NOT use csh : SHAR archive format. Archive created Fri Jun 9 10:15:06 EDT 1989 echo x - sixel.c sed 's/^X//' > sixel.c <<'+FUNKY+STUFF+' X#include X Xunsigned dsixel; Xunsigned char data[4]; X Xmain() X{ X register int i,n; X register unsigned sixel; X X while ((n=read(0,data,4)) > 0) { X sixel = 0; X for (i=0; i= 0x30 && data[i] <= 0x39) X fprintf(stderr,"found repeat count %X\n",data[i]); X sixel |= (data[i] - 0x3f) & 0x3f; X sixel <<= 6; X } X dsixel = sixel << 2; X write(1,&dsixel,3); X } X} +FUNKY+STUFF+ echo '-rw-r--r-- 1 djh 392 Jun 9 10:14 sixel.c (as sent)' chmod u=rw,g=r,o=r sixel.c ls -l sixel.c echo x - giftoxp.c sed 's/^X//' > giftoxp.c <<'+FUNKY+STUFF+' X/********************************************* X * GIF to Xerox 3700 Converter * X * * X * Aug 10, 1988 by Dan Hazekamp * X * modified from GIFtoPS * X * by Scott Hemphill * X * * X * I wrote this program, and hereby place it * X * in the public domain, i.e. there are no * X * copying restrictions of any kind. * X *********************************************/ X X#include Xchar *malloc(); Xint strncmp(); X X#define min(x,y) ((x) < (y) ? (x) : (y)) X#define FALSE 0 X#define TRUE 1 X Xtypedef int bool; Xtypedef struct codestruct { X struct codestruct *prefix; X unsigned char first,suffix; X 3 codetype; X XFILE *infile; Xunsigned int screenwidth; /* The dimensions of the screen */ Xunsigned int screenheight; /* (not those of the image) */ Xbool global; /* Is there a global color map? */ Xint globalbits; /* Number of bits of global colors */ Xunsigned char globalmap[256][3]; /* RGB values for global color map */ Xunsigned char colortable[256]; /* 4-bit greyscale code */ Xunsigned char *raster; /* Decoded image data */ Xcodetype *codetable; /* LZW compression code data */ Xint datasize,codesize,codemask; /* Decoder working variables */ Xint clear,eoi; /* Special code values */ Xchar *res = "300"; Xcflag = 0; /* Don't center image on page */ Xdflag = 0; /* Use 8x8 dots instead of 4x4 dots */ Xpflag = 0; /* Print in Portrait Orientation */ X Xvoid usage() X{ X fprintf(stderr,"usage: giftohp [-c -d -p -rres] input-file > output-file\n"); X exit(-1); X} X Xvoid fatal(s) Xchar *s; X{ X fprintf(stderr,"gifthp: %s\n",s); X exit(-1); X} X Xvoid sixel(c) Xunsigned char c; X{ X static bits = 0; X static int quad = 0; X char out[5]; X X quad = (quad << 8) | c; X bits += 8; X if (bits == 24) { X out[3] = (quad & 0x3f) + 0x3f; X quad >>= 6; X out[2] = (quad & 0x3f) + 0x3f; X quad >>= 6; X out[1] = (quad & 0x3f) + 0x3f; X quad >>= 6; X out[0] = (quad & 0x3f) + 0x3f; X out[4] = 0; X printf("%s",out); X bits = 0; X } X} X Xvoid checksignature() X{ X char buf[6]; X X fread(buf,1,6,infile); X if (strncmp(buf,"GIF",3)) fatal("file is not a GIF file"); X if (strncmp(&buf[3],"87a",3)) fatal("unknown GIF version number"); X} X X/* Get information which is global to all the images stored in the file */ X Xvoid readscreen() X{ X unsigned char buf[7]; X X fread(buf,1,7,infile); X screenwidth = buf[0] + (buf[1] << 8); X screenheight = buf[2] + (buf[3] << 8); X global = buf[4] & 0x80; X if (global) { X globalbits = (buf[4] & 0x07) + 1; X fread(globalmap,3,1<>= 12; X colortable[i] = color & 0xf; X } X} X X/* Write a header to the standard output. Standard paper size X (8.5 by 11) is hard-coded, as is the whole initialization sequence. */ X Xvoid writeheader(left,top,width,height) Xint left,top,width,height; X{ X register int x,y; X X /* if (cflag) { X x = pflag ? left : top; X y = pflag ? top : left; X if (!dflag) { X x *= 2; X y *= 2; X } X } else { X if (dflag) { X height *= 2; X width *= 2; X } X /* 600 = 8.0 usable inches x 300dpi / 4 */ X /* 788 = 10.5 usable inches x 300dpi / 4 */ X /* x = 600 - (pflag ? width : height); X y = 788 - (pflag ? height : width); X } X x *= 2; X y *= 2;*/ X if (pflag) X printf("\033+1Titan10iso-P\r\n\0331"); X else X printf("\033+1XCP14-L\r\n\0331"); X printf("\033gw;,,%d,%d\r\n", dflag?width*8:width*4, X dflag?height*8:height*4); X} X X/* Output the bytes associated with a code to the raster array */ X Xvoid outcode(p,fill) Xregister codetype *p; Xregister unsigned char **fill; X{ X if (p->prefix) outcode(p->prefix,fill); X *(*fill)++ = p->suffix; X} X X/* Process a compression code. "clear" resets the code table. Otherwise X make a new code table entry, and output the bytes associated with the X code. */ X Xvoid process(code,fill) Xregister code; Xunsigned char **fill; X{ X static avail,oldcode; X register codetype *p; X X if (code == clear) { X codesize = datasize + 1; X codemask = (1 << codesize) - 1; X avail = clear + 2; X oldcode = -1; X } else if (code < avail) { X outcode(&codetable[code],fill); X if (oldcode != -1) { X p = &codetable[avail++]; X p->prefix = &codetable[oldcode]; X p->first = p->prefix->first; X p->suffix = codetable[code].first; X if ((avail & codemask) == 0 && avail < 4096) { X codesize++; X codemask += avail; X } X } X oldcode = code; X } else if (code == avail && oldcode != -1) { X p = &codetable[avail++]; X p->prefix = &codetable[oldcode]; X p->first = p->prefix->first; X p->suffix = p->first; X outcode(p,fill); X if ((avail & codemask) == 0 && avail < 4096) { X codesize++; X codemask += avail; X } X oldcode = code; X } else { X fprintf(stderr,"giftohp: illegal code '%x' in raster data, avail: %x, oldcode: %x\n",code,avail,oldcode); X exit(-1); X } X} X X/* Decode a raster image */ X Xvoid readraster(width,height) Xunsigned width,height; X{ X unsigned char *fill = raster; X unsigned char buf[255]; X register bits=0; X register unsigned count,datum=0; X register unsigned char *ch; X register int code; X X datasize = getc(infile); X clear = 1 << datasize; X eoi = clear+1; X codesize = datasize + 1; X codemask = (1 << codesize) - 1; X codetable = (codetype*)malloc(4096*sizeof(codetype)); X if (!codetable) fatal("not enough memory for code table"); X for (code = 0; code < clear; code++) { X codetable[code].prefix = (codetype*)0; X codetable[code].first = code; X codetable[code].suffix = code; X } X for (count = getc(infile); count > 0; count = getc(infile)) { X fread(buf,1,count,infile); X for (ch=buf; count-- > 0; ch++) { X datum += *ch << bits; X bits += 8; X while (bits >= codesize) { X code = datum & codemask; X datum >>= codesize; X bits -= codesize; X if (code == eoi) goto exitloop; /* This kludge put in X because some GIF files X aren't standard */ X process(code,&fill); X } X } X } Xexitloop: X if (fill != raster + width*height) fatal("raster has the wrong size"); X free(codetable); X} X X/* Read a row out of the raster image and write it to the output file */ X X Xchar grey[][8] = { X { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, X { 0xff, 0xff, 0xee, 0xdd, 0xff, 0xff, 0xee, 0xdd }, X { 0xff, 0xff, 0xee, 0xcc, 0xff, 0xff, 0xee, 0xcc }, X { 0xee, 0xff, 0xee, 0xcc, 0xee, 0xff, 0xee, 0xcc }, X { 0xee, 0xff, 0xee, 0x44, 0xee, 0xff, 0xee, 0x44 }, X { 0xee, 0xee, 0xee, 0x44, 0xee, 0xee, 0xee, 0x44 }, X { 0xee, 0xee, 0xee, 0x00, 0xee, 0xee, 0xee, 0x00 }, X { 0xee, 0xee, 0xcc, 0x00, 0xee, 0xee, 0xcc, 0x00 }, X { 0xee, 0xee, 0x44, 0x00, 0xee, 0xee, 0x44, 0x00 }, X { 0xcc, 0xee, 0x44, 0x00, 0xcc, 0xee, 0x44, 0x00 }, X { 0xcc, 0xcc, 0x44, 0x00, 0xcc, 0xcc, 0x44, 0x00 }, X { 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00 }, X { 0xcc, 0x88, 0x00, 0x00, 0xcc, 0x88, 0x00, 0x00 }, X { 0xcc, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00 }, X { 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00 }, X { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } X}; Xint *interleavetable; Xbool interleaved; X Xvoid rasterize(height,width) Xint height,width; X{ X register unsigned char *sp; X register row, col, x, y; X unsigned char rast; X X y = dflag ? 8 : 4; X for (row=0; row1 && argv[1][0]=='-'; argc--,argv++) { X switch(argv[1][1]) { X case 'c': X cflag++; X break; X case 'd': X dflag++; X break; X case 'p': X pflag++; X break; X case 'r': X res = &argv[1][2]; X break; X } X } X strcpy(filename,argv[1]); X if (index(filename,'.') == 0) X strcat(filename,".gif"); X infile = fopen(filename,"r"); X if (!infile) { X perror(filename); X exit(-1); X } X checksignature(); X readscreen(); X do { X ch = getc(infile); X switch (ch) { X case '\0': break; /* this kludge for non-standard files */ X case ',': readimage(); X break; X case ';': quit = TRUE; X break; X case '!': readextension(); X break; X default: fatal("illegal GIF block type"); X break; X } X } while (!quit); X exit(0); X} +FUNKY+STUFF+ echo '-rw-r--r-- 1 djh 12314 Jun 9 10:14 giftoxp.c (as sent)' chmod u=rw,g=r,o=r giftoxp.c ls -l giftoxp.c exit 0 -- Dan Hazekamp rochester!cci632!djh Computer Consoles Inc. (CCI) uunet!ccicpg!cci632!djh Rochester, NY uunet!rlgvax!cci632!djh