Thread View: comp.lang.postscript
2 messages
2 total messages
Started by Boyd Blackwell
Fri, 14 Aug 1992 03:04
Level II compression questions
Author: Boyd Blackwell
Date: Fri, 14 Aug 1992 03:04
Date: Fri, 14 Aug 1992 03:04
70 lines
3081 bytes
3081 bytes
I have just attempted to convert gnu-compress4.01 to produce compressed
output suitable for feeding into LZWDecode filter in Level II postscript. It
works up to the first token length change. Before beating my haed against the
wall, I would like to know if anyone already has c code for LZWEncode.
It is like unix compress, BUT
a/ does not start with the magic number and the bit length
b/ DOES start with an explicit table clear 256(10)
c/ appears to change bit length smoothly without a buffer flush
d/ ends with an EOD token (what a good idea!) 257(10)
e/ pushes bits the other way - i.e. the MSBit
first (CLEAR is 0x80 0x0.. not 0x00 0x8..)
This is based on the Postscript Language Reference Manual *SECOND* edition
pp.130 132 - (yes it is worth buying!)
If anyone can correct my interpretation or provide more info, I will post a
corrected article.
Hint: If you want to test any of these filters, you can let your Laserwriter
IIf or IIg or your Tek Phaser II PXe/i do it for you - they can encode and
decode.
Here is some smaple code
%!
%designed as a quick test bdb 6/92
(filter test: ) print
/=print where not {/=print {( ) cvs print} def 1} if pop % 1 or dict
statusdict begin revision ( )
printername product
print ([) print print (] rev. ) print =print ( ) print
pagecount =print ( pages ) print
end
(\nLZWEncode ASCII info following this file:\n) print
realtime
(%stdout) (w) file
/ASCIIHexEncode filter dup
/LZWEncode filter dup /FILTER exch def
{ FILTER (%stdin) (r) file 256 string readstring
{writestring} {writestring closefile closefile
(\nEND: ) print
realtime exch sub 1000 div =print ( sec ) print exit} ifelse} loop
-----A---B
% replace the above line (-----A)with your test data line(s) - up to about 20k chars
% the example -----A---B comes from the Ps Lang. Ref Man (45 45 45 45 45 65...)
Sample run:
===========
% setenv PRINTER scu_colour
% /usr/local/cap/lwpr ~/ps/foo.ps
abInit: [ddp: 4.23, 51], [GW: 4.23, 33] starting
Status: status: idle
status: idle
Sending /users/prl1/bdb112/ps/foo.ps
filter test: Phaser II PXe[Phaser II PXe] rev. 2 103 pages
LZWEncode ASCII info following this file:
800B6050220C0C840A8080>
END: 0.0 sec bdb112@rsphy1>
Note the line 800B.... is the same as p 132. Ps Lang. Ref Man
--
-Boyd Blackwell
Plasma Research Lab, RSPhysSE, ANU/ GPO Box 4 /Canberra ACT 2601/AUSTRALIA
internet: bdb112@prl1.anu.edu.au
PHONE: +61 62 49 2482 +61 62 51 2605(h) FAX: Boyd Blackwell, PRL +61 62 49 1884
Re: Level II compression questions
Author: David Haight
Date: Mon, 17 Aug 1992 18:52
Date: Mon, 17 Aug 1992 18:52
200 lines
4603 bytes
4603 bytes
In article <1992Aug14.030418.1512@newshost.anu.edu.au> bdb112@rsphy3.anu.edu.au (Boyd Blackwell) writes:
>I have just attempted to convert gnu-compress4.01 to produce compressed
>output suitable for feeding into LZWDecode filter in Level II postscript. It
>works up to the first token length change. Before beating my haed against the
>wall, I would like to know if anyone already has c code for LZWEncode.
>
.............Code and such deleted
Here's a PS LZW filter we've been using here, PS in LZW compressed out.
#include <stdio.h>
/* Various constants
*/
#define EOD 257 /* End of Data marker */
#define CLR 256 /* Clear Table Marker */
#define MAXSTRINGS 4096 /* using 12 bit max codes */
#define TRUE (1==1)
#define FALSE !TRUE
/* This is the structure for a single entry into the string table
*/
typedef struct
{
short prefix;
short suffix;
short next;
} stringrec;
/* Global data
*/
int codeWidth = 9, bitsInAcc = 0; /* Used by code send function */
unsigned long acc; /* =bits left over from a sendcode */
int nextIndex; /* Used by newentry function */
stringrec stringarray[4096]; /* This is the string table */
long incount = 0, outcount = 0; /* Input/output tally */
void Initialize(void);
void SendCode(short theCode);
int FindString(short *prefix, short suffix);
int main(int argc, char *argv[]);
void AddString(short prefix, short suffix);
void ShowStats(void);
void Initialize()
{
int index;
for(index = 0; index < 256; index++)
{
stringarray[index].prefix = -1;
stringarray[index].suffix = (char) index;
stringarray[index].next = -1;
}
nextIndex = EOD + 1;
codeWidth = 9;
}
void SendCode(short theCode)
{
acc += (long) theCode << (32 - codeWidth - bitsInAcc);
bitsInAcc += codeWidth;
while(bitsInAcc >= 8)
{
fputc(acc >> 24, stdout);
acc = acc << 8;
bitsInAcc -= 8;
outcount++;
}
if(theCode == CLR)
{
Initialize();
}
if(theCode == EOD && bitsInAcc != 0)
{
fputc(acc >> 24, stdout);
outcount++;
}
return;
}
int main(int argc, char *argv[])
{
short lastCode;
short thisCode;
double comppct;
if(argc != 1)
{
if(argc != 2)
{
fprintf(stderr, "\nToo many arguments.\n");
fflush(stderr);
return(1);
}
if(*argv[1] == 'h')
{
fprintf(stdout, "\ncurrentfile /LZWDecode filter cvx exec\n");
incount += 41;
fflush(stdout);
}
}
fprintf(stderr, "\nCompressing...");
fflush(stderr);
SendCode(CLR);
if((lastCode = fgetc(stdin)) == EOF)
{
++incount;
SendCode(EOD);
return;
}
while((thisCode = fgetc(stdin)) != EOF)
{
if(!(++incount & 0x00004FFF))
{
ShowStats();
}
if(FindString(&lastCode, thisCode))
{
continue;
} else
{
SendCode(lastCode);
AddString(lastCode, thisCode);
lastCode = thisCode;
}
}
SendCode(lastCode);
SendCode(EOD);
ShowStats();
fprintf(stderr, "\nDone.\n");
fflush(stderr);
return;
}
int FindString(short *prefix, short suffix)
{
short index = *prefix;
while(index != -1)
{
if(stringarray[index].prefix == *prefix &&
stringarray[index].suffix == suffix)
{
*prefix = index;
return(TRUE);
} else
{
index = stringarray[index].next;
}
}
return(FALSE);
}
void AddString(short prefix, short suffix)
{
stringarray[nextIndex].prefix = prefix;
stringarray[nextIndex].suffix = suffix;
stringarray[nextIndex].next = stringarray[prefix].next;
stringarray[prefix].next = nextIndex;
if(++nextIndex >> codeWidth)
{
if(++codeWidth > 12)
{
--codeWidth;
SendCode(CLR);
}
}
return;
}
void ShowStats()
{
double comppct;
comppct = 100.0 * (1.0 - (double) outcount / (double) incount);
fprintf(stderr, "\rCompressing: %d bytes input, %d bytes output, %3.2f%% saved.",
incount, outcount, comppct);
fflush(stderr);
}
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads