examples/PIPS/antiword/src/asc85enc.c

00001 /*
00002  * asc85enc.c
00003  * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
00004  *
00005  * Description:
00006  * Functions to for ASCII 85 encoding
00007  *
00008  *====================================================================
00009  * This part of the software is based on:
00010  * asc85ec.c - ASCII85 and Hex encoding for PostScript Level 2 and PDF
00011  * Copyright (C) 1994-99 Thomas Merz ([email protected])
00012  *====================================================================
00013  * The credit should go to him, but all the bugs are mine.
00014  */
00015 
00016 #include <stdio.h>
00017 #include "antiword.h"
00018 
00019 static const ULONG      aulPower85[5] = {
00020         1UL, 85UL, 85UL * 85, 85UL * 85 * 85, 85UL * 85 * 85 * 85,
00021 };
00022 static int      iOutBytes = 0;  /* Number of characters in an output line */
00023 static char     cCharPrev = '\0';
00024 
00025 /*
00026  * Two percent characters at the start of a line will cause trouble
00027  * with some post-processing software. In order to avoid this, we
00028  * simply insert a line break if we encounter two percent characters
00029  * at the start of the line. Of course, this rather simplistic
00030  * algorithm may lead to a large line count in pathological cases,
00031  * but the chance for hitting such a case is very small, and even
00032  * so it's only a cosmetic flaw and not a functional restriction.
00033  */
00034 
00035 /*
00036  * vOutputByte - output one byte
00037  */
00038 static void
00039 vOutputByte(ULONG ulChar, FILE *pOutFile)
00040 {
00041         if (iOutBytes == 1 && cCharPrev == '%' && ulChar == (ULONG)'%') {
00042                 if (putc('\n', pOutFile) != EOF) {
00043                         iOutBytes = 0;
00044                 }
00045         }
00046         if (putc((int)ulChar, pOutFile) == EOF) {
00047                 return;
00048         }
00049         iOutBytes++;
00050         if (iOutBytes > 63) {
00051                 if (putc('\n', pOutFile) != EOF) {
00052                         iOutBytes = 0;
00053                 }
00054         }
00055         cCharPrev = (char)ulChar;
00056 } /* end of vOutputByte */
00057 
00058 /*
00059  * vASCII85EncodeByte - ASCII 85 encode a byte
00060  */
00061 void
00062 vASCII85EncodeByte(FILE *pOutFile, int iByte)
00063 {
00064         static ULONG    ulBuffer[4] = { 0, 0, 0, 0 };
00065         static int      iInBuffer = 0;
00066         ULONG   ulValue, ulTmp;
00067         int     iIndex;
00068 
00069         fail(pOutFile == NULL);
00070         fail(iInBuffer < 0);
00071         fail(iInBuffer > 3);
00072 
00073         if (iByte == EOF) {
00074                 /* End Of File, time to clean up */
00075                 if (iInBuffer > 0 && iInBuffer < 4) {
00076                         /* Encode the remaining bytes */
00077                         ulValue = 0;
00078                         for (iIndex = iInBuffer - 1; iIndex >= 0; iIndex--) {
00079                                 ulValue |=
00080                                         ulBuffer[iIndex] << (8 * (3 - iIndex));
00081                         }
00082                         for (iIndex = 4; iIndex >= 4 - iInBuffer; iIndex--) {
00083                                 ulTmp = ulValue / aulPower85[iIndex];
00084                                 vOutputByte(ulTmp + '!', pOutFile);
00085                                 ulValue -= ulTmp * aulPower85[iIndex];
00086                         }
00087                 }
00088                 /* Add the End Of Data marker */
00089                 (void)putc('~', pOutFile);
00090                 (void)putc('>', pOutFile);
00091                 (void)putc('\n', pOutFile);
00092                 /* Reset the control variables */
00093                 iInBuffer = 0;
00094                 iOutBytes = 0;
00095                 cCharPrev = '\0';
00096                 return;
00097         }
00098 
00099         ulBuffer[iInBuffer] = (ULONG)iByte & 0xff;
00100         iInBuffer++;
00101 
00102         if (iInBuffer >= 4) {
00103                 ulValue = (ulBuffer[0] << 24) | (ulBuffer[1] << 16) |
00104                         (ulBuffer[2] << 8) | ulBuffer[3];
00105                 if (ulValue == 0) {
00106                         vOutputByte((ULONG)'z', pOutFile); /* Shortcut for 0 */
00107                 } else {
00108                         for (iIndex = 4; iIndex >= 0; iIndex--) {
00109                                 ulTmp = ulValue / aulPower85[iIndex];
00110                                 vOutputByte(ulTmp + '!', pOutFile);
00111                                 ulValue -= ulTmp * aulPower85[iIndex];
00112                         }
00113                 }
00114                 /* Reset the buffer */
00115                 iInBuffer = 0;
00116         }
00117 } /* end of vASCII85EncodeByte */
00118 
00119 /*
00120  * vASCII85EncodeArray - ASCII 85 encode a byte array
00121  */
00122 void
00123 vASCII85EncodeArray(FILE *pInFile, FILE *pOutFile, size_t tLength)
00124 {
00125         size_t  tCount;
00126         int     iByte;
00127 
00128         fail(pInFile == NULL);
00129         fail(pOutFile == NULL);
00130 
00131         DBG_DEC(tLength);
00132 
00133         for (tCount = 0; tCount < tLength; tCount++) {
00134                 iByte = iNextByte(pInFile);
00135                 if (iByte == EOF) {
00136                         break;
00137                 }
00138                 vASCII85EncodeByte(pOutFile, iByte);
00139         }
00140 } /* end of vASCII85EncodeArray */
00141 
00142 /*
00143  * vASCII85EncodeFile - ASCII 85 encode part of a file
00144  */
00145 void
00146 vASCII85EncodeFile(FILE *pInFile, FILE *pOutFile, size_t tLength)
00147 {
00148         fail(pInFile == NULL);
00149         fail(pOutFile == NULL);
00150         fail(tLength == 0);
00151 
00152         vASCII85EncodeArray(pInFile, pOutFile, tLength);
00153         vASCII85EncodeByte(pOutFile, EOF);
00154 } /* end of vASCII85EncodeFile */

Generated by  doxygen 1.6.2