3 * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
6 * Functions to for ASCII 85 encoding
8 *====================================================================
9 * This part of the software is based on:
10 * asc85ec.c - ASCII85 and Hex encoding for PostScript Level 2 and PDF
11 * Copyright (C) 1994-99 Thomas Merz (tm@muc.de)
12 *====================================================================
13 * The credit should go to him, but all the bugs are mine.
19 static const ULONG aulPower85
[5] = {
20 1UL, 85UL, 85UL * 85, 85UL * 85 * 85, 85UL * 85 * 85 * 85,
22 static int iOutBytes
= 0; /* Number of characters in an output line */
23 static char cCharPrev
= '\0';
26 * Two percent characters at the start of a line will cause trouble
27 * with some post-processing software. In order to avoid this, we
28 * simply insert a line break if we encounter two percent characters
29 * at the start of the line. Of course, this rather simplistic
30 * algorithm may lead to a large line count in pathological cases,
31 * but the chance for hitting such a case is very small, and even
32 * so it's only a cosmetic flaw and not a functional restriction.
36 * vOutputByte - output one byte
39 vOutputByte(ULONG ulChar
, FILE *pOutFile
)
41 if (iOutBytes
== 1 && cCharPrev
== '%' && ulChar
== (ULONG
)'%') {
42 if (putc('\n', pOutFile
) != EOF
) {
46 if (putc((int)ulChar
, pOutFile
) == EOF
) {
51 if (putc('\n', pOutFile
) != EOF
) {
55 cCharPrev
= (char)ulChar
;
56 } /* end of vOutputByte */
59 * vASCII85EncodeByte - ASCII 85 encode a byte
62 vASCII85EncodeByte(FILE *pOutFile
, int iByte
)
64 static ULONG ulBuffer
[4] = { 0, 0, 0, 0 };
65 static int iInBuffer
= 0;
69 fail(pOutFile
== NULL
);
74 /* End Of File, time to clean up */
75 if (iInBuffer
> 0 && iInBuffer
< 4) {
76 /* Encode the remaining bytes */
78 for (iIndex
= iInBuffer
- 1; iIndex
>= 0; iIndex
--) {
80 ulBuffer
[iIndex
] << (8 * (3 - iIndex
));
82 for (iIndex
= 4; iIndex
>= 4 - iInBuffer
; iIndex
--) {
83 ulTmp
= ulValue
/ aulPower85
[iIndex
];
84 vOutputByte(ulTmp
+ '!', pOutFile
);
85 ulValue
-= ulTmp
* aulPower85
[iIndex
];
88 /* Add the End Of Data marker */
89 (void)putc('~', pOutFile
);
90 (void)putc('>', pOutFile
);
91 (void)putc('\n', pOutFile
);
92 /* Reset the control variables */
99 ulBuffer
[iInBuffer
] = (ULONG
)iByte
& 0xff;
102 if (iInBuffer
>= 4) {
103 ulValue
= (ulBuffer
[0] << 24) | (ulBuffer
[1] << 16) |
104 (ulBuffer
[2] << 8) | ulBuffer
[3];
106 vOutputByte((ULONG
)'z', pOutFile
); /* Shortcut for 0 */
108 for (iIndex
= 4; iIndex
>= 0; iIndex
--) {
109 ulTmp
= ulValue
/ aulPower85
[iIndex
];
110 vOutputByte(ulTmp
+ '!', pOutFile
);
111 ulValue
-= ulTmp
* aulPower85
[iIndex
];
114 /* Reset the buffer */
117 } /* end of vASCII85EncodeByte */
120 * vASCII85EncodeArray - ASCII 85 encode a byte array
123 vASCII85EncodeArray(FILE *pInFile
, FILE *pOutFile
, size_t tLength
)
128 fail(pInFile
== NULL
);
129 fail(pOutFile
== NULL
);
133 for (tCount
= 0; tCount
< tLength
; tCount
++) {
134 iByte
= iNextByte(pInFile
);
138 vASCII85EncodeByte(pOutFile
, iByte
);
140 } /* end of vASCII85EncodeArray */
143 * vASCII85EncodeFile - ASCII 85 encode part of a file
146 vASCII85EncodeFile(FILE *pInFile
, FILE *pOutFile
, size_t tLength
)
148 fail(pInFile
== NULL
);
149 fail(pOutFile
== NULL
);
152 vASCII85EncodeArray(pInFile
, pOutFile
, tLength
);
153 vASCII85EncodeByte(pOutFile
, EOF
);
154 } /* end of vASCII85EncodeFile */