-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathasc85enc.c
154 lines (139 loc) · 3.82 KB
/
asc85enc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
* asc85enc.c
* Copyright (C) 2000-2003 A.J. van Os; Released under GPL
*
* Description:
* Functions to for ASCII 85 encoding
*
*====================================================================
* This part of the software is based on:
* asc85ec.c - ASCII85 and Hex encoding for PostScript Level 2 and PDF
* Copyright (C) 1994-99 Thomas Merz ([email protected])
*====================================================================
* The credit should go to him, but all the bugs are mine.
*/
#include <stdio.h>
#include "antiword.h"
static const ULONG aulPower85[5] = {
1UL, 85UL, 85UL * 85, 85UL * 85 * 85, 85UL * 85 * 85 * 85,
};
static int iOutBytes = 0; /* Number of characters in an output line */
static char cCharPrev = '\0';
/*
* Two percent characters at the start of a line will cause trouble
* with some post-processing software. In order to avoid this, we
* simply insert a line break if we encounter two percent characters
* at the start of the line. Of course, this rather simplistic
* algorithm may lead to a large line count in pathological cases,
* but the chance for hitting such a case is very small, and even
* so it's only a cosmetic flaw and not a functional restriction.
*/
/*
* vOutputByte - output one byte
*/
static void
vOutputByte(ULONG ulChar, FILE *pOutFile)
{
if (iOutBytes == 1 && cCharPrev == '%' && ulChar == (ULONG)'%') {
if (putc('\n', pOutFile) != EOF) {
iOutBytes = 0;
}
}
if (putc((int)ulChar, pOutFile) == EOF) {
return;
}
iOutBytes++;
if (iOutBytes > 63) {
if (putc('\n', pOutFile) != EOF) {
iOutBytes = 0;
}
}
cCharPrev = (char)ulChar;
} /* end of vOutputByte */
/*
* vASCII85EncodeByte - ASCII 85 encode a byte
*/
void
vASCII85EncodeByte(FILE *pOutFile, int iByte)
{
static ULONG ulBuffer[4] = { 0, 0, 0, 0 };
static int iInBuffer = 0;
ULONG ulValue, ulTmp;
int iIndex;
fail(pOutFile == NULL);
fail(iInBuffer < 0);
fail(iInBuffer > 3);
if (iByte == EOF) {
/* End Of File, time to clean up */
if (iInBuffer > 0 && iInBuffer < 4) {
/* Encode the remaining bytes */
ulValue = 0;
for (iIndex = iInBuffer - 1; iIndex >= 0; iIndex--) {
ulValue |=
ulBuffer[iIndex] << (8 * (3 - iIndex));
}
for (iIndex = 4; iIndex >= 4 - iInBuffer; iIndex--) {
ulTmp = ulValue / aulPower85[iIndex];
vOutputByte(ulTmp + '!', pOutFile);
ulValue -= ulTmp * aulPower85[iIndex];
}
}
/* Add the End Of Data marker */
(void)putc('~', pOutFile);
(void)putc('>', pOutFile);
(void)putc('\n', pOutFile);
/* Reset the control variables */
iInBuffer = 0;
iOutBytes = 0;
cCharPrev = '\0';
return;
}
ulBuffer[iInBuffer] = (ULONG)iByte & 0xff;
iInBuffer++;
if (iInBuffer >= 4) {
ulValue = (ulBuffer[0] << 24) | (ulBuffer[1] << 16) |
(ulBuffer[2] << 8) | ulBuffer[3];
if (ulValue == 0) {
vOutputByte((ULONG)'z', pOutFile); /* Shortcut for 0 */
} else {
for (iIndex = 4; iIndex >= 0; iIndex--) {
ulTmp = ulValue / aulPower85[iIndex];
vOutputByte(ulTmp + '!', pOutFile);
ulValue -= ulTmp * aulPower85[iIndex];
}
}
/* Reset the buffer */
iInBuffer = 0;
}
} /* end of vASCII85EncodeByte */
/*
* vASCII85EncodeArray - ASCII 85 encode a byte array
*/
void
vASCII85EncodeArray(FILE *pInFile, FILE *pOutFile, size_t tLength)
{
size_t tCount;
int iByte;
fail(pInFile == NULL);
fail(pOutFile == NULL);
DBG_DEC(tLength);
for (tCount = 0; tCount < tLength; tCount++) {
iByte = iNextByte(pInFile);
if (iByte == EOF) {
break;
}
vASCII85EncodeByte(pOutFile, iByte);
}
} /* end of vASCII85EncodeArray */
/*
* vASCII85EncodeFile - ASCII 85 encode part of a file
*/
void
vASCII85EncodeFile(FILE *pInFile, FILE *pOutFile, size_t tLength)
{
fail(pInFile == NULL);
fail(pOutFile == NULL);
fail(tLength == 0);
vASCII85EncodeArray(pInFile, pOutFile, tLength);
vASCII85EncodeByte(pOutFile, EOF);
} /* end of vASCII85EncodeFile */