/contrib/media/updf/build.zip |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/contrib/media/updf/Makefile |
---|
10,8 → 10,15 |
CFLAGS += -Ifitz -Ipdf -Iscripts -fno-stack-protector -nostdinc -fno-builtin -m32 -I include -fno-pic -w |
LIBS += -lfreetype2 -lpng -ljbig2dec -ljpeg -lopenjpeg -lz -lm -lc |
THIRD_LIBS := $(FREETYPE_LIB) $(JBIG2DEC_LIB) $(JPEG_LIB) $(OPENJPEG_LIB) $(ZLIB_LIB) |
#include Makerules |
#include Makethird |
THIRD_LIBS := $(FREETYPE_LIB) |
THIRD_LIBS += $(JBIG2DEC_LIB) |
THIRD_LIBS += $(JPEG_LIB) |
THIRD_LIBS += $(OPENJPEG_LIB) |
THIRD_LIBS += $(ZLIB_LIB) |
ifeq "$(verbose)" "" |
QUIET_AR = @ echo ' ' ' ' AR $@ ; |
QUIET_CC = @ echo ' ' ' ' CC $@ ; |
47,6 → 54,8 |
$(OUT)/%.o : scripts/%.c | $(OUT) |
$(CC_CMD) |
.PRECIOUS : $(OUT)/%.o # Keep intermediates from chained rules |
# --- Fitz and MuPDF libraries --- |
FITZ_LIB := $(OUT)/libfitz.a |
59,10 → 68,12 |
$(MUPDF_LIB) : $(addprefix $(OUT)/, $(MUPDF_SRC:%.c=%.o)) |
libs: $(MUPDF_LIB) $(FITZ_LIB) $(THIRD_LIBS) |
@ echo MuPDF and underlying libraries built |
# --- Generated CMAP and FONT files --- |
CMAPDUMP := scripts/cmapdump |
# FONTDUMP := scripts/fontdump |
CMAP_CNS_SRC := $(wildcard cmaps/cns/*) |
CMAP_GB_SRC := $(wildcard cmaps/gb/*) |
104,6 → 115,10 |
# --- Tools and Apps --- |
PDF_APPS := $(addprefix $(OUT)/, pdfdraw pdfclean pdfextract pdfinfo pdfshow) |
$(PDF_APPS) : $(MUPDF_LIB) $(FITZ_LIB) $(THIRD_LIBS) |
MUPDF := $(OUT)/mupdf |
$(MUPDF) : $(MUPDF_LIB) $(FITZ_LIB) $(THIRD_LIBS) |
ifeq "$(NOX11)" "" |
/contrib/media/updf/apps/kos_main.c |
---|
6,11 → 6,79 |
#include "icons/allbtns.h" |
#include "kolibri.c" |
// need to be a part of menuet/os.h |
#define BT_DEL 0x80000000 |
#define BT_HIDE 0x40000000 |
#define BT_NOFRAME 0x20000000 |
#define evReDraw 1 |
#define evKey 2 |
#define evButton 3 |
#define evMouse 6 |
#define evNetwork 8 |
#define ASCII_KEY_LEFT 176 |
#define ASCII_KEY_RIGHT 179 |
#define ASCII_KEY_DOWN 177 |
#define ASCII_KEY_UP 178 |
#define ASCII_KEY_HOME 180 |
#define ASCII_KEY_END 181 |
#define ASCII_KEY_PGDN 183 |
#define ASCII_KEY_PGUP 184 |
#define ASCII_KEY_BS 8 |
#define ASCII_KEY_TAB 9 |
#define ASCII_KEY_ENTER 13 |
#define ASCII_KEY_ESC 27 |
#define ASCII_KEY_DEL 182 |
#define ASCII_KEY_INS 185 |
#define ASCII_KEY_SPACE 032 |
struct blit_call |
{ |
int dstx; |
int dsty; |
int w; |
int h; |
int srcx; |
int srcy; |
int srcw; |
int srch; |
unsigned char *d; |
int stride; |
}; |
void blit(int dstx, int dsty, int w, int h, int srcx, int srcy,int srcw, int srch, int stride, char *d) //Вызов сисфункции Blitter |
{ |
struct blit_call image; |
image.dstx=dstx; |
image.dsty=dsty; |
image.w=w; |
image.h=h; |
image.srcx=srcx; |
image.srcy=srcy; |
image.srcw=srcw; |
image.srch=srch; |
image.stride=stride; |
image.d=d; |
asm ("int $0x40"::"a"(73),"b"(0),"c"(&image)); |
} |
void run_app() |
{ |
return; |
} |
int __menuet__get_mouse_wheels(void) |
{ |
int val; |
asm ("int $0x40":"=a"(val):"a"(37),"b"(7)); |
return val; |
}; |
/*==== DATA ====*/ |
static char Title[1024] = "uPDF"; |
127,7 → 195,7 |
gapp.panx = 0; |
if (gapp.image->n == 4) { |
kos_blit(window_center + Form.client_left, |
blit(window_center + Form.client_left, |
Form.client_top + TOOLBAR_HEIGHT, |
Form.client_width, |
Form.client_height - TOOLBAR_HEIGHT, |
153,7 → 221,7 |
d[3] = *s++; |
d += 4; |
} |
kos_blit(window_center + Form.client_left, |
blit(window_center + Form.client_left, |
Form.client_top + TOOLBAR_HEIGHT, |
Form.client_width, |
Form.client_height - TOOLBAR_HEIGHT, |
172,30 → 240,142 |
void DrawPageSides(void) |
{ |
if (gapp.image->h < Form.client_height - TOOLBAR_HEIGHT) { |
draw_h = gapp.image->h - gapp.pany; |
} else { |
draw_h = Form.client_height - TOOLBAR_HEIGHT; |
} |
if (gapp.image->w < Form.client_width) { |
window_center = (Form.client_width - gapp.image->w) / 2; |
draw_w = gapp.image->w + 2; |
if (Form.client_width > gapp.image->w) window_center = (Form.client_width - gapp.image->w) / 2; else window_center = 0; |
if (gapp.image->h < Form.client_height - TOOLBAR_HEIGHT) draw_h = gapp.image->h - gapp.pany; else draw_h = Form.client_height - TOOLBAR_HEIGHT; |
if (gapp.image->w < Form.client_width) |
{ |
kol_paint_bar(0, TOOLBAR_HEIGHT, window_center-1, Form.client_height - TOOLBAR_HEIGHT, DOCUMENT_BG); |
kol_paint_bar(window_center-1, TOOLBAR_HEIGHT, 1, draw_h, DOCUMENT_BORDER); |
kol_paint_bar(window_center + gapp.image->w, TOOLBAR_HEIGHT, 1, draw_h, DOCUMENT_BORDER); |
kol_paint_bar(window_center + gapp.image->w+1, TOOLBAR_HEIGHT, Form.client_width - window_center - gapp.image->w - 1, Form.client_height - TOOLBAR_HEIGHT, DOCUMENT_BG); |
} else { |
} |
if (gapp.image->w < Form.client_width) |
{ |
draw_w = gapp.image->w + 2; |
} |
else |
{ |
window_center = 1; |
draw_w = Form.client_width; |
} |
kol_paint_bar(window_center - 1, gapp.image->h - gapp.pany + TOOLBAR_HEIGHT, draw_w, 1, DOCUMENT_BORDER); |
kol_paint_bar(window_center - 1, gapp.image->h - gapp.pany + TOOLBAR_HEIGHT + 1, |
draw_w, Form.client_height - gapp.image->h - TOOLBAR_HEIGHT + gapp.pany - 1, DOCUMENT_BG); |
kol_paint_bar(window_center - 1, gapp.image->h - gapp.pany + TOOLBAR_HEIGHT + 1, draw_w, Form.client_height - gapp.image->h - TOOLBAR_HEIGHT + gapp.pany - 1, DOCUMENT_BG); |
} |
int main (void) |
{ |
char ii, mouse_wheels_state; |
char* original_command_line = *(char**)0x1C; |
if (*original_command_line == 0) { |
kol_board_puts("Running uPDF without any param"); |
RunOpenApp(); |
__menuet__sys_exit(); |
} |
kol_board_puts(original_command_line); |
kol_board_puts("\n"); |
char buf[128]; |
int resolution = 72; |
int pageno = 1; |
fz_accelerate(); |
kol_board_puts("PDF init\n"); |
pdfapp_init(&gapp); |
gapp.scrw = 600; |
gapp.scrh = 400; |
gapp.resolution = resolution; |
gapp.pageno = pageno; |
kol_board_puts("PDF Open\n"); |
pdfapp_open(&gapp, original_command_line, 0, 0); |
kol_board_puts("PDF Opened\n"); |
wintitle(&gapp, 0); |
kol_board_puts("Inital paint\n"); |
int butt, key, screen_max_x, screen_max_y; |
__menuet__get_screen_max(&screen_max_x, &screen_max_y); |
__menuet__set_bitfield_for_wanted_events(EVENT_REDRAW+EVENT_KEY+EVENT_BUTTON+EVENT_MOUSE_CHANGE); |
for(;;) |
{ |
switch(__menuet__wait_for_event()) |
{ |
case evReDraw: |
// gapp.shrinkwrap = 2; |
__menuet__window_redraw(1); |
__menuet__define_window(screen_max_x / 2 - 350-50+kos_random(50), |
screen_max_y / 2 - 300-50+kos_random(50), |
700, 600, 0x73000000, 0x800000FF, Title); |
__menuet__window_redraw(2); |
__menuet__get_process_table(&Form, PID_WHOAMI); |
if (Form.window_state > 2) continue; //fix rolled up |
Form.client_width++; //fix for Menuet kernel bug |
Form.client_height++; //fix for Menuet kernel bug |
DrawWindow(); |
break; |
case evKey: |
key = __menuet__getkey(); |
if (key_mode_enter_page_number) |
{ |
HandleNewPageNumber(key); |
break; |
} |
if (key==ASCII_KEY_ESC) DrawWindow(); //close help |
if (key==ASCII_KEY_PGDN) pdfapp_onkey(&gapp, ']'); |
if (key==ASCII_KEY_PGUP) pdfapp_onkey(&gapp, '['); |
if (key==ASCII_KEY_HOME) pdfapp_onkey(&gapp, 'g'); |
if (key==ASCII_KEY_END ) pdfapp_onkey(&gapp, 'G'); |
if (key=='g' ) pdfapp_onkey(&gapp, 'c'); |
if ((key=='[' ) || (key=='l')) PageRotateLeft(); |
if ((key==']' ) || (key=='r')) PageRotateRight(); |
if (key==ASCII_KEY_DOWN ) PageScrollDown(); |
if (key==ASCII_KEY_UP ) PageScrollUp(); |
if (key=='-') PageZoomOut(); |
if ((key=='=') || (key=='+')) PageZoomIn(); |
break; |
case evButton: |
butt = __menuet__get_button_id(); |
if(butt==1) __menuet__sys_exit(); |
if(butt==10) RunOpenApp(); |
if(butt==11) PageZoomOut(); //magnify - |
if(butt==12) PageZoomIn(); //magnify + |
if(butt==13) //show help |
{ |
kol_paint_bar(0, TOOLBAR_HEIGHT, Form.client_width, Form.client_height - TOOLBAR_HEIGHT, 0xF2F2F2); |
__menuet__write_text(20, TOOLBAR_HEIGHT + 20 , 0x90000000, "uPDF for KolibriOS v1.2", 0); |
__menuet__write_text(21, TOOLBAR_HEIGHT + 20 , 0x90000000, "uPDF for KolibriOS v1.2", 0); |
for (ii=0; help[ii]!=0; ii++) { |
__menuet__write_text(20, TOOLBAR_HEIGHT + 60 + ii * 15, 0x80000000, help[ii], 0); |
} |
} |
if(butt==14) pdfapp_onkey(&gapp, '['); //previous page |
if(butt==15) pdfapp_onkey(&gapp, ']'); //next page |
if(butt==16) PageRotateLeft(); |
if(butt==17) PageRotateRight(); |
if(butt==20) GetNewPageNumber(); |
break; |
case evMouse: |
if (mouse_wheels_state = __menuet__get_mouse_wheels()) |
{ |
if (mouse_wheels_state==1) { PageScrollDown(); PageScrollDown(); } |
if (mouse_wheels_state==-1) { PageScrollUp(); PageScrollUp(); } |
} |
//sprintf (debugstr, "mouse_wheels_state: %d \n", mouse_wheels_state); |
//kol_board_puts(debugstr); |
//pdfapp_onmouse(&gapp, int x, int y, int btn, int modifiers, int state) |
break; |
} |
} |
} |
void GetNewPageNumber(void) |
{ |
new_page_number = gapp.pageno; |
250,12 → 430,9 |
__menuet__write_text(show_area_x + show_area_w/2 - strlen(pages_display)*6/2, 14, 0x000000, pages_display, strlen(pages_display)); |
} |
void DrawToolbarButton(int x, char image_id) |
{ |
__menuet__make_button(x, 5, 26-1, 24-1, 10 + image_id + BT_HIDE, 0); |
__menuet__putimage(x, 5, 26, 24, image_id * 24 * 26 * 3 + toolbar_image); |
} |
void DrawWindow(void) |
{ |
kol_paint_bar(0, 0, Form.client_width, TOOLBAR_HEIGHT - 1, 0xe1e1e1); // bar on the top (buttons holder) |
276,7 → 453,13 |
DrawPageSides(); |
} |
void DrawToolbarButton(int x, char image_id) |
{ |
__menuet__make_button(x, 5, 26-1, 24-1, 10 + image_id + BT_HIDE, 0); |
__menuet__putimage(x, 5, 26, 24, image_id * 24 * 26 * 3 + toolbar_image); |
} |
/* Actions */ |
void PageScrollDown(void) |
353,113 → 536,3 |
DrawPageSides(); |
} |
int main (void) |
{ |
char ii, mouse_wheels_state; |
char* original_command_line = *(char**)0x1C; |
if (*original_command_line == 0) { |
kol_board_puts("uPDF: no param set, showing OpenDialog"); |
RunOpenApp(); |
__menuet__sys_exit(); |
} |
kol_board_puts(original_command_line); |
kol_board_puts("\n"); |
char buf[128]; |
int resolution = 72; |
int pageno = 1; |
fz_accelerate(); |
kol_board_puts("PDF init\n"); |
pdfapp_init(&gapp); |
gapp.scrw = 600; |
gapp.scrh = 400; |
gapp.resolution = resolution; |
gapp.pageno = pageno; |
kol_board_puts("PDF Open\n"); |
pdfapp_open(&gapp, original_command_line, 0, 0); |
kol_board_puts("PDF Opened\n"); |
wintitle(&gapp, 0); |
kol_board_puts("Inital paint\n"); |
int butt, key, screen_max_x, screen_max_y; |
__menuet__get_screen_max(&screen_max_x, &screen_max_y); |
__menuet__set_bitfield_for_wanted_events(EVENT_REDRAW+EVENT_KEY+EVENT_BUTTON+EVENT_MOUSE_CHANGE); |
for(;;) |
{ |
switch(__menuet__wait_for_event()) |
{ |
case evReDraw: |
// gapp.shrinkwrap = 2; |
__menuet__window_redraw(1); |
__menuet__define_window(screen_max_x / 2 - 350-50+kos_random(50), |
screen_max_y / 2 - 300-50+kos_random(50), |
700, 600, 0x73000000, 0x800000FF, Title); |
__menuet__window_redraw(2); |
__menuet__get_process_table(&Form, PID_WHOAMI); |
if (Form.window_state > 2) continue; //fix rolled up |
Form.client_width++; //fix for Menuet kernel bug |
Form.client_height++; //fix for Menuet kernel bug |
DrawWindow(); |
break; |
case evKey: |
key = __menuet__getkey(); |
if (key_mode_enter_page_number) |
{ |
HandleNewPageNumber(key); |
break; |
} |
if (key==ASCII_KEY_ESC) DrawWindow(); //close help |
if (key==ASCII_KEY_PGDN) pdfapp_onkey(&gapp, ']'); |
if (key==ASCII_KEY_PGUP) pdfapp_onkey(&gapp, '['); |
if (key==ASCII_KEY_HOME) pdfapp_onkey(&gapp, 'g'); |
if (key==ASCII_KEY_END ) pdfapp_onkey(&gapp, 'G'); |
if (key=='g' ) pdfapp_onkey(&gapp, 'c'); |
if ((key=='[' ) || (key=='l')) PageRotateLeft(); |
if ((key==']' ) || (key=='r')) PageRotateRight(); |
if (key==ASCII_KEY_DOWN ) PageScrollDown(); |
if (key==ASCII_KEY_UP ) PageScrollUp(); |
if (key=='-') PageZoomOut(); |
if ((key=='=') || (key=='+')) PageZoomIn(); |
break; |
case evButton: |
butt = __menuet__get_button_id(); |
if(butt==1) __menuet__sys_exit(); |
if(butt==10) RunOpenApp(); |
if(butt==11) PageZoomOut(); //magnify - |
if(butt==12) PageZoomIn(); //magnify + |
if(butt==13) //show help |
{ |
kol_paint_bar(0, TOOLBAR_HEIGHT, Form.client_width, Form.client_height - TOOLBAR_HEIGHT, 0xF2F2F2); |
__menuet__write_text(20, TOOLBAR_HEIGHT + 20 , 0x90000000, "uPDF for KolibriOS v1.2", 0); |
__menuet__write_text(21, TOOLBAR_HEIGHT + 20 , 0x90000000, "uPDF for KolibriOS v1.2", 0); |
for (ii=0; help[ii]!=0; ii++) { |
__menuet__write_text(20, TOOLBAR_HEIGHT + 60 + ii * 15, 0x80000000, help[ii], 0); |
} |
} |
if(butt==14) pdfapp_onkey(&gapp, '['); //previous page |
if(butt==15) pdfapp_onkey(&gapp, ']'); //next page |
if(butt==16) PageRotateLeft(); |
if(butt==17) PageRotateRight(); |
if(butt==20) GetNewPageNumber(); |
break; |
case evMouse: |
if (mouse_wheels_state = kos_get_mouse_wheels()) |
{ |
if (mouse_wheels_state==1) { PageScrollDown(); PageScrollDown(); } |
if (mouse_wheels_state==-1) { PageScrollUp(); PageScrollUp(); } |
} |
//sprintf (debugstr, "mouse_wheels_state: %d \n", mouse_wheels_state); |
//kol_board_puts(debugstr); |
//pdfapp_onmouse(&gapp, int x, int y, int btn, int modifiers, int state) |
break; |
} |
} |
} |
/contrib/media/updf/apps/kolibri.c |
---|
436,6 → 436,7 |
asm volatile ("int $0x40"::"a"(54), "b"(2), "c"(n), "d"(buffer)); |
} |
int kos_random(int num) |
{ |
srand(kol_time_tick()); |
442,44 → 443,3 |
return rand() % num; |
} |
int kos_get_mouse_wheels(void) |
{ |
int val; |
asm ("int $0x40":"=a"(val):"a"(37),"b"(7)); |
return val; |
}; |
struct blit_call |
{ |
int dstx; |
int dsty; |
int w; |
int h; |
int srcx; |
int srcy; |
int srcw; |
int srch; |
unsigned char *d; |
int stride; |
}; |
void kos_blit(int dstx, int dsty, int w, int h, int srcx, |
int srcy,int srcw, int srch, int stride, char *d) |
{ |
struct blit_call image; |
image.dstx=dstx; |
image.dsty=dsty; |
image.w=w; |
image.h=h; |
image.srcx=srcx; |
image.srcy=srcy; |
image.srcw=srcw; |
image.srch=srch; |
image.stride=stride; |
image.d=d; |
asm ("int $0x40"::"a"(73),"b"(0),"c"(&image)); |
} |
/contrib/media/updf/apps/kolibri.h |
---|
14,33 → 14,6 |
#define FILENAME_MAX 1024 |
#define BT_DEL 0x80000000 |
#define BT_HIDE 0x40000000 |
#define BT_NOFRAME 0x20000000 |
#define evReDraw 1 |
#define evKey 2 |
#define evButton 3 |
#define evMouse 6 |
#define evNetwork 8 |
#define ASCII_KEY_LEFT 176 |
#define ASCII_KEY_RIGHT 179 |
#define ASCII_KEY_DOWN 177 |
#define ASCII_KEY_UP 178 |
#define ASCII_KEY_HOME 180 |
#define ASCII_KEY_END 181 |
#define ASCII_KEY_PGDN 183 |
#define ASCII_KEY_PGUP 184 |
#define ASCII_KEY_BS 8 |
#define ASCII_KEY_TAB 9 |
#define ASCII_KEY_ENTER 13 |
#define ASCII_KEY_ESC 27 |
#define ASCII_KEY_DEL 182 |
#define ASCII_KEY_INS 185 |
#define ASCII_KEY_SPACE 032 |
#pragma pack(push,1) |
typedef struct |
{ |
/contrib/media/updf/apps/pdfclean.c |
---|
0,0 → 1,775 |
/* |
* PDF cleaning tool: general purpose pdf syntax washer. |
* |
* Rewrite PDF with pretty printed objects. |
* Garbage collect unreachable objects. |
* Inflate compressed streams. |
* Create subset documents. |
* |
* TODO: linearize document for fast web view |
*/ |
#include "fitz.h" |
#include "mupdf.h" |
static FILE *out = NULL; |
static char *uselist = NULL; |
static int *ofslist = NULL; |
static int *genlist = NULL; |
static int *renumbermap = NULL; |
static int dogarbage = 0; |
static int doexpand = 0; |
static int doascii = 0; |
static pdf_xref *xref = NULL; |
void die(fz_error error) |
{ |
fz_catch(error, "aborting"); |
if (xref) |
pdf_free_xref(xref); |
exit(1); |
} |
static void usage(void) |
{ |
fprintf(stderr, |
"usage: pdfclean [options] input.pdf [output.pdf] [pages]\n" |
"\t-p -\tpassword\n" |
"\t-g\tgarbage collect unused objects\n" |
"\t-gg\tin addition to -g compact xref table\n" |
"\t-ggg\tin addition to -gg merge duplicate objects\n" |
"\t-d\tdecompress streams\n" |
"\t-a\tascii hex encode binary streams\n" |
"\tpages\tcomma separated list of ranges\n"); |
exit(1); |
} |
/* |
* Garbage collect objects not reachable from the trailer. |
*/ |
static void sweepref(fz_obj *ref); |
static void sweepobj(fz_obj *obj) |
{ |
int i; |
if (fz_is_indirect(obj)) |
sweepref(obj); |
else if (fz_is_dict(obj)) |
for (i = 0; i < fz_dict_len(obj); i++) |
sweepobj(fz_dict_get_val(obj, i)); |
else if (fz_is_array(obj)) |
for (i = 0; i < fz_array_len(obj); i++) |
sweepobj(fz_array_get(obj, i)); |
} |
static void sweepref(fz_obj *obj) |
{ |
int num = fz_to_num(obj); |
int gen = fz_to_gen(obj); |
if (num < 0 || num >= xref->len) |
return; |
if (uselist[num]) |
return; |
uselist[num] = 1; |
/* Bake in /Length in stream objects */ |
if (pdf_is_stream(xref, num, gen)) |
{ |
fz_obj *len = fz_dict_gets(obj, "Length"); |
if (fz_is_indirect(len)) |
{ |
uselist[fz_to_num(len)] = 0; |
len = fz_resolve_indirect(len); |
fz_dict_puts(obj, "Length", len); |
} |
} |
sweepobj(fz_resolve_indirect(obj)); |
} |
/* |
* Scan for and remove duplicate objects (slow) |
*/ |
static void removeduplicateobjs(void) |
{ |
int num, other; |
for (num = 1; num < xref->len; num++) |
{ |
/* Only compare an object to objects preceeding it */ |
for (other = 1; other < num; other++) |
{ |
fz_obj *a, *b; |
if (num == other || !uselist[num] || !uselist[other]) |
continue; |
/* |
* Comparing stream objects data contents would take too long. |
* |
* pdf_is_stream calls pdf_cache_object and ensures |
* that the xref table has the objects loaded. |
*/ |
if (pdf_is_stream(xref, num, 0) || pdf_is_stream(xref, other, 0)) |
continue; |
a = xref->table[num].obj; |
b = xref->table[other].obj; |
a = fz_resolve_indirect(a); |
b = fz_resolve_indirect(b); |
if (fz_objcmp(a, b)) |
continue; |
/* Keep the lowest numbered object */ |
renumbermap[num] = MIN(num, other); |
renumbermap[other] = MIN(num, other); |
uselist[MAX(num, other)] = 0; |
/* One duplicate was found, do not look for another */ |
break; |
} |
} |
} |
/* |
* Renumber objects sequentially so the xref is more compact |
*/ |
static void compactxref(void) |
{ |
int num, newnum; |
/* |
* Update renumbermap in-place, clustering all used |
* objects together at low object ids. Objects that |
* already should be renumbered will have their new |
* object ids be updated to reflect the compaction. |
*/ |
newnum = 1; |
for (num = 1; num < xref->len; num++) |
{ |
if (uselist[num] && renumbermap[num] == num) |
renumbermap[num] = newnum++; |
else if (renumbermap[num] != num) |
renumbermap[num] = renumbermap[renumbermap[num]]; |
} |
} |
/* |
* Update indirect objects according to renumbering established when |
* removing duplicate objects and compacting the xref. |
*/ |
static void renumberobj(fz_obj *obj) |
{ |
int i; |
if (fz_is_dict(obj)) |
{ |
for (i = 0; i < fz_dict_len(obj); i++) |
{ |
fz_obj *key = fz_dict_get_key(obj, i); |
fz_obj *val = fz_dict_get_val(obj, i); |
if (fz_is_indirect(val)) |
{ |
val = fz_new_indirect(renumbermap[fz_to_num(val)], 0, xref); |
fz_dict_put(obj, key, val); |
fz_drop_obj(val); |
} |
else |
{ |
renumberobj(val); |
} |
} |
} |
else if (fz_is_array(obj)) |
{ |
for (i = 0; i < fz_array_len(obj); i++) |
{ |
fz_obj *val = fz_array_get(obj, i); |
if (fz_is_indirect(val)) |
{ |
val = fz_new_indirect(renumbermap[fz_to_num(val)], 0, xref); |
fz_array_put(obj, i, val); |
fz_drop_obj(val); |
} |
else |
{ |
renumberobj(val); |
} |
} |
} |
} |
static void renumberobjs(void) |
{ |
pdf_xref_entry *oldxref; |
int newlen; |
int num; |
/* Apply renumber map to indirect references in all objects in xref */ |
renumberobj(xref->trailer); |
for (num = 0; num < xref->len; num++) |
{ |
fz_obj *obj = xref->table[num].obj; |
if (fz_is_indirect(obj)) |
{ |
obj = fz_new_indirect(renumbermap[fz_to_num(obj)], 0, xref); |
pdf_update_object(xref, num, 0, obj); |
fz_drop_obj(obj); |
} |
else |
{ |
renumberobj(obj); |
} |
} |
/* Create new table for the reordered, compacted xref */ |
oldxref = xref->table; |
xref->table = fz_calloc(xref->len, sizeof(pdf_xref_entry)); |
xref->table[0] = oldxref[0]; |
/* Move used objects into the new compacted xref */ |
newlen = 0; |
for (num = 1; num < xref->len; num++) |
{ |
if (uselist[num]) |
{ |
if (newlen < renumbermap[num]) |
newlen = renumbermap[num]; |
xref->table[renumbermap[num]] = oldxref[num]; |
} |
else |
{ |
if (oldxref[num].obj) |
fz_drop_obj(oldxref[num].obj); |
} |
} |
fz_free(oldxref); |
/* Update the used objects count in compacted xref */ |
xref->len = newlen + 1; |
/* Update list of used objects to fit with compacted xref */ |
for (num = 1; num < xref->len; num++) |
uselist[num] = 1; |
} |
/* |
* Recreate page tree to only retain specified pages. |
*/ |
static void retainpages(int argc, char **argv) |
{ |
fz_error error; |
fz_obj *oldroot, *root, *pages, *kids, *countobj, *parent; |
/* Load the old page tree */ |
error = pdf_load_page_tree(xref); |
if (error) |
die(fz_rethrow(error, "cannot load page tree")); |
/* Keep only pages/type entry to avoid references to unretained pages */ |
oldroot = fz_dict_gets(xref->trailer, "Root"); |
pages = fz_dict_gets(oldroot, "Pages"); |
root = fz_new_dict(2); |
fz_dict_puts(root, "Type", fz_dict_gets(oldroot, "Type")); |
fz_dict_puts(root, "Pages", fz_dict_gets(oldroot, "Pages")); |
pdf_update_object(xref, fz_to_num(oldroot), fz_to_gen(oldroot), root); |
fz_drop_obj(root); |
/* Create a new kids array with only the pages we want to keep */ |
parent = fz_new_indirect(fz_to_num(pages), fz_to_gen(pages), xref); |
kids = fz_new_array(1); |
/* Retain pages specified */ |
while (argc - fz_optind) |
{ |
int page, spage, epage; |
char *spec, *dash; |
char *pagelist = argv[fz_optind]; |
spec = fz_strsep(&pagelist, ","); |
while (spec) |
{ |
dash = strchr(spec, '-'); |
if (dash == spec) |
spage = epage = pdf_count_pages(xref); |
else |
spage = epage = atoi(spec); |
if (dash) |
{ |
if (strlen(dash) > 1) |
epage = atoi(dash + 1); |
else |
epage = pdf_count_pages(xref); |
} |
if (spage > epage) |
page = spage, spage = epage, epage = page; |
if (spage < 1) |
spage = 1; |
if (epage > pdf_count_pages(xref)) |
epage = pdf_count_pages(xref); |
for (page = spage; page <= epage; page++) |
{ |
fz_obj *pageobj = xref->page_objs[page-1]; |
fz_obj *pageref = xref->page_refs[page-1]; |
fz_dict_puts(pageobj, "Parent", parent); |
/* Store page object in new kids array */ |
fz_array_push(kids, pageref); |
} |
spec = fz_strsep(&pagelist, ","); |
} |
fz_optind++; |
} |
fz_drop_obj(parent); |
/* Update page count and kids array */ |
countobj = fz_new_int(fz_array_len(kids)); |
fz_dict_puts(pages, "Count", countobj); |
fz_drop_obj(countobj); |
fz_dict_puts(pages, "Kids", kids); |
fz_drop_obj(kids); |
} |
/* |
* Make sure we have loaded objects from object streams. |
*/ |
static void preloadobjstms(void) |
{ |
fz_error error; |
fz_obj *obj; |
int num; |
for (num = 0; num < xref->len; num++) |
{ |
if (xref->table[num].type == 'o') |
{ |
error = pdf_load_object(&obj, xref, num, 0); |
if (error) |
die(error); |
fz_drop_obj(obj); |
} |
} |
} |
/* |
* Save streams and objects to the output |
*/ |
static inline int isbinary(int c) |
{ |
if (c == '\n' || c == '\r' || c == '\t') |
return 0; |
return c < 32 || c > 127; |
} |
static int isbinarystream(fz_buffer *buf) |
{ |
int i; |
for (i = 0; i < buf->len; i++) |
if (isbinary(buf->data[i])) |
return 1; |
return 0; |
} |
static fz_buffer *hexbuf(unsigned char *p, int n) |
{ |
static const char hex[16] = "0123456789abcdef"; |
fz_buffer *buf; |
int x = 0; |
buf = fz_new_buffer(n * 2 + (n / 32) + 2); |
while (n--) |
{ |
buf->data[buf->len++] = hex[*p >> 4]; |
buf->data[buf->len++] = hex[*p & 15]; |
if (++x == 32) |
{ |
buf->data[buf->len++] = '\n'; |
x = 0; |
} |
p++; |
} |
buf->data[buf->len++] = '>'; |
buf->data[buf->len++] = '\n'; |
return buf; |
} |
static void addhexfilter(fz_obj *dict) |
{ |
fz_obj *f, *dp, *newf, *newdp; |
fz_obj *ahx, *nullobj; |
ahx = fz_new_name("ASCIIHexDecode"); |
nullobj = fz_new_null(); |
newf = newdp = NULL; |
f = fz_dict_gets(dict, "Filter"); |
dp = fz_dict_gets(dict, "DecodeParms"); |
if (fz_is_name(f)) |
{ |
newf = fz_new_array(2); |
fz_array_push(newf, ahx); |
fz_array_push(newf, f); |
f = newf; |
if (fz_is_dict(dp)) |
{ |
newdp = fz_new_array(2); |
fz_array_push(newdp, nullobj); |
fz_array_push(newdp, dp); |
dp = newdp; |
} |
} |
else if (fz_is_array(f)) |
{ |
fz_array_insert(f, ahx); |
if (fz_is_array(dp)) |
fz_array_insert(dp, nullobj); |
} |
else |
f = ahx; |
fz_dict_puts(dict, "Filter", f); |
if (dp) |
fz_dict_puts(dict, "DecodeParms", dp); |
fz_drop_obj(ahx); |
fz_drop_obj(nullobj); |
if (newf) |
fz_drop_obj(newf); |
if (newdp) |
fz_drop_obj(newdp); |
} |
static void copystream(fz_obj *obj, int num, int gen) |
{ |
fz_error error; |
fz_buffer *buf, *tmp; |
fz_obj *newlen; |
error = pdf_load_raw_stream(&buf, xref, num, gen); |
if (error) |
die(error); |
if (doascii && isbinarystream(buf)) |
{ |
tmp = hexbuf(buf->data, buf->len); |
fz_drop_buffer(buf); |
buf = tmp; |
addhexfilter(obj); |
newlen = fz_new_int(buf->len); |
fz_dict_puts(obj, "Length", newlen); |
fz_drop_obj(newlen); |
} |
fprintf(out, "%d %d obj\n", num, gen); |
fz_fprint_obj(out, obj, !doexpand); |
fprintf(out, "stream\n"); |
fwrite(buf->data, 1, buf->len, out); |
fprintf(out, "endstream\nendobj\n\n"); |
fz_drop_buffer(buf); |
} |
static void expandstream(fz_obj *obj, int num, int gen) |
{ |
fz_error error; |
fz_buffer *buf, *tmp; |
fz_obj *newlen; |
error = pdf_load_stream(&buf, xref, num, gen); |
if (error) |
die(error); |
fz_dict_dels(obj, "Filter"); |
fz_dict_dels(obj, "DecodeParms"); |
if (doascii && isbinarystream(buf)) |
{ |
tmp = hexbuf(buf->data, buf->len); |
fz_drop_buffer(buf); |
buf = tmp; |
addhexfilter(obj); |
} |
newlen = fz_new_int(buf->len); |
fz_dict_puts(obj, "Length", newlen); |
fz_drop_obj(newlen); |
fprintf(out, "%d %d obj\n", num, gen); |
fz_fprint_obj(out, obj, !doexpand); |
fprintf(out, "stream\n"); |
fwrite(buf->data, 1, buf->len, out); |
fprintf(out, "endstream\nendobj\n\n"); |
fz_drop_buffer(buf); |
} |
static void writeobject(int num, int gen) |
{ |
fz_error error; |
fz_obj *obj; |
fz_obj *type; |
error = pdf_load_object(&obj, xref, num, gen); |
if (error) |
die(error); |
/* skip ObjStm and XRef objects */ |
if (fz_is_dict(obj)) |
{ |
type = fz_dict_gets(obj, "Type"); |
if (fz_is_name(type) && !strcmp(fz_to_name(type), "ObjStm")) |
{ |
uselist[num] = 0; |
fz_drop_obj(obj); |
return; |
} |
if (fz_is_name(type) && !strcmp(fz_to_name(type), "XRef")) |
{ |
uselist[num] = 0; |
fz_drop_obj(obj); |
return; |
} |
} |
if (!pdf_is_stream(xref, num, gen)) |
{ |
fprintf(out, "%d %d obj\n", num, gen); |
fz_fprint_obj(out, obj, !doexpand); |
fprintf(out, "endobj\n\n"); |
} |
else |
{ |
if (doexpand && !pdf_is_jpx_image(obj)) |
expandstream(obj, num, gen); |
else |
copystream(obj, num, gen); |
} |
fz_drop_obj(obj); |
} |
static void writexref(void) |
{ |
fz_obj *trailer; |
fz_obj *obj; |
int startxref; |
int num; |
startxref = ftell(out); |
fprintf(out, "xref\n0 %d\n", xref->len); |
for (num = 0; num < xref->len; num++) |
{ |
if (uselist[num]) |
fprintf(out, "%010d %05d n \n", ofslist[num], genlist[num]); |
else |
fprintf(out, "%010d %05d f \n", ofslist[num], genlist[num]); |
} |
fprintf(out, "\n"); |
trailer = fz_new_dict(5); |
obj = fz_new_int(xref->len); |
fz_dict_puts(trailer, "Size", obj); |
fz_drop_obj(obj); |
obj = fz_dict_gets(xref->trailer, "Info"); |
if (obj) |
fz_dict_puts(trailer, "Info", obj); |
obj = fz_dict_gets(xref->trailer, "Root"); |
if (obj) |
fz_dict_puts(trailer, "Root", obj); |
obj = fz_dict_gets(xref->trailer, "ID"); |
if (obj) |
fz_dict_puts(trailer, "ID", obj); |
fprintf(out, "trailer\n"); |
fz_fprint_obj(out, trailer, !doexpand); |
fprintf(out, "\n"); |
fz_drop_obj(trailer); |
fprintf(out, "startxref\n%d\n%%%%EOF\n", startxref); |
} |
static void writepdf(void) |
{ |
int lastfree; |
int num; |
for (num = 0; num < xref->len; num++) |
{ |
if (xref->table[num].type == 'f') |
genlist[num] = xref->table[num].gen; |
if (xref->table[num].type == 'n') |
genlist[num] = xref->table[num].gen; |
if (xref->table[num].type == 'o') |
genlist[num] = 0; |
if (dogarbage && !uselist[num]) |
continue; |
if (xref->table[num].type == 'n' || xref->table[num].type == 'o') |
{ |
uselist[num] = 1; |
ofslist[num] = ftell(out); |
writeobject(num, genlist[num]); |
} |
} |
/* Construct linked list of free object slots */ |
lastfree = 0; |
for (num = 0; num < xref->len; num++) |
{ |
if (!uselist[num]) |
{ |
genlist[num]++; |
ofslist[lastfree] = num; |
lastfree = num; |
} |
} |
writexref(); |
} |
int main(int argc, char **argv) |
{ |
fz_error error; |
char *infile; |
char *outfile = "out.pdf"; |
char *password = ""; |
int c, num; |
int subset; |
while ((c = fz_getopt(argc, argv, "adgp:")) != -1) |
{ |
switch (c) |
{ |
case 'p': password = fz_optarg; break; |
case 'g': dogarbage ++; break; |
case 'd': doexpand ++; break; |
case 'a': doascii ++; break; |
default: usage(); break; |
} |
} |
if (argc - fz_optind < 1) |
usage(); |
infile = argv[fz_optind++]; |
if (argc - fz_optind > 0 && |
(strstr(argv[fz_optind], ".pdf") || strstr(argv[fz_optind], ".PDF"))) |
{ |
outfile = argv[fz_optind++]; |
} |
subset = 0; |
if (argc - fz_optind > 0) |
subset = 1; |
error = pdf_open_xref(&xref, infile, password); |
if (error) |
die(fz_rethrow(error, "cannot open input file '%s'", infile)); |
out = fopen(outfile, "wb"); |
if (!out) |
die(fz_throw("cannot open output file '%s'", outfile)); |
fprintf(out, "%%PDF-%d.%d\n", xref->version / 10, xref->version % 10); |
fprintf(out, "%%\316\274\341\277\246\n\n"); |
uselist = fz_calloc(xref->len + 1, sizeof(char)); |
ofslist = fz_calloc(xref->len + 1, sizeof(int)); |
genlist = fz_calloc(xref->len + 1, sizeof(int)); |
renumbermap = fz_calloc(xref->len + 1, sizeof(int)); |
for (num = 0; num < xref->len; num++) |
{ |
uselist[num] = 0; |
ofslist[num] = 0; |
genlist[num] = 0; |
renumbermap[num] = num; |
} |
/* Make sure any objects hidden in compressed streams have been loaded */ |
preloadobjstms(); |
/* Only retain the specified subset of the pages */ |
if (subset) |
retainpages(argc, argv); |
/* Sweep & mark objects from the trailer */ |
if (dogarbage >= 1) |
sweepobj(xref->trailer); |
/* Coalesce and renumber duplicate objects */ |
if (dogarbage >= 3) |
removeduplicateobjs(); |
/* Compact xref by renumbering and removing unused objects */ |
if (dogarbage >= 2) |
compactxref(); |
/* Make renumbering affect all indirect references and update xref */ |
if (dogarbage >= 2) |
renumberobjs(); |
writepdf(); |
if (fclose(out)) |
die(fz_throw("cannot close output file '%s'", outfile)); |
fz_free(uselist); |
fz_free(ofslist); |
fz_free(genlist); |
fz_free(renumbermap); |
pdf_free_xref(xref); |
fz_flush_warnings(); |
return 0; |
} |
/contrib/media/updf/apps/pdfinfo.c |
---|
0,0 → 1,1011 |
/* |
* Information tool. |
* Print information about the input pdf. |
*/ |
#include "fitz.h" |
#include "mupdf.h" |
pdf_xref *xref; |
int pagecount; |
void closexref(void); |
void die(fz_error error) |
{ |
fz_catch(error, "aborting"); |
closexref(); |
exit(1); |
} |
void openxref(char *filename, char *password, int dieonbadpass, int loadpages); |
enum |
{ |
DIMENSIONS = 0x01, |
FONTS = 0x02, |
IMAGES = 0x04, |
SHADINGS = 0x08, |
PATTERNS = 0x10, |
XOBJS = 0x20, |
ALL = DIMENSIONS | FONTS | IMAGES | SHADINGS | PATTERNS | XOBJS |
}; |
struct info |
{ |
int page; |
fz_obj *pageref; |
fz_obj *pageobj; |
union { |
struct { |
fz_obj *obj; |
} info; |
struct { |
fz_obj *obj; |
} crypt; |
struct { |
fz_obj *obj; |
fz_rect *bbox; |
} dim; |
struct { |
fz_obj *obj; |
fz_obj *subtype; |
fz_obj *name; |
} font; |
struct { |
fz_obj *obj; |
fz_obj *width; |
fz_obj *height; |
fz_obj *bpc; |
fz_obj *filter; |
fz_obj *cs; |
fz_obj *altcs; |
} image; |
struct { |
fz_obj *obj; |
fz_obj *type; |
} shading; |
struct { |
fz_obj *obj; |
fz_obj *type; |
fz_obj *paint; |
fz_obj *tiling; |
fz_obj *shading; |
} pattern; |
struct { |
fz_obj *obj; |
fz_obj *groupsubtype; |
fz_obj *reference; |
} form; |
} u; |
}; |
static struct info *dim = NULL; |
static int dims = 0; |
static struct info *font = NULL; |
static int fonts = 0; |
static struct info *image = NULL; |
static int images = 0; |
static struct info *shading = NULL; |
static int shadings = 0; |
static struct info *pattern = NULL; |
static int patterns = 0; |
static struct info *form = NULL; |
static int forms = 0; |
static struct info *psobj = NULL; |
static int psobjs = 0; |
void closexref(void) |
{ |
int i; |
if (xref) |
{ |
pdf_free_xref(xref); |
xref = NULL; |
} |
if (dim) |
{ |
for (i = 0; i < dims; i++) |
fz_free(dim[i].u.dim.bbox); |
fz_free(dim); |
dim = NULL; |
dims = 0; |
} |
if (font) |
{ |
fz_free(font); |
font = NULL; |
fonts = 0; |
} |
if (image) |
{ |
fz_free(image); |
image = NULL; |
images = 0; |
} |
if (shading) |
{ |
fz_free(shading); |
shading = NULL; |
shadings = 0; |
} |
if (pattern) |
{ |
fz_free(pattern); |
pattern = NULL; |
patterns = 0; |
} |
if (form) |
{ |
fz_free(form); |
form = NULL; |
forms = 0; |
} |
if (psobj) |
{ |
fz_free(psobj); |
psobj = NULL; |
psobjs = 0; |
} |
if (xref && xref->store) |
{ |
pdf_free_store(xref->store); |
xref->store = NULL; |
} |
} |
static void |
infousage(void) |
{ |
fprintf(stderr, |
"usage: pdfinfo [options] [file.pdf ... ]\n" |
"\t-d -\tpassword for decryption\n" |
"\t-f\tlist fonts\n" |
"\t-i\tlist images\n" |
"\t-m\tlist dimensions\n" |
"\t-p\tlist patterns\n" |
"\t-s\tlist shadings\n" |
"\t-x\tlist form and postscript xobjects\n"); |
exit(1); |
} |
static void |
showglobalinfo(void) |
{ |
fz_obj *obj; |
printf("\nPDF-%d.%d\n", xref->version / 10, xref->version % 10); |
obj = fz_dict_gets(xref->trailer, "Info"); |
if (obj) |
{ |
printf("Info object (%d %d R):\n", fz_to_num(obj), fz_to_gen(obj)); |
fz_debug_obj(fz_resolve_indirect(obj)); |
} |
obj = fz_dict_gets(xref->trailer, "Encrypt"); |
if (obj) |
{ |
printf("\nEncryption object (%d %d R):\n", fz_to_num(obj), fz_to_gen(obj)); |
fz_debug_obj(fz_resolve_indirect(obj)); |
} |
printf("\nPages: %d\n\n", pagecount); |
} |
static void |
gatherdimensions(int page, fz_obj *pageref, fz_obj *pageobj) |
{ |
fz_rect bbox; |
fz_obj *obj; |
int j; |
obj = fz_dict_gets(pageobj, "MediaBox"); |
if (!fz_is_array(obj)) |
return; |
bbox = pdf_to_rect(obj); |
for (j = 0; j < dims; j++) |
if (!memcmp(dim[j].u.dim.bbox, &bbox, sizeof (fz_rect))) |
break; |
if (j < dims) |
return; |
dims++; |
dim = fz_realloc(dim, dims, sizeof(struct info)); |
dim[dims - 1].page = page; |
dim[dims - 1].pageref = pageref; |
dim[dims - 1].pageobj = pageobj; |
dim[dims - 1].u.dim.bbox = fz_malloc(sizeof(fz_rect)); |
memcpy(dim[dims - 1].u.dim.bbox, &bbox, sizeof (fz_rect)); |
return; |
} |
static void |
gatherfonts(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict) |
{ |
int i; |
for (i = 0; i < fz_dict_len(dict); i++) |
{ |
fz_obj *fontdict = NULL; |
fz_obj *subtype = NULL; |
fz_obj *basefont = NULL; |
fz_obj *name = NULL; |
int k; |
fontdict = fz_dict_get_val(dict, i); |
if (!fz_is_dict(fontdict)) |
{ |
fz_warn("not a font dict (%d %d R)", fz_to_num(fontdict), fz_to_gen(fontdict)); |
continue; |
} |
subtype = fz_dict_gets(fontdict, "Subtype"); |
basefont = fz_dict_gets(fontdict, "BaseFont"); |
if (!basefont || fz_is_null(basefont)) |
name = fz_dict_gets(fontdict, "Name"); |
for (k = 0; k < fonts; k++) |
if (!fz_objcmp(font[k].u.font.obj, fontdict)) |
break; |
if (k < fonts) |
continue; |
fonts++; |
font = fz_realloc(font, fonts, sizeof(struct info)); |
font[fonts - 1].page = page; |
font[fonts - 1].pageref = pageref; |
font[fonts - 1].pageobj = pageobj; |
font[fonts - 1].u.font.obj = fontdict; |
font[fonts - 1].u.font.subtype = subtype; |
font[fonts - 1].u.font.name = basefont ? basefont : name; |
} |
} |
static void |
gatherimages(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict) |
{ |
int i; |
for (i = 0; i < fz_dict_len(dict); i++) |
{ |
fz_obj *imagedict; |
fz_obj *type; |
fz_obj *width; |
fz_obj *height; |
fz_obj *bpc = NULL; |
fz_obj *filter = NULL; |
fz_obj *cs = NULL; |
fz_obj *altcs; |
int k; |
imagedict = fz_dict_get_val(dict, i); |
if (!fz_is_dict(imagedict)) |
{ |
fz_warn("not an image dict (%d %d R)", fz_to_num(imagedict), fz_to_gen(imagedict)); |
continue; |
} |
type = fz_dict_gets(imagedict, "Subtype"); |
if (strcmp(fz_to_name(type), "Image")) |
continue; |
filter = fz_dict_gets(imagedict, "Filter"); |
altcs = NULL; |
cs = fz_dict_gets(imagedict, "ColorSpace"); |
if (fz_is_array(cs)) |
{ |
fz_obj *cses = cs; |
cs = fz_array_get(cses, 0); |
if (fz_is_name(cs) && (!strcmp(fz_to_name(cs), "DeviceN") || !strcmp(fz_to_name(cs), "Separation"))) |
{ |
altcs = fz_array_get(cses, 2); |
if (fz_is_array(altcs)) |
altcs = fz_array_get(altcs, 0); |
} |
} |
width = fz_dict_gets(imagedict, "Width"); |
height = fz_dict_gets(imagedict, "Height"); |
bpc = fz_dict_gets(imagedict, "BitsPerComponent"); |
for (k = 0; k < images; k++) |
if (!fz_objcmp(image[k].u.image.obj, imagedict)) |
break; |
if (k < images) |
continue; |
images++; |
image = fz_realloc(image, images, sizeof(struct info)); |
image[images - 1].page = page; |
image[images - 1].pageref = pageref; |
image[images - 1].pageobj = pageobj; |
image[images - 1].u.image.obj = imagedict; |
image[images - 1].u.image.width = width; |
image[images - 1].u.image.height = height; |
image[images - 1].u.image.bpc = bpc; |
image[images - 1].u.image.filter = filter; |
image[images - 1].u.image.cs = cs; |
image[images - 1].u.image.altcs = altcs; |
} |
} |
static void |
gatherforms(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict) |
{ |
int i; |
for (i = 0; i < fz_dict_len(dict); i++) |
{ |
fz_obj *xobjdict; |
fz_obj *type; |
fz_obj *subtype; |
fz_obj *group; |
fz_obj *groupsubtype; |
fz_obj *reference; |
int k; |
xobjdict = fz_dict_get_val(dict, i); |
if (!fz_is_dict(xobjdict)) |
{ |
fz_warn("not a xobject dict (%d %d R)", fz_to_num(xobjdict), fz_to_gen(xobjdict)); |
continue; |
} |
type = fz_dict_gets(xobjdict, "Subtype"); |
if (strcmp(fz_to_name(type), "Form")) |
continue; |
subtype = fz_dict_gets(xobjdict, "Subtype2"); |
if (!strcmp(fz_to_name(subtype), "PS")) |
continue; |
group = fz_dict_gets(xobjdict, "Group"); |
groupsubtype = fz_dict_gets(group, "S"); |
reference = fz_dict_gets(xobjdict, "Ref"); |
for (k = 0; k < forms; k++) |
if (!fz_objcmp(form[k].u.form.obj, xobjdict)) |
break; |
if (k < forms) |
continue; |
forms++; |
form = fz_realloc(form, forms, sizeof(struct info)); |
form[forms - 1].page = page; |
form[forms - 1].pageref = pageref; |
form[forms - 1].pageobj = pageobj; |
form[forms - 1].u.form.obj = xobjdict; |
form[forms - 1].u.form.groupsubtype = groupsubtype; |
form[forms - 1].u.form.reference = reference; |
} |
} |
static void |
gatherpsobjs(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict) |
{ |
int i; |
for (i = 0; i < fz_dict_len(dict); i++) |
{ |
fz_obj *xobjdict; |
fz_obj *type; |
fz_obj *subtype; |
int k; |
xobjdict = fz_dict_get_val(dict, i); |
if (!fz_is_dict(xobjdict)) |
{ |
fz_warn("not a xobject dict (%d %d R)", fz_to_num(xobjdict), fz_to_gen(xobjdict)); |
continue; |
} |
type = fz_dict_gets(xobjdict, "Subtype"); |
subtype = fz_dict_gets(xobjdict, "Subtype2"); |
if (strcmp(fz_to_name(type), "PS") && |
(strcmp(fz_to_name(type), "Form") || strcmp(fz_to_name(subtype), "PS"))) |
continue; |
for (k = 0; k < psobjs; k++) |
if (!fz_objcmp(psobj[k].u.form.obj, xobjdict)) |
break; |
if (k < psobjs) |
continue; |
psobjs++; |
psobj = fz_realloc(psobj, psobjs, sizeof(struct info)); |
psobj[psobjs - 1].page = page; |
psobj[psobjs - 1].pageref = pageref; |
psobj[psobjs - 1].pageobj = pageobj; |
psobj[psobjs - 1].u.form.obj = xobjdict; |
} |
} |
static void |
gathershadings(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict) |
{ |
int i; |
for (i = 0; i < fz_dict_len(dict); i++) |
{ |
fz_obj *shade; |
fz_obj *type; |
int k; |
shade = fz_dict_get_val(dict, i); |
if (!fz_is_dict(shade)) |
{ |
fz_warn("not a shading dict (%d %d R)", fz_to_num(shade), fz_to_gen(shade)); |
continue; |
} |
type = fz_dict_gets(shade, "ShadingType"); |
if (!fz_is_int(type) || fz_to_int(type) < 1 || fz_to_int(type) > 7) |
{ |
fz_warn("not a shading type (%d %d R)", fz_to_num(shade), fz_to_gen(shade)); |
type = NULL; |
} |
for (k = 0; k < shadings; k++) |
if (!fz_objcmp(shading[k].u.shading.obj, shade)) |
break; |
if (k < shadings) |
continue; |
shadings++; |
shading = fz_realloc(shading, shadings, sizeof(struct info)); |
shading[shadings - 1].page = page; |
shading[shadings - 1].pageref = pageref; |
shading[shadings - 1].pageobj = pageobj; |
shading[shadings - 1].u.shading.obj = shade; |
shading[shadings - 1].u.shading.type = type; |
} |
} |
static void |
gatherpatterns(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict) |
{ |
int i; |
for (i = 0; i < fz_dict_len(dict); i++) |
{ |
fz_obj *patterndict; |
fz_obj *type; |
fz_obj *paint = NULL; |
fz_obj *tiling = NULL; |
fz_obj *shading = NULL; |
int k; |
patterndict = fz_dict_get_val(dict, i); |
if (!fz_is_dict(patterndict)) |
{ |
fz_warn("not a pattern dict (%d %d R)", fz_to_num(patterndict), fz_to_gen(patterndict)); |
continue; |
} |
type = fz_dict_gets(patterndict, "PatternType"); |
if (!fz_is_int(type) || fz_to_int(type) < 1 || fz_to_int(type) > 2) |
{ |
fz_warn("not a pattern type (%d %d R)", fz_to_num(patterndict), fz_to_gen(patterndict)); |
type = NULL; |
} |
if (fz_to_int(type) == 1) |
{ |
paint = fz_dict_gets(patterndict, "PaintType"); |
if (!fz_is_int(paint) || fz_to_int(paint) < 1 || fz_to_int(paint) > 2) |
{ |
fz_warn("not a pattern paint type (%d %d R)", fz_to_num(patterndict), fz_to_gen(patterndict)); |
paint = NULL; |
} |
tiling = fz_dict_gets(patterndict, "TilingType"); |
if (!fz_is_int(tiling) || fz_to_int(tiling) < 1 || fz_to_int(tiling) > 3) |
{ |
fz_warn("not a pattern tiling type (%d %d R)", fz_to_num(patterndict), fz_to_gen(patterndict)); |
tiling = NULL; |
} |
} |
else |
{ |
shading = fz_dict_gets(patterndict, "Shading"); |
} |
for (k = 0; k < patterns; k++) |
if (!fz_objcmp(pattern[k].u.pattern.obj, patterndict)) |
break; |
if (k < patterns) |
continue; |
patterns++; |
pattern = fz_realloc(pattern, patterns, sizeof(struct info)); |
pattern[patterns - 1].page = page; |
pattern[patterns - 1].pageref = pageref; |
pattern[patterns - 1].pageobj = pageobj; |
pattern[patterns - 1].u.pattern.obj = patterndict; |
pattern[patterns - 1].u.pattern.type = type; |
pattern[patterns - 1].u.pattern.paint = paint; |
pattern[patterns - 1].u.pattern.tiling = tiling; |
pattern[patterns - 1].u.pattern.shading = shading; |
} |
} |
static void |
gatherresourceinfo(int page, fz_obj *rsrc) |
{ |
fz_obj *pageobj; |
fz_obj *pageref; |
fz_obj *font; |
fz_obj *xobj; |
fz_obj *shade; |
fz_obj *pattern; |
fz_obj *subrsrc; |
int i; |
pageobj = xref->page_objs[page-1]; |
pageref = xref->page_refs[page-1]; |
if (!pageobj) |
die(fz_throw("cannot retrieve info from page %d", page)); |
font = fz_dict_gets(rsrc, "Font"); |
if (font) |
{ |
gatherfonts(page, pageref, pageobj, font); |
for (i = 0; i < fz_dict_len(font); i++) |
{ |
fz_obj *obj = fz_dict_get_val(font, i); |
subrsrc = fz_dict_gets(obj, "Resources"); |
if (subrsrc && fz_objcmp(rsrc, subrsrc)) |
gatherresourceinfo(page, subrsrc); |
} |
} |
xobj = fz_dict_gets(rsrc, "XObject"); |
if (xobj) |
{ |
gatherimages(page, pageref, pageobj, xobj); |
gatherforms(page, pageref, pageobj, xobj); |
gatherpsobjs(page, pageref, pageobj, xobj); |
for (i = 0; i < fz_dict_len(xobj); i++) |
{ |
fz_obj *obj = fz_dict_get_val(xobj, i); |
subrsrc = fz_dict_gets(obj, "Resources"); |
if (subrsrc && fz_objcmp(rsrc, subrsrc)) |
gatherresourceinfo(page, subrsrc); |
} |
} |
shade = fz_dict_gets(rsrc, "Shading"); |
if (shade) |
gathershadings(page, pageref, pageobj, shade); |
pattern = fz_dict_gets(rsrc, "Pattern"); |
if (pattern) |
{ |
gatherpatterns(page, pageref, pageobj, pattern); |
for (i = 0; i < fz_dict_len(pattern); i++) |
{ |
fz_obj *obj = fz_dict_get_val(pattern, i); |
subrsrc = fz_dict_gets(obj, "Resources"); |
if (subrsrc && fz_objcmp(rsrc, subrsrc)) |
gatherresourceinfo(page, subrsrc); |
} |
} |
} |
static void |
gatherpageinfo(int page) |
{ |
fz_obj *pageobj; |
fz_obj *pageref; |
fz_obj *rsrc; |
pageobj = xref->page_objs[page-1]; |
pageref = xref->page_refs[page-1]; |
if (!pageobj) |
die(fz_throw("cannot retrieve info from page %d", page)); |
gatherdimensions(page, pageref, pageobj); |
rsrc = fz_dict_gets(pageobj, "Resources"); |
gatherresourceinfo(page, rsrc); |
} |
static void |
printinfo(char *filename, int show, int page) |
{ |
int i; |
int j; |
#define PAGE_FMT "\t% 5d (% 7d %1d R): " |
if (show & DIMENSIONS && dims > 0) |
{ |
printf("Mediaboxes (%d):\n", dims); |
for (i = 0; i < dims; i++) |
{ |
printf(PAGE_FMT "[ %g %g %g %g ]\n", |
dim[i].page, |
fz_to_num(dim[i].pageref), fz_to_gen(dim[i].pageref), |
dim[i].u.dim.bbox->x0, |
dim[i].u.dim.bbox->y0, |
dim[i].u.dim.bbox->x1, |
dim[i].u.dim.bbox->y1); |
} |
printf("\n"); |
} |
if (show & FONTS && fonts > 0) |
{ |
printf("Fonts (%d):\n", fonts); |
for (i = 0; i < fonts; i++) |
{ |
printf(PAGE_FMT "%s '%s' (%d %d R)\n", |
font[i].page, |
fz_to_num(font[i].pageref), fz_to_gen(font[i].pageref), |
fz_to_name(font[i].u.font.subtype), |
fz_to_name(font[i].u.font.name), |
fz_to_num(font[i].u.font.obj), fz_to_gen(font[i].u.font.obj)); |
} |
printf("\n"); |
} |
if (show & IMAGES && images > 0) |
{ |
printf("Images (%d):\n", images); |
for (i = 0; i < images; i++) |
{ |
char *cs = NULL; |
char *altcs = NULL; |
printf(PAGE_FMT "[ ", |
image[i].page, |
fz_to_num(image[i].pageref), fz_to_gen(image[i].pageref)); |
if (fz_is_array(image[i].u.image.filter)) |
for (j = 0; j < fz_array_len(image[i].u.image.filter); j++) |
{ |
fz_obj *obj = fz_array_get(image[i].u.image.filter, j); |
char *filter = fz_strdup(fz_to_name(obj)); |
if (strstr(filter, "Decode")) |
*(strstr(filter, "Decode")) = '\0'; |
printf("%s%s", |
filter, |
j == fz_array_len(image[i].u.image.filter) - 1 ? "" : " "); |
fz_free(filter); |
} |
else if (image[i].u.image.filter) |
{ |
fz_obj *obj = image[i].u.image.filter; |
char *filter = fz_strdup(fz_to_name(obj)); |
if (strstr(filter, "Decode")) |
*(strstr(filter, "Decode")) = '\0'; |
printf("%s", filter); |
fz_free(filter); |
} |
else |
printf("Raw"); |
if (image[i].u.image.cs) |
{ |
cs = fz_strdup(fz_to_name(image[i].u.image.cs)); |
if (!strncmp(cs, "Device", 6)) |
{ |
int len = strlen(cs + 6); |
memmove(cs + 3, cs + 6, len + 1); |
cs[3 + len + 1] = '\0'; |
} |
if (strstr(cs, "ICC")) |
fz_strlcpy(cs, "ICC", 4); |
if (strstr(cs, "Indexed")) |
fz_strlcpy(cs, "Idx", 4); |
if (strstr(cs, "Pattern")) |
fz_strlcpy(cs, "Pat", 4); |
if (strstr(cs, "Separation")) |
fz_strlcpy(cs, "Sep", 4); |
} |
if (image[i].u.image.altcs) |
{ |
altcs = fz_strdup(fz_to_name(image[i].u.image.altcs)); |
if (!strncmp(altcs, "Device", 6)) |
{ |
int len = strlen(altcs + 6); |
memmove(altcs + 3, altcs + 6, len + 1); |
altcs[3 + len + 1] = '\0'; |
} |
if (strstr(altcs, "ICC")) |
fz_strlcpy(altcs, "ICC", 4); |
if (strstr(altcs, "Indexed")) |
fz_strlcpy(altcs, "Idx", 4); |
if (strstr(altcs, "Pattern")) |
fz_strlcpy(altcs, "Pat", 4); |
if (strstr(altcs, "Separation")) |
fz_strlcpy(altcs, "Sep", 4); |
} |
printf(" ] %dx%d %dbpc %s%s%s (%d %d R)\n", |
fz_to_int(image[i].u.image.width), |
fz_to_int(image[i].u.image.height), |
image[i].u.image.bpc ? fz_to_int(image[i].u.image.bpc) : 1, |
image[i].u.image.cs ? cs : "ImageMask", |
image[i].u.image.altcs ? " " : "", |
image[i].u.image.altcs ? altcs : "", |
fz_to_num(image[i].u.image.obj), fz_to_gen(image[i].u.image.obj)); |
fz_free(cs); |
fz_free(altcs); |
} |
printf("\n"); |
} |
if (show & SHADINGS && shadings > 0) |
{ |
printf("Shading patterns (%d):\n", shadings); |
for (i = 0; i < shadings; i++) |
{ |
char *shadingtype[] = |
{ |
"", |
"Function", |
"Axial", |
"Radial", |
"Triangle mesh", |
"Lattice", |
"Coons patch", |
"Tensor patch", |
}; |
printf(PAGE_FMT "%s (%d %d R)\n", |
shading[i].page, |
fz_to_num(shading[i].pageref), fz_to_gen(shading[i].pageref), |
shadingtype[fz_to_int(shading[i].u.shading.type)], |
fz_to_num(shading[i].u.shading.obj), fz_to_gen(shading[i].u.shading.obj)); |
} |
printf("\n"); |
} |
if (show & PATTERNS && patterns > 0) |
{ |
printf("Patterns (%d):\n", patterns); |
for (i = 0; i < patterns; i++) |
{ |
if (fz_to_int(pattern[i].u.pattern.type) == 1) |
{ |
char *painttype[] = |
{ |
"", |
"Colored", |
"Uncolored", |
}; |
char *tilingtype[] = |
{ |
"", |
"Constant", |
"No distortion", |
"Constant/fast tiling", |
}; |
printf(PAGE_FMT "Tiling %s %s (%d %d R)\n", |
pattern[i].page, |
fz_to_num(pattern[i].pageref), fz_to_gen(pattern[i].pageref), |
painttype[fz_to_int(pattern[i].u.pattern.paint)], |
tilingtype[fz_to_int(pattern[i].u.pattern.tiling)], |
fz_to_num(pattern[i].u.pattern.obj), fz_to_gen(pattern[i].u.pattern.obj)); |
} |
else |
{ |
printf(PAGE_FMT "Shading %d %d R (%d %d R)\n", |
pattern[i].page, |
fz_to_num(pattern[i].pageref), fz_to_gen(pattern[i].pageref), |
fz_to_num(pattern[i].u.pattern.shading), fz_to_gen(pattern[i].u.pattern.shading), |
fz_to_num(pattern[i].u.pattern.obj), fz_to_gen(pattern[i].u.pattern.obj)); |
} |
} |
printf("\n"); |
} |
if (show & XOBJS && forms > 0) |
{ |
printf("Form xobjects (%d):\n", forms); |
for (i = 0; i < forms; i++) |
{ |
printf(PAGE_FMT "Form%s%s%s%s (%d %d R)\n", |
form[i].page, |
fz_to_num(form[i].pageref), fz_to_gen(form[i].pageref), |
form[i].u.form.groupsubtype ? " " : "", |
form[i].u.form.groupsubtype ? fz_to_name(form[i].u.form.groupsubtype) : "", |
form[i].u.form.groupsubtype ? " Group" : "", |
form[i].u.form.reference ? " Reference" : "", |
fz_to_num(form[i].u.form.obj), fz_to_gen(form[i].u.form.obj)); |
} |
printf("\n"); |
} |
if (show & XOBJS && psobjs > 0) |
{ |
printf("Postscript xobjects (%d):\n", psobjs); |
for (i = 0; i < psobjs; i++) |
{ |
printf(PAGE_FMT "(%d %d R)\n", |
psobj[i].page, |
fz_to_num(psobj[i].pageref), fz_to_gen(psobj[i].pageref), |
fz_to_num(psobj[i].u.form.obj), fz_to_gen(psobj[i].u.form.obj)); |
} |
printf("\n"); |
} |
} |
static void |
showinfo(char *filename, int show, char *pagelist) |
{ |
int page, spage, epage; |
char *spec, *dash; |
int allpages; |
if (!xref) |
infousage(); |
allpages = !strcmp(pagelist, "1-"); |
spec = fz_strsep(&pagelist, ","); |
while (spec) |
{ |
dash = strchr(spec, '-'); |
if (dash == spec) |
spage = epage = pagecount; |
else |
spage = epage = atoi(spec); |
if (dash) |
{ |
if (strlen(dash) > 1) |
epage = atoi(dash + 1); |
else |
epage = pagecount; |
} |
if (spage > epage) |
page = spage, spage = epage, epage = page; |
if (spage < 1) |
spage = 1; |
if (epage > pagecount) |
epage = pagecount; |
if (spage > pagecount) |
spage = pagecount; |
if (allpages) |
printf("Retrieving info from pages %d-%d...\n", spage, epage); |
if (spage >= 1) |
{ |
for (page = spage; page <= epage; page++) |
{ |
gatherpageinfo(page); |
if (!allpages) |
{ |
printf("Page %d:\n", page); |
printinfo(filename, show, page); |
printf("\n"); |
} |
} |
} |
spec = fz_strsep(&pagelist, ","); |
} |
if (allpages) |
printinfo(filename, show, -1); |
} |
int main(int argc, char **argv) |
{ |
enum { NO_FILE_OPENED, NO_INFO_GATHERED, INFO_SHOWN } state; |
fz_error error; |
char *filename = ""; |
char *password = ""; |
int show = ALL; |
int c; |
while ((c = fz_getopt(argc, argv, "mfispxd:")) != -1) |
{ |
switch (c) |
{ |
case 'm': if (show == ALL) show = DIMENSIONS; else show |= DIMENSIONS; break; |
case 'f': if (show == ALL) show = FONTS; else show |= FONTS; break; |
case 'i': if (show == ALL) show = IMAGES; else show |= IMAGES; break; |
case 's': if (show == ALL) show = SHADINGS; else show |= SHADINGS; break; |
case 'p': if (show == ALL) show = PATTERNS; else show |= PATTERNS; break; |
case 'x': if (show == ALL) show = XOBJS; else show |= XOBJS; break; |
case 'd': password = fz_optarg; break; |
default: |
infousage(); |
break; |
} |
} |
if (fz_optind == argc) |
infousage(); |
state = NO_FILE_OPENED; |
while (fz_optind < argc) |
{ |
if (strstr(argv[fz_optind], ".pdf") || strstr(argv[fz_optind], ".PDF")) |
{ |
if (state == NO_INFO_GATHERED) |
{ |
showinfo(filename, show, "1-"); |
closexref(); |
} |
closexref(); |
filename = argv[fz_optind]; |
printf("%s:\n", filename); |
error = pdf_open_xref(&xref, filename, password); |
if (error) |
die(fz_rethrow(error, "cannot open input file '%s'", filename)); |
error = pdf_load_page_tree(xref); |
if (error) |
die(fz_rethrow(error, "cannot load page tree: %s", filename)); |
pagecount = pdf_count_pages(xref); |
showglobalinfo(); |
state = NO_INFO_GATHERED; |
} |
else |
{ |
showinfo(filename, show, argv[fz_optind]); |
state = INFO_SHOWN; |
} |
fz_optind++; |
} |
if (state == NO_INFO_GATHERED) |
showinfo(filename, show, "1-"); |
closexref(); |
return 0; |
} |
/contrib/media/updf/apps/pdfshow.c |
---|
0,0 → 1,240 |
/* |
* pdfshow -- the ultimate pdf debugging tool |
*/ |
#include "fitz.h" |
#include "mupdf.h" |
static pdf_xref *xref = NULL; |
static int showbinary = 0; |
static int showdecode = 1; |
static int showcolumn; |
void die(fz_error error) |
{ |
fz_catch(error, "aborting"); |
if (xref) |
pdf_free_xref(xref); |
exit(1); |
} |
static void usage(void) |
{ |
fprintf(stderr, "usage: pdfshow [options] file.pdf [grepable] [xref] [trailer] [pagetree] [object numbers]\n"); |
fprintf(stderr, "\t-b\tprint streams as binary data\n"); |
fprintf(stderr, "\t-e\tprint encoded streams (don't decode)\n"); |
fprintf(stderr, "\t-p\tpassword\n"); |
exit(1); |
} |
static void showtrailer(void) |
{ |
if (!xref) |
die(fz_throw("no file specified")); |
printf("trailer\n"); |
fz_debug_obj(xref->trailer); |
printf("\n"); |
} |
static void showxref(void) |
{ |
if (!xref) |
die(fz_throw("no file specified")); |
pdf_debug_xref(xref); |
printf("\n"); |
} |
static void showpagetree(void) |
{ |
fz_error error; |
fz_obj *ref; |
int count; |
int i; |
if (!xref) |
die(fz_throw("no file specified")); |
if (!xref->page_len) |
{ |
error = pdf_load_page_tree(xref); |
if (error) |
die(fz_rethrow(error, "cannot load page tree")); |
} |
count = pdf_count_pages(xref); |
for (i = 0; i < count; i++) |
{ |
ref = xref->page_refs[i]; |
printf("page %d = %d %d R\n", i + 1, fz_to_num(ref), fz_to_gen(ref)); |
} |
printf("\n"); |
} |
static void showsafe(unsigned char *buf, int n) |
{ |
int i; |
for (i = 0; i < n; i++) { |
if (buf[i] == '\r' || buf[i] == '\n') { |
putchar('\n'); |
showcolumn = 0; |
} |
else if (buf[i] < 32 || buf[i] > 126) { |
putchar('.'); |
showcolumn ++; |
} |
else { |
putchar(buf[i]); |
showcolumn ++; |
} |
if (showcolumn == 79) { |
putchar('\n'); |
showcolumn = 0; |
} |
} |
} |
static void showstream(int num, int gen) |
{ |
fz_error error; |
fz_stream *stm; |
unsigned char buf[2048]; |
int n; |
showcolumn = 0; |
if (showdecode) |
error = pdf_open_stream(&stm, xref, num, gen); |
else |
error = pdf_open_raw_stream(&stm, xref, num, gen); |
if (error) |
die(error); |
while (1) |
{ |
n = fz_read(stm, buf, sizeof buf); |
if (n < 0) |
die(n); |
if (n == 0) |
break; |
if (showbinary) |
fwrite(buf, 1, n, stdout); |
else |
showsafe(buf, n); |
} |
fz_close(stm); |
} |
static void showobject(int num, int gen) |
{ |
fz_error error; |
fz_obj *obj; |
if (!xref) |
die(fz_throw("no file specified")); |
error = pdf_load_object(&obj, xref, num, gen); |
if (error) |
die(error); |
if (pdf_is_stream(xref, num, gen)) |
{ |
if (showbinary) |
{ |
showstream(num, gen); |
} |
else |
{ |
printf("%d %d obj\n", num, gen); |
fz_debug_obj(obj); |
printf("stream\n"); |
showstream(num, gen); |
printf("endstream\n"); |
printf("endobj\n\n"); |
} |
} |
else |
{ |
printf("%d %d obj\n", num, gen); |
fz_debug_obj(obj); |
printf("endobj\n\n"); |
} |
fz_drop_obj(obj); |
} |
static void showgrep(char *filename) |
{ |
fz_error error; |
fz_obj *obj; |
int i; |
for (i = 0; i < xref->len; i++) |
{ |
if (xref->table[i].type == 'n' || xref->table[i].type == 'o') |
{ |
error = pdf_load_object(&obj, xref, i, 0); |
if (error) |
die(error); |
fz_sort_dict(obj); |
printf("%s:%d: ", filename, i); |
fz_fprint_obj(stdout, obj, 1); |
fz_drop_obj(obj); |
} |
} |
printf("%s:trailer: ", filename); |
fz_fprint_obj(stdout, xref->trailer, 1); |
} |
int main(int argc, char **argv) |
{ |
char *password = NULL; /* don't throw errors if encrypted */ |
char *filename; |
fz_error error; |
int c; |
while ((c = fz_getopt(argc, argv, "p:be")) != -1) |
{ |
switch (c) |
{ |
case 'p': password = fz_optarg; break; |
case 'b': showbinary = 1; break; |
case 'e': showdecode = 0; break; |
default: usage(); break; |
} |
} |
if (fz_optind == argc) |
usage(); |
filename = argv[fz_optind++]; |
error = pdf_open_xref(&xref, filename, password); |
if (error) |
die(fz_rethrow(error, "cannot open document: %s", filename)); |
if (fz_optind == argc) |
showtrailer(); |
while (fz_optind < argc) |
{ |
switch (argv[fz_optind][0]) |
{ |
case 't': showtrailer(); break; |
case 'x': showxref(); break; |
case 'p': showpagetree(); break; |
case 'g': showgrep(filename); break; |
default: showobject(atoi(argv[fz_optind]), 0); break; |
} |
fz_optind++; |
} |
pdf_free_xref(xref); |
fz_flush_warnings(); |
return 0; |
} |
/contrib/media/updf/stub/Makefile |
---|
0,0 → 1,18 |
include osrules.mak |
.SUFFIXES: .asm; |
OBJS = crt0.o |
all: $(OBJS) |
ifdef ON_WINDOWS |
crt0.o: crt0_$(STUBFMT).asm |
fasm crt0_$(STUBFMT).asm crt0.o |
else |
crt0.o: crt0_$(STUBFMT)_nounderscores.asm |
fasm crt0_$(STUBFMT)_nounderscores.asm crt0.o |
endif |
clean: |
$(RM) $(OBJS) |
/contrib/media/updf/stub/osrules.mak |
---|
0,0 → 1,58 |
ifdef windir |
ON_WINDOWS = 1 |
else |
ifdef WINDIR |
ON_WINDOWS = 1 |
endif |
endif |
ifndef ON_WINDOWS |
VERSION_OS = linux |
NEED_UNDERSCORES = undef |
EXESUFFIX = |
RM = rm -f |
MV = mv |
D_ECHO = echo |
LIBDIR = $(MENUETDEV)/lib |
ASMFMT = elf |
else |
ifdef HOME |
VERSION_OS = cygwin |
NEED_UNDERSCORES = define |
EXESUFFIX = .exe |
RM = rm -f |
MV = mv |
D_ECHO = echo |
LIBDIR = $(MENUETDEV)/lib |
ASMFMT = elf |
else |
VERSION_OS = MinGW |
NEED_UNDERSCORES = define |
EXESUFFIX = .exe |
RM = del |
MV = move |
D_ECHO = echo. |
ON_MINGW = 1 |
LIBDIR = $(MENUETDEV)\lib |
ASMFMT = coff |
endif |
endif |
HAS_DEVENV = 0 |
GPP_TOOLNAME = g++ |
STUBFMT = elf |
MMKDEP = $(MENUETDEV)/linuxtools/mmkdep |
MGCC = $(MENUETDEV)/linuxtools/mgcc |
MGPP = $(MENUETDEV)/linuxtools/mgpp |
MLD = $(MENUETDEV)/linuxtools/mld |
MCHMEM = $(MENUETDEV)/linuxtools/mchmem |
GCC32OPT = |
AS32OPT = |
LD32OPT = |
ifneq (,$(findstring 64,$(shell gcc -dumpmachine))) |
GCC32OPT = -m32 |
AS32OPT = --32 |
LD32OPT = -m$(ASMFMT)_i386 |
endif |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/media/updf/stub/crt0.asm |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/contrib/media/updf/stub/crt0_coff.asm |
---|
0,0 → 1,58 |
CATCH_NULL_CALL = 0 |
format MS COFF |
section '.text' code readable executable |
public start |
;EXTRN _edata |
EXTRN ___menuet__app_param_area |
EXTRN ___menuet__app_path_area |
EXTRN ___crt1_startup |
start: |
public ___menuet__app_header |
public ___menuet__memsize |
section '.A' code readable executable |
___menuet__app_header: |
db 'MENUET01' |
dd 0x01 |
if CATCH_NULL_CALL |
dd do_start |
else |
dd ___crt1_startup |
end if |
; dd _edata |
dd 0 |
___menuet__memsize: |
dd 0x400000 |
dd app_stack |
dd ___menuet__app_param_area |
dd ___menuet__app_path_area |
if CATCH_NULL_CALL |
do_start: |
mov byte [0], 0xE9 |
mov dword [1], _libc_null_call-5 |
call ___crt1_startup |
; Handle exit if __crt1_startup returns (shouldn't happen) |
mov eax,-1 |
int 0x40 |
end if |
if CATCH_NULL_CALL |
EXTRN ___libc_null_call |
_libc_null_call: |
push eax |
push ebx |
push ecx |
push edx |
push esi |
push edi |
push ebp |
call ___libc_null_call |
mov eax,-1 |
int 0x40 |
end if |
section '.bss' readable writeable |
rd 0x20000 |
app_stack: |
/contrib/media/updf/stub/crt0_elf.asm |
---|
0,0 → 1,56 |
CATCH_NULL_CALL = 0 |
format ELF |
section '.text' executable |
public start |
EXTRN _edata |
EXTRN ___menuet__app_param_area |
EXTRN ___menuet__app_path_area |
EXTRN ___crt1_startup |
start: |
public ___menuet__app_header |
public ___menuet__memsize |
___menuet__app_header: |
db 'MENUET01' |
dd 0x01 |
if CATCH_NULL_CALL |
dd do_start |
else |
dd ___crt1_startup |
end if |
dd _edata |
___menuet__memsize: |
dd 0x800000 |
dd app_stack |
dd ___menuet__app_param_area |
dd ___menuet__app_path_area |
if CATCH_NULL_CALL |
do_start: |
mov byte [0], 0xE9 |
mov dword [1], _libc_null_call-5 |
call ___crt1_startup |
; Handle exit if __crt1_startup returns (shouldn't happen) |
mov eax,-1 |
int 0x40 |
end if |
if CATCH_NULL_CALL |
EXTRN ___libc_null_call |
_libc_null_call: |
push eax |
push ebx |
push ecx |
push edx |
push esi |
push edi |
push ebp |
call ___libc_null_call |
mov eax,-1 |
int 0x40 |
end if |
section '.bss' writeable |
rd 0x20000 |
app_stack: |
/contrib/media/updf/stub/crt0_elf_nounderscores.asm |
---|
0,0 → 1,56 |
CATCH_NULL_CALL = 0 |
format ELF |
section '.text' executable |
public start |
EXTRN edata |
EXTRN __menuet__app_param_area |
EXTRN __menuet__app_path_area |
EXTRN __crt1_startup |
start: |
public __menuet__app_header |
public __menuet__memsize |
__menuet__app_header: |
db 'MENUET01' |
dd 0x01 |
if CATCH_NULL_CALL |
dd do_start |
else |
dd __crt1_startup |
end if |
dd edata |
__menuet__memsize: |
dd 0x800000 |
dd app_stack |
dd __menuet__app_param_area |
dd __menuet__app_path_area |
if CATCH_NULL_CALL |
do_start: |
mov byte [0], 0xE9 |
mov dword [1], _libc_null_call-5 |
call __crt1_startup |
; Handle exit if __crt1_startup returns (shouldn't happen) |
mov eax,-1 |
int 0x40 |
end if |
if CATCH_NULL_CALL |
EXTRN __libc_null_call |
_libc_null_call: |
push eax |
push ebx |
push ecx |
push edx |
push esi |
push edi |
push ebp |
call __libc_null_call |
mov eax,-1 |
int 0x40 |
end if |
section '.bss' writeable |
rd 4096*4 |
app_stack: |
/contrib/media/updf/freetypesrc |
---|
0,0 → 1,22 |
FREETYPE_SRC := \ |
ftbase.c \ |
ftbbox.c \ |
ftbitmap.c \ |
ftgasp.c \ |
ftglyph.c \ |
ftinit.c \ |
ftstroke.c \ |
ftsynth.c \ |
ftsystem.c \ |
fttype1.c \ |
ftxf86.c \ |
cff.c \ |
psaux.c \ |
pshinter.c \ |
psnames.c \ |
raster.c \ |
sfnt.c \ |
smooth.c \ |
truetype.c \ |
type1.c \ |
type1cid.c \ |