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; |
|
} |
} |