diff options
Diffstat (limited to 'Build/source/texk/dvipdfm/pdfparse.c')
-rw-r--r-- | Build/source/texk/dvipdfm/pdfparse.c | 692 |
1 files changed, 0 insertions, 692 deletions
diff --git a/Build/source/texk/dvipdfm/pdfparse.c b/Build/source/texk/dvipdfm/pdfparse.c deleted file mode 100644 index 94654a39a33..00000000000 --- a/Build/source/texk/dvipdfm/pdfparse.c +++ /dev/null @@ -1,692 +0,0 @@ -/* $Header$ - This is dvipdfm, a DVI to PDF translator. - Copyright (C) 1998, 1999 by Mark A. Wicks - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - The author may be contacted via the e-mail address - - mwicks@kettering.edu -*/ - - -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -#include "system.h" -#include "mem.h" -#include "mfileio.h" -#include "numbers.h" -#include "dvi.h" -#include "pdfparse.h" -#include "pdfspecial.h" -#include "pdfobj.h" -#include "pdfdoc.h" -#include "pdfdev.h" - -#define verbose 0 -#define debug 0 - -#define DUMP_LIMIT 50 -void dump(char *start, char *end) -{ - char *p = start; - fprintf (stderr, "\nCurrent input buffer is "); - fprintf (stderr, "-->"); - while (p < end && p < start+DUMP_LIMIT) - fprintf (stderr, "%c", *(p++)); - if (p == start+DUMP_LIMIT) - fprintf (stderr, "...\n"); - fprintf (stderr, "<--\n"); -} - -void skip_white (char **start, char *end) -{ - while (*start < end && (isspace (**start) || **start == '%')) { - if (**start == '%') - skip_line (start, end); - else /* Skip the white char */ - (*start)++; - } - return; -} - -void skip_line (char **start, char *end) -{ - /* Note: PDF spec says that all platforms must end line with '\n' - after a "stream" keyword */ - while (*start < end && **start != '\n' && **start != '\r') - (*start)++; - if (*start < end && **start == '\r') - (*start) += 1; - if (*start < end && **start == '\n') - (*start) += 1; - return; -} - -void parse_crap (char **start, char *end) -{ - skip_white(start, end); - if (*start != end) { - fprintf (stderr, "\nCrap left over after object!!\n"); - dump(*start, end); - } -} - -int is_an_int(const char *s) -{ - int i; - for (i=0; i<strlen(s); i++) { - if (i == 0 && s[i] == '-') - continue; - if (!isdigit (s[i])) - return 0; - } - return 1; -} - -int is_a_number(const char *s) -{ - int i, period = 0; - for (i=0; i<strlen(s); i++) { - if (s[i] == '-' && i == 0) - continue; - if (s[i] == '.' && !period) { - period = 1; - continue; - } - if (!isdigit (s[i])) - return 0; - } - return 1; -} - - -pdf_obj *parse_pdf_dict (char **start, char *end) -{ - pdf_obj *result, *tmp1, *tmp2; - char *save = *start; - skip_white(start, end); - if (*((*start)++) != '<' || - *((*start)++) != '<') { - *start = save; - dump (*start, end); - return NULL; - } - result = pdf_new_dict (); - skip_white(start, end); - while (*start < end && - **start != '>') { - if ((tmp1 = parse_pdf_name (start, end)) == NULL) { - pdf_release_obj (result); - { - *start = save; - dump (*start, end); - return NULL; - } - }; - if ((tmp2 = parse_pdf_object (start, end)) == NULL) { - pdf_release_obj (result); - pdf_release_obj (tmp1); - { - *start = save; - dump (*start, end); - return NULL; - } - } - pdf_add_dict (result, tmp1, tmp2); - skip_white(start, end); - } - if (*start >= end) { - pdf_release_obj (result); - *start = save; - dump (*start, end); - return NULL; - } - if (*((*start)++) == '>' && - *((*start)++) == '>') { - return result; - } else { - pdf_release_obj (result); - fprintf (stderr, "\nDictionary object ended prematurely\n"); - *start = save; - dump (*start, end); - return NULL; - } -} - -pdf_obj *parse_pdf_array (char **start, char *end) -{ - pdf_obj *result, *tmp1; -#ifdef MEM_DEBUG -MEM_START -#endif - skip_white(start, end); - if (*((*start)++) != '[') - return NULL; - result = pdf_new_array (); - skip_white(start, end); - while (*start < end && - **start != ']') { - if ((tmp1 = parse_pdf_object (start, end)) == NULL) { - pdf_release_obj (result); - return NULL; - }; - pdf_add_array (result, tmp1); - skip_white(start, end); - } - if (*start >= end) { - pdf_release_obj (result); - fprintf (stderr, "\nArray ended prematurely\n"); - return NULL; - } - (*start)++; -#ifdef MEM_DEBUG -MEM_END -#endif - return result; -} - -char *parse_number (char **start, char *end) -{ - char *number, *save; -#ifdef MEM_DEBUG -MEM_START -#endif - skip_white(start, end); - save = *start; - if (*start < end && (**start == '+' || **start == '-')) { - *start += 1; - } - while (*start < end && - isdigit(**start)) - (*start)++; - if (*start < end && **start == '.') { - (*start)++; - while (*start < end && - isdigit(**start)) - (*start)++; - } - if (*start > save) { - number = NEW ((*start-save)+1, char); - memcpy (number, save, (*start-save)); - number[*start-save] = 0; - return number; - } - *start = save; -#ifdef MEM_DEBUG -MEM_END -#endif - return NULL; -} - -char *parse_unsigned (char **start, char *end) -{ - char *number, *save; -#ifdef MEM_DEBUG -MEM_START -#endif - skip_white(start, end); - save = *start; - while (*start < end && - isdigit(**start)) - (*start)++; - if (*start > save) { - number = NEW ((*start-save)+1, char); - memcpy (number, save, (*start-save)); - number[*start-save] = 0; - return number; - } - *start = save; -#ifdef MEM_DEBUG -MEM_END -#endif - return NULL; -} - -static char *parse_gen_ident (char **start, char *end, char *valid_chars) -{ - char *ident, *save; - save = *start; - skip_white(start, end); - while (*start < end && strchr (valid_chars, **start)) - (*start)++; - if (save == *start) - return NULL; - ident = NEW (*start-save+1, char); - memcpy (ident, save, *start-save); - ident[*start-save] = 0; - return ident; -} - -char *parse_ident (char **start, char *end) -{ - static char *valid_chars = - "!\"#$&'*+,-.0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~"; - return parse_gen_ident (start, end, valid_chars); -} - -char *parse_val_ident (char **start, char *end) -{ - static char *valid_chars = - "!\"#$&'*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz|~"; - return parse_gen_ident (start, end, valid_chars); -} - -char *parse_c_ident (char **start, char *end) -{ - static char *valid_chars = - "0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; - return parse_gen_ident (start, end, valid_chars); -} - -char *parse_opt_ident(char **start, char *end) -{ - if (*start >= end || (**start) != '@') - return NULL; - (*start)++; - return parse_ident(start, end); -} - - -pdf_obj *parse_pdf_name (char **start, char *end) -{ - pdf_obj *result; - char *name; - skip_white(start, end); - if (**start != '/') { - fprintf (stderr, "\nPDF Name expected and not found.\n"); - dump(*start, end); - return NULL; - } - (*start)++; - if ((name = parse_ident(start, end)) != NULL) { - result = pdf_new_name (name); - RELEASE (name); - return result; - } - return NULL; -} - -char *parse_pdf_reference(char **start, char *end) -{ - skip_white (start, end); - if (**start != '@') { - fprintf (stderr, "\nPDF Name expected and not found.\n"); - dump(*start, end); - return NULL; - } - (*start)++; - return parse_ident(start, end); -} - -pdf_obj *parse_pdf_boolean (char **start, char *end) -{ - skip_white (start, end); - if (end-*start > strlen ("true") && - !strncmp (*start, "true", strlen("true"))) { - *start += strlen("true"); - return pdf_new_boolean (1); - } - if (end - *start > strlen ("false") && - !strncmp (*start, "false", strlen("false"))) { - *start += strlen("false"); - return pdf_new_boolean (0); - } - return NULL; -} - -pdf_obj *parse_pdf_null (char **start, char *end) -{ - char *save = *start; - char *ident; - skip_white (start, end); - ident = parse_ident(start, end); - if (!strcmp (ident, "null")) { - RELEASE(ident); - return pdf_new_null(); - } - *start = save; - fprintf (stderr, "\nNot a valid object\n"); - dump(*start, end); - return NULL; -} - -static pdf_obj *parse_pdf_number (char **start, char *end) -{ - char *number; - pdf_obj *result; - skip_white(start, end); - if ((number = parse_number(start, end)) != NULL) { - result = pdf_new_number (atof(number)); - RELEASE (number); - return result; - } - return NULL; -} - -int xtod (char c) -{ - if (c >= '0' && c <= '9') - return c-'0'; - if (c >= 'A' && c <= 'F') - return (c-'A')+10; - if (c >= 'a' && c <= 'f') - return (c-'a')+10; - return 0; -} - -pdf_obj *parse_pdf_hex_string (char **start, char *end) -{ - pdf_obj *result; - char *save; - unsigned char *string = NULL; - int strlength; - skip_white (start, end); - if (*start == end || *((*start)++) != '<') - return NULL; - save = *start; - string = NEW ((end - *start)/2+2, unsigned char); /* A little excess here */ - strlength = 0; - while (*start < end && **start != '>') { - string[strlength] = xtod(**start) * 16; - (*start) += 1; - if (*start < end && **start != '>') { - string[strlength] += xtod(**start); - (*start) += 1; - } - skip_white (start, end); - strlength += 1; - } - if (*start < end) { - *start += 1; - result = pdf_new_string (string, strlength); - } else { - result = NULL; - } - if (string) - RELEASE(string); - return result; -} - -pdf_obj *parse_pdf_string (char **start, char *end) -{ - pdf_obj *result; - int balance = 0; - char *save; - unsigned char *string; - int strlength; - skip_white(start, end); - save = *start; - if (*start == end || **start != '(') { - return NULL; - } - ++(*start); - string = NEW (end - *start, unsigned char); - strlength = 0; - balance = 0; - while (*start < end && - (**start != ')' || balance > 0)) { - if (**start == '\\') - switch (*(++(*start))) { - case 'n': - string[strlength++] = '\n'; - (*start)++; - break; - case 'r': - string[strlength++] = '\r'; - (*start)++; - break; - case 't': - string[strlength++] = '\t'; - (*start)++; - break; - case 'b': - string[strlength++] = '\b'; - (*start)++; - break; - default: - if (isdigit(**start)) { - int i; - string[strlength] = 0; - for (i=0; i<3; i++) - string[strlength] = string[strlength]*8 + (*((*start)++)-'0'); - strlength+= 1; - } else { - string[strlength++] = *((*start)++); - } - } - else { - if (**start == '(') - balance += 1; - if (**start == ')') - balance -= 1; - string[strlength++] = *((*start)++); - } - } - if (*start >= end) { - fprintf (stderr, "\nString object ended prematurely\n"); - dump (save, *start); - return NULL; - } - (*start)++; - result = pdf_new_string (string, strlength); - RELEASE (string); - return result; -} - -char *parse_c_string (char **start, char *end) -{ - char *string, *save; - int strlength; - skip_white(start, end); - save = *start; - if (*start == end || **start != '"') { - return NULL; - } - ++(*start); - string = NEW (end - *start, char); - strlength = 0; - while (*start < end && (**start != '"')) { - if (**start == '\\') - switch (*(++(*start))) { - case '"': - string[strlength++] = '"'; - (*start)++; - break; - case 'n': - string[strlength++] = '\n'; - (*start)++; - break; - case 'r': - string[strlength++] = '\r'; - (*start)++; - break; - case 't': - string[strlength++] = '\t'; - (*start)++; - break; - case 'b': - string[strlength++] = '\b'; - (*start)++; - break; - default: - if (isdigit(**start)) { - int i; - string[strlength] = 0; - for (i=0; i<3; i++) - string[strlength] = string[strlength]*8 + (*((*start)++)-'0'); - strlength+= 1; - } else { - string[strlength++] = *((*start)++); - } - } - else { - string[strlength++] = *((*start)++); - } - string[strlength]=0; - } - if (*start >= end) { - fprintf (stderr, "\nString ended prematurely\n"); - dump (save, *start); - return NULL; - } - string[strlength] = 0; - (*start)++; - return string; -} - -static pdf_obj *parse_pdf_stream (char **start, char *end, pdf_obj - *dict) -{ - pdf_obj *result, *new_dict, *tmp1, *length_obj; - unsigned long length; - if (pdf_lookup_dict(dict, "F")) { - fprintf (stderr, "File streams not implemented (yet)"); - return NULL; - } - if ((tmp1 = pdf_lookup_dict(dict, "Length")) == NULL) { - fprintf (stderr, "No length specified"); - return NULL; - } - length = pdf_number_value (length_obj = pdf_deref_obj (tmp1)); - pdf_release_obj (length_obj); - skip_white(start, end); - skip_line(start, end); - result = pdf_new_stream(0); - new_dict = pdf_stream_dict(result); - pdf_merge_dict (new_dict, dict); - pdf_release_obj (dict); - pdf_add_stream (result, *start, length); - *start += length; - skip_white(start, end); - if (*start+strlen("endstream") > end || - strncmp(*start, "endstream", strlen("endstream"))) { - fprintf (stderr, "\nendstream not found\n"); - return NULL; - } - *start += strlen("endstream"); - return result; -} - -pdf_obj *parse_pdf_object (char **start, char *end) -{ - pdf_obj *result, *tmp1=NULL, *tmp2=NULL; - char *save = *start; - char *position2; - skip_white(start, end); - if (*start >= end) - return NULL; - switch (**start) { - case '<': - /* Check for those troublesome strings starting with '<' */ - if (*start+1 < end && *(*start+1) != '<') { - result = parse_pdf_hex_string (start, end); - break; - } - result = parse_pdf_dict (start, end); - skip_white(start, end); - if (end - *start > strlen("stream") && - !strncmp(*start, "stream", strlen("stream"))) { - result = parse_pdf_stream (start, end, result); - } - /* Check for stream */ - break; - case '(': - result = parse_pdf_string(start, end); - break; - case '[': - result = parse_pdf_array(start, end); - break; - case '/': - result = parse_pdf_name(start, end); - break; - case '@': - result = get_reference(start, end); - break; - case 't': - case 'f': - result = parse_pdf_boolean(start, end); - break; - default: - /* This is a bit of a hack, but PDF doesn't easily allow you to - tell a number from an indirect object reference with some - serious looking ahead */ - - if (*start < end && - (isdigit(**start) || **start == '+' || **start == '-' || **start == '.')) { - tmp1 = parse_pdf_number(start, end); - tmp2 = NULL; - /* This could be a # # R type reference. We can't be sure unless - we look ahead for the second number and the 'R' */ - skip_white(start, end); - position2 = *start; - if (*start < end && isdigit(**start)) { - tmp2 = parse_pdf_number(start, end); - } else - tmp2 = NULL; - skip_white(start, end); - if (tmp1 != NULL && tmp2 != NULL && *start < end && *((*start)++) == 'R') { - result = pdf_new_ref ((unsigned long) pdf_number_value (tmp1), - (int) pdf_number_value (tmp2)); - pdf_release_obj (tmp1); - pdf_release_obj (tmp2); - break; - } - /* Following checks if we got two numbers, but not 'r' */ - if (tmp1 != NULL && tmp2 != NULL) { - pdf_release_obj (tmp2); - *start = position2; - } - result = tmp1; - break; - } - if (*start < end && **start == 'n') { - result = parse_pdf_null(start, end); - break; - } - result = NULL; - break; - } - if (result == NULL) { - fprintf (stderr, "\nExpecting an object, but didn't find one"); - *start = save; - dump(*start, end); - } - return result; -} - -void parse_key_val (char **start, char *end, char **key, char **val) -{ - *key = NULL; - *val = NULL; - skip_white (start, end); - if ((*key = parse_c_ident (start, end))) { - skip_white (start, end); - if (*start < end && **start == '=') - { - (*start) += 1; - skip_white (start, end); - if (*start < end) switch (**start) { - case '"': - *val = parse_c_string (start, end); - break; - default: - *val = parse_val_ident (start, end); - } - } - } -} |