]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/antiword/asc85enc.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / aux / antiword / asc85enc.c
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 */