home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / anwor032.zip / antiword.0.32 / asc85enc.c < prev    next >
C/C++ Source or Header  |  2000-10-26  |  4KB  |  155 lines

  1. /*
  2.  * asc85enc.c
  3.  * Copyright (C) 2000 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 unsigned long 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(unsigned long ulChar, FILE *pOutFile)
  40. {
  41.     if (iOutBytes == 1 && cCharPrev == '%' && ulChar == '%') {
  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 unsigned long ulBuffer[4] = { 0, 0, 0, 0 };
  65.     static int    iInBuffer = 0;
  66.     unsigned long    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) {
  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] = (unsigned long)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('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, int iLength)
  124. {
  125.     int    iCount, iByte;
  126.  
  127.     fail(pInFile == NULL);
  128.     fail(pOutFile == NULL);
  129.     fail(iLength < 0);
  130.  
  131.     DBG_DEC(iLength);
  132.  
  133.     for (iCount = 0; iCount < iLength; iCount++) {
  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, int iLength)
  147. {
  148.     fail(pInFile == NULL);
  149.     fail(pOutFile == NULL);
  150.     fail(iLength <= 0);
  151.  
  152.     vASCII85EncodeArray(pInFile, pOutFile, iLength);
  153.     vASCII85EncodeByte(pOutFile, EOF);
  154. } /* end of vASCII85EncodeFile */
  155.