1 /* $XConsortium: t1io.c,v 1.10 95/06/09 22:29:35 gildea Exp $ */
2 /* Copyright International Business Machines,Corp. 1991
5 * License to use, copy, modify, and distribute this software
6 * and its documentation for any purpose and without fee is
7 * hereby granted, provided that the above copyright notice
8 * appear in all copies and that both that copyright notice and
9 * this permission notice appear in supporting documentation,
10 * and that the name of IBM not be used in advertising or
11 * publicity pertaining to distribution of the software without
12 * specific, written prior permission.
14 * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
15 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
16 * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
18 * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND
19 * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
20 * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF
21 * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
22 * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN
23 * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
25 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
26 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
27 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
29 * Author: Carol H. Thompson IBM Almaden Research Center
31 /*******************************************************************
32 * I/O package for Type 1 font reading
33 ********************************************************************/
43 #include <X11/Xw32defs.h>
46 /* Constants and variables used in the decryption */
47 #define c1 ((unsigned short)52845)
48 #define c2 ((unsigned short)22719)
49 static unsigned short r;
50 static int asc, Decrypt;
52 static int haveextrach;
54 /* Our single FILE structure and buffer for this package */
55 STATIC F_FILE TheFile;
56 STATIC unsigned char TheBuffer[F_BUFSIZ];
59 F_FILE *T1Open(), *T1Eexec();
61 int T1Read(), T1Getc(), T1Ungetc();
62 STATIC int T1Decrypt(), T1Fill();
64 /* -------------------------------------------------------------- */
66 F_FILE *T1Open(fn, mode)
67 char *fn; /* Pointer to filename */
68 char *mode; /* Pointer to open mode string */
70 F_FILE *of = &TheFile;
71 int oflags = O_RDONLY; /* We know we are only reading */
75 #ifdef O_BINARY /* VMS or DOS */
78 of->fd = open(fn, oflags);
82 /* Initialize the buffer information of our file descriptor */
83 of->b_base = TheBuffer;
84 of->b_size = F_BUFSIZ;
93 /* -------------------------------------------------------------- */
94 int T1Getc(f) /* Read one character */
95 F_FILE *f; /* Stream descriptor */
97 if (f->b_base == NULL) return EOF; /* already closed */
99 if (f->flags & UNGOTTENC) { /* there is an ungotten c */
100 f->flags &= ~UNGOTTENC;
101 return (int) f->ungotc;
104 if (f->b_cnt == 0) /* Buffer needs to be (re)filled */
105 f->b_cnt = T1Fill(f);
106 if (f->b_cnt > 0) return (f->b_cnt--, (int) *(f->b_ptr++));
113 /* -------------------------------------------------------------- */
114 int T1Ungetc(c, f) /* Put back one character */
116 F_FILE *f; /* Stream descriptor */
120 f->flags |= UNGOTTENC; /* set flag */
121 f->flags &= ~FIOEOF; /* reset EOF */
126 /* -------------------------------------------------------------- */
127 int T1Read(buffP, size, n, f) /* Read n items into caller's buffer */
128 char *buffP; /* Buffer to be filled */
129 int size; /* Size of each item */
130 int n; /* Number of items to read */
131 F_FILE *f; /* Stream descriptor */
134 F_char *p = (F_char *)buffP;
135 int icnt; /* Number of characters to read */
137 if (f->b_base == NULL) return 0; /* closed */
138 icnt = (size!=1)?n*size:n; /* Number of bytes we want */
140 if (f->flags & UNGOTTENC) { /* there is an ungotten c */
141 f->flags &= ~UNGOTTENC;
148 /* First use any bytes we have buffered in the stream buffer */
149 if ((cnt=f->b_cnt) > 0) {
150 if (cnt > icnt) cnt = icnt;
151 for (i=0; i<cnt; i++) *(p++) = *(f->b_ptr++);
157 if ((icnt == 0) || (f->flags & FIOEOF)) break;
159 f->b_cnt = T1Fill(f);
161 return ((size!=1)?bytelen/size:bytelen);
164 /* -------------------------------------------------------------- */
165 int T1Close(f) /* Close the file */
166 F_FILE *f; /* Stream descriptor */
168 if (f->b_base == NULL) return 0; /* already closed */
169 f->b_base = NULL; /* no valid stream */
174 #define pointer void *
176 #define pointer char *
179 /* -------------------------------------------------------------- */
180 F_FILE *T1eexec(f) /* Initialization */
181 F_FILE *f; /* Stream descriptor */
186 unsigned char randomP[8];
188 r = 55665; /* initial key */
189 asc = 1; /* indicate ASCII form */
191 /* Consume the 4 random bytes, determining if we are also to
192 ASCIIDecodeHex as we process our input. (See pages 63-64
193 of the Adobe Type 1 Font Format book.) */
195 /* Skip over any initial white space chars */
196 while (HighHexP[c=getc(f)] == HWHITE_SPACE) ;
198 /* If ASCII, the next 7 chars are guaranteed consecutive */
199 randomP[0] = c; /* store first non white space char */
200 fread((pointer)(randomP+1), 1, 3, f); /* read 3 more, for a total of 4 */
201 /* store first four chars */
202 for (i=0,p=randomP; i<4; i++) { /* Check 4 valid ASCIIEncode chars */
203 if (HighHexP[*p++] > LAST_HDIGIT) { /* non-ASCII byte */
208 if (asc) { /* ASCII form, convert first eight bytes to binary */
209 fread((pointer)(randomP+4), 1, 4, f); /* Need four more */
210 for (i=0,p=randomP; i<4; i++) { /* Convert */
212 randomP[i] = H | LowHexP[*p++];
217 for (i=0,p=randomP; i<4; i++) {
218 r = (*p++ + r) * c1 + c2;
221 /* Decrypt the remaining buffered bytes */
222 f->b_cnt = T1Decrypt(f->b_ptr, f->b_cnt);
224 return (feof(f))?NULL:f;
227 /* -------------------------------------------------------------- */
228 STATIC int T1Decrypt(p, len)
234 unsigned char *inp = p;
242 else tblP = HighHexP;
243 for (n=0; len>0; len--) {
245 if (L == HWHITE_SPACE) continue;
246 if (L > LAST_HDIGIT) break;
247 if (tblP == HighHexP) { /* Got first hexit value */
250 } else { /* Got second hexit value; compute value and store it */
254 /* H is an int, 0 <= H <= 255, so all of this will work */
256 r = (H + r) * c1 + c2;
259 if (tblP != HighHexP) { /* We had an odd number of hexits */
262 } else haveextrach = 0;
265 for (n = len; n>0; n--) {
268 r = (H + r) * c1 + c2;
274 /* -------------------------------------------------------------- */
275 STATIC int T1Fill(f) /* Refill stream buffer */
276 F_FILE *f; /* Stream descriptor */
280 rc = read(f->fd, f->b_base, F_BUFSIZ);
281 /* propagate any error or eof to current file */
283 if (rc == 0) /* means EOF */
286 f->error = (short)-rc;
287 f->flags |= FIOERROR;
291 f->b_ptr = f->b_base;
292 if (Decrypt) rc = T1Decrypt(f->b_base, rc);