Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * asc85enc.c
3
 * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
4
 *
5
 * Description:
6
 * Functions to for ASCII 85 encoding
7
 *
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.
14
 */
15
 
16
#include <stdio.h>
17
#include "antiword.h"
18
 
19
static const ULONG	aulPower85[5] = {
20
	1UL, 85UL, 85UL * 85, 85UL * 85 * 85, 85UL * 85 * 85 * 85,
21
};
22
static int	iOutBytes = 0;	/* Number of characters in an output line */
23
static char	cCharPrev = '\0';
24
 
25
/*
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.
33
 */
34
 
35
/*
36
 * vOutputByte - output one byte
37
 */
38
static void
39
vOutputByte(ULONG ulChar, FILE *pOutFile)
40
{
41
	if (iOutBytes == 1 && cCharPrev == '%' && ulChar == (ULONG)'%') {
42
		if (putc('\n', pOutFile) != EOF) {
43
			iOutBytes = 0;
44
		}
45
	}
46
	if (putc((int)ulChar, pOutFile) == EOF) {
47
		return;
48
	}
49
	iOutBytes++;
50
	if (iOutBytes > 63) {
51
		if (putc('\n', pOutFile) != EOF) {
52
			iOutBytes = 0;
53
		}
54
	}
55
	cCharPrev = (char)ulChar;
56
} /* end of vOutputByte */
57
 
58
/*
59
 * vASCII85EncodeByte - ASCII 85 encode a byte
60
 */
61
void
62
vASCII85EncodeByte(FILE *pOutFile, int iByte)
63
{
64
	static ULONG	ulBuffer[4] = { 0, 0, 0, 0 };
65
	static int	iInBuffer = 0;
66
	ULONG	ulValue, ulTmp;
67
	int	iIndex;
68
 
69
	fail(pOutFile == NULL);
70
	fail(iInBuffer < 0);
71
	fail(iInBuffer > 3);
72
 
73
	if (iByte == EOF) {
74
		/* End Of File, time to clean up */
75
		if (iInBuffer > 0 && iInBuffer < 4) {
76
			/* Encode the remaining bytes */
77
			ulValue = 0;
78
			for (iIndex = iInBuffer - 1; iIndex >= 0; iIndex--) {
79
				ulValue |=
80
					ulBuffer[iIndex] << (8 * (3 - iIndex));
81
			}
82
			for (iIndex = 4; iIndex >= 4 - iInBuffer; iIndex--) {
83
				ulTmp = ulValue / aulPower85[iIndex];
84
				vOutputByte(ulTmp + '!', pOutFile);
85
				ulValue -= ulTmp * aulPower85[iIndex];
86
			}
87
		}
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 */
93
		iInBuffer = 0;
94
		iOutBytes = 0;
95
		cCharPrev = '\0';
96
		return;
97
	}
98
 
99
	ulBuffer[iInBuffer] = (ULONG)iByte & 0xff;
100
	iInBuffer++;
101
 
102
	if (iInBuffer >= 4) {
103
		ulValue = (ulBuffer[0] << 24) | (ulBuffer[1] << 16) |
104
			(ulBuffer[2] << 8) | ulBuffer[3];
105
		if (ulValue == 0) {
106
			vOutputByte((ULONG)'z', pOutFile); /* Shortcut for 0 */
107
		} else {
108
			for (iIndex = 4; iIndex >= 0; iIndex--) {
109
				ulTmp = ulValue / aulPower85[iIndex];
110
				vOutputByte(ulTmp + '!', pOutFile);
111
				ulValue -= ulTmp * aulPower85[iIndex];
112
			}
113
		}
114
		/* Reset the buffer */
115
		iInBuffer = 0;
116
	}
117
} /* end of vASCII85EncodeByte */
118
 
119
/*
120
 * vASCII85EncodeArray - ASCII 85 encode a byte array
121
 */
122
void
123
vASCII85EncodeArray(FILE *pInFile, FILE *pOutFile, size_t tLength)
124
{
125
	size_t	tCount;
126
	int	iByte;
127
 
128
	fail(pInFile == NULL);
129
	fail(pOutFile == NULL);
130
 
131
	DBG_DEC(tLength);
132
 
133
	for (tCount = 0; tCount < tLength; tCount++) {
134
		iByte = iNextByte(pInFile);
135
		if (iByte == EOF) {
136
			break;
137
		}
138
		vASCII85EncodeByte(pOutFile, iByte);
139
	}
140
} /* end of vASCII85EncodeArray */
141
 
142
/*
143
 * vASCII85EncodeFile - ASCII 85 encode part of a file
144
 */
145
void
146
vASCII85EncodeFile(FILE *pInFile, FILE *pOutFile, size_t tLength)
147
{
148
	fail(pInFile == NULL);
149
	fail(pOutFile == NULL);
150
	fail(tLength == 0);
151
 
152
	vASCII85EncodeArray(pInFile, pOutFile, tLength);
153
	vASCII85EncodeByte(pOutFile, EOF);
154
} /* end of vASCII85EncodeFile */