| verzia 1.16, 2002/10/26 06:27:52 |
verzia 1.17, 2002/11/10 16:58:30 |
| Riadok 118 char **array(char *buffer) |
|
| Riadok 118 char **array(char *buffer) |
|
| |
|
| |
|
| #define BUFLEN 255 |
#define BUFLEN 255 |
| void read_obj(long offset) |
char *read_obj(long offset,int *obj_num) |
| { |
{ |
| char buffer[BUFLEN]; |
char buffer[BUFLEN]; |
| int obj_num, size = 0; |
int size = 0; |
| struct object *obj = |
char *obj = NULL; |
| (struct object *) xcalloc(sizeof(struct object), 1); |
|
| fseek(fp, offset, SEEK_SET); |
fseek(fp, offset, SEEK_SET); |
| fget(buffer, BUFLEN, fp); |
fget(buffer, BUFLEN, fp); |
| sscanf(buffer, "%d ", &obj_num); |
sscanf(buffer, "%d 0 obj ", obj_num); |
| fget(buffer, BUFLEN, fp); |
fget(buffer, BUFLEN, fp); |
| if (buffer[0] == '<' && buffer[1] == '<') |
if (buffer[0] == '<' && buffer[1] == '<') |
| fget(buffer, BUFLEN, fp); |
fget(buffer, BUFLEN, fp); |
| while (!strstr(buffer, "endobj")) { |
while (!strstr(buffer, "endobj")) { |
| size += strlen(buffer) + 1; |
size += strlen(buffer) + 1; |
| obj->unparsed = realloc(obj->unparsed, size); |
obj = (char *) realloc(obj, size); |
| strcat(obj->unparsed, buffer); |
strcat(obj, buffer); |
| fget(buffer, BUFLEN, fp); |
fget(buffer, BUFLEN, fp); |
| } |
} |
| object[obj_num] = obj; |
return obj; |
| return; |
|
| } |
} |
| |
|
| /* add object to object structure */ |
/* add object to object structure */ |
| void add_obj(char *s) |
void add_obj(char *s) |
| { |
{ |
| |
int obj_num; |
| long offset, old_off; |
long offset, old_off; |
| |
struct object *o = (struct object *) xcalloc(sizeof(struct object),1); |
| sscanf(s, "%ld ", &offset); |
sscanf(s, "%ld ", &offset); |
| old_off = ftell(fp); |
old_off = ftell(fp); |
| read_obj(offset); |
o->unparsed = read_obj(offset,&obj_num); |
| |
object[obj_num] = o; |
| fseek(fp, old_off, SEEK_SET); |
fseek(fp, old_off, SEEK_SET); |
| |
return; |
| } |
} |
| |
|
| /* get filter number */ |
/* get filter number */ |
| char get_filternum(char *filter) |
char get_filternum(char *filter) |
| { |
{ |
| if (!strcmp(filter, "/FlateDecode")) |
if (!strncmp(filter, "/FlateDecode",12)) |
| return FLATEDECODE; |
return FLATEDECODE; |
| if (!strcmp(filter, "/DCTDecode")) |
if (!strncmp(filter, "/DCTDecode",10)) |
| return DCTDECODE; |
return DCTDECODE; |
| return -1; |
return -1; |
| } |
} |
| Riadok 164 char get_filternum(char *filter) |
|
| Riadok 166 char get_filternum(char *filter) |
|
| long get_startxref(void) |
long get_startxref(void) |
| { |
{ |
| char startxref[XREFLINE]; |
char startxref[XREFLINE]; |
| long offset; |
|
| int i = XREFLINE - 2; |
int i = XREFLINE - 2; |
| |
long offset; |
| startxref[XREFLINE - 1] = '\0'; |
startxref[XREFLINE - 1] = '\0'; |
| fstat(fp->_fileno, &fpstat); |
fstat(fp->_fileno, &fpstat); |
| offset = fpstat.st_size - 8; |
offset = fpstat.st_size - EOFSIZE; |
| fseek(fp, offset, SEEK_SET); |
fseek(fp, offset, SEEK_SET); |
| while (1) { |
while (1) { |
| startxref[i] = fgetc(fp); |
startxref[i] = fgetc(fp); |
| Riadok 196 void probe_ptree(int num) |
|
| Riadok 198 void probe_ptree(int num) |
|
| current_page++; |
current_page++; |
| return; |
return; |
| } |
} |
| p = strstr(object[num]->unparsed, "/Kids "); |
p = strstr(object[num]->unparsed, "/Kids"); |
| if (!p) { |
if (!p) { |
| /* error */ |
/* error */ |
| return; |
return; |
| Riadok 213 void probe_ptree(int num) |
|
| Riadok 215 void probe_ptree(int num) |
|
| } |
} |
| |
|
| /* find objects and add it to object structure */ |
/* find objects and add it to object structure */ |
| void xref(void) |
void parse_xref(void) |
| { |
{ |
| char xref[XREFLINE]; |
char xref[XREFLINE]; |
| long offset = 0; |
char *p; |
| offset = get_startxref(); |
fseek(fp, get_startxref(), SEEK_SET); |
| fseek(fp, offset, SEEK_SET); |
|
| fget(xref, XREFLINE, fp); |
fget(xref, XREFLINE, fp); |
| if (!strstr(xref, "xref")) { |
if (!strstr(xref, "xref")) { |
| /* error */ |
fprintf(stderr, "PDF document si corrupted!\n"); |
| |
/* reconstruction */ |
| return; |
return; |
| } |
} |
| object = NULL; |
object = NULL; |
| Riadok 237 void xref(void) |
|
| Riadok 239 void xref(void) |
|
| obj_count = entry[0] + entry[1]; |
obj_count = entry[0] + entry[1]; |
| } |
} |
| do { |
do { |
| fget(xref, XREFLINE, fp); |
fget(xref, XREFLINE, fp); |
| if(xref[XREFLINE - 3] == 'f') |
if (!strncmp(xref,"trailer",7)) |
| continue; |
break; |
| add_obj(&xref[0]); |
if (xref[XREFLINE - 3] == 'f') |
| } while (strncmp(xref, "trailer", 7)); |
continue; |
| fseek(fp, 3, SEEK_CUR); |
add_obj(&xref[0]); |
| |
} while (1); |
| |
if (memchr(xref, '<', strlen(xref)) == NULL) |
| |
fseek(fp, 3, SEEK_CUR); |
| fget(xref, XREFLINE, fp); |
fget(xref, XREFLINE, fp); |
| trailer.prev = 0; |
trailer.prev = 0; |
| while (xref[0] != '>' && xref[1] != '>') { |
while (xref[0] != '>' && xref[1] != '>') { |
| if (!strncmp(xref, "/Root", 5)) |
if ((p = strstr(xref, "/Root")) != NULL) |
| sscanf(xref, |
sscanf(p, |
| "/Root %d 0 R \n", |
"/Root %d 0 R", |
| &trailer.root); |
&trailer.root); |
| if (!strncmp(xref, "/Info", 5)) |
if ((p = strstr(xref, "/Info")) != NULL) |
| sscanf(xref, |
sscanf(xref, |
| "/Info %d 0 R \n", |
"/Info %d 0 R", |
| &trailer.info); |
&trailer.info); |
| if (!strncmp(xref, "/Prev", 5)) |
if ((p = strstr(xref, "/Prev")) != NULL) |
| sscanf(xref, "/Prev %ld", |
sscanf(xref, "/Prev %ld", |
| &trailer.prev); |
&trailer.prev); |
| if (!strncmp(xref, "/Encrypt",8)) |
if ((p = strstr(xref, "/Encrypt")) != NULL) |
| sscanf(xref, |
sscanf(xref, |
| "/Encrypt %d 0 R \n", |
"/Encrypt %d 0 R", |
| &trailer.encrypt); |
&trailer.encrypt); |
| fget(xref, XREFLINE, fp); |
fget(xref, XREFLINE, fp); |
| } |
} |
| if (!trailer.prev) |
if (!trailer.prev) |
| Riadok 282 int parse_catalog(void) |
|
| Riadok 287 int parse_catalog(void) |
|
| } |
} |
| object[trailer.root]->parsed = c = |
object[trailer.root]->parsed = c = |
| (struct catalog *) xmalloc(sizeof(struct catalog)); |
(struct catalog *) xmalloc(sizeof(struct catalog)); |
| sscanf(p, "/Pages %d 0 R \n", &c->pages); |
sscanf(p, "/Pages %d 0 R", &c->pages); |
| free(object[trailer.root]->unparsed); |
free(object[trailer.root]->unparsed); |
| object[trailer.root]->unparsed = NULL; |
object[trailer.root]->unparsed = NULL; |
| return c->pages; |
return c->pages; |
| Riadok 292 void parse_pdf(void) |
|
| Riadok 297 void parse_pdf(void) |
|
| { |
{ |
| int ret, count; |
int ret, count; |
| char *p; |
char *p; |
| xref(); |
parse_xref(); |
| ret = parse_catalog(); |
ret = parse_catalog(); |
| p = strstr(object[ret]->unparsed, "/Count "); |
p = strstr(object[ret]->unparsed, "/Count"); |
| sscanf(p, "/Count %d \n", &count); |
sscanf(p, "/Count %d", &count); |
| page_tree = (int *) malloc(count); |
page_tree = (int *) malloc(count); |
| current_page = 0; |
current_page = 0; |
| probe_ptree(ret); |
probe_ptree(ret); |
| |
current_page = 0; |
| |
loop(); |
| return; |
return; |
| } |
} |
| |
|
| Riadok 306 void fill_page(int page_num) |
|
| Riadok 313 void fill_page(int page_num) |
|
| { |
{ |
| struct page *page; |
struct page *page; |
| struct object *obj; |
struct object *obj; |
| char *p, **mediabox; |
char *p, **mediabox,dict = 0; |
| int contents, resources; |
int contents, resources; |
| if (object[page_num]->type == PAGE) |
if (object[page_num]->type == PAGE) |
| return; |
return; |
| page = (struct page *) xmalloc(sizeof(struct page)); |
page = (struct page *) xmalloc(sizeof(struct page)); |
| obj = object[page_num]; |
obj = object[page_num]; |
| p = strstr(obj->unparsed, "/Contents "); |
p = strstr(obj->unparsed, "/Contents"); |
| if (!p) { |
if (!p) { |
| /* error */ |
/* error */ |
| return; |
return; |
| } |
} |
| if(p[11] == '<') /* if /Contents << */ |
if (p[11] == '<') { /* if /Contents << */ |
| contents = page_num; |
contents = page_num; |
| |
dict = 1; |
| |
} |
| else |
else |
| sscanf(p, "/Contents %d 0 R", &contents); |
sscanf(p, "/Contents %d 0 R", &contents); |
| p = strstr(obj->unparsed, "/Resources "); |
page->contents = fill_contents(contents,dict); |
| |
p = strstr(obj->unparsed, "/Resources"); |
| if (!p) { |
if (!p) { |
| /* error */ |
/* error */ |
| return; |
return; |
| } |
} |
| if(p[11] == '<') /* if /Resources << */ |
if (p[11] == '<') { /* if /Resources << */ |
| resources = page_num; |
resources = page_num; |
| else |
dict = 1; |
| |
} |
| |
else |
| sscanf(p, "/Resources %d 0 R", &resources); |
sscanf(p, "/Resources %d 0 R", &resources); |
| page->contents = fill_contents(contents); |
page->resources = fill_resources(resources,dict); |
| page->resources = fill_resources(resources); |
p = strstr(obj->unparsed, "/MediaBox"); |
| p = strstr(obj->unparsed, "/Mediabox "); |
|
| if (!p) { |
if (!p) { |
| /* error */ |
/* error */ |
| return; |
return; |
| } |
} |
| mediabox = array(&p[11]); |
mediabox = array(&p[10]); |
| page->mediabox[0] = (short) strtoul(mediabox[1], NULL, 10); |
page->mediabox[0] = (short) strtoul(mediabox[1], NULL, 10); |
| free(mediabox[1]); |
free(mediabox[1]); |
| page->mediabox[1] = (short) strtoul(mediabox[2], NULL, 10); |
page->mediabox[1] = (short) strtoul(mediabox[2], NULL, 10); |
| Riadok 347 void fill_page(int page_num) |
|
| Riadok 358 void fill_page(int page_num) |
|
| page->mediabox[3] = (short) strtoul(mediabox[4], NULL, 10); |
page->mediabox[3] = (short) strtoul(mediabox[4], NULL, 10); |
| free(mediabox[4]); |
free(mediabox[4]); |
| free(mediabox); |
free(mediabox); |
| p = strstr(obj->unparsed, "/Parent "); |
p = strstr(obj->unparsed, "/Parent"); |
| if (!p) { |
if (!p) { |
| /* error */ |
/* error */ |
| return; |
return; |
| } |
} |
| sscanf(p, "/Parent %d 0 R", &page->parent); |
sscanf(p, "/Parent %d 0 R", &page->parent); |
| |
p = strstr(obj->unparsed, "/Rotate"); |
| |
if(p) |
| |
sscanf(p, "/Rotate %hd",&page->rotate); |
| free(obj->unparsed); |
free(obj->unparsed); |
| obj->unparsed = NULL; |
obj->unparsed = NULL; |
| obj->type = PAGE; |
obj->type = PAGE; |
| Riadok 367 struct contents *fill_contents(int page_ |
|
| Riadok 381 struct contents *fill_contents(int page_ |
|
| struct page *page; |
struct page *page; |
| char *p; |
char *p; |
| obj = object[page_num]; |
obj = object[page_num]; |
| page = (struct page *) obj->parsed; |
|
| if(page->contents) |
|
| return page->contents; |
|
| content = (struct contents *) xmalloc(sizeof(struct contents)); |
content = (struct contents *) xmalloc(sizeof(struct contents)); |
| p = strstr(obj->unparsed, "/Length "); |
p = strstr(obj->unparsed, "/Length"); |
| if (!p) { |
if (!p) { |
| /* error */ |
/* error */ |
| free(content); |
free(content); |
| return NULL; |
return NULL; |
| } |
} |
| sscanf(p, "/Length %d", &content->length); |
sscanf(p, "/Length %d", &content->length); |
| p = strstr(obj->unparsed, "/Filter "); |
p = strstr(obj->unparsed, "/Filter"); |
| if (!p) { |
if (!p) { |
| /* error */ |
/* error */ |
| free(content); |
free(content); |
| return NULL; |
return NULL; |
| } |
} |
| content->filter = get_filternum(&p[9]); |
content->filter = get_filternum(&p[8]); |
| p = strstr(obj->unparsed, "stream"); |
p = strstr(obj->unparsed, "stream"); |
| if (!p) { |
if (!p) { |
| /* error */ |
/* error */ |
| free(content); |
free(content); |
| return NULL; |
return NULL; |
| |
} |
| |
content->stream = (unsigned char *) xmalloc(content->length); |
| |
strncpy((char *) content->stream, &p[7], content->length); |
| |
if(!dict) { |
| |
obj->type = CONTENT; |
| |
free(obj->unparsed); |
| |
obj->unparsed = NULL; |
| |
obj->parsed = content; |
| } |
} |
| content->stream = (char *) xmalloc(content->length); |
|
| strncpy(content->stream, &p[7], content->length); |
|
| return content; |
return content; |
| } |
} |
| |
|
| struct resources *fill_resources(int page_num) |
struct resources *fill_resources(int page_num) |
| { |
{ |
| struct resources *resources; |
struct resources *resources; |
| struct object *obj; |
struct object *obj; |
| struct page *page; |
struct page *page; |
| obj = object[page_num]; |
obj = object[page_num]; |
| page = obj->parsed; |
resources = (struct resources *) xmalloc(sizeof(struct resources)); |
| if(page->resources) |
return resources; |
| return page->resources; |
|
| resources = (struct resources *) xmalloc(sizeof(struct resources)); |
|
| return resources; |
|
| } |
} |