diff options
114 files changed, 2659 insertions, 2035 deletions
diff --git a/apps/mudraw.c b/apps/mudraw.c index e74f3081..19f359a1 100644 --- a/apps/mudraw.c +++ b/apps/mudraw.c @@ -3,7 +3,6 @@ */ #include "fitz.h" -#include "mupdf.h" #ifdef _MSC_VER #include <winsock2.h> @@ -273,24 +272,18 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) else if (strstr(output, ".png")) fz_write_png(ctx, pix, buf, savealpha); else if (strstr(output, ".pbm")) { - fz_halftone *ht = fz_get_default_halftone(ctx, 1); - fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, ht); + fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, NULL); fz_write_pbm(ctx, bit, buf); fz_drop_bitmap(ctx, bit); - fz_drop_halftone(ctx, ht); } } if (showmd5) { - fz_md5 md5; unsigned char digest[16]; int i; - fz_md5_init(&md5); - fz_md5_update(&md5, pix->samples, pix->w * pix->h * pix->n); - fz_md5_final(&md5, digest); - + fz_md5_pixmap(pix, digest); printf(" "); for (i = 0; i < 16; i++) printf("%02x", digest[i]); @@ -382,9 +375,9 @@ static void drawoutline(fz_context *ctx, fz_document *doc) { fz_outline *outline = fz_load_outline(doc); if (showoutline > 1) - fz_debug_outline_xml(ctx, outline, 0); + fz_debug_outline_xml(ctx, outline); else - fz_debug_outline(ctx, outline, 0); + fz_debug_outline(ctx, outline); fz_free_outline(ctx, outline); } diff --git a/apps/mupdfclean.c b/apps/mupdfclean.c index c8a81274..caee8d5b 100644 --- a/apps/mupdfclean.c +++ b/apps/mupdfclean.c @@ -10,7 +10,7 @@ */ #include "fitz.h" -#include "mupdf.h" +#include "mupdf-internal.h" static FILE *out = NULL; diff --git a/apps/mupdfextract.c b/apps/mupdfextract.c index 88a3630d..398ff6d9 100644 --- a/apps/mupdfextract.c +++ b/apps/mupdfextract.c @@ -2,7 +2,6 @@ * pdfextract -- the ultimate way to extract images and fonts from pdfs */ -#include "fitz.h" #include "mupdf.h" static pdf_document *doc = NULL; @@ -34,7 +33,7 @@ static void saveimage(int num) fz_image *image; fz_pixmap *img; pdf_obj *ref; - char name[1024]; + char name[32]; ref = pdf_new_indirect(ctx, num, 0, doc); @@ -44,27 +43,8 @@ static void saveimage(int num) img = fz_image_to_pixmap(ctx, image, 0, 0); fz_drop_image(ctx, image); - if (dorgb && img->colorspace && img->colorspace != fz_device_rgb) - { - fz_pixmap *temp; - temp = fz_new_pixmap_with_rect(ctx, fz_device_rgb, fz_bound_pixmap(img)); - fz_convert_pixmap(ctx, img, temp); - fz_drop_pixmap(ctx, img); - img = temp; - } - - if (img->n <= 4) - { - sprintf(name, "img-%04d.png", num); - printf("extracting image %s\n", name); - fz_write_png(ctx, img, name, 0); - } - else - { - sprintf(name, "img-%04d.pam", num); - printf("extracting image %s\n", name); - fz_write_pam(ctx, img, name, 0); - } + sprintf(name, "img-%04d", num); + fz_save_pixmap(ctx, img, name, dorgb); fz_drop_pixmap(ctx, img); pdf_drop_obj(ref); @@ -80,7 +60,8 @@ static void savefont(pdf_obj *dict, int num) char *ext = ""; FILE *f; char *fontname = "font"; - int n; + int n, len; + char *data; obj = pdf_dict_gets(dict, "FontName"); if (obj) @@ -133,8 +114,9 @@ static void savefont(pdf_obj *dict, int num) if (!f) fz_throw(ctx, "Error creating font file"); - n = fwrite(buf->data, 1, buf->len, f); - if (n < buf->len) + len = fz_buffer_storage(ctx, buf, &data); + n = fwrite(data, 1, len, f); + if (n < len) fz_throw(ctx, "Error writing font file"); if (fclose(f) < 0) @@ -199,7 +181,7 @@ int main(int argc, char **argv) if (fz_optind == argc) { - for (o = 0; o < doc->len; o++) + for (o = 0; o < pdf_count_objects(doc); o++) showobject(o); } else diff --git a/apps/mupdfinfo.c b/apps/mupdfinfo.c index 161a80f1..d567bf8e 100644 --- a/apps/mupdfinfo.c +++ b/apps/mupdfinfo.c @@ -4,7 +4,7 @@ */ #include "fitz.h" -#include "mupdf.h" +#include "mupdf-internal.h" pdf_document *xref; fz_context *ctx; diff --git a/apps/mupdfshow.c b/apps/mupdfshow.c index 92fcac2d..94aa90d6 100644 --- a/apps/mupdfshow.c +++ b/apps/mupdfshow.c @@ -2,8 +2,7 @@ * pdfshow -- the ultimate pdf debugging tool */ -#include "fitz.h" -#include "mupdf.h" +#include "mupdf-internal.h" static pdf_document *doc = NULL; static fz_context *ctx = NULL; @@ -145,7 +144,7 @@ static void showgrep(char *filename) pdf_obj *obj; int i; - for (i = 0; i < doc->len; i++) + for (i = 0; i < pdf_count_objects(doc); i++) { if (doc->table[i].type == 'n' || doc->table[i].type == 'o') { diff --git a/apps/pdfapp.c b/apps/pdfapp.c index 6f2d766d..4f093508 100644 --- a/apps/pdfapp.c +++ b/apps/pdfapp.c @@ -1,8 +1,7 @@ -#include "fitz.h" +#include "pdfapp.h" #include "mupdf.h" #include "muxps.h" #include "mucbz.h" -#include "pdfapp.h" #include <ctype.h> /* for tolower() */ @@ -80,23 +79,7 @@ void pdfapp_init(fz_context *ctx, pdfapp_t *app) void pdfapp_invert(pdfapp_t *app, fz_bbox rect) { - unsigned char *p; - int x, y, n; - - int x0 = CLAMP(rect.x0 - app->image->x, 0, app->image->w - 1); - int x1 = CLAMP(rect.x1 - app->image->x, 0, app->image->w - 1); - int y0 = CLAMP(rect.y0 - app->image->y, 0, app->image->h - 1); - int y1 = CLAMP(rect.y1 - app->image->y, 0, app->image->h - 1); - - for (y = y0; y < y1; y++) - { - p = app->image->samples + (y * app->image->w + x0) * app->image->n; - for (x = x0; x < x1; x++) - { - for (n = app->image->n; n > 0; n--, p++) - *p = 255 - *p; - } - } + fz_invert_pixmap_rect(app->image, rect); } void pdfapp_open(pdfapp_t *app, char *filename, int fd, int reload) diff --git a/apps/pdfapp.h b/apps/pdfapp.h index bb067bb4..0c1b6ac4 100644 --- a/apps/pdfapp.h +++ b/apps/pdfapp.h @@ -1,3 +1,8 @@ +#ifndef PDFAPP_H +#define PDFAPP_H + +#include "fitz.h" + /* * Utility object for handling a pdf application / view * Takes care of PDF loading and displaying and navigation, @@ -106,3 +111,5 @@ void pdfapp_onresize(pdfapp_t *app, int w, int h); void pdfapp_invert(pdfapp_t *app, fz_bbox rect); void pdfapp_inverthit(pdfapp_t *app); + +#endif diff --git a/apps/win_main.c b/apps/win_main.c index c87faa97..3417a11e 100644 --- a/apps/win_main.c +++ b/apps/win_main.c @@ -317,7 +317,7 @@ void wintitle(pdfapp_t *app, char *title) sp = title; while (*sp && dp < wide + 255) { - sp += chartorune(&rune, sp); + sp += fz_chartorune(&rune, sp); *dp++ = rune; } *dp = 0; @@ -355,10 +355,15 @@ void winblitsearch() void winblit() { + fz_bbox bb = fz_bound_pixmap(gapp.image); + int image_w = bb.x1-bb.x0; + int image_h = bb.y1-bb.y0; + int image_n = fz_pixmap_components(context, gapp.image); + unsigned char *samples = fz_pixmap_pixels(context, gapp.image); int x0 = gapp.panx; int y0 = gapp.pany; - int x1 = gapp.panx + gapp.image->w; - int y1 = gapp.pany + gapp.image->h; + int x1 = gapp.panx + image_w; + int y1 = gapp.pany + image_h; RECT r; if (gapp.image) @@ -371,15 +376,15 @@ void winblit() pdfapp_inverthit(&gapp); - dibinf->bmiHeader.biWidth = gapp.image->w; - dibinf->bmiHeader.biHeight = -gapp.image->h; - dibinf->bmiHeader.biSizeImage = gapp.image->h * 4; + dibinf->bmiHeader.biWidth = image_w; + dibinf->bmiHeader.biHeight = -image_h; + dibinf->bmiHeader.biSizeImage = image_h * 4; if (gapp.image->n == 2) { - int i = gapp.image->w * gapp.image->h; + int i = image_w * image_h; unsigned char *color = malloc(i*4); - unsigned char *s = gapp.image->samples; + unsigned char *s = samples; unsigned char *d = color; for (; i > 0 ; i--) { @@ -388,16 +393,16 @@ void winblit() d += 4; } SetDIBitsToDevice(hdc, - gapp.panx, gapp.pany, gapp.image->w, gapp.image->h, - 0, 0, 0, gapp.image->h, color, + gapp.panx, gapp.pany, image_w, image_h, + 0, 0, 0, image_h, color, dibinf, DIB_RGB_COLORS); free(color); } if (gapp.image->n == 4) { SetDIBitsToDevice(hdc, - gapp.panx, gapp.pany, gapp.image->w, gapp.image->h, - 0, 0, 0, gapp.image->h, gapp.image->samples, + gapp.panx, gapp.pany, image_w, image_h, + 0, 0, 0, image_h, samples, dibinf, DIB_RGB_COLORS); } diff --git a/apps/x11_image.c b/apps/x11_image.c index 35b32c7e..06764313 100644 --- a/apps/x11_image.c +++ b/apps/x11_image.c @@ -22,6 +22,12 @@ extern int ffs(int); +static int is_big_endian(void) +{ + static const int one = 1; + return *(char*)&one == 0; +} + typedef void (*ximage_convert_func_t) ( const unsigned char *src, @@ -212,7 +218,7 @@ select_mode(void) unsigned long rs, gs, bs; byteorder = ImageByteOrder(info.display); - if (fz_is_big_endian()) + if (is_big_endian()) byterev = byteorder != MSBFirst; else byterev = byteorder != LSBFirst; diff --git a/apps/x11_main.c b/apps/x11_main.c index 281618ef..091f0ec6 100644 --- a/apps/x11_main.c +++ b/apps/x11_main.c @@ -1,7 +1,3 @@ -#include "fitz.h" -#include "mupdf.h" -#include "muxps.h" -#include "mucbz.h" #include "pdfapp.h" #include <X11/Xlib.h> @@ -253,6 +249,9 @@ void winhelp(pdfapp_t *app) void winresize(pdfapp_t *app, int w, int h) { + fz_bbox bb = fz_bound_pixmap(gapp.image); + int image_w = bb.x1 - bb.x0; + int image_h = bb.y1 - bb.y0; XWindowChanges values; int mask, width, height; @@ -287,7 +286,7 @@ void winresize(pdfapp_t *app, int w, int h) } XSetForeground(xdpy, xgc, WhitePixel(xdpy, xscr)); - XFillRectangle(xdpy, xwin, xgc, 0, 0, gapp.image->w, gapp.image->h); + XFillRectangle(xdpy, xwin, xgc, 0, 0, image_w, image_h); XFlush(xdpy); if (width != reqw || height != reqh) @@ -338,10 +337,15 @@ static void winblitsearch(pdfapp_t *app) static void winblit(pdfapp_t *app) { + fz_bbox bb = fz_bound_pixmap(gapp.image); + int image_w = bb.x1 - bb.x0; + int image_h = bb.y1 - bb.y0; + int image_n = fz_pixmap_components(gapp.ctx, gapp.image); + unsigned char *image_samples = fz_pixmap_pixels(gapp.ctx, gapp.image); int x0 = gapp.panx; int y0 = gapp.pany; - int x1 = gapp.panx + gapp.image->w; - int y1 = gapp.pany + gapp.image->h; + int x1 = gapp.panx + image_w; + int y1 = gapp.pany + image_h; XSetForeground(xdpy, xgc, xbgcolor.pixel); fillrect(0, 0, x0, gapp.winh); @@ -350,8 +354,8 @@ static void winblit(pdfapp_t *app) fillrect(0, y1, gapp.winw, gapp.winh - y1); XSetForeground(xdpy, xgc, xshcolor.pixel); - fillrect(x0+2, y1, gapp.image->w, 2); - fillrect(x1, y0+2, 2, gapp.image->h); + fillrect(x0+2, y1, image_w, 2); + fillrect(x1, y0+2, 2, image_h); if (gapp.iscopying || justcopied) { @@ -361,21 +365,21 @@ static void winblit(pdfapp_t *app) pdfapp_inverthit(&gapp); - if (gapp.image->n == 4) + if (image_n == 4) ximage_blit(xwin, xgc, x0, y0, - gapp.image->samples, + image_samples, 0, 0, - gapp.image->w, - gapp.image->h, - gapp.image->w * gapp.image->n); - else if (gapp.image->n == 2) + image_w, + image_h, + image_w * image_n); + else if (image_n == 2) { - int i = gapp.image->w*gapp.image->h; + int i = image_w*image_h; unsigned char *color = malloc(i*4); if (color) { - unsigned char *s = gapp.image->samples; + unsigned char *s = image_samples; unsigned char *d = color; for (; i > 0 ; i--) { @@ -387,9 +391,9 @@ static void winblit(pdfapp_t *app) x0, y0, color, 0, 0, - gapp.image->w, - gapp.image->h, - gapp.image->w * 4); + image_w, + image_h, + image_w * 4); free(color); } } diff --git a/cbz/mucbz.c b/cbz/mucbz.c index 89c9d4dd..08f21bb6 100644 --- a/cbz/mucbz.c +++ b/cbz/mucbz.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "mucbz.h" #include <zlib.h> diff --git a/cbz/mucbz.h b/cbz/mucbz.h index cdda3472..080423bf 100644 --- a/cbz/mucbz.h +++ b/cbz/mucbz.h @@ -1,9 +1,7 @@ -#ifndef _MUCBZ_H_ -#define _MUCBZ_H_ +#ifndef MUCBZ_H +#define MUCBZ_H -#ifndef _FITZ_H_ -#error "fitz.h must be included before mucbz.h" -#endif +#include "fitz.h" typedef struct cbz_document_s cbz_document; typedef struct cbz_page_s cbz_page; diff --git a/draw/draw_affine.c b/draw/draw_affine.c index dc15eaf5..67361faf 100644 --- a/draw/draw_affine.c +++ b/draw/draw_affine.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" typedef unsigned char byte; diff --git a/draw/draw_blend.c b/draw/draw_blend.c index e60c09c5..3e81568f 100644 --- a/draw/draw_blend.c +++ b/draw/draw_blend.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* PDF 1.4 blend modes. These are slow. */ diff --git a/draw/draw_device.c b/draw/draw_device.c index f40c6627..e2c22db1 100644 --- a/draw/draw_device.c +++ b/draw/draw_device.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #define QUANT(x,a) (((int)((x) * (a))) / (a)) #define HSUBPIX 5.0 @@ -248,7 +248,7 @@ fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, fz_matrix ctm, if (state->blendmode & FZ_BLEND_KNOCKOUT) state = fz_knockout_begin(dev); - fz_convert_color(dev->ctx, colorspace, color, model, colorfv); + fz_convert_color(dev->ctx, model, colorfv, colorspace, color); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; @@ -302,7 +302,7 @@ fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, fz_ if (state->blendmode & FZ_BLEND_KNOCKOUT) state = fz_knockout_begin(dev); - fz_convert_color(dev->ctx, colorspace, color, model, colorfv); + fz_convert_color(dev->ctx, model, colorfv, colorspace, color); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; @@ -472,7 +472,7 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm, if (state->blendmode & FZ_BLEND_KNOCKOUT) state = fz_knockout_begin(dev); - fz_convert_color(dev->ctx, colorspace, color, model, colorfv); + fz_convert_color(dev->ctx, model, colorfv, colorspace, color); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; @@ -532,7 +532,7 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_ if (state->blendmode & FZ_BLEND_KNOCKOUT) state = fz_knockout_begin(dev); - fz_convert_color(dev->ctx, colorspace, color, model, colorfv); + fz_convert_color(dev->ctx, model, colorfv, colorspace, color); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; @@ -775,7 +775,7 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha) { unsigned char *s; int x, y, n, i; - fz_convert_color(dev->ctx, shade->colorspace, shade->background, model, colorfv); + fz_convert_color(dev->ctx, model, colorfv, shade->colorspace, shade->background); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = 255; @@ -927,7 +927,7 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha) if (pixmap->colorspace != model && !after) { converted = fz_new_pixmap_with_rect(ctx, model, fz_bound_pixmap(pixmap)); - fz_convert_pixmap(ctx, pixmap, converted); + fz_convert_pixmap(ctx, converted, pixmap); pixmap = converted; } @@ -957,7 +957,7 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha) else { converted = fz_new_pixmap_with_rect(ctx, model, fz_bound_pixmap(pixmap)); - fz_convert_pixmap(ctx, pixmap, converted); + fz_convert_pixmap(ctx, converted, pixmap); pixmap = converted; } } @@ -1027,7 +1027,7 @@ fz_draw_fill_image_mask(fz_device *devp, fz_image *image, fz_matrix ctm, pixmap = scaled; } - fz_convert_color(dev->ctx, colorspace, color, model, colorfv); + fz_convert_color(dev->ctx, model, colorfv, colorspace, color); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; @@ -1228,7 +1228,7 @@ fz_draw_begin_mask(fz_device *devp, fz_rect rect, int luminosity, fz_colorspace float bc; if (!colorspace) colorspace = fz_device_gray; - fz_convert_color(dev->ctx, colorspace, colorfv, fz_device_gray, &bc); + fz_convert_color(dev->ctx, fz_device_gray, &bc, colorspace, colorfv); fz_clear_pixmap_with_value(dev->ctx, dest, bc * 255); if (shape) fz_clear_pixmap_with_value(dev->ctx, shape, 255); diff --git a/draw/draw_edge.c b/draw/draw_edge.c index adb460ac..fa192bb8 100644 --- a/draw/draw_edge.c +++ b/draw/draw_edge.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #define BBOX_MIN -(1<<20) #define BBOX_MAX (1<<20) @@ -41,6 +41,12 @@ void fz_new_aa_context(fz_context *ctx) #endif } +void fz_copy_aa_context(fz_context *dst, fz_context *src) +{ + if (dst && src) + memcpy(dst, src, sizeof(*src)); +} + void fz_free_aa_context(fz_context *ctx) { #ifndef AA_BITS diff --git a/draw/draw_glyph.c b/draw/draw_glyph.c index b8f69ce3..0761b8a9 100644 --- a/draw/draw_glyph.c +++ b/draw/draw_glyph.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #define MAX_FONT_SIZE 1000 #define MAX_GLYPH_SIZE 256 diff --git a/draw/draw_mesh.c b/draw/draw_mesh.c index 79bac732..1d6f1759 100644 --- a/draw/draw_mesh.c +++ b/draw/draw_mesh.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* * polygon clipping @@ -509,7 +509,7 @@ fz_paint_mesh(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, tri[k][2] = *mesh++ * 255; else { - fz_convert_color(ctx, shade->colorspace, mesh, dest->colorspace, tri[k] + 2); + fz_convert_color(ctx, dest->colorspace, tri[k] + 2, shade->colorspace, mesh); for (i = 0; i < dest->colorspace->n; i++) tri[k][i + 2] *= 255; mesh += shade->colorspace->n; @@ -539,7 +539,7 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, { for (i = 0; i < 256; i++) { - fz_convert_color(ctx, shade->colorspace, shade->function[i], dest->colorspace, color); + fz_convert_color(ctx, dest->colorspace, color, shade->colorspace, shade->function[i]); for (k = 0; k < dest->colorspace->n; k++) clut[i][k] = color[k] * 255; clut[i][k] = shade->function[i][shade->colorspace->n] * 255; diff --git a/draw/draw_paint.c b/draw/draw_paint.c index 3b02b870..6a73783b 100644 --- a/draw/draw_paint.c +++ b/draw/draw_paint.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* diff --git a/draw/draw_path.c b/draw/draw_path.c index eca7dc08..2ef8cf3a 100644 --- a/draw/draw_path.c +++ b/draw/draw_path.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #define MAX_DEPTH 8 diff --git a/draw/draw_scale.c b/draw/draw_scale.c index e758c989..aceec939 100644 --- a/draw/draw_scale.c +++ b/draw/draw_scale.c @@ -6,7 +6,7 @@ given by taking the source pixmap src, scaling it to width w, and height h, and then positioning it at (frac(x),frac(y)). */ -#include "fitz.h" +#include "fitz-internal.h" /* Do we special case handling of single pixel high/wide images? The * 'purest' handling is given by not special casing them, but certain diff --git a/draw/draw_simple_scale.c b/draw/draw_simple_scale.c index 6d0ad481..8143b6fd 100644 --- a/draw/draw_simple_scale.c +++ b/draw/draw_simple_scale.c @@ -10,7 +10,7 @@ that return values strictly in the 0..1 range, and uses bytes for intermediate results rather than ints. */ -#include "fitz.h" +#include "fitz-internal.h" /* Do we special case handling of single pixel high/wide images? The * 'purest' handling is given by not special casing them, but certain diff --git a/draw/draw_unpack.c b/draw/draw_unpack.c index 6da5e8a3..f988dcf9 100644 --- a/draw/draw_unpack.c +++ b/draw/draw_unpack.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* Unpack image samples and optionally pad pixels with opaque alpha */ diff --git a/fitz/base_context.c b/fitz/base_context.c index 2eeb6683..075a3d02 100644 --- a/fitz/base_context.c +++ b/fitz/base_context.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" void fz_free_context(fz_context *ctx) @@ -122,6 +122,8 @@ fz_clone_context_internal(fz_context *ctx) if (ctx == NULL || ctx->alloc == NULL) return NULL; new_ctx = new_context_phase1(ctx->alloc, ctx->locks); + /* Inherit AA defaults from old context. */ + fz_copy_aa_context(new_ctx, ctx); new_ctx->store = fz_keep_store_context(ctx); new_ctx->glyph_cache = fz_keep_glyph_cache(ctx); new_ctx->font = fz_keep_font_context(ctx); diff --git a/fitz/base_error.c b/fitz/base_error.c index f3ca4efa..71a32a2e 100644 --- a/fitz/base_error.c +++ b/fitz/base_error.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* Warning context */ diff --git a/fitz/base_geometry.c b/fitz/base_geometry.c index fc5ce517..84134179 100644 --- a/fitz/base_geometry.c +++ b/fitz/base_geometry.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #define MAX4(a,b,c,d) MAX(MAX(a,b), MAX(c,d)) #define MIN4(a,b,c,d) MIN(MIN(a,b), MIN(c,d)) diff --git a/fitz/base_hash.c b/fitz/base_hash.c index 76c95304..59ed8872 100644 --- a/fitz/base_hash.c +++ b/fitz/base_hash.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* Simple hashtable with open addressing linear probe. diff --git a/fitz/base_memory.c b/fitz/base_memory.c index c9ec2628..32c7ff84 100644 --- a/fitz/base_memory.c +++ b/fitz/base_memory.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" static void * do_scavenging_malloc(fz_context *ctx, unsigned int size) diff --git a/fitz/base_string.c b/fitz/base_string.c index 2c8877c8..8ed08911 100644 --- a/fitz/base_string.c +++ b/fitz/base_string.c @@ -1,11 +1,4 @@ -#include "fitz.h" - -int -fz_is_big_endian(void) -{ - static const int one = 1; - return *(char*)&one == 0; -} +#include "fitz-internal.h" char * fz_strsep(char **stringp, const char *delim) @@ -36,8 +29,8 @@ fz_strlcpy(char *dst, const char *src, int siz) if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; + while (*s++) + ; } return(s - src - 1); /* count does not include NUL */ @@ -108,7 +101,7 @@ enum }; int -chartorune(int *rune, char *str) +fz_chartorune(int *rune, char *str) { int c, c1, c2, c3; long l; @@ -183,16 +176,15 @@ bad: } int -runetochar(char *str, int *rune) +fz_runetochar(char *str, int rune) { /* Runes are signed, so convert to unsigned for range check. */ - unsigned long c; + unsigned long c = (unsigned long)rune; /* * one character sequence * 00000-0007F => 00-7F */ - c = *rune; if(c <= Rune1) { str[0] = c; return 1; @@ -240,10 +232,10 @@ runetochar(char *str, int *rune) } int -runelen(int c) +fz_runelen(int c) { char str[10]; - return runetochar(str, &c); + return fz_runetochar(str, c); } float fz_atof(const char *s) diff --git a/fitz/crypt_aes.c b/fitz/crypt_aes.c index afdff0fe..4d8c4498 100644 --- a/fitz/crypt_aes.c +++ b/fitz/crypt_aes.c @@ -36,7 +36,7 @@ * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf */ -#include "fitz.h" +#include "fitz-internal.h" #define aes_context fz_aes diff --git a/fitz/crypt_arc4.c b/fitz/crypt_arc4.c index 272891ce..596bf652 100644 --- a/fitz/crypt_arc4.c +++ b/fitz/crypt_arc4.c @@ -21,7 +21,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "fitz.h" +#include "fitz-internal.h" void fz_arc4_init(fz_arc4 *arc4, const unsigned char *key, unsigned keylen) diff --git a/fitz/crypt_md5.c b/fitz/crypt_md5.c index b6e06845..87c0909d 100644 --- a/fitz/crypt_md5.c +++ b/fitz/crypt_md5.c @@ -23,7 +23,7 @@ These notices must be retained in any copies of any part of this documentation and/or software. */ -#include "fitz.h" +#include "fitz-internal.h" /* Constants for MD5Transform routine */ enum diff --git a/fitz/crypt_sha2.c b/fitz/crypt_sha2.c index f17146c6..64284cfa 100644 --- a/fitz/crypt_sha2.c +++ b/fitz/crypt_sha2.c @@ -7,7 +7,7 @@ This file has been put into the public domain. You can do whatever you want with this file. */ -#include "fitz.h" +#include "fitz-internal.h" static inline int isbigendian(void) { diff --git a/fitz/dev_bbox.c b/fitz/dev_bbox.c index b015c585..163780d0 100644 --- a/fitz/dev_bbox.c +++ b/fitz/dev_bbox.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* TODO: add clip stack and use to intersect bboxes */ diff --git a/fitz/dev_list.c b/fitz/dev_list.c index 1d82421e..d0dfabc5 100644 --- a/fitz/dev_list.c +++ b/fitz/dev_list.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" typedef struct fz_display_node_s fz_display_node; diff --git a/fitz/dev_null.c b/fitz/dev_null.c index d817932d..886cebe1 100644 --- a/fitz/dev_null.c +++ b/fitz/dev_null.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" fz_device * fz_new_device(fz_context *ctx, void *user) diff --git a/fitz/dev_text.c b/fitz/dev_text.c index d38fab21..79d8c137 100644 --- a/fitz/dev_text.c +++ b/fitz/dev_text.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #define LINE_DIST 0.9f #define SPACE_DIST 0.2f @@ -172,7 +172,7 @@ fz_debug_text_span_xml(fz_text_span *span) putchar(c); else { - n = runetochar(buf, &c); + n = fz_runetochar(buf, c); for (k = 0; k < n; k++) putchar(buf[k]); } @@ -204,7 +204,7 @@ fz_debug_text_span(fz_text_span *span) putchar(c); else { - n = runetochar(buf, &c); + n = fz_runetochar(buf, c); for (k = 0; k < n; k++) putchar(buf[k]); } diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c index 9faffc35..f75f19d5 100644 --- a/fitz/dev_trace.c +++ b/fitz/dev_trace.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" static void fz_trace_matrix(fz_matrix ctm) diff --git a/fitz/doc_document.c b/fitz/doc_document.c index ca13af72..2da7a110 100644 --- a/fitz/doc_document.c +++ b/fitz/doc_document.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* Yuck! Promiscuous we are. */ extern struct pdf_document *pdf_open_document(fz_context *ctx, char *filename); diff --git a/fitz/doc_link.c b/fitz/doc_link.c index 71f5dfbf..d558d18a 100644 --- a/fitz/doc_link.c +++ b/fitz/doc_link.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" void fz_free_link_dest(fz_context *ctx, fz_link_dest *dest) diff --git a/fitz/doc_outline.c b/fitz/doc_outline.c index b69debaf..4847b919 100644 --- a/fitz/doc_outline.c +++ b/fitz/doc_outline.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" void fz_free_outline(fz_context *ctx, fz_outline *outline) @@ -14,8 +14,8 @@ fz_free_outline(fz_context *ctx, fz_outline *outline) } } -void -fz_debug_outline_xml(fz_context *ctx, fz_outline *outline, int level) +static void +do_debug_outline_xml(fz_outline *outline, int level) { while (outline) { @@ -23,7 +23,7 @@ fz_debug_outline_xml(fz_context *ctx, fz_outline *outline, int level) if (outline->down) { printf(">\n"); - fz_debug_outline_xml(ctx, outline->down, level + 1); + do_debug_outline_xml(outline->down, level + 1); printf("</outline>\n"); } else @@ -35,7 +35,13 @@ fz_debug_outline_xml(fz_context *ctx, fz_outline *outline, int level) } void -fz_debug_outline(fz_context *ctx, fz_outline *outline, int level) +fz_debug_outline_xml(fz_context *ctx, fz_outline *outline) +{ + do_debug_outline_xml(outline, 0); +} + +static void +do_debug_outline(fz_outline *outline, int level) { int i; while (outline) @@ -44,7 +50,13 @@ fz_debug_outline(fz_context *ctx, fz_outline *outline, int level) putchar('\t'); printf("%s\t%d\n", outline->title, outline->dest.kind == FZ_LINK_GOTO ? outline->dest.ld.gotor.page + 1 : 0); if (outline->down) - fz_debug_outline(ctx, outline->down, level + 1); + do_debug_outline(outline->down, level + 1); outline = outline->next; } } + +void +fz_debug_outline(fz_context *ctx, fz_outline *outline) +{ + do_debug_outline(outline, 0); +} diff --git a/fitz/filt_basic.c b/fitz/filt_basic.c index ae239fed..09d63402 100644 --- a/fitz/filt_basic.c +++ b/fitz/filt_basic.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* Pretend we have a filter that just copies data forever */ diff --git a/fitz/filt_dctd.c b/fitz/filt_dctd.c index 3abe0468..23744f01 100644 --- a/fitz/filt_dctd.c +++ b/fitz/filt_dctd.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include <jpeglib.h> #include <setjmp.h> diff --git a/fitz/filt_faxd.c b/fitz/filt_faxd.c index 4e522eb5..ada7e87b 100644 --- a/fitz/filt_faxd.c +++ b/fitz/filt_faxd.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* Fax G3/G4 decoder */ diff --git a/fitz/filt_flate.c b/fitz/filt_flate.c index 2eb0c563..24b6c081 100644 --- a/fitz/filt_flate.c +++ b/fitz/filt_flate.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include <zlib.h> diff --git a/fitz/filt_jbig2d.c b/fitz/filt_jbig2d.c index 3afcbcb0..415534c0 100644 --- a/fitz/filt_jbig2d.c +++ b/fitz/filt_jbig2d.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #ifdef _WIN32 /* Microsoft Visual C++ */ diff --git a/fitz/filt_lzwd.c b/fitz/filt_lzwd.c index ac952ccf..3ee4d34c 100644 --- a/fitz/filt_lzwd.c +++ b/fitz/filt_lzwd.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* TODO: error checking */ diff --git a/fitz/filt_predict.c b/fitz/filt_predict.c index 8221c251..e68743d3 100644 --- a/fitz/filt_predict.c +++ b/fitz/filt_predict.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* TODO: check if this works with 16bpp images */ diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h new file mode 100644 index 00000000..0f4b47c7 --- /dev/null +++ b/fitz/fitz-internal.h @@ -0,0 +1,1091 @@ +#ifndef FITZ_INTERNAL_H +#define FITZ_INTERNAL_H + +#include "fitz.h" + +struct fz_warn_context_s +{ + char message[256]; + int count; +}; + + +fz_context *fz_clone_context_internal(fz_context *ctx); + +void fz_new_aa_context(fz_context *ctx); +void fz_free_aa_context(fz_context *ctx); +void fz_copy_aa_context(fz_context *dst, fz_context *src); + +/* Default locks */ +extern fz_locks_context fz_locks_default; + +#if defined(MEMENTO) || defined(DEBUG) +#define FITZ_DEBUG_LOCKING +#endif + +#ifdef FITZ_DEBUG_LOCKING + +void fz_assert_lock_held(fz_context *ctx, int lock); +void fz_assert_lock_not_held(fz_context *ctx, int lock); +void fz_lock_debug_lock(fz_context *ctx, int lock); +void fz_lock_debug_unlock(fz_context *ctx, int lock); + +#else + +#define fz_assert_lock_held(A,B) do { } while (0) +#define fz_assert_lock_not_held(A,B) do { } while (0) +#define fz_lock_debug_lock(A,B) do { } while (0) +#define fz_lock_debug_unlock(A,B) do { } while (0) + +#endif /* !FITZ_DEBUG_LOCKING */ + +static inline void +fz_lock(fz_context *ctx, int lock) +{ + fz_lock_debug_lock(ctx, lock); + ctx->locks->lock(ctx->locks->user, lock); +} + +static inline void +fz_unlock(fz_context *ctx, int lock) +{ + fz_lock_debug_unlock(ctx, lock); + ctx->locks->unlock(ctx->locks->user, lock); +} + + +/* + * Basic runtime and utility functions + */ + +/* + fz_malloc_struct: Allocate storage for a structure (with scavenging), + clear it, and (in Memento builds) tag the pointer as belonging to a + struct of this type. + + CTX: The context. + + STRUCT: The structure type. + + Returns a pointer to allocated (and cleared) structure. Throws + exception on failure to allocate. +*/ +/* alloc and zero a struct, and tag it for memento */ +#define fz_malloc_struct(CTX, STRUCT) \ + Memento_label(fz_calloc(CTX,1,sizeof(STRUCT)), #STRUCT) + +/* Range checking atof */ +float fz_atof(const char *s); + +/* + * Generic hash-table with fixed-length keys. + */ + +typedef struct fz_hash_table_s fz_hash_table; + +fz_hash_table *fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock); +void fz_debug_hash(fz_context *ctx, fz_hash_table *table); +void fz_empty_hash(fz_context *ctx, fz_hash_table *table); +void fz_free_hash(fz_context *ctx, fz_hash_table *table); + +void *fz_hash_find(fz_context *ctx, fz_hash_table *table, void *key); +void *fz_hash_insert(fz_context *ctx, fz_hash_table *table, void *key, void *val); +void fz_hash_remove(fz_context *ctx, fz_hash_table *table, void *key); + +int fz_hash_len(fz_context *ctx, fz_hash_table *table); +void *fz_hash_get_key(fz_context *ctx, fz_hash_table *table, int idx); +void *fz_hash_get_val(fz_context *ctx, fz_hash_table *table, int idx); + +/* + * Math and geometry + */ + +/* Multiply scaled two integers in the 0..255 range */ +static inline int fz_mul255(int a, int b) +{ + /* see Jim Blinn's book "Dirty Pixels" for how this works */ + int x = a * b + 128; + x += x >> 8; + return x >> 8; +} + +/* Expand a value A from the 0...255 range to the 0..256 range */ +#define FZ_EXPAND(A) ((A)+((A)>>7)) + +/* Combine values A (in any range) and B (in the 0..256 range), + * to give a single value in the same range as A was. */ +#define FZ_COMBINE(A,B) (((A)*(B))>>8) + +/* Combine values A and C (in the same (any) range) and B and D (in the + * 0..256 range), to give a single value in the same range as A and C were. */ +#define FZ_COMBINE2(A,B,C,D) (FZ_COMBINE((A), (B)) + FZ_COMBINE((C), (D))) + +/* Blend SRC and DST (in the same range) together according to + * AMOUNT (in the 0...256 range). */ +#define FZ_BLEND(SRC, DST, AMOUNT) ((((SRC)-(DST))*(AMOUNT) + ((DST)<<8))>>8) + +void fz_gridfit_matrix(fz_matrix *m); +float fz_matrix_max_expansion(fz_matrix m); + +/* + * Basic crypto functions. + * Independent of the rest of fitz. + * For further encapsulation in filters, or not. + */ + +/* md5 digests */ + +typedef struct fz_md5_s fz_md5; + +struct fz_md5_s +{ + unsigned int state[4]; + unsigned int count[2]; + unsigned char buffer[64]; +}; + +void fz_md5_init(fz_md5 *state); +void fz_md5_update(fz_md5 *state, const unsigned char *input, unsigned inlen); +void fz_md5_final(fz_md5 *state, unsigned char digest[16]); + +/* sha-256 digests */ + +typedef struct fz_sha256_s fz_sha256; + +struct fz_sha256_s +{ + unsigned int state[8]; + unsigned int count[2]; + union { + unsigned char u8[64]; + unsigned int u32[16]; + } buffer; +}; + +void fz_sha256_init(fz_sha256 *state); +void fz_sha256_update(fz_sha256 *state, const unsigned char *input, unsigned int inlen); +void fz_sha256_final(fz_sha256 *state, unsigned char digest[32]); + +/* arc4 crypto */ + +typedef struct fz_arc4_s fz_arc4; + +struct fz_arc4_s +{ + unsigned x; + unsigned y; + unsigned char state[256]; +}; + +void fz_arc4_init(fz_arc4 *state, const unsigned char *key, unsigned len); +void fz_arc4_encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *src, unsigned len); + +/* AES block cipher implementation from XYSSL */ + +typedef struct fz_aes_s fz_aes; + +#define AES_DECRYPT 0 +#define AES_ENCRYPT 1 + +struct fz_aes_s +{ + int nr; /* number of rounds */ + unsigned long *rk; /* AES round keys */ + unsigned long buf[68]; /* unaligned data */ +}; + +void aes_setkey_enc( fz_aes *ctx, const unsigned char *key, int keysize ); +void aes_setkey_dec( fz_aes *ctx, const unsigned char *key, int keysize ); +void aes_crypt_cbc( fz_aes *ctx, int mode, int length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/* + Resource store + + MuPDF stores decoded "objects" into a store for potential reuse. + If the size of the store gets too big, objects stored within it can + be evicted and freed to recover space. When MuPDF comes to decode + such an object, it will check to see if a version of this object is + already in the store - if it is, it will simply reuse it. If not, it + will decode it and place it into the store. + + All objects that can be placed into the store are derived from the + fz_storable type (i.e. this should be the first component of the + objects structure). This allows for consistent (thread safe) + reference counting, and includes a function that will be called to + free the object as soon as the reference count reaches zero. + + Most objects offer fz_keep_XXXX/fz_drop_XXXX functions derived + from fz_keep_storable/fz_drop_storable. Creation of such objects + includes a call to FZ_INIT_STORABLE to set up the fz_storable header. + */ + +typedef struct fz_storable_s fz_storable; + +typedef void (fz_store_free_fn)(fz_context *, fz_storable *); + +struct fz_storable_s { + int refs; + fz_store_free_fn *free; +}; + +#define FZ_INIT_STORABLE(S_,RC,FREE) \ + do { fz_storable *S = &(S_)->storable; S->refs = (RC); \ + S->free = (FREE); \ + } while (0) + +void *fz_keep_storable(fz_context *, fz_storable *); +void fz_drop_storable(fz_context *, fz_storable *); + +/* + The store can be seen as a dictionary that maps keys to fz_storable + values. In order to allow keys of different types to be stored, we + have a structure full of functions for each key 'type'; this + fz_store_type pointer is stored with each key, and tells the store + how to perform certain operations (like taking/dropping a reference, + comparing two keys, outputting details for debugging etc). + + The store uses a hash table internally for speed where possible. In + order for this to work, we need a mechanism for turning a generic + 'key' into 'a hashable string'. For this purpose the type structure + contains a make_hash_key function pointer that maps from a void * + to an fz_store_hash structure. If make_hash_key function returns 0, + then the key is determined not to be hashable, and the value is + not stored in the hash table. +*/ +typedef struct fz_store_hash_s fz_store_hash; + +struct fz_store_hash_s +{ + fz_store_free_fn *free; + union + { + struct + { + int i0; + int i1; + } i; + struct + { + void *ptr; + int i; + } pi; + } u; +}; + +typedef struct fz_store_type_s fz_store_type; + +struct fz_store_type_s +{ + int (*make_hash_key)(fz_store_hash *, void *); + void *(*keep_key)(fz_context *,void *); + void (*drop_key)(fz_context *,void *); + int (*cmp_key)(void *, void *); + void (*debug)(void *); +}; + +/* + fz_store_new_context: Create a new store inside the context + + max: The maximum size (in bytes) that the store is allowed to grow + to. FZ_STORE_UNLIMITED means no limit. +*/ +void fz_new_store_context(fz_context *ctx, unsigned int max); + +/* + fz_drop_store_context: Drop a reference to the store. +*/ +void fz_drop_store_context(fz_context *ctx); + +/* + fz_keep_store_context: Take a reference to the store. +*/ +fz_store *fz_keep_store_context(fz_context *ctx); + +/* + fz_debug_store: Dump the contents of the store for debugging. +*/ +void fz_debug_store(fz_context *ctx); + +/* + fz_store_item: Add an item to the store. + + Add an item into the store, returning NULL for success. If an item + with the same key is found in the store, then our item will not be + inserted, and the function will return a pointer to that value + instead. This function takes its own reference to val, as required + (i.e. the caller maintains ownership of its own reference). + + key: The key to use to index the item. + + val: The value to store. + + itemsize: The size in bytes of the value (as counted towards the + store size). + + type: Functions used to manipulate the key. +*/ +void *fz_store_item(fz_context *ctx, void *key, void *val, unsigned int itemsize, fz_store_type *type); + +/* + fz_find_item: Find an item within the store. + + free: The function used to free the value (to ensure we get a value + of the correct type). + + key: The key to use to index the item. + + type: Functions used to manipulate the key. + + Returns NULL for not found, otherwise returns a pointer to the value + indexed by key to which a reference has been taken. +*/ +void *fz_find_item(fz_context *ctx, fz_store_free_fn *free, void *key, fz_store_type *type); + +/* + fz_remove_item: Remove an item from the store. + + If an item indexed by the given key exists in the store, remove it. + + free: The function used to free the value (to ensure we get a value + of the correct type). + + key: The key to use to find the item to remove. + + type: Functions used to manipulate the key. +*/ +void fz_remove_item(fz_context *ctx, fz_store_free_fn *free, void *key, fz_store_type *type); + +/* + fz_empty_store: Evict everything from the store. +*/ +void fz_empty_store(fz_context *ctx); + +/* + fz_store_scavenge: Internal function used as part of the scavenging + allocator; when we fail to allocate memory, before returning a + failure to the caller, we try to scavenge space within the store by + evicting at least 'size' bytes. The allocator then retries. + + size: The number of bytes we are trying to have free. + + phase: What phase of the scavenge we are in. Updated on exit. + + Returns non zero if we managed to free any memory. +*/ +int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase); + +struct fz_buffer_s +{ + int refs; + unsigned char *data; + int cap, len; +}; + +/* + fz_new_buffer: Create a new buffer. + + capacity: Initial capacity. + + Returns pointer to new buffer. Throws exception on allocation + failure. +*/ +fz_buffer *fz_new_buffer(fz_context *ctx, int capacity); + +/* + fz_resize_buffer: Ensure that a buffer has a given capacity, + truncating data if required. + + buf: The buffer to alter. + + capacity: The desired capacity for the buffer. If the current size + of the buffer contents is smaller than capacity, it is truncated. + +*/ +void fz_resize_buffer(fz_context *ctx, fz_buffer *buf, int capacity); + +/* + fz_grow_buffer: Make some space within a buffer (i.e. ensure that + capacity > size). + + buf: The buffer to grow. + + May throw exception on failure to allocate. +*/ +void fz_grow_buffer(fz_context *ctx, fz_buffer *buf); + +/* + fz_trim_buffer: Trim wasted capacity from a buffer. + + buf: The buffer to trim. +*/ +void fz_trim_buffer(fz_context *ctx, fz_buffer *buf); + +struct fz_stream_s +{ + fz_context *ctx; + int refs; + int error; + int eof; + int pos; + int avail; + int bits; + int locked; + unsigned char *bp, *rp, *wp, *ep; + void *state; + int (*read)(fz_stream *stm, unsigned char *buf, int len); + void (*close)(fz_context *ctx, void *state); + void (*seek)(fz_stream *stm, int offset, int whence); + unsigned char buf[4096]; +}; + +void fz_lock_stream(fz_stream *stm); + +fz_stream *fz_new_stream(fz_context *ctx, void*, int(*)(fz_stream*, unsigned char*, int), void(*)(fz_context *, void *)); +fz_stream *fz_keep_stream(fz_stream *stm); +void fz_fill_buffer(fz_stream *stm); + +void fz_read_line(fz_stream *stm, char *buf, int max); + +static inline int fz_read_byte(fz_stream *stm) +{ + if (stm->rp == stm->wp) + { + fz_fill_buffer(stm); + return stm->rp < stm->wp ? *stm->rp++ : EOF; + } + return *stm->rp++; +} + +static inline int fz_peek_byte(fz_stream *stm) +{ + if (stm->rp == stm->wp) + { + fz_fill_buffer(stm); + return stm->rp < stm->wp ? *stm->rp : EOF; + } + return *stm->rp; +} + +static inline void fz_unread_byte(fz_stream *stm) +{ + if (stm->rp > stm->bp) + stm->rp--; +} + +static inline int fz_is_eof(fz_stream *stm) +{ + if (stm->rp == stm->wp) + { + if (stm->eof) + return 1; + return fz_peek_byte(stm) == EOF; + } + return 0; +} + +static inline unsigned int fz_read_bits(fz_stream *stm, int n) +{ + unsigned int x; + + if (n <= stm->avail) + { + stm->avail -= n; + x = (stm->bits >> stm->avail) & ((1 << n) - 1); + } + else + { + x = stm->bits & ((1 << stm->avail) - 1); + n -= stm->avail; + stm->avail = 0; + + while (n > 8) + { + x = (x << 8) | fz_read_byte(stm); + n -= 8; + } + + if (n > 0) + { + stm->bits = fz_read_byte(stm); + stm->avail = 8 - n; + x = (x << n) | (stm->bits >> stm->avail); + } + } + + return x; +} + +static inline void fz_sync_bits(fz_stream *stm) +{ + stm->avail = 0; +} + +static inline int fz_is_eof_bits(fz_stream *stm) +{ + return fz_is_eof(stm) && (stm->avail == 0 || stm->bits == EOF); +} + +/* + * Data filters. + */ + +fz_stream *fz_open_copy(fz_stream *chain); +fz_stream *fz_open_null(fz_stream *chain, int len); +fz_stream *fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen); +fz_stream *fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen); +fz_stream *fz_open_a85d(fz_stream *chain); +fz_stream *fz_open_ahxd(fz_stream *chain); +fz_stream *fz_open_rld(fz_stream *chain); +fz_stream *fz_open_dctd(fz_stream *chain, int color_transform); +fz_stream *fz_open_resized_dctd(fz_stream *chain, int color_transform, int factor); +fz_stream *fz_open_faxd(fz_stream *chain, + int k, int end_of_line, int encoded_byte_align, + int columns, int rows, int end_of_block, int black_is_1); +fz_stream *fz_open_flated(fz_stream *chain); +fz_stream *fz_open_lzwd(fz_stream *chain, int early_change); +fz_stream *fz_open_predict(fz_stream *chain, int predictor, int columns, int colors, int bpc); +fz_stream *fz_open_jbig2d(fz_stream *chain, fz_buffer *global); + +/* + * Resources and other graphics related objects. + */ + +enum { FZ_MAX_COLORS = 32 }; + +int fz_find_blendmode(char *name); +char *fz_blendmode_name(int blendmode); + +struct fz_bitmap_s +{ + int refs; + int w, h, stride, n; + unsigned char *samples; +}; + +fz_bitmap *fz_new_bitmap(fz_context *ctx, int w, int h, int n); + +void fz_bitmap_details(fz_bitmap *bitmap, int *w, int *h, int *n, int *stride); + +void fz_clear_bitmap(fz_context *ctx, fz_bitmap *bit); + +/* + Pixmaps represent a set of pixels for a 2 dimensional region of a + plane. Each pixel has n components per pixel, the last of which is + always alpha. The data is in premultiplied alpha when rendering, but + non-premultiplied for colorspace conversions and rescaling. + + x, y: The minimum x and y coord of the region in pixels. + + w, h: The width and height of the region in pixels. + + n: The number of color components in the image. Always + includes a separate alpha channel. For mask images n=1, for greyscale + (plus alpha) images n=2, for rgb (plus alpha) images n=3. + + interpolate: A boolean flag set to non-zero if the image + will be drawn using linear interpolation, or set to zero if + image will be using nearest neighbour sampling. + + xres, yres: Image resolution in dpi. Default is 96 dpi. + + colorspace: Pointer to a colorspace object describing the colorspace + the pixmap is in. If NULL, the image is a mask. + + samples: A simple block of memory w * h * n bytes of memory in which + the components are stored. The first n bytes are components 0 to n-1 + for the pixel at (x,y). Each successive n bytes gives another pixel + in scanline order. Subsequent scanlines follow on with no padding. + + free_samples: Is zero when an application has provided its own + buffer for pixel data through fz_new_pixmap_with_rect_and_data. + If not zero the buffer will be freed when fz_drop_pixmap is + called for the pixmap. +*/ +struct fz_pixmap_s +{ + fz_storable storable; + int x, y, w, h, n; + int interpolate; + int xres, yres; + fz_colorspace *colorspace; + unsigned char *samples; + int free_samples; +}; + +fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, unsigned char *samples); + +fz_pixmap *fz_new_pixmap_with_rect_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_bbox bbox, unsigned char *samples); + +void fz_free_pixmap_imp(fz_context *ctx, fz_storable *pix); + +void fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *pix, int value, fz_bbox r); +void fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_bbox r); +void fz_premultiply_pixmap(fz_context *ctx, fz_pixmap *pix); +fz_pixmap *fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray, int luminosity); +unsigned int fz_pixmap_size(fz_context *ctx, fz_pixmap *pix); + +fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_bbox *clip); + +struct fz_image_s +{ + fz_storable storable; + int w, h; + fz_image *mask; + fz_colorspace *colorspace; + fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, int w, int h); +}; + +fz_pixmap *fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *cs); +fz_pixmap *fz_load_jpeg(fz_context *doc, unsigned char *data, int size); +fz_pixmap *fz_load_png(fz_context *doc, unsigned char *data, int size); +fz_pixmap *fz_load_tiff(fz_context *doc, unsigned char *data, int size); + +struct fz_halftone_s +{ + int refs; + int n; + fz_pixmap *comp[1]; +}; + +fz_halftone *fz_new_halftone(fz_context *ctx, int num_comps); +fz_halftone *fz_get_default_halftone(fz_context *ctx, int num_comps); +void fz_drop_halftone(fz_context *ctx, fz_halftone *half); +fz_halftone *fz_keep_halftone(fz_context *ctx, fz_halftone *half); + +struct fz_colorspace_s +{ + fz_storable storable; + unsigned int size; + char name[16]; + int n; + void (*to_rgb)(fz_context *ctx, fz_colorspace *, float *src, float *rgb); + void (*from_rgb)(fz_context *ctx, fz_colorspace *, float *rgb, float *dst); + void (*free_data)(fz_context *Ctx, fz_colorspace *); + void *data; +}; + +fz_colorspace *fz_new_colorspace(fz_context *ctx, char *name, int n); +fz_colorspace *fz_keep_colorspace(fz_context *ctx, fz_colorspace *colorspace); +void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace); +void fz_free_colorspace_imp(fz_context *ctx, fz_storable *colorspace); + +void fz_convert_color(fz_context *ctx, fz_colorspace *dsts, float *dstv, fz_colorspace *srcs, float *srcv); + +/* + * Fonts come in two variants: + * Regular fonts are handled by FreeType. + * Type 3 fonts have callbacks to the interpreter. + */ + +char *ft_error_string(int err); + +struct fz_font_s +{ + int refs; + char name[32]; + + void *ft_face; /* has an FT_Face if used */ + int ft_substitute; /* ... substitute metrics */ + int ft_bold; /* ... synthesize bold */ + int ft_italic; /* ... synthesize italic */ + int ft_hint; /* ... force hinting for DynaLab fonts */ + + /* origin of font data */ + char *ft_file; + unsigned char *ft_data; + int ft_size; + + fz_matrix t3matrix; + void *t3resources; + fz_buffer **t3procs; /* has 256 entries if used */ + float *t3widths; /* has 256 entries if used */ + char *t3flags; /* has 256 entries if used */ + void *t3doc; /* a pdf_document for the callback */ + void (*t3run)(void *doc, void *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate); + void (*t3freeres)(void *doc, void *resources); + + fz_rect bbox; /* font bbox is used only for t3 fonts */ + + /* per glyph bounding box cache */ + int use_glyph_bbox; + int bbox_count; + fz_rect *bbox_table; + + /* substitute metrics */ + int width_count; + int *width_table; /* in 1000 units */ +}; + +void fz_new_font_context(fz_context *ctx); +fz_font_context *fz_keep_font_context(fz_context *ctx); +void fz_drop_font_context(fz_context *ctx); + +fz_font *fz_new_type3_font(fz_context *ctx, char *name, fz_matrix matrix); + +fz_font *fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index, int use_glyph_bbox); +fz_font *fz_new_font_from_file(fz_context *ctx, char *path, int index, int use_glyph_bbox); + +fz_font *fz_keep_font(fz_context *ctx, fz_font *font); +void fz_drop_font(fz_context *ctx, fz_font *font); + +void fz_debug_font(fz_context *ctx, fz_font *font); + +void fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float xmax, float ymax); +fz_rect fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm); +int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid); + +/* + * Vector path buffer. + * It can be stroked and dashed, or be filled. + * It has a fill rule (nonzero or even_odd). + * + * When rendering, they are flattened, stroked and dashed straight + * into the Global Edge List. + */ + +typedef struct fz_path_s fz_path; +typedef struct fz_stroke_state_s fz_stroke_state; + +typedef union fz_path_item_s fz_path_item; + +typedef enum fz_path_item_kind_e +{ + FZ_MOVETO, + FZ_LINETO, + FZ_CURVETO, + FZ_CLOSE_PATH +} fz_path_item_kind; + +typedef enum fz_linecap_e +{ + FZ_LINECAP_BUTT = 0, + FZ_LINECAP_ROUND = 1, + FZ_LINECAP_SQUARE = 2, + FZ_LINECAP_TRIANGLE = 3 +} fz_linecap; + +typedef enum fz_linejoin_e +{ + FZ_LINEJOIN_MITER = 0, + FZ_LINEJOIN_ROUND = 1, + FZ_LINEJOIN_BEVEL = 2, + FZ_LINEJOIN_MITER_XPS = 3 +} fz_linejoin; + +union fz_path_item_s +{ + fz_path_item_kind k; + float v; +}; + +struct fz_path_s +{ + int len, cap; + fz_path_item *items; + int last; +}; + +struct fz_stroke_state_s +{ + fz_linecap start_cap, dash_cap, end_cap; + fz_linejoin linejoin; + float linewidth; + float miterlimit; + float dash_phase; + int dash_len; + float dash_list[32]; +}; + +fz_path *fz_new_path(fz_context *ctx); +void fz_moveto(fz_context*, fz_path*, float x, float y); +void fz_lineto(fz_context*, fz_path*, float x, float y); +void fz_curveto(fz_context*,fz_path*, float, float, float, float, float, float); +void fz_curvetov(fz_context*,fz_path*, float, float, float, float); +void fz_curvetoy(fz_context*,fz_path*, float, float, float, float); +void fz_closepath(fz_context*,fz_path*); +void fz_free_path(fz_context *ctx, fz_path *path); + +void fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix transform); + +fz_path *fz_clone_path(fz_context *ctx, fz_path *old); + +fz_rect fz_bound_path(fz_context *ctx, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm); +void fz_debug_path(fz_context *ctx, fz_path *, int indent); + +/* + * Glyph cache + */ + +void fz_new_glyph_cache_context(fz_context *ctx); +fz_glyph_cache *fz_keep_glyph_cache(fz_context *ctx); +void fz_drop_glyph_cache_context(fz_context *ctx); +void fz_purge_glyph_cache(fz_context *ctx); + +fz_pixmap *fz_render_ft_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, int aa); +fz_pixmap *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model); +fz_pixmap *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state); +fz_pixmap *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_colorspace *model); +fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke); +void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate); + +/* + * Text buffer. + * + * The trm field contains the a, b, c and d coefficients. + * The e and f coefficients come from the individual elements, + * together they form the transform matrix for the glyph. + * + * Glyphs are referenced by glyph ID. + * The Unicode text equivalent is kept in a separate array + * with indexes into the glyph array. + */ + +typedef struct fz_text_s fz_text; +typedef struct fz_text_item_s fz_text_item; + +struct fz_text_item_s +{ + float x, y; + int gid; /* -1 for one gid to many ucs mappings */ + int ucs; /* -1 for one ucs to many gid mappings */ +}; + +struct fz_text_s +{ + fz_font *font; + fz_matrix trm; + int wmode; + int len, cap; + fz_text_item *items; +}; + +fz_text *fz_new_text(fz_context *ctx, fz_font *face, fz_matrix trm, int wmode); +void fz_add_text(fz_context *ctx, fz_text *text, int gid, int ucs, float x, float y); +void fz_free_text(fz_context *ctx, fz_text *text); +fz_rect fz_bound_text(fz_context *ctx, fz_text *text, fz_matrix ctm); +fz_text *fz_clone_text(fz_context *ctx, fz_text *old); +void fz_debug_text(fz_context *ctx, fz_text*, int indent); + +/* + * The shading code uses gouraud shaded triangle meshes. + */ + +enum +{ + FZ_LINEAR, + FZ_RADIAL, + FZ_MESH, +}; + +typedef struct fz_shade_s fz_shade; + +struct fz_shade_s +{ + fz_storable storable; + + fz_rect bbox; /* can be fz_infinite_rect */ + fz_colorspace *colorspace; + + fz_matrix matrix; /* matrix from pattern dict */ + int use_background; /* background color for fills but not 'sh' */ + float background[FZ_MAX_COLORS]; + + int use_function; + float function[256][FZ_MAX_COLORS + 1]; + + int type; /* linear, radial, mesh */ + int extend[2]; + + int mesh_len; + int mesh_cap; + float *mesh; /* [x y 0], [x y r], [x y t] or [x y c1 ... cn] */ +}; + +fz_shade *fz_keep_shade(fz_context *ctx, fz_shade *shade); +void fz_drop_shade(fz_context *ctx, fz_shade *shade); +void fz_free_shade_imp(fz_context *ctx, fz_storable *shade); +void fz_debug_shade(fz_context *ctx, fz_shade *shade); + +fz_rect fz_bound_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm); +void fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox); + +/* + * Scan converter + */ + +typedef struct fz_gel_s fz_gel; + +fz_gel *fz_new_gel(fz_context *ctx); +void fz_insert_gel(fz_gel *gel, float x0, float y0, float x1, float y1); +void fz_reset_gel(fz_gel *gel, fz_bbox clip); +void fz_sort_gel(fz_gel *gel); +fz_bbox fz_bound_gel(fz_gel *gel); +void fz_free_gel(fz_gel *gel); +int fz_is_rect_gel(fz_gel *gel); + +void fz_scan_convert(fz_gel *gel, int eofill, fz_bbox clip, fz_pixmap *pix, unsigned char *colorbv); + +void fz_flatten_fill_path(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness); +void fz_flatten_stroke_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth); +void fz_flatten_dash_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth); + +/* + * The device interface. + */ + +fz_device *fz_new_draw_device_type3(fz_context *ctx, fz_pixmap *dest); + +enum +{ + /* Hints */ + FZ_IGNORE_IMAGE = 1, + FZ_IGNORE_SHADE = 2, + + /* Flags */ + FZ_DEVFLAG_MASK = 1, + FZ_DEVFLAG_COLOR = 2, + FZ_DEVFLAG_UNCACHEABLE = 4, + FZ_DEVFLAG_FILLCOLOR_UNDEFINED = 8, + FZ_DEVFLAG_STROKECOLOR_UNDEFINED = 16, + FZ_DEVFLAG_STARTCAP_UNDEFINED = 32, + FZ_DEVFLAG_DASHCAP_UNDEFINED = 64, + FZ_DEVFLAG_ENDCAP_UNDEFINED = 128, + FZ_DEVFLAG_LINEJOIN_UNDEFINED = 256, + FZ_DEVFLAG_MITERLIMIT_UNDEFINED = 512, + FZ_DEVFLAG_LINEWIDTH_UNDEFINED = 1024, + /* Arguably we should have a bit for the dash pattern itself being + * undefined, but that causes problems; do we assume that it should + * always be set to non-dashing at the start of every glyph? */ +}; + +struct fz_device_s +{ + int hints; + int flags; + + void *user; + void (*free_user)(fz_device *); + fz_context *ctx; + + void (*fill_path)(fz_device *, fz_path *, int even_odd, fz_matrix, fz_colorspace *, float *color, float alpha); + void (*stroke_path)(fz_device *, fz_path *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha); + void (*clip_path)(fz_device *, fz_path *, fz_rect *rect, int even_odd, fz_matrix); + void (*clip_stroke_path)(fz_device *, fz_path *, fz_rect *rect, fz_stroke_state *, fz_matrix); + + void (*fill_text)(fz_device *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha); + void (*stroke_text)(fz_device *, fz_text *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha); + void (*clip_text)(fz_device *, fz_text *, fz_matrix, int accumulate); + void (*clip_stroke_text)(fz_device *, fz_text *, fz_stroke_state *, fz_matrix); + void (*ignore_text)(fz_device *, fz_text *, fz_matrix); + + void (*fill_shade)(fz_device *, fz_shade *shd, fz_matrix ctm, float alpha); + void (*fill_image)(fz_device *, fz_image *img, fz_matrix ctm, float alpha); + void (*fill_image_mask)(fz_device *, fz_image *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha); + void (*clip_image_mask)(fz_device *, fz_image *img, fz_rect *rect, fz_matrix ctm); + + void (*pop_clip)(fz_device *); + + void (*begin_mask)(fz_device *, fz_rect, int luminosity, fz_colorspace *, float *bc); + void (*end_mask)(fz_device *); + void (*begin_group)(fz_device *, fz_rect, int isolated, int knockout, int blendmode, float alpha); + void (*end_group)(fz_device *); + + void (*begin_tile)(fz_device *, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm); + void (*end_tile)(fz_device *); +}; + +void fz_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); +void fz_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); +void fz_clip_path(fz_device *dev, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm); +void fz_clip_stroke_path(fz_device *dev, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm); +void fz_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); +void fz_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); +void fz_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate); +void fz_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm); +void fz_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm); +void fz_pop_clip(fz_device *dev); +void fz_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha); +void fz_fill_image(fz_device *dev, fz_image *image, fz_matrix ctm, float alpha); +void fz_fill_image_mask(fz_device *dev, fz_image *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); +void fz_clip_image_mask(fz_device *dev, fz_image *image, fz_rect *rect, fz_matrix ctm); +void fz_begin_mask(fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, float *bc); +void fz_end_mask(fz_device *dev); +void fz_begin_group(fz_device *dev, fz_rect area, int isolated, int knockout, int blendmode, float alpha); +void fz_end_group(fz_device *dev); +void fz_begin_tile(fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm); +void fz_end_tile(fz_device *dev); + +fz_device *fz_new_device(fz_context *ctx, void *user); + + + +/* + * Plotting functions. + */ + +void fz_decode_tile(fz_pixmap *pix, float *decode); +void fz_decode_indexed_tile(fz_pixmap *pix, float *decode, int maxval); +void fz_unpack_tile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride, int scale); + +void fz_paint_solid_alpha(unsigned char * restrict dp, int w, int alpha); +void fz_paint_solid_color(unsigned char * restrict dp, int n, int w, unsigned char *color); + +void fz_paint_span(unsigned char * restrict dp, unsigned char * restrict sp, int n, int w, int alpha); +void fz_paint_span_with_color(unsigned char * restrict dp, unsigned char * restrict mp, int n, int w, unsigned char *color); + +void fz_paint_image(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, int alpha); +void fz_paint_image_with_color(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, unsigned char *colorbv); + +void fz_paint_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha); +void fz_paint_pixmap_with_mask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk); +void fz_paint_pixmap_with_rect(fz_pixmap *dst, fz_pixmap *src, int alpha, fz_bbox bbox); + +void fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int isolated, fz_pixmap *shape); +void fz_blend_pixel(unsigned char dp[3], unsigned char bp[3], unsigned char sp[3], int blendmode); + +enum +{ + /* PDF 1.4 -- standard separable */ + FZ_BLEND_NORMAL, + FZ_BLEND_MULTIPLY, + FZ_BLEND_SCREEN, + FZ_BLEND_OVERLAY, + FZ_BLEND_DARKEN, + FZ_BLEND_LIGHTEN, + FZ_BLEND_COLOR_DODGE, + FZ_BLEND_COLOR_BURN, + FZ_BLEND_HARD_LIGHT, + FZ_BLEND_SOFT_LIGHT, + FZ_BLEND_DIFFERENCE, + FZ_BLEND_EXCLUSION, + + /* PDF 1.4 -- standard non-separable */ + FZ_BLEND_HUE, + FZ_BLEND_SATURATION, + FZ_BLEND_COLOR, + FZ_BLEND_LUMINOSITY, + + /* For packing purposes */ + FZ_BLEND_MODEMASK = 15, + FZ_BLEND_ISOLATED = 16, + FZ_BLEND_KNOCKOUT = 32 +}; + +struct fz_document_s +{ + void (*close)(fz_document *); + int (*needs_password)(fz_document *doc); + int (*authenticate_password)(fz_document *doc, char *password); + fz_outline *(*load_outline)(fz_document *doc); + int (*count_pages)(fz_document *doc); + fz_page *(*load_page)(fz_document *doc, int number); + fz_link *(*load_links)(fz_document *doc, fz_page *page); + fz_rect (*bound_page)(fz_document *doc, fz_page *page); + void (*run_page)(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie); + void (*free_page)(fz_document *doc, fz_page *page); +}; + +#endif diff --git a/fitz/fitz.h b/fitz/fitz.h index 1ec1eb97..4592f315 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -1,9 +1,9 @@ -#ifndef _FITZ_H_ -#define _FITZ_H_ +#ifndef FITZ_H +#define FITZ_H /* - * Include the standard libc headers. - */ + Include the standard libc headers. +*/ #include <stdio.h> #include <stdlib.h> @@ -22,6 +22,12 @@ #include "memento.h" +/* + Some versions of setjmp/longjmp (notably MacOSX and ios) store/restore + signal handlers too. We don't alter signal handlers within mupdf, so + there is no need for us to store/restore - hence we use the + non-restoring variants. This makes a large speed difference. +*/ #ifdef __APPLE__ #define fz_setjmp _setjmp #define fz_longjmp _longjmp @@ -49,8 +55,8 @@ #define DIV_BY_ZERO(a, b, min, max) (((a) < 0) ^ ((b) < 0) ? (min) : (max)) /* - * Some differences in libc can be smoothed over - */ + Some differences in libc can be smoothed over +*/ #ifdef _MSC_VER /* Microsoft Visual C */ @@ -84,8 +90,8 @@ int gettimeofday(struct timeval *tv, struct timezone *tz); #endif /* - * Variadic macros, inline and restrict keywords - */ + Variadic macros, inline and restrict keywords +*/ #if __STDC_VERSION__ == 199901L /* C99 */ #elif _MSC_VER >= 1500 /* MSVC 9 or newer */ @@ -100,8 +106,8 @@ int gettimeofday(struct timeval *tv, struct timezone *tz); #endif /* - * GCC can do type checking of printf strings - */ + GCC can do type checking of printf strings +*/ #ifndef __printflike #if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7 @@ -148,8 +154,10 @@ struct fz_error_context_s void fz_var_imp(void *); #define fz_var(var) fz_var_imp((void *)&(var)) -/* Exception macro definitions. Just treat these as a black box - pay no - * attention to the man behind the curtain. */ +/* + Exception macro definitions. Just treat these as a black box - pay no + attention to the man behind the curtain. +*/ #define fz_try(ctx) \ if (fz_push_try(ctx->error), \ @@ -166,77 +174,11 @@ void fz_var_imp(void *); } \ if (ctx->error->stack[ctx->error->top--].code) -/* - -We also include a couple of other formulations of the macros, with -different strengths and weaknesses. These will be removed shortly, but -I want them in git for at least 1 revision so I have a record of them. - -A formulation of try/always/catch that lifts limitation 2 above, but -has problems when try/catch are nested in the same function; the inner -nestings need to use fz_always_(ctx, label) and fz_catch_(ctx, label) -instead. This was held as too high a price to pay to drop limitation 2. - -#define fz_try(ctx) \ - if (fz_push_try(ctx->error), \ - (ctx->error->stack[ctx->error->top].code = fz_setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0) \ - { do { - -#define fz_always_(ctx, label) \ - } while (0); \ - goto ALWAYS_LABEL_ ## label ; \ - } \ - else if (ctx->error->stack[ctx->error->top].code) \ - { ALWAYS_LABEL_ ## label : \ - do { - -#define fz_catch_(ctx, label) \ - } while(0); \ - if (ctx->error->stack[ctx->error->top--].code) \ - goto CATCH_LABEL_ ## label; \ - } \ - else if (ctx->error->top--, 1) \ - CATCH_LABEL ## label: - -#define fz_always(ctx) fz_always_(ctx, TOP) -#define fz_catch(ctx) fz_catch_(ctx, TOP) - -Another alternative formulation, that again removes limitation 2, but at -the cost of an always block always costing us 1 extra longjmp per -execution. Again this was felt to be too high a cost to use. - -#define fz_try(ctx) \ - if (fz_push_try(ctx->error), \ - (ctx->error->stack[ctx->error->top].code = fz_setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0) \ - { do { - -#define fz_always(ctx) \ - } while (0); \ - fz_longjmp(ctx->error->stack[ctx->error->top].buffer, 3); \ - } \ - else if (ctx->error->stack[ctx->error->top].code & 1) \ - { do { - -#define fz_catch(ctx) \ - } while(0); \ - if (ctx->error->stack[ctx->error->top].code == 1) \ - fz_longjmp(ctx->error->stack[ctx->error->top].buffer, 2); \ - ctx->error->top--;\ - } \ - else if (ctx->error->top--, 1) -*/ - void fz_push_try(fz_error_context *ex); void fz_throw(fz_context *, char *, ...) __printflike(2, 3); void fz_rethrow(fz_context *); - -struct fz_warn_context_s -{ - char message[256]; - int count; -}; - void fz_warn(fz_context *ctx, char *fmt, ...) __printflike(2, 3); + /* fz_flush_warnings: Flush any repeated warnings. @@ -263,6 +205,20 @@ struct fz_context_s }; /* + Specifies the maximum size in bytes of the resource store in + fz_context. Given as argument to fz_new_context. + + FZ_STORE_UNLIMITED: Let resource store grow unbounded. + + FZ_STORE_DEFAULT: A reasonable upper bound on the size, for + devices that are not memory constrained. +*/ +enum { + FZ_STORE_UNLIMITED = 0, + FZ_STORE_DEFAULT = 256 << 20, +}; + +/* fz_new_context: Allocate context containing global state. The global state contains an exception stack, resource store, @@ -308,7 +264,6 @@ fz_context *fz_new_context(fz_alloc_context *alloc, fz_locks_context *locks, uns Does not throw exception, but may return NULL. */ fz_context *fz_clone_context(fz_context *ctx); -fz_context *fz_clone_context_internal(fz_context *ctx); /* fz_free_context: Free a context and its global state. @@ -321,8 +276,19 @@ fz_context *fz_clone_context_internal(fz_context *ctx); */ void fz_free_context(fz_context *ctx); -void fz_new_aa_context(fz_context *ctx); -void fz_free_aa_context(fz_context *ctx); +/* + fz_get_aa_level: Get the number of bits of antialiasing we are + using. Between 0 and 8. +*/ +int fz_get_aa_level(fz_context *ctx); + +/* + fz_set_aa_level: Set the number of bits of antialiasing we should use. + + bits: The number of bits of antialiasing to use (values are clamped + to within the 0 to 8 range). +*/ +void fz_set_aa_level(fz_context *ctx, int bits); /* Locking functions @@ -345,15 +311,11 @@ void fz_free_aa_context(fz_context *ctx); enabled by defining FITZ_DEBUG_LOCKING. */ -#if defined(MEMENTO) || defined(DEBUG) -#define FITZ_DEBUG_LOCKING -#endif - struct fz_locks_context_s { void *user; - void (*lock)(void *, int); - void (*unlock)(void *, int); + void (*lock)(void *user, int lock); + void (*unlock)(void *user, int lock); }; enum { @@ -364,51 +326,80 @@ enum { FZ_LOCK_MAX }; -/* Default locks */ -extern fz_locks_context fz_locks_default; +/* + Memory Allocation and Scavenging: -#ifdef FITZ_DEBUG_LOCKING + All calls to MuPDFs allocator functions pass through to the + underlying allocators passed in when the initial context is + created, after locks are taken (using the supplied locking function) + to ensure that only one thread at a time calls through. -void fz_assert_lock_held(fz_context *ctx, int lock); -void fz_assert_lock_not_held(fz_context *ctx, int lock); -void fz_lock_debug_lock(fz_context *ctx, int lock); -void fz_lock_debug_unlock(fz_context *ctx, int lock); + If the underlying allocator fails, MuPDF attempts to make room for + the allocation by evicting elements from the store, then retrying. -#else + Any call to allocate may then result in several calls to the underlying + allocator, and result in elements that are only referred to by the + store being freed. +*/ -#define fz_assert_lock_held(A,B) do { } while (0) -#define fz_assert_lock_not_held(A,B) do { } while (0) -#define fz_lock_debug_lock(A,B) do { } while (0) -#define fz_lock_debug_unlock(A,B) do { } while (0) +/* + fz_malloc: Allocate a block of memory (with scavenging) -#endif /* !FITZ_DEBUG_LOCKING */ + size: The number of bytes to allocate. -static inline void -fz_lock(fz_context *ctx, int lock) -{ - fz_lock_debug_lock(ctx, lock); - ctx->locks->lock(ctx->locks->user, lock); -} + Returns a pointer to the allocated block. May return NULL if size is + 0. Throws exception on failure to allocate. +*/ +void *fz_malloc(fz_context *ctx, unsigned int size); -static inline void -fz_unlock(fz_context *ctx, int lock) -{ - fz_lock_debug_unlock(ctx, lock); - ctx->locks->unlock(ctx->locks->user, lock); -} +/* + fz_calloc: Allocate a zeroed block of memory (with scavenging) + + count: The number of objects to allocate space for. + size: The size (in bytes) of each object. + + Returns a pointer to the allocated block. May return NULL if size + and/or count are 0. Throws exception on failure to allocate. +*/ +void *fz_calloc(fz_context *ctx, unsigned int count, unsigned int size); /* - * Basic runtime and utility functions - */ + fz_malloc_array: Allocate a block of (non zeroed) memory (with + scavenging). Equivalent to fz_calloc without the memory clearing. -/* memory allocation */ + count: The number of objects to allocate space for. -/* The following throw exceptions on failure to allocate */ -void *fz_malloc(fz_context *ctx, unsigned int size); -void *fz_calloc(fz_context *ctx, unsigned int count, unsigned int size); + size: The size (in bytes) of each object. + + Returns a pointer to the allocated block. May return NULL if size + and/or count are 0. Throws exception on failure to allocate. +*/ void *fz_malloc_array(fz_context *ctx, unsigned int count, unsigned int size); + +/* + fz_resize_array: Resize a block of memory (with scavenging). + + p: The existing block to resize + + count: The number of objects to resize to. + + size: The size (in bytes) of each object. + + Returns a pointer to the resized block. May return NULL if size + and/or count are 0. Throws exception on failure to resize (original + block is left unchanged). +*/ void *fz_resize_array(fz_context *ctx, void *p, unsigned int count, unsigned int size); + +/* + fz_strdup: Duplicate a C string (with scavenging) + + s: The string to duplicate. + + Returns a pointer to a duplicated string. Throws exception on failure + to allocate. +*/ char *fz_strdup(fz_context *ctx, char *s); /* @@ -418,89 +409,201 @@ char *fz_strdup(fz_context *ctx, char *s); */ void fz_free(fz_context *ctx, void *p); -/* The following returns NULL on failure to allocate */ +/* + fz_malloc_no_throw: Allocate a block of memory (with scavenging) + + size: The number of bytes to allocate. + + Returns a pointer to the allocated block. May return NULL if size is + 0. Returns NULL on failure to allocate. +*/ void *fz_malloc_no_throw(fz_context *ctx, unsigned int size); -void *fz_malloc_array_no_throw(fz_context *ctx, unsigned int count, unsigned int size); + +/* + fz_calloc_no_throw: Allocate a zeroed block of memory (with scavenging) + + count: The number of objects to allocate space for. + + size: The size (in bytes) of each object. + + Returns a pointer to the allocated block. May return NULL if size + and/or count are 0. Returns NULL on failure to allocate. +*/ void *fz_calloc_no_throw(fz_context *ctx, unsigned int count, unsigned int size); + +/* + fz_malloc_array_no_throw: Allocate a block of (non zeroed) memory + (with scavenging). Equivalent to fz_calloc_no_throw without the + memory clearing. + + count: The number of objects to allocate space for. + + size: The size (in bytes) of each object. + + Returns a pointer to the allocated block. May return NULL if size + and/or count are 0. Returns NULL on failure to allocate. +*/ +void *fz_malloc_array_no_throw(fz_context *ctx, unsigned int count, unsigned int size); + +/* + fz_resize_array_no_throw: Resize a block of memory (with scavenging). + + p: The existing block to resize + + count: The number of objects to resize to. + + size: The size (in bytes) of each object. + + Returns a pointer to the resized block. May return NULL if size + and/or count are 0. Returns NULL on failure to resize (original + block is left unchanged). +*/ void *fz_resize_array_no_throw(fz_context *ctx, void *p, unsigned int count, unsigned int size); -char *fz_strdup_no_throw(fz_context *ctx, char *s); -/* alloc and zero a struct, and tag it for memento */ -#define fz_malloc_struct(CTX, STRUCT) \ - Memento_label(fz_calloc(CTX,1,sizeof(STRUCT)), #STRUCT) +/* + fz_strdup_no_throw: Duplicate a C string (with scavenging) -/* runtime (hah!) test for endian-ness */ -int fz_is_big_endian(void); + s: The string to duplicate. + + Returns a pointer to a duplicated string. Returns NULL on failure + to allocate. +*/ +char *fz_strdup_no_throw(fz_context *ctx, char *s); /* safe string functions */ +/* + fz_strsep: Given a pointer to a C string (or a pointer to NULL) break + it at the first occurence of a delimiter char (from a given set). + + stringp: Pointer to a C string pointer (or NULL). Updated on exit to + point to the first char of the string after the delimiter that was + found. The string pointed to by stringp will be corrupted by this + call (as the found delimiter will be overwritten by 0). + + delim: A C string of acceptable delimiter characters. + + Returns a pointer to a C string containing the chars of stringp up + to the first delimiter char (or the end of the string), or NULL. +*/ char *fz_strsep(char **stringp, const char *delim); + +/* + fz_strlcpy: Copy at most n-1 chars of a string into a destination + buffer with null termination, returning the real length of the + initial string (excluding terminator). + + dst: Destination buffer, at least n bytes long. + + src: C string (non-NULL). + + n: Size of dst buffer in bytes. + + Returns the length (excluding terminator) of src. +*/ int fz_strlcpy(char *dst, const char *src, int n); -int fz_strlcat(char *dst, const char *src, int n); -/* Range checking atof */ -float fz_atof(const char *s); +/* + fz_strlcat: Concatenate 2 strings, with a maximum length. -/* utf-8 encoding and decoding */ -int chartorune(int *rune, char *str); -int runetochar(char *str, int *rune); -int runelen(int c); + dst: pointer to first string in a buffer of n bytes. -/* getopt */ -extern int fz_getopt(int nargc, char * const *nargv, const char *ostr); -extern int fz_optind; -extern char *fz_optarg; + src: pointer to string to concatenate. + + n: Size (in bytes) of buffer that dst is in. + + Returns the real length that a concatenated dst + src would have been + (not including terminator). +*/ +int fz_strlcat(char *dst, const char *src, int n); /* - * Generic hash-table with fixed-length keys. - */ + fz_chartorune: UTF8 decode a string of chars to a rune. -typedef struct fz_hash_table_s fz_hash_table; + rune: Pointer to an int to assign the decoded 'rune' to. -fz_hash_table *fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock); -void fz_debug_hash(fz_context *ctx, fz_hash_table *table); -void fz_empty_hash(fz_context *ctx, fz_hash_table *table); -void fz_free_hash(fz_context *ctx, fz_hash_table *table); + str: Pointer to a UTF8 encoded string -void *fz_hash_find(fz_context *ctx, fz_hash_table *table, void *key); -void *fz_hash_insert(fz_context *ctx, fz_hash_table *table, void *key, void *val); -void fz_hash_remove(fz_context *ctx, fz_hash_table *table, void *key); + Returns the number of bytes consumed. Does not throw exceptions. +*/ +int fz_chartorune(int *rune, char *str); + +/* + runetochar: UTF8 encode a run to a string of chars. -int fz_hash_len(fz_context *ctx, fz_hash_table *table); -void *fz_hash_get_key(fz_context *ctx, fz_hash_table *table, int idx); -void *fz_hash_get_val(fz_context *ctx, fz_hash_table *table, int idx); + str: Pointer to a place to put the UTF8 encoded string. + + rune: Pointer to a 'rune'. + + Returns the number of bytes the rune took to output. Does not throw + exceptions. +*/ +int fz_runetochar(char *str, int rune); /* - * Math and geometry - */ + fz_runelen: Count many chars are required to represent a rune. + + rune: The rune to encode. + + Returns the number of bytes required to represent this run in UTF8. +*/ +int fz_runelen(int rune); + +/* getopt */ +extern int fz_getopt(int nargc, char * const *nargv, const char *ostr); +extern int fz_optind; +extern char *fz_optarg; -/* Multiply scaled two integers in the 0..255 range */ -static inline int fz_mul255(int a, int b) +/* + fz_point is a point in a two-dimensional space. +*/ +typedef struct fz_point_s fz_point; +struct fz_point_s { - /* see Jim Blinn's book "Dirty Pixels" for how this works */ - int x = a * b + 128; - x += x >> 8; - return x >> 8; -} + float x, y; +}; -/* Expand a value A from the 0...255 range to the 0..256 range */ -#define FZ_EXPAND(A) ((A)+((A)>>7)) +/* + fz_rect is a rectangle represented by two diagonally opposite + corners at arbitrary coordinates. -/* Combine values A (in any range) and B (in the 0..256 range), - * to give a single value in the same range as A was. */ -#define FZ_COMBINE(A,B) (((A)*(B))>>8) + Rectangles are always axis-aligned with the X- and Y- axes. + The relationship between the coordinates are that x0 <= x1 and + y0 <= y1 in all cases except for infinte rectangles. The area + of a rectangle is defined as (x1 - x0) * (y1 - y0). If either + x0 > x1 or y0 > y1 is true for a given rectangle then it is + defined to be infinite. -/* Combine values A and C (in the same (any) range) and B and D (in the - * 0..256 range), to give a single value in the same range as A and C were. */ -#define FZ_COMBINE2(A,B,C,D) (FZ_COMBINE((A), (B)) + FZ_COMBINE((C), (D))) + To check for empty or infinite rectangles use fz_is_empty_rect + and fz_is_infinite_rect. Compare to fz_bbox which has corners + at integer coordinates. -/* Blend SRC and DST (in the same range) together according to - * AMOUNT (in the 0...256 range). */ -#define FZ_BLEND(SRC, DST, AMOUNT) ((((SRC)-(DST))*(AMOUNT) + ((DST)<<8))>>8) + x0, y0: The top left corner. -typedef struct fz_matrix_s fz_matrix; -typedef struct fz_point_s fz_point; + x1, y1: The botton right corner. +*/ typedef struct fz_rect_s fz_rect; +struct fz_rect_s +{ + float x0, y0; + float x1, y1; +}; + +/* + fz_bbox is a bounding box similar to a fz_rect, except that + all corner coordinates are rounded to integer coordinates. + To check for empty or infinite bounding boxes use + fz_is_empty_bbox and fz_is_infinite_bbox. + + x0, y0: The top left corner. + + x1, y1: The bottom right corner. +*/ typedef struct fz_bbox_s fz_bbox; +struct fz_bbox_s +{ + int x0, y0; + int x1, y1; +}; /* A rectangle with sides of length one. @@ -584,59 +687,12 @@ extern const fz_bbox fz_infinite_bbox; | c d 0 | normally represented as [ a b c d e f ]. \ e f 1 / */ +typedef struct fz_matrix_s fz_matrix; struct fz_matrix_s { float a, b, c, d, e, f; }; -/* - fz_point is a point in a two-dimensional space. -*/ -struct fz_point_s -{ - float x, y; -}; - -/* - fz_rect is a rectangle represented by two diagonally opposite - corners at arbitrary coordinates. - - Rectangles are always axis-aligned with the X- and Y- axes. - The relationship between the coordinates are that x0 <= x1 and - y0 <= y1 in all cases except for infinte rectangles. The area - of a rectangle is defined as (x1 - x0) * (y1 - y0). If either - x0 > x1 or y0 > y1 is true for a given rectangle then it is - defined to be infinite. - - To check for empty or infinite rectangles use fz_is_empty_rect - and fz_is_infinite_rect. Compare to fz_bbox which has corners - at integer coordinates. - - x0, y0: The top left corner. - - x1, y1: The botton right corner. -*/ -struct fz_rect_s -{ - float x0, y0; - float x1, y1; -}; - -/* - fz_bbox is a bounding box similar to a fz_rect, except that - all corner coordinates are rounded to integer coordinates. - To check for empty or infinite bounding boxes use - fz_is_empty_bbox and fz_is_infinite_bbox. - - x0, y0: The top left corner. - - x1, y1: The botton right corner. -*/ -struct fz_bbox_s -{ - int x0, y0; - int x1, y1; -}; /* fz_identity: Identity transform matrix. @@ -727,8 +783,10 @@ fz_matrix fz_invert_matrix(fz_matrix matrix); */ int fz_is_rectilinear(fz_matrix m); -float fz_matrix_expansion(fz_matrix m); -float fz_matrix_max_expansion(fz_matrix m); +/* + fz_matrix_expansion: Calculate average scaling factor of matrix. +*/ +float fz_matrix_expansion(fz_matrix m); /* sumatrapdf */ /* fz_round_rect: Convert a rect into a bounding box. @@ -841,291 +899,39 @@ fz_rect fz_transform_rect(fz_matrix transform, fz_rect rect); */ fz_bbox fz_transform_bbox(fz_matrix matrix, fz_bbox bbox); -void fz_gridfit_matrix(fz_matrix *m); - /* - * Basic crypto functions. - * Independent of the rest of fitz. - * For further encapsulation in filters, or not. - */ + fz_buffer is a wrapper around a dynamically allocated array of bytes. -/* md5 digests */ - -typedef struct fz_md5_s fz_md5; - -struct fz_md5_s -{ - unsigned int state[4]; - unsigned int count[2]; - unsigned char buffer[64]; -}; - -void fz_md5_init(fz_md5 *state); -void fz_md5_update(fz_md5 *state, const unsigned char *input, unsigned inlen); -void fz_md5_final(fz_md5 *state, unsigned char digest[16]); - -/* sha-256 digests */ - -typedef struct fz_sha256_s fz_sha256; - -struct fz_sha256_s -{ - unsigned int state[8]; - unsigned int count[2]; - union { - unsigned char u8[64]; - unsigned int u32[16]; - } buffer; -}; - -void fz_sha256_init(fz_sha256 *state); -void fz_sha256_update(fz_sha256 *state, const unsigned char *input, unsigned int inlen); -void fz_sha256_final(fz_sha256 *state, unsigned char digest[32]); - -/* arc4 crypto */ - -typedef struct fz_arc4_s fz_arc4; - -struct fz_arc4_s -{ - unsigned x; - unsigned y; - unsigned char state[256]; -}; - -void fz_arc4_init(fz_arc4 *state, const unsigned char *key, unsigned len); -void fz_arc4_encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *src, unsigned len); - -/* AES block cipher implementation from XYSSL */ - -typedef struct fz_aes_s fz_aes; - -#define AES_DECRYPT 0 -#define AES_ENCRYPT 1 - -struct fz_aes_s -{ - int nr; /* number of rounds */ - unsigned long *rk; /* AES round keys */ - unsigned long buf[68]; /* unaligned data */ -}; - -void aes_setkey_enc( fz_aes *ctx, const unsigned char *key, int keysize ); -void aes_setkey_dec( fz_aes *ctx, const unsigned char *key, int keysize ); -void aes_crypt_cbc( fz_aes *ctx, int mode, int length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -/* - fz_buffer is a XXX + Buffers have a capacity (the number of bytes storage immediately + available) and a current size. */ typedef struct fz_buffer_s fz_buffer; -struct fz_buffer_s -{ - int refs; - unsigned char *data; - int cap, len; -}; - -fz_buffer *fz_new_buffer(fz_context *ctx, int size); -fz_buffer *fz_keep_buffer(fz_context *ctx, fz_buffer *buf); -void fz_drop_buffer(fz_context *ctx, fz_buffer *buf); - -void fz_resize_buffer(fz_context *ctx, fz_buffer *buf, int size); -void fz_grow_buffer(fz_context *ctx, fz_buffer *buf); -void fz_trim_buffer(fz_context *ctx, fz_buffer *buf); - -/* - Resource store - - MuPDF stores decoded "objects" into a store for potential reuse. - If the size of the store gets too big, objects stored within it can - be evicted and freed to recover space. When MuPDF comes to decode - such an object, it will check to see if a version of this object is - already in the store - if it is, it will simply reuse it. If not, it - will decode it and place it into the store. - - All objects that can be placed into the store are derived from the - fz_storable type (i.e. this should be the first component of the - objects structure). This allows for consistent (thread safe) - reference counting, and includes a function that will be called to - free the object as soon as the reference count reaches zero. - - Most objects offer fz_keep_XXXX/fz_drop_XXXX functions derived - from fz_keep_storable/fz_drop_storable. Creation of such objects - includes a call to FZ_INIT_STORABLE to set up the fz_storable header. - */ - -typedef struct fz_storable_s fz_storable; - -typedef void (fz_store_free_fn)(fz_context *, fz_storable *); - -struct fz_storable_s { - int refs; - fz_store_free_fn *free; -}; - -#define FZ_INIT_STORABLE(S_,RC,FREE) \ - do { fz_storable *S = &(S_)->storable; S->refs = (RC); \ - S->free = (FREE); \ - } while (0) - -void *fz_keep_storable(fz_context *, fz_storable *); -void fz_drop_storable(fz_context *, fz_storable *); - -/* - Specifies the maximum size in bytes of the resource store in - fz_context. Given as argument to fz_new_context. - - FZ_STORE_UNLIMITED: Let resource store grow unbounded. - - FZ_STORE_DEFAULT: A reasonable upper bound on the size, for - devices that are not memory constrained. -*/ -enum { - FZ_STORE_UNLIMITED = 0, - FZ_STORE_DEFAULT = 256 << 20, -}; - -/* - The store can be seen as a dictionary that maps keys to fz_storable - values. In order to allow keys of different types to be stored, we - have a structure full of functions for each key 'type'; this - fz_store_type pointer is stored with each key, and tells the store - how to perform certain operations (like taking/dropping a reference, - comparing two keys, outputting details for debugging etc). - - The store uses a hash table internally for speed where possible. In - order for this to work, we need a mechanism for turning a generic - 'key' into 'a hashable string'. For this purpose the type structure - contains a make_hash_key function pointer that maps from a void * - to an fz_store_hash structure. If make_hash_key function returns 0, - then the key is determined not to be hashable, and the value is - not stored in the hash table. -*/ -typedef struct fz_store_hash_s fz_store_hash; - -struct fz_store_hash_s -{ - fz_store_free_fn *free; - union - { - struct - { - int i0; - int i1; - } i; - struct - { - void *ptr; - int i; - } pi; - } u; -}; - -typedef struct fz_store_type_s fz_store_type; - -struct fz_store_type_s -{ - int (*make_hash_key)(fz_store_hash *, void *); - void *(*keep_key)(fz_context *,void *); - void (*drop_key)(fz_context *,void *); - int (*cmp_key)(void *, void *); - void (*debug)(void *); -}; - -/* - fz_store_new_context: Create a new store inside the context - - max: The maximum size (in bytes) that the store is allowed to grow - to. FZ_STORE_UNLIMITED means no limit. -*/ -void fz_new_store_context(fz_context *ctx, unsigned int max); - -/* - fz_drop_store_context: Drop a reference to the store. -*/ -void fz_drop_store_context(fz_context *ctx); - -/* - fz_keep_store_context: Take a reference to the store. -*/ -fz_store *fz_keep_store_context(fz_context *ctx); - -/* - fz_debug_store: Dump the contents of the store for debugging. -*/ -void fz_debug_store(fz_context *ctx); - -/* - fz_store_item: Add an item to the store. - - Add an item into the store, returning NULL for success. If an item - with the same key is found in the store, then our item will not be - inserted, and the function will return a pointer to that value - instead. This function takes its own reference to val, as required - (i.e. the caller maintains ownership of its own reference). - - key: The key to use to index the item. - - val: The value to store. - - itemsize: The size in bytes of the value (as counted towards the - store size). - - type: Functions used to manipulate the key. -*/ -void *fz_store_item(fz_context *ctx, void *key, void *val, unsigned int itemsize, fz_store_type *type); - /* - fz_find_item: Find an item within the store. - - free: The function used to free the value (to ensure we get a value - of the correct type). - - key: The key to use to index the item. + fz_keep_buffer: Increment the reference count for a buffer. - type: Functions used to manipulate the key. + buf: The buffer to increment the reference count for. - Returns NULL for not found, otherwise returns a pointer to the value - indexed by key to which a reference has been taken. + Returns a pointer to the buffer. Does not throw exceptions. */ -void *fz_find_item(fz_context *ctx, fz_store_free_fn *free, void *key, fz_store_type *type); +fz_buffer *fz_keep_buffer(fz_context *ctx, fz_buffer *buf); /* - fz_remove_item: Remove an item from the store. - - If an item indexed by the given key exists in the store, remove it. - - free: The function used to free the value (to ensure we get a value - of the correct type). + fz_drop_buffer: Decrement the reference count for a buffer. - key: The key to use to find the item to remove. - - type: Functions used to manipulate the key. + buf: The buffer to decrement the reference count for. */ -void fz_remove_item(fz_context *ctx, fz_store_free_fn *free, void *key, fz_store_type *type); - -/* - fz_empty_store: Evict everything from the store. -*/ -void fz_empty_store(fz_context *ctx); +void fz_drop_buffer(fz_context *ctx, fz_buffer *buf); /* - fz_store_scavenge: Internal function used as part of the scavenging - allocator; when we fail to allocate memory, before returning a - failure to the caller, we try to scavenge space within the store by - evicting at least 'size' bytes. The allocator then retries. - - size: The number of bytes we are trying to have free. + fz_buffer_storage: Retrieve information on the storage currently used + by a buffer. - phase: What phase of the scavenge we are in. Updated on exit. + data: Pointer to place to retrieve data pointer. - Returns non zero if we managed to free any memory. + Returns length of stream. */ -int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase); +int fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **data); /* fz_stream is a buffered reader capable of seeking in both @@ -1138,24 +944,6 @@ int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase); */ typedef struct fz_stream_s fz_stream; -struct fz_stream_s -{ - fz_context *ctx; - int refs; - int error; - int eof; - int pos; - int avail; - int bits; - int locked; - unsigned char *bp, *rp, *wp, *ep; - void *state; - int (*read)(fz_stream *stm, unsigned char *buf, int len); - void (*close)(fz_context *ctx, void *state); - void (*seek)(fz_stream *stm, int offset, int whence); - unsigned char buf[4096]; -}; - /* fz_open_file: Open the named file and wrap it in a stream. @@ -1185,14 +973,28 @@ fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename); fz_stream *fz_open_fd(fz_context *ctx, int file); /* - fz_open_buffer: XXX + fz_open_memory: Open a block of memory as a stream. + + data: Pointer to start of data block. Ownership of the data block is + NOT passed in. + + len: Number of bytes in data block. + + Returns pointer to newly created stream. May throw exceptions on + failure to allocate. */ -fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf); +fz_stream *fz_open_memory(fz_context *ctx, unsigned char *data, int len); /* - fz_open_memory: XXX + fz_open_buffer: Open a buffer as a stream. + + buf: The buffer to open. Ownership of the buffer is NOT passed in + (this function takes it's own reference). + + Returns pointer to newly created stream. May throw exceptions on + failure to allocate. */ -fz_stream *fz_open_memory(fz_context *ctx, unsigned char *data, int len); +fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf); /* fz_close: Close an open stream. @@ -1205,176 +1007,141 @@ fz_stream *fz_open_memory(fz_context *ctx, unsigned char *data, int len); */ void fz_close(fz_stream *stm); -void fz_lock_stream(fz_stream *stm); +/* + fz_tell: return the current reading position within a stream +*/ +int fz_tell(fz_stream *stm); -fz_stream *fz_new_stream(fz_context *ctx, void*, int(*)(fz_stream*, unsigned char*, int), void(*)(fz_context *, void *)); -fz_stream *fz_keep_stream(fz_stream *stm); -void fz_fill_buffer(fz_stream *stm); +/* + fz_seek: Seek within a stream. -int fz_tell(fz_stream *stm); + stm: The stream to seek within. + + offset: The offset to seek to. + + whence: From where the offset is measured (see fseek). +*/ void fz_seek(fz_stream *stm, int offset, int whence); -int fz_read(fz_stream *stm, unsigned char *buf, int len); -void fz_read_line(fz_stream *stm, char *buf, int max); -fz_buffer *fz_read_all(fz_stream *stm, int initial); +/* + fz_read: Read from a stream into a given data block. -static inline int fz_read_byte(fz_stream *stm) -{ - if (stm->rp == stm->wp) - { - fz_fill_buffer(stm); - return stm->rp < stm->wp ? *stm->rp++ : EOF; - } - return *stm->rp++; -} + stm: The stream to read from. -static inline int fz_peek_byte(fz_stream *stm) -{ - if (stm->rp == stm->wp) - { - fz_fill_buffer(stm); - return stm->rp < stm->wp ? *stm->rp : EOF; - } - return *stm->rp; -} + data: The data block to read into. -static inline void fz_unread_byte(fz_stream *stm) -{ - if (stm->rp > stm->bp) - stm->rp--; -} + len: The length of the data block (in bytes). -static inline int fz_is_eof(fz_stream *stm) -{ - if (stm->rp == stm->wp) - { - if (stm->eof) - return 1; - return fz_peek_byte(stm) == EOF; - } - return 0; -} + Returns the number of bytes read. May throw exceptions. +*/ +int fz_read(fz_stream *stm, unsigned char *data, int len); -static inline unsigned int fz_read_bits(fz_stream *stm, int n) -{ - unsigned int x; +/* + fz_read_all: Read all of a stream into a buffer. - if (n <= stm->avail) - { - stm->avail -= n; - x = (stm->bits >> stm->avail) & ((1 << n) - 1); - } - else - { - x = stm->bits & ((1 << stm->avail) - 1); - n -= stm->avail; - stm->avail = 0; + stm: The stream to read from - while (n > 8) - { - x = (x << 8) | fz_read_byte(stm); - n -= 8; - } + initial: Suggested initial size for the buffer. - if (n > 0) - { - stm->bits = fz_read_byte(stm); - stm->avail = 8 - n; - x = (x << n) | (stm->bits >> stm->avail); - } - } + Returns a buffer created from reading from the stream. May throw + exceptions on failure to allocate. +*/ +fz_buffer *fz_read_all(fz_stream *stm, int initial); - return x; -} +/* + Bitmaps have 1 bit per component. Only used for creating halftoned + versions of contone buffers, and saving out. Samples are stored msb + first, akin to pbms. +*/ +typedef struct fz_bitmap_s fz_bitmap; -static inline void fz_sync_bits(fz_stream *stm) -{ - stm->avail = 0; -} +/* + fz_keep_bitmap: Take a reference to a bitmap. -static inline int fz_is_eof_bits(fz_stream *stm) -{ - return fz_is_eof(stm) && (stm->avail == 0 || stm->bits == EOF); -} + bit: The bitmap to increment the reference for. + + Returns bit. Does not throw exceptions. +*/ +fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit); /* - * Data filters. - */ + fz_drop_bitmap: Drop a reference and free a bitmap. -fz_stream *fz_open_copy(fz_stream *chain); -fz_stream *fz_open_null(fz_stream *chain, int len); -fz_stream *fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen); -fz_stream *fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen); -fz_stream *fz_open_a85d(fz_stream *chain); -fz_stream *fz_open_ahxd(fz_stream *chain); -fz_stream *fz_open_rld(fz_stream *chain); -fz_stream *fz_open_dctd(fz_stream *chain, int color_transform); -fz_stream *fz_open_resized_dctd(fz_stream *chain, int color_transform, int factor); -fz_stream *fz_open_faxd(fz_stream *chain, - int k, int end_of_line, int encoded_byte_align, - int columns, int rows, int end_of_block, int black_is_1); -fz_stream *fz_open_flated(fz_stream *chain); -fz_stream *fz_open_lzwd(fz_stream *chain, int early_change); -fz_stream *fz_open_predict(fz_stream *chain, int predictor, int columns, int colors, int bpc); -fz_stream *fz_open_jbig2d(fz_stream *chain, fz_buffer *global); - -/* - * Resources and other graphics related objects. - */ + Decrement the reference count for the bitmap. When no + references remain the pixmap will be freed. -enum { FZ_MAX_COLORS = 32 }; + Does not throw exceptions. +*/ +void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit); -int fz_find_blendmode(char *name); -char *fz_blendmode_name(int blendmode); +/* + An fz_colorspace object represents an abstract colorspace. While + this should be treated as a black box by callers of the library at + this stage, know that it encapsulates knowledge of how to convert + colors to and from the colorspace, any lookup tables generated, the + number of components in the colorspace etc. +*/ +typedef struct fz_colorspace_s fz_colorspace; /* - * Pixmaps have n components per pixel. the last is always alpha. - * premultiplied alpha when rendering, but non-premultiplied for colorspace - * conversions and rescaling. - */ + fz_find_device_colorspace: Find a standard colorspace based upon + it's name. +*/ +fz_colorspace *fz_find_device_colorspace(char *name); -typedef struct fz_pixmap_s fz_pixmap; -typedef struct fz_colorspace_s fz_colorspace; +/* + fz_device_gray: Abstract colorspace representing device specific + gray. +*/ +extern fz_colorspace *fz_device_gray; /* - fz_pixmap is an image XXX + fz_device_rgb: Abstract colorspace representing device specific + rgb. +*/ +extern fz_colorspace *fz_device_rgb; - x, y: XXX +/* + fz_device_bgr: Abstract colorspace representing device specific + bgr. +*/ +extern fz_colorspace *fz_device_bgr; - w, h: The width and height of the image in pixels. +/* + fz_device_cmyk: Abstract colorspace representing device specific + CMYK. +*/ +extern fz_colorspace *fz_device_cmyk; - n: The number of color components in the image. Always - includes a separate alpha channel. XXX RGBA=4 +/* + Pixmaps represent a set of pixels for a 2 dimensional region of a + plane. Each pixel has n components per pixel, the last of which is + always alpha. The data is in premultiplied alpha when rendering, but + non-premultiplied for colorspace conversions and rescaling. +*/ +typedef struct fz_pixmap_s fz_pixmap; - interpolate: A boolean flag set to non-zero if the image - will be drawn using linear interpolation, or set to zero if - image will be using nearest neighbour sampling. +/* + fz_bound_pixmap: Return a bounding box for a pixmap. - xres, yres: Image resolution in dpi. Default is 96 dpi. + Returns an exact bounding box for the supplied pixmap. +*/ +fz_bbox fz_bound_pixmap(fz_pixmap *pix); - colorspace: XXX +/* + fz_new_pixmap: Create a new pixmap, with it's origin at (0,0) - samples: + cs: The colorspace to use for the pixmap, or NULL for an alpha + plane/mask. - free_samples: Is zero when an application has provided its own - buffer for pixel data through fz_new_pixmap_with_rect_and_data. - If not zero the buffer will be freed when fz_drop_pixmap is - called for the pixmap. -*/ -struct fz_pixmap_s -{ - fz_storable storable; - int x, y, w, h, n; - int interpolate; - int xres, yres; - fz_colorspace *colorspace; - unsigned char *samples; - int free_samples; -}; + w: The width of the pixmap (in pixels) -fz_bbox fz_bound_pixmap(fz_pixmap *pix); + h: The height of the pixmap (in pixels) -fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, unsigned char *samples); + Returns a pointer to the new pixmap. Throws exception on failure to + allocate. +*/ +fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h); /* fz_new_pixmap_with_rect: Create a pixmap of a given size, @@ -1393,22 +1160,12 @@ fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, i fz_pixmap *fz_new_pixmap_with_rect(fz_context *ctx, fz_colorspace *colorspace, fz_bbox bbox); /* - fz_new_pixmap_with_rect_and_data: Create a pixmap using the - provided buffer for pixel data. + fz_keep_pixmap: Take a reference to a pixmap. - While fz_new_pixmap_with_rect allocates its own buffer for - pixel data, fz_new_pixmap_with_rect_and_data lets the caller - allocate and provide a buffer to be used. Otherwise the two - functions are identical. + pix: The pixmap to increment the reference for. - samples: An array of pixel samples. The created pixmap will - keep a pointer to the array so it must not be modified or - freed until the created pixmap is dropped and freed by - fz_drop_pixmap. + Returns pix. Does not throw exceptions. */ -fz_pixmap *fz_new_pixmap_with_rect_and_data(fz_context *ctx, -fz_colorspace *colorspace, fz_bbox bbox, unsigned char *samples); -fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *, int w, int h); fz_pixmap *fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix); /* @@ -1421,13 +1178,31 @@ fz_pixmap *fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix); */ void fz_drop_pixmap(fz_context *ctx, fz_pixmap *pix); -void fz_free_pixmap_imp(fz_context *ctx, fz_storable *pix); -void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix); +/* + fz_pixmap_colorspace: Return the colorspace of a pixmap + + Returns colorspace. Does not throw exceptions. +*/ +fz_colorspace *fz_pixmap_colorspace(fz_context *ctx, fz_pixmap *pix); + +/* + fz_pixmap_components: Return the number of components in a pixmap. + + Returns the number of components. Does not throw exceptions. +*/ +int fz_pixmap_components(fz_context *ctx, fz_pixmap *pix); /* - fz_clear_pixmap_with_value: Clears a pixmap with the given value + fz_pixmap_pixels: Returns a pointer to the pixel data of a pixmap. - pix: Pixmap obtained from fz_new_pixmap*. + Returns the pointer. Does not throw exceptions. +*/ +unsigned char *fz_pixmap_pixels(fz_context *ctx, fz_pixmap *pix); + +/* + fz_clear_pixmap_with_value: Clears a pixmap with the given value. + + pix: The pixmap to clear. value: Values in the range 0 to 255 are valid. Each component sample for each pixel in the pixmap will be set to this value, @@ -1437,512 +1212,188 @@ void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix); */ void fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value); -void fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *pix, int value, fz_bbox r); -void fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_bbox r); -void fz_premultiply_pixmap(fz_context *ctx, fz_pixmap *pix); -void fz_unmultiply_pixmap(fz_context *ctx, fz_pixmap *pix); -fz_pixmap *fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray, int luminosity); -void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix); -void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma); -unsigned int fz_pixmap_size(fz_context *ctx, fz_pixmap *pix); +/* + fz_clear_pixmap_with_value: Sets all components (including alpha) of + all pixels in a pixmap to 0. -fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_bbox *clip); + pix: The pixmap to clear. -void fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename); -void fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); -void fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); + Does not throw exceptions. +*/ +void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix); /* - Images are storable objects from which we can obtain fz_pixmaps. - These may be implemented as simple wrappers around a pixmap, or as - more complex things that decode at different subsample settings on - demand. - */ -typedef struct fz_image_s fz_image; + fz_invert_pixmap: Invert all the pixels in a pixmap. All components + of all pixels are inverted (except alpha, which is unchanged). -struct fz_image_s -{ - fz_storable storable; - int w, h; - fz_image *mask; - fz_colorspace *colorspace; - fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, int w, int h); -}; + Does not throw exceptions. +*/ +void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix); /* - fz_image_to_pixmap: Called to get a handle to a pixmap from an image. + fz_invert_pixmap: Invert all the pixels in a given rectangle of a + pixmap. All components of all pixels in the rectangle are inverted + (except alpha, which is unchanged). - image: The image to retrieve a pixmap from. + Does not throw exceptions. +*/ +void fz_invert_pixmap_rect(fz_pixmap *image, fz_bbox rect); - w: The desired width (in pixels). This may be completely ignored, but - may serve as an indication of a suitable subsample factor to use for - image types that support this. +/* + fz_gamma_pixmap: Apply gamma correction to a pixmap. All components + of all pixels are modified (except alpha, which is unchanged). - h: The desired height (in pixels). This may be completely ignored, but - may serve as an indication of a suitable subsample factor to use for - image types that support this. + gamma: The gamma value to apply; 1.0 for no change. - Returns a non NULL pixmap pointer. May throw exceptions. + Does not throw exceptions. */ -fz_pixmap *fz_image_to_pixmap(fz_context *ctx, fz_image *image, int w, int h); +void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma); /* - fz_drop_image: Drop a reference to an image. + fz_unmultiply_pixmap: Convert a pixmap from premultiplied to + non-premultiplied format. - image: The image to drop a reference to. + Does not throw exceptions. */ -void fz_drop_image(fz_context *ctx, fz_image *image); +void fz_unmultiply_pixmap(fz_context *ctx, fz_pixmap *pix); /* - fz_keep_image: Increment the reference count of an image. + fz_convert_pixmap: Convert from one pixmap to another (assumed to be + the same size, but possibly with a different colorspace). - image: The image to take a reference to. + dst: the source pixmap. - Returns a pointer to the image. + src: the destination pixmap. */ -fz_image *fz_keep_image(fz_context *ctx, fz_image *image); - -fz_pixmap *fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *cs); -fz_pixmap *fz_load_jpeg(fz_context *doc, unsigned char *data, int size); -fz_pixmap *fz_load_png(fz_context *doc, unsigned char *data, int size); -fz_pixmap *fz_load_tiff(fz_context *doc, unsigned char *data, int size); +void fz_convert_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src); /* - Bitmaps have 1 bit per component. Only used for creating halftoned - versions of contone buffers, and saving out. Samples are stored msb - first, akin to pbms. -*/ -typedef struct fz_bitmap_s fz_bitmap; + fz_save_pixmap: Save a pixmap out. -struct fz_bitmap_s -{ - int refs; - int w, h, stride, n; - unsigned char *samples; -}; - -fz_bitmap *fz_new_bitmap(fz_context *ctx, int w, int h, int n); -fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit); -void fz_clear_bitmap(fz_context *ctx, fz_bitmap *bit); -void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit); + name: The prefix for the name of the pixmap. The pixmap will be saved + as "name.png" if the pixmap is RGB or Greyscale, "name.pam" otherwise. -void fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename); - -/* - A halftone is a set of threshold tiles, one per component. Each - threshold tile is a pixmap, possibly of varying sizes and phases. + rgb: If non zero, the pixmap is converted to rgb (if possible) before + saving. */ -typedef struct fz_halftone_s fz_halftone; - -struct fz_halftone_s -{ - int refs; - int n; - fz_pixmap *comp[1]; -}; - -fz_halftone *fz_new_halftone(fz_context *ctx, int num_comps); -fz_halftone *fz_get_default_halftone(fz_context *ctx, int num_comps); -fz_halftone *fz_keep_halftone(fz_context *ctx, fz_halftone *half); -void fz_drop_halftone(fz_context *ctx, fz_halftone *half); - -fz_bitmap *fz_halftone_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht); +void fz_save_pixmap(fz_context *ctx, fz_pixmap *img, char *name, int rgb); /* - * Colorspace resources. - */ + fz_write_pnm: Save a pixmap as a pnm -/* - fz_device_gray: XXX + filename: The filename to save as (including extension). */ -extern fz_colorspace *fz_device_gray; +void fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename); /* - fz_device_rgb: XXX -*/ -extern fz_colorspace *fz_device_rgb; + fz_write_pam: Save a pixmap as a pam -/* - fz_device_bgr: XXX + filename: The filename to save as (including extension). */ -extern fz_colorspace *fz_device_bgr; +void fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); /* - fz_device_cmyk: XXX -*/ -extern fz_colorspace *fz_device_cmyk; - -struct fz_colorspace_s -{ - fz_storable storable; - unsigned int size; - char name[16]; - int n; - void (*to_rgb)(fz_context *ctx, fz_colorspace *, float *src, float *rgb); - void (*from_rgb)(fz_context *ctx, fz_colorspace *, float *rgb, float *dst); - void (*free_data)(fz_context *Ctx, fz_colorspace *); - void *data; -}; - -fz_colorspace *fz_new_colorspace(fz_context *ctx, char *name, int n); -fz_colorspace *fz_keep_colorspace(fz_context *ctx, fz_colorspace *colorspace); -void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace); -void fz_free_colorspace_imp(fz_context *ctx, fz_storable *colorspace); + fz_write_png: Save a pixmap as a png -void fz_convert_color(fz_context *ctx, fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv); -void fz_convert_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst); - -fz_colorspace *fz_find_device_colorspace(char *name); + filename: The filename to save as (including extension). +*/ +void fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); /* - * Fonts come in two variants: - * Regular fonts are handled by FreeType. - * Type 3 fonts have callbacks to the interpreter. - */ - -typedef struct fz_device_s fz_device; - -typedef struct fz_font_s fz_font; -char *ft_error_string(int err); - -struct fz_font_s -{ - int refs; - char name[32]; - - void *ft_face; /* has an FT_Face if used */ - int ft_substitute; /* ... substitute metrics */ - int ft_bold; /* ... synthesize bold */ - int ft_italic; /* ... synthesize italic */ - int ft_hint; /* ... force hinting for DynaLab fonts */ - - /* origin of font data */ - char *ft_file; - unsigned char *ft_data; - int ft_size; - - fz_matrix t3matrix; - void *t3resources; - fz_buffer **t3procs; /* has 256 entries if used */ - float *t3widths; /* has 256 entries if used */ - char *t3flags; /* has 256 entries if used */ - void *t3doc; /* a pdf_document for the callback */ - void (*t3run)(void *doc, void *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate); - void (*t3freeres)(void *doc, void *resources); - - fz_rect bbox; /* font bbox is used only for t3 fonts */ - - /* per glyph bounding box cache */ - int use_glyph_bbox; - int bbox_count; - fz_rect *bbox_table; - - /* substitute metrics */ - int width_count; - int *width_table; /* in 1000 units */ -}; - -void fz_new_font_context(fz_context *ctx); -fz_font_context *fz_keep_font_context(fz_context *ctx); -void fz_drop_font_context(fz_context *ctx); - -fz_font *fz_new_type3_font(fz_context *ctx, char *name, fz_matrix matrix); - -fz_font *fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index, int use_glyph_bbox); -fz_font *fz_new_font_from_file(fz_context *ctx, char *path, int index, int use_glyph_bbox); - -fz_font *fz_keep_font(fz_context *ctx, fz_font *font); -void fz_drop_font(fz_context *ctx, fz_font *font); + fz_write_pbm: Save a bitmap as a pbm -void fz_debug_font(fz_context *ctx, fz_font *font); - -void fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float xmax, float ymax); -fz_rect fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm); -int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid); + filename: The filename to save as (including extension). +*/ +void fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename); /* - * Vector path buffer. - * It can be stroked and dashed, or be filled. - * It has a fill rule (nonzero or even_odd). - * - * When rendering, they are flattened, stroked and dashed straight - * into the Global Edge List. - */ - -typedef struct fz_path_s fz_path; -typedef struct fz_stroke_state_s fz_stroke_state; - -typedef union fz_path_item_s fz_path_item; + fz_md5_pixmap: Return the md5 digest for a pixmap -typedef enum fz_path_item_kind_e -{ - FZ_MOVETO, - FZ_LINETO, - FZ_CURVETO, - FZ_CLOSE_PATH -} fz_path_item_kind; - -typedef enum fz_linecap_e -{ - FZ_LINECAP_BUTT = 0, - FZ_LINECAP_ROUND = 1, - FZ_LINECAP_SQUARE = 2, - FZ_LINECAP_TRIANGLE = 3 -} fz_linecap; - -typedef enum fz_linejoin_e -{ - FZ_LINEJOIN_MITER = 0, - FZ_LINEJOIN_ROUND = 1, - FZ_LINEJOIN_BEVEL = 2, - FZ_LINEJOIN_MITER_XPS = 3 -} fz_linejoin; - -union fz_path_item_s -{ - fz_path_item_kind k; - float v; -}; - -struct fz_path_s -{ - int len, cap; - fz_path_item *items; - int last; -}; - -struct fz_stroke_state_s -{ - fz_linecap start_cap, dash_cap, end_cap; - fz_linejoin linejoin; - float linewidth; - float miterlimit; - float dash_phase; - int dash_len; - float dash_list[32]; -}; - -fz_path *fz_new_path(fz_context *ctx); -void fz_moveto(fz_context*, fz_path*, float x, float y); -void fz_lineto(fz_context*, fz_path*, float x, float y); -void fz_curveto(fz_context*,fz_path*, float, float, float, float, float, float); -void fz_curvetov(fz_context*,fz_path*, float, float, float, float); -void fz_curvetoy(fz_context*,fz_path*, float, float, float, float); -void fz_closepath(fz_context*,fz_path*); -void fz_free_path(fz_context *ctx, fz_path *path); - -void fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix transform); - -fz_path *fz_clone_path(fz_context *ctx, fz_path *old); - -fz_rect fz_bound_path(fz_context *ctx, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm); -void fz_debug_path(fz_context *ctx, fz_path *, int indent); + filename: The filename to save as (including extension). +*/ +void fz_md5_pixmap(fz_pixmap *pixmap, unsigned char digest[16]); /* - * Glyph cache - */ - -void fz_new_glyph_cache_context(fz_context *ctx); -fz_glyph_cache *fz_keep_glyph_cache(fz_context *ctx); -void fz_drop_glyph_cache_context(fz_context *ctx); -void fz_purge_glyph_cache(fz_context *ctx); - -fz_pixmap *fz_render_ft_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, int aa); -fz_pixmap *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model); -fz_pixmap *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state); -fz_pixmap *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_colorspace *model); -fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke); -void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate); - -/* - * Text buffer. - * - * The trm field contains the a, b, c and d coefficients. - * The e and f coefficients come from the individual elements, - * together they form the transform matrix for the glyph. - * - * Glyphs are referenced by glyph ID. - * The Unicode text equivalent is kept in a separate array - * with indexes into the glyph array. + Images are storable objects from which we can obtain fz_pixmaps. + These may be implemented as simple wrappers around a pixmap, or as + more complex things that decode at different subsample settings on + demand. */ - -typedef struct fz_text_s fz_text; -typedef struct fz_text_item_s fz_text_item; - -struct fz_text_item_s -{ - float x, y; - int gid; /* -1 for one gid to many ucs mappings */ - int ucs; /* -1 for one ucs to many gid mappings */ -}; - -struct fz_text_s -{ - fz_font *font; - fz_matrix trm; - int wmode; - int len, cap; - fz_text_item *items; -}; - -fz_text *fz_new_text(fz_context *ctx, fz_font *face, fz_matrix trm, int wmode); -void fz_add_text(fz_context *ctx, fz_text *text, int gid, int ucs, float x, float y); -void fz_free_text(fz_context *ctx, fz_text *text); -fz_rect fz_bound_text(fz_context *ctx, fz_text *text, fz_matrix ctm); -fz_text *fz_clone_text(fz_context *ctx, fz_text *old); -void fz_debug_text(fz_context *ctx, fz_text*, int indent); +typedef struct fz_image_s fz_image; /* - * The shading code uses gouraud shaded triangle meshes. - */ - -enum -{ - FZ_LINEAR, - FZ_RADIAL, - FZ_MESH, -}; + fz_image_to_pixmap: Called to get a handle to a pixmap from an image. -typedef struct fz_shade_s fz_shade; + image: The image to retrieve a pixmap from. -struct fz_shade_s -{ - fz_storable storable; + w: The desired width (in pixels). This may be completely ignored, but + may serve as an indication of a suitable subsample factor to use for + image types that support this. - fz_rect bbox; /* can be fz_infinite_rect */ - fz_colorspace *colorspace; + h: The desired height (in pixels). This may be completely ignored, but + may serve as an indication of a suitable subsample factor to use for + image types that support this. - fz_matrix matrix; /* matrix from pattern dict */ - int use_background; /* background color for fills but not 'sh' */ - float background[FZ_MAX_COLORS]; + Returns a non NULL pixmap pointer. May throw exceptions. +*/ +fz_pixmap *fz_image_to_pixmap(fz_context *ctx, fz_image *image, int w, int h); - int use_function; - float function[256][FZ_MAX_COLORS + 1]; +/* + fz_drop_image: Drop a reference to an image. - int type; /* linear, radial, mesh */ - int extend[2]; + image: The image to drop a reference to. +*/ +void fz_drop_image(fz_context *ctx, fz_image *image); - int mesh_len; - int mesh_cap; - float *mesh; /* [x y 0], [x y r], [x y t] or [x y c1 ... cn] */ -}; +/* + fz_keep_image: Increment the reference count of an image. -fz_shade *fz_keep_shade(fz_context *ctx, fz_shade *shade); -void fz_drop_shade(fz_context *ctx, fz_shade *shade); -void fz_free_shade_imp(fz_context *ctx, fz_storable *shade); -void fz_debug_shade(fz_context *ctx, fz_shade *shade); + image: The image to take a reference to. -fz_rect fz_bound_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm); -void fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox); + Returns a pointer to the image. +*/ +fz_image *fz_keep_image(fz_context *ctx, fz_image *image); /* - * Scan converter - */ - -int fz_get_aa_level(fz_context *ctx); -void fz_set_aa_level(fz_context *ctx, int bits); + A halftone is a set of threshold tiles, one per component. Each + threshold tile is a pixmap, possibly of varying sizes and phases. + Currently, we only provide one 'default' halftone tile for operating + on 1 component plus alpha pixmaps (where the alpha is ignored). This + is signified by an fz_halftone pointer to NULL. +*/ +typedef struct fz_halftone_s fz_halftone; -typedef struct fz_gel_s fz_gel; +/* + fz_halftone_pixmap: Make a bitmap from a pixmap and a halftone. -fz_gel *fz_new_gel(fz_context *ctx); -void fz_insert_gel(fz_gel *gel, float x0, float y0, float x1, float y1); -void fz_reset_gel(fz_gel *gel, fz_bbox clip); -void fz_sort_gel(fz_gel *gel); -fz_bbox fz_bound_gel(fz_gel *gel); -void fz_free_gel(fz_gel *gel); -int fz_is_rect_gel(fz_gel *gel); + pix: The pixmap to generate from. Currently must be a single color + component + alpha (where the alpha is assumed to be solid). -void fz_scan_convert(fz_gel *gel, int eofill, fz_bbox clip, fz_pixmap *pix, unsigned char *colorbv); + ht: The halftone to use. NULL implies the default halftone. -void fz_flatten_fill_path(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness); -void fz_flatten_stroke_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth); -void fz_flatten_dash_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth); + Returns the resultant bitmap. Throws exceptions in the case of + failure to allocate. +*/ +fz_bitmap *fz_halftone_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht); /* - * The device interface. - */ - -enum -{ - /* Hints */ - FZ_IGNORE_IMAGE = 1, - FZ_IGNORE_SHADE = 2, - - /* Flags */ - FZ_DEVFLAG_MASK = 1, - FZ_DEVFLAG_COLOR = 2, - FZ_DEVFLAG_UNCACHEABLE = 4, - FZ_DEVFLAG_FILLCOLOR_UNDEFINED = 8, - FZ_DEVFLAG_STROKECOLOR_UNDEFINED = 16, - FZ_DEVFLAG_STARTCAP_UNDEFINED = 32, - FZ_DEVFLAG_DASHCAP_UNDEFINED = 64, - FZ_DEVFLAG_ENDCAP_UNDEFINED = 128, - FZ_DEVFLAG_LINEJOIN_UNDEFINED = 256, - FZ_DEVFLAG_MITERLIMIT_UNDEFINED = 512, - FZ_DEVFLAG_LINEWIDTH_UNDEFINED = 1024, - /* Arguably we should have a bit for the dash pattern itself being - * undefined, but that causes problems; do we assume that it should - * always be set to non-dashing at the start of every glyph? */ -}; - -struct fz_device_s -{ - int hints; - int flags; - - void *user; - void (*free_user)(fz_device *); - fz_context *ctx; - - void (*fill_path)(fz_device *, fz_path *, int even_odd, fz_matrix, fz_colorspace *, float *color, float alpha); - void (*stroke_path)(fz_device *, fz_path *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha); - void (*clip_path)(fz_device *, fz_path *, fz_rect *rect, int even_odd, fz_matrix); - void (*clip_stroke_path)(fz_device *, fz_path *, fz_rect *rect, fz_stroke_state *, fz_matrix); - - void (*fill_text)(fz_device *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha); - void (*stroke_text)(fz_device *, fz_text *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha); - void (*clip_text)(fz_device *, fz_text *, fz_matrix, int accumulate); - void (*clip_stroke_text)(fz_device *, fz_text *, fz_stroke_state *, fz_matrix); - void (*ignore_text)(fz_device *, fz_text *, fz_matrix); - - void (*fill_shade)(fz_device *, fz_shade *shd, fz_matrix ctm, float alpha); - void (*fill_image)(fz_device *, fz_image *img, fz_matrix ctm, float alpha); - void (*fill_image_mask)(fz_device *, fz_image *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha); - void (*clip_image_mask)(fz_device *, fz_image *img, fz_rect *rect, fz_matrix ctm); - - void (*pop_clip)(fz_device *); - - void (*begin_mask)(fz_device *, fz_rect, int luminosity, fz_colorspace *, float *bc); - void (*end_mask)(fz_device *); - void (*begin_group)(fz_device *, fz_rect, int isolated, int knockout, int blendmode, float alpha); - void (*end_group)(fz_device *); - - void (*begin_tile)(fz_device *, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm); - void (*end_tile)(fz_device *); -}; + An abstract font handle. Currently there are no public API functions + for handling these. +*/ +typedef struct fz_font_s fz_font; -void fz_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); -void fz_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); -void fz_clip_path(fz_device *dev, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm); -void fz_clip_stroke_path(fz_device *dev, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm); -void fz_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); -void fz_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); -void fz_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate); -void fz_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm); -void fz_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm); -void fz_pop_clip(fz_device *dev); -void fz_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha); -void fz_fill_image(fz_device *dev, fz_image *image, fz_matrix ctm, float alpha); -void fz_fill_image_mask(fz_device *dev, fz_image *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); -void fz_clip_image_mask(fz_device *dev, fz_image *image, fz_rect *rect, fz_matrix ctm); -void fz_begin_mask(fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, float *bc); -void fz_end_mask(fz_device *dev); -void fz_begin_group(fz_device *dev, fz_rect area, int isolated, int knockout, int blendmode, float alpha); -void fz_end_group(fz_device *dev); -void fz_begin_tile(fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm); -void fz_end_tile(fz_device *dev); - -fz_device *fz_new_device(fz_context *ctx, void *user); +/* + The different format handlers (pdf, xps etc) interpret pages to a + device. These devices can then process the stream of calls they + recieve in various ways: + The trace device outputs debugging information for the calls. + The draw device will render them. + The list device stores them in a list to play back later. + The text device performs text extraction and searching. + The bbox device calculates the bounding box for the page. + Other devices can (and will) be written in future. +*/ +typedef struct fz_device_s fz_device; /* fz_free_device: Free a devices of any type and its resources. @@ -1952,8 +1403,6 @@ void fz_free_device(fz_device *dev); /* fz_new_trace_device: Create a device to print a debug trace of all device calls. - - XXX */ fz_device *fz_new_trace_device(fz_context *ctx); @@ -1977,12 +1426,9 @@ fz_device *fz_new_bbox_device(fz_context *ctx, fz_bbox *bboxp); */ fz_device *fz_new_draw_device(fz_context *ctx, fz_pixmap *dest); -fz_device *fz_new_draw_device_type3(fz_context *ctx, fz_pixmap *dest); - /* - * Text extraction device - */ - + Text extraction device +*/ typedef struct fz_text_span_s fz_text_span; typedef struct fz_text_char_s fz_text_char; @@ -2070,8 +1516,8 @@ struct fz_cookie_s }; /* - * Display list device -- record and play back device commands. - */ + Display list device -- record and play back device commands. +*/ /* fz_display_list is a list containing drawing commands (text, @@ -2146,58 +1592,6 @@ void fz_run_display_list(fz_display_list *list, fz_device *dev, fz_matrix ctm, f */ void fz_free_display_list(fz_context *ctx, fz_display_list *list); -/* - * Plotting functions. - */ - -void fz_decode_tile(fz_pixmap *pix, float *decode); -void fz_decode_indexed_tile(fz_pixmap *pix, float *decode, int maxval); -void fz_unpack_tile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride, int scale); - -void fz_paint_solid_alpha(unsigned char * restrict dp, int w, int alpha); -void fz_paint_solid_color(unsigned char * restrict dp, int n, int w, unsigned char *color); - -void fz_paint_span(unsigned char * restrict dp, unsigned char * restrict sp, int n, int w, int alpha); -void fz_paint_span_with_color(unsigned char * restrict dp, unsigned char * restrict mp, int n, int w, unsigned char *color); - -void fz_paint_image(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, int alpha); -void fz_paint_image_with_color(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, unsigned char *colorbv); - -void fz_paint_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha); -void fz_paint_pixmap_with_mask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk); -void fz_paint_pixmap_with_rect(fz_pixmap *dst, fz_pixmap *src, int alpha, fz_bbox bbox); - -void fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int isolated, fz_pixmap *shape); -void fz_blend_pixel(unsigned char dp[3], unsigned char bp[3], unsigned char sp[3], int blendmode); - -enum -{ - /* PDF 1.4 -- standard separable */ - FZ_BLEND_NORMAL, - FZ_BLEND_MULTIPLY, - FZ_BLEND_SCREEN, - FZ_BLEND_OVERLAY, - FZ_BLEND_DARKEN, - FZ_BLEND_LIGHTEN, - FZ_BLEND_COLOR_DODGE, - FZ_BLEND_COLOR_BURN, - FZ_BLEND_HARD_LIGHT, - FZ_BLEND_SOFT_LIGHT, - FZ_BLEND_DIFFERENCE, - FZ_BLEND_EXCLUSION, - - /* PDF 1.4 -- standard non-separable */ - FZ_BLEND_HUE, - FZ_BLEND_SATURATION, - FZ_BLEND_COLOR, - FZ_BLEND_LUMINOSITY, - - /* For packing purposes */ - FZ_BLEND_MODEMASK = 15, - FZ_BLEND_ISOLATED = 16, - FZ_BLEND_KNOCKOUT = 32 -}; - /* Links */ typedef struct fz_link_s fz_link; @@ -2357,8 +1751,16 @@ struct fz_outline_s fz_outline *down; }; -void fz_debug_outline_xml(fz_context *ctx, fz_outline *outline, int level); -void fz_debug_outline(fz_context *ctx, fz_outline *outline, int level); +/* + fz_debug_outline_xml: Dump the given outlines to stdout as (pseudo) + XML. +*/ +void fz_debug_outline_xml(fz_context *ctx, fz_outline *outline); + +/* + fz_debug_outline: Dump the given outlines to stdout as text. +*/ +void fz_debug_outline(fz_context *ctx, fz_outline *outline); /* fz_free_outline: Free hierarchical outline. @@ -2369,24 +1771,11 @@ void fz_debug_outline(fz_context *ctx, fz_outline *outline, int level); */ void fz_free_outline(fz_context *ctx, fz_outline *outline); -/* Document interface */ - +/* + Document interface +*/ typedef struct fz_document_s fz_document; -typedef struct fz_page_s fz_page; /* doesn't have a definition -- always cast to *_page */ - -struct fz_document_s -{ - void (*close)(fz_document *); - int (*needs_password)(fz_document *doc); - int (*authenticate_password)(fz_document *doc, char *password); - fz_outline *(*load_outline)(fz_document *doc); - int (*count_pages)(fz_document *doc); - fz_page *(*load_page)(fz_document *doc, int number); - fz_link *(*load_links)(fz_document *doc, fz_page *page); - fz_rect (*bound_page)(fz_document *doc, fz_page *page); - void (*run_page)(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie); - void (*free_page)(fz_document *doc, fz_page *page); -}; +typedef struct fz_page_s fz_page; /* fz_open_document: Open a PDF, XPS or CBZ document. diff --git a/fitz/image_jpeg.c b/fitz/image_jpeg.c index cef53d93..2840adbf 100644 --- a/fitz/image_jpeg.c +++ b/fitz/image_jpeg.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include <jpeglib.h> #include <setjmp.h> diff --git a/fitz/image_jpx.c b/fitz/image_jpx.c index 4d76b4e8..ac1db35a 100644 --- a/fitz/image_jpx.c +++ b/fitz/image_jpx.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #define OPJ_STATIC #include <openjpeg.h> @@ -144,7 +144,7 @@ fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *defcs if (n == 4) { fz_pixmap *tmp = fz_new_pixmap(ctx, fz_device_rgb, w, h); - fz_convert_pixmap(ctx, img, tmp); + fz_convert_pixmap(ctx, tmp, img); fz_drop_pixmap(ctx, img); img = tmp; } diff --git a/fitz/image_md5.c b/fitz/image_md5.c new file mode 100644 index 00000000..86ba0a12 --- /dev/null +++ b/fitz/image_md5.c @@ -0,0 +1,11 @@ +#include "fitz-internal.h" + +void fz_md5_pixmap(fz_pixmap *pix, unsigned char digest[16]) +{ + fz_md5 md5; + + fz_md5_init(&md5); + if (pix) + fz_md5_update(&md5, pix->samples, pix->w * pix->h * pix->n); + fz_md5_final(&md5, digest); +} diff --git a/fitz/image_png.c b/fitz/image_png.c index b3fe39cc..e2092c10 100644 --- a/fitz/image_png.c +++ b/fitz/image_png.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include <zlib.h> diff --git a/fitz/image_save.c b/fitz/image_save.c new file mode 100644 index 00000000..29d3e8fc --- /dev/null +++ b/fitz/image_save.c @@ -0,0 +1,32 @@ +#include "fitz-internal.h" + +void fz_save_pixmap(fz_context *ctx, fz_pixmap *img, char *file, int rgb) +{ + char name[1024]; + fz_pixmap *converted = NULL; + + if (!img) + return; + + if (rgb && img->colorspace && img->colorspace != fz_device_rgb) + { + converted = fz_new_pixmap_with_rect(ctx, fz_device_rgb, fz_bound_pixmap(img)); + fz_convert_pixmap(ctx, converted, img); + img = converted; + } + + if (img->n <= 4) + { + sprintf(name, "%s.png", file); + printf("extracting image %s\n", name); + fz_write_png(ctx, img, name, 0); + } + else + { + sprintf(name, "%s.pam", file); + printf("extracting image %s\n", name); + fz_write_pam(ctx, img, name, 0); + } + + fz_drop_pixmap(ctx, converted); +} diff --git a/fitz/image_tiff.c b/fitz/image_tiff.c index fff91a9e..ffd0ea88 100644 --- a/fitz/image_tiff.c +++ b/fitz/image_tiff.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" /* * TIFF image loader. Should be enough to support TIFF files in XPS. @@ -789,7 +789,7 @@ fz_load_tiff(fz_context *ctx, unsigned char *buf, int len) if (image->n == 5) { fz_pixmap *rgb = fz_new_pixmap(tiff.ctx, fz_device_rgb, image->w, image->h); - fz_convert_pixmap(tiff.ctx, image, rgb); + fz_convert_pixmap(tiff.ctx, rgb, image); rgb->xres = image->xres; rgb->yres = image->yres; fz_drop_pixmap(ctx, image); diff --git a/fitz/res_bitmap.c b/fitz/res_bitmap.c index 2aa28b02..25e88187 100644 --- a/fitz/res_bitmap.c +++ b/fitz/res_bitmap.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" fz_bitmap * fz_new_bitmap(fz_context *ctx, int w, int h, int n) @@ -74,3 +74,48 @@ fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename) fclose(fp); } + +fz_colorspace *fz_pixmap_colorspace(fz_context *ctx, fz_pixmap *pix) +{ + if (!pix) + return NULL; + return pix->colorspace; +} + +int fz_pixmap_components(fz_context *ctx, fz_pixmap *pix) +{ + if (!pix) + return 0; + return pix->n; +} + +unsigned char *fz_pixmap_pixels(fz_context *ctx, fz_pixmap *pix) +{ + if (!pix) + return NULL; + return pix->samples; +} + +void fz_bitmap_details(fz_bitmap *bit, int *w, int *h, int *n, int *stride) +{ + if (!bit) + { + if (w) + *w = 0; + if (h) + *h = 0; + if (n) + *n = 0; + if (stride) + *stride = 0; + return; + } + if (w) + *w = bit->w; + if (h) + *h = bit->h; + if (n) + *n = bit->n; + if (stride) + *w = bit->stride; +} diff --git a/fitz/res_colorspace.c b/fitz/res_colorspace.c index 3cdc0fa3..03d5967b 100644 --- a/fitz/res_colorspace.c +++ b/fitz/res_colorspace.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #define SLOWCMYK @@ -180,7 +180,7 @@ fz_find_device_colorspace(char *name) /* Fast pixmap color conversions */ -static void fast_gray_to_rgb(fz_pixmap *src, fz_pixmap *dst) +static void fast_gray_to_rgb(fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -196,7 +196,7 @@ static void fast_gray_to_rgb(fz_pixmap *src, fz_pixmap *dst) } } -static void fast_gray_to_cmyk(fz_pixmap *src, fz_pixmap *dst) +static void fast_gray_to_cmyk(fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -213,7 +213,7 @@ static void fast_gray_to_cmyk(fz_pixmap *src, fz_pixmap *dst) } } -static void fast_rgb_to_gray(fz_pixmap *src, fz_pixmap *dst) +static void fast_rgb_to_gray(fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -227,7 +227,7 @@ static void fast_rgb_to_gray(fz_pixmap *src, fz_pixmap *dst) } } -static void fast_bgr_to_gray(fz_pixmap *src, fz_pixmap *dst) +static void fast_bgr_to_gray(fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -241,7 +241,7 @@ static void fast_bgr_to_gray(fz_pixmap *src, fz_pixmap *dst) } } -static void fast_rgb_to_cmyk(fz_pixmap *src, fz_pixmap *dst) +static void fast_rgb_to_cmyk(fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -262,7 +262,7 @@ static void fast_rgb_to_cmyk(fz_pixmap *src, fz_pixmap *dst) } } -static void fast_bgr_to_cmyk(fz_pixmap *src, fz_pixmap *dst) +static void fast_bgr_to_cmyk(fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -283,7 +283,7 @@ static void fast_bgr_to_cmyk(fz_pixmap *src, fz_pixmap *dst) } } -static void fast_cmyk_to_gray(fz_pixmap *src, fz_pixmap *dst) +static void fast_cmyk_to_gray(fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -300,7 +300,7 @@ static void fast_cmyk_to_gray(fz_pixmap *src, fz_pixmap *dst) } } -static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst) +static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -328,7 +328,7 @@ static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst) } } -static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst) +static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -356,7 +356,7 @@ static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst) } } -static void fast_rgb_to_bgr(fz_pixmap *src, fz_pixmap *dst) +static void fast_rgb_to_bgr(fz_pixmap *dst, fz_pixmap *src) { unsigned char *s = src->samples; unsigned char *d = dst->samples; @@ -373,7 +373,7 @@ static void fast_rgb_to_bgr(fz_pixmap *src, fz_pixmap *dst) } static void -fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst) +fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src) { float srcv[FZ_MAX_COLORS]; float dstv[FZ_MAX_COLORS]; @@ -404,7 +404,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst) srcv[1] = *s++ - 128; srcv[2] = *s++ - 128; - fz_convert_color(ctx, ss, srcv, ds, dstv); + fz_convert_color(ctx, ds, dstv, ss, srcv); for (k = 0; k < dstn; k++) *d++ = dstv[k] * 255; @@ -424,7 +424,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst) for (k = 0; k < srcn; k++) srcv[k] = *s++ / 255.0f; - fz_convert_color(ctx, ss, srcv, ds, dstv); + fz_convert_color(ctx, ds, dstv, ss, srcv); for (k = 0; k < dstn; k++) *d++ = dstv[k] * 255; @@ -442,7 +442,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst) for (i = 0; i < 256; i++) { srcv[0] = i / 255.0f; - fz_convert_color(ctx, ss, srcv, ds, dstv); + fz_convert_color(ctx, ds, dstv, ss, srcv); for (k = 0; k < dstn; k++) lookup[i * dstn + k] = dstv[k] * 255; } @@ -483,7 +483,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst) { for (k = 0; k < srcn; k++) srcv[k] = *s++ / 255.0f; - fz_convert_color(ctx, ss, srcv, ds, dstv); + fz_convert_color(ctx, ds, dstv, ss, srcv); for (k = 0; k < dstn; k++) *d++ = dstv[k] * 255; @@ -499,7 +499,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst) } void -fz_convert_pixmap(fz_context *ctx, fz_pixmap *sp, fz_pixmap *dp) +fz_convert_pixmap(fz_context *ctx, fz_pixmap *dp, fz_pixmap *sp) { fz_colorspace *ss = sp->colorspace; fz_colorspace *ds = dp->colorspace; @@ -510,37 +510,37 @@ fz_convert_pixmap(fz_context *ctx, fz_pixmap *sp, fz_pixmap *dp) if (ss == fz_device_gray) { - if (ds == fz_device_rgb) fast_gray_to_rgb(sp, dp); - else if (ds == fz_device_bgr) fast_gray_to_rgb(sp, dp); /* bgr == rgb here */ - else if (ds == fz_device_cmyk) fast_gray_to_cmyk(sp, dp); - else fz_std_conv_pixmap(ctx, sp, dp); + if (ds == fz_device_rgb) fast_gray_to_rgb(dp, sp); + else if (ds == fz_device_bgr) fast_gray_to_rgb(dp, sp); /* bgr == rgb here */ + else if (ds == fz_device_cmyk) fast_gray_to_cmyk(dp, sp); + else fz_std_conv_pixmap(ctx, dp, sp); } else if (ss == fz_device_rgb) { - if (ds == fz_device_gray) fast_rgb_to_gray(sp, dp); - else if (ds == fz_device_bgr) fast_rgb_to_bgr(sp, dp); - else if (ds == fz_device_cmyk) fast_rgb_to_cmyk(sp, dp); - else fz_std_conv_pixmap(ctx, sp, dp); + if (ds == fz_device_gray) fast_rgb_to_gray(dp, sp); + else if (ds == fz_device_bgr) fast_rgb_to_bgr(dp, sp); + else if (ds == fz_device_cmyk) fast_rgb_to_cmyk(dp, sp); + else fz_std_conv_pixmap(ctx, dp, sp); } else if (ss == fz_device_bgr) { - if (ds == fz_device_gray) fast_bgr_to_gray(sp, dp); - else if (ds == fz_device_rgb) fast_rgb_to_bgr(sp, dp); /* bgr = rgb here */ + if (ds == fz_device_gray) fast_bgr_to_gray(dp, sp); + else if (ds == fz_device_rgb) fast_rgb_to_bgr(dp, sp); /* bgr = rgb here */ else if (ds == fz_device_cmyk) fast_bgr_to_cmyk(sp, dp); - else fz_std_conv_pixmap(ctx, sp, dp); + else fz_std_conv_pixmap(ctx, dp, sp); } else if (ss == fz_device_cmyk) { - if (ds == fz_device_gray) fast_cmyk_to_gray(sp, dp); - else if (ds == fz_device_bgr) fast_cmyk_to_bgr(ctx, sp, dp); - else if (ds == fz_device_rgb) fast_cmyk_to_rgb(ctx, sp, dp); - else fz_std_conv_pixmap(ctx, sp, dp); + if (ds == fz_device_gray) fast_cmyk_to_gray(dp, sp); + else if (ds == fz_device_bgr) fast_cmyk_to_bgr(ctx, dp, sp); + else if (ds == fz_device_rgb) fast_cmyk_to_rgb(ctx, dp, sp); + else fz_std_conv_pixmap(ctx, dp, sp); } - else fz_std_conv_pixmap(ctx, sp, dp); + else fz_std_conv_pixmap(ctx, dp, sp); } /* Convert a single color */ @@ -567,7 +567,7 @@ fz_std_conv_color(fz_context *ctx, fz_colorspace *srcs, float *srcv, fz_colorspa } void -fz_convert_color(fz_context *ctx, fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv) +fz_convert_color(fz_context *ctx, fz_colorspace *ds, float *dv, fz_colorspace *ss, float *sv) { if (ss == fz_device_gray) { diff --git a/fitz/res_font.c b/fitz/res_font.c index f6207e80..dd4e68da 100644 --- a/fitz/res_font.c +++ b/fitz/res_font.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include <ft2build.h> #include FT_FREETYPE_H diff --git a/fitz/res_halftone.c b/fitz/res_halftone.c index 7258ad01..ec26571e 100644 --- a/fitz/res_halftone.c +++ b/fitz/res_halftone.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" fz_halftone * fz_new_halftone(fz_context *ctx, int comps) @@ -162,13 +162,18 @@ fz_bitmap *fz_halftone_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht) fz_bitmap *out; unsigned char *ht_line, *o, *p; int w, h, x, y, n, pstride, ostride; + fz_halftone *ht_orig = ht; - if (!pix || !ht) + if (!pix) return NULL; assert(pix->n == 2); /* Mono + Alpha */ n = pix->n-1; /* Remove alpha */ + if (ht == NULL) + { + ht = fz_get_default_halftone(ctx, n); + } ht_line = fz_malloc(ctx, pix->w * n); out = fz_new_bitmap(ctx, pix->w, pix->h, n); o = out->samples; @@ -187,5 +192,7 @@ fz_bitmap *fz_halftone_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht) o += ostride; p += pstride; } + if (!ht_orig) + fz_drop_halftone(ctx, ht); return out; } diff --git a/fitz/res_path.c b/fitz/res_path.c index a645f9d5..4964a09e 100644 --- a/fitz/res_path.c +++ b/fitz/res_path.c @@ -1,5 +1,5 @@ #include <assert.h> -#include "fitz.h" +#include "fitz-internal.h" fz_path * fz_new_path(fz_context *ctx) diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c index 1b254f36..fc40135e 100644 --- a/fitz/res_pixmap.c +++ b/fitz/res_pixmap.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" fz_pixmap * fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix) @@ -282,6 +282,27 @@ fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix) } } +void fz_invert_pixmap_rect(fz_pixmap *image, fz_bbox rect) +{ + unsigned char *p; + int x, y, n; + + int x0 = CLAMP(rect.x0 - image->x, 0, image->w - 1); + int x1 = CLAMP(rect.x1 - image->x, 0, image->w - 1); + int y0 = CLAMP(rect.y0 - image->y, 0, image->h - 1); + int y1 = CLAMP(rect.y1 - image->y, 0, image->h - 1); + + for (y = y0; y < y1; y++) + { + p = image->samples + (y * image->w + x0) * image->n; + for (x = x0; x < x1; x++) + { + for (n = image->n; n > 0; n--, p++) + *p = 255 - *p; + } + } +} + void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma) { diff --git a/fitz/res_shade.c b/fitz/res_shade.c index 3fdf2e15..f8f11a81 100644 --- a/fitz/res_shade.c +++ b/fitz/res_shade.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" fz_shade * fz_keep_shade(fz_context *ctx, fz_shade *shade) diff --git a/fitz/res_store.c b/fitz/res_store.c index df9c6e33..e85aead9 100644 --- a/fitz/res_store.c +++ b/fitz/res_store.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" typedef struct fz_item_s fz_item; diff --git a/fitz/res_text.c b/fitz/res_text.c index cdfaaa98..433ff8f9 100644 --- a/fitz/res_text.c +++ b/fitz/res_text.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" fz_text * fz_new_text(fz_context *ctx, fz_font *font, fz_matrix trm, int wmode) diff --git a/fitz/stm_buffer.c b/fitz/stm_buffer.c index d70118e1..4be0165a 100644 --- a/fitz/stm_buffer.c +++ b/fitz/stm_buffer.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" fz_buffer * fz_new_buffer(fz_context *ctx, int size) @@ -70,3 +70,11 @@ fz_trim_buffer(fz_context *ctx, fz_buffer *buf) if (buf->cap > buf->len+1) fz_resize_buffer(ctx, buf, buf->len); } + +int +fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **datap) +{ + if (datap) + *datap = (buf ? buf->data : NULL); + return (buf ? buf->len : 0); +} diff --git a/fitz/stm_open.c b/fitz/stm_open.c index e634f729..1e303825 100644 --- a/fitz/stm_open.c +++ b/fitz/stm_open.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" fz_stream * fz_new_stream(fz_context *ctx, void *state, diff --git a/fitz/stm_read.c b/fitz/stm_read.c index a95c62c0..216d2207 100644 --- a/fitz/stm_read.c +++ b/fitz/stm_read.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #define MIN_BOMB (100 << 20) diff --git a/pdf/base_object.c b/pdf/base_object.c index 94f1acfc..1dc07f1a 100644 --- a/pdf/base_object.c +++ b/pdf/base_object.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" typedef enum pdf_objkind_e { diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h new file mode 100644 index 00000000..faec16b5 --- /dev/null +++ b/pdf/mupdf-internal.h @@ -0,0 +1,535 @@ +#ifndef MUPDF_INTERNAL_H +#define MUPDF_INTERNAL_H + +#include "mupdf.h" +#include "fitz-internal.h" + +void pdf_set_str_len(pdf_obj *obj, int newlen); +void *pdf_get_indirect_document(pdf_obj *obj); + +/* + * PDF Images + */ + +typedef struct pdf_image_params_s pdf_image_params; + +struct pdf_image_params_s +{ + int type; + fz_colorspace *colorspace; + union + { + struct + { + int columns; + int rows; + int k; + int eol; + int eba; + int eob; + int bi1; + } + fax; + struct + { + int ct; + } + jpeg; + struct + { + int columns; + int colors; + int predictor; + int bpc; + } + flate; + struct + { + int columns; + int colors; + int predictor; + int bpc; + int ec; + } + lzw; + } + u; +}; + + +typedef struct pdf_image_s pdf_image; + +struct pdf_image_s +{ + fz_image base; + fz_pixmap *tile; + int n, bpc; + pdf_image_params params; + fz_buffer *buffer; + int colorkey[FZ_MAX_COLORS * 2]; + float decode[FZ_MAX_COLORS * 2]; + int imagemask; + int interpolate; + int usecolorkey; +}; + +enum +{ + PDF_IMAGE_RAW, + PDF_IMAGE_FAX, + PDF_IMAGE_JPEG, + PDF_IMAGE_RLD, + PDF_IMAGE_FLATE, + PDF_IMAGE_LZW, + PDF_IMAGE_JPX +}; + +/* + * tokenizer and low-level object parser + */ + +enum +{ + PDF_TOK_ERROR, PDF_TOK_EOF, + PDF_TOK_OPEN_ARRAY, PDF_TOK_CLOSE_ARRAY, + PDF_TOK_OPEN_DICT, PDF_TOK_CLOSE_DICT, + PDF_TOK_OPEN_BRACE, PDF_TOK_CLOSE_BRACE, + PDF_TOK_NAME, PDF_TOK_INT, PDF_TOK_REAL, PDF_TOK_STRING, PDF_TOK_KEYWORD, + PDF_TOK_R, PDF_TOK_TRUE, PDF_TOK_FALSE, PDF_TOK_NULL, + PDF_TOK_OBJ, PDF_TOK_ENDOBJ, + PDF_TOK_STREAM, PDF_TOK_ENDSTREAM, + PDF_TOK_XREF, PDF_TOK_TRAILER, PDF_TOK_STARTXREF, + PDF_NUM_TOKENS +}; + +enum +{ + PDF_LEXBUF_SMALL = 256, + PDF_LEXBUF_LARGE = 65536 +}; + +typedef struct pdf_lexbuf_s pdf_lexbuf; +typedef struct pdf_lexbuf_large_s pdf_lexbuf_large; + +struct pdf_lexbuf_s +{ + int size; + int len; + int i; + float f; + char scratch[PDF_LEXBUF_SMALL]; +}; + +struct pdf_lexbuf_large_s +{ + pdf_lexbuf base; + char scratch[PDF_LEXBUF_LARGE - PDF_LEXBUF_SMALL]; +}; + +int pdf_lex(fz_stream *f, pdf_lexbuf *lexbuf); + +pdf_obj *pdf_parse_array(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf); +pdf_obj *pdf_parse_dict(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf); +pdf_obj *pdf_parse_stm_obj(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf); +pdf_obj *pdf_parse_ind_obj(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf, int *num, int *gen, int *stm_ofs); + +/* + * xref and object / stream api + */ + +typedef struct pdf_xref_entry_s pdf_xref_entry; + +struct pdf_xref_entry_s +{ + int ofs; /* file offset / objstm object number */ + int gen; /* generation / objstm index */ + int stm_ofs; /* on-disk stream */ + pdf_obj *obj; /* stored/cached object */ + int type; /* 0=unset (f)ree i(n)use (o)bjstm */ +}; + +typedef struct pdf_crypt_s pdf_crypt; +typedef struct pdf_ocg_descriptor_s pdf_ocg_descriptor; +typedef struct pdf_ocg_entry_s pdf_ocg_entry; + +struct pdf_ocg_entry_s +{ + int num; + int gen; + int state; +}; + +struct pdf_ocg_descriptor_s +{ + int len; + pdf_ocg_entry *ocgs; + pdf_obj *intent; +}; + +struct pdf_document_s +{ + fz_document super; + + fz_context *ctx; + fz_stream *file; + + int version; + int startxref; + int file_size; + pdf_crypt *crypt; + pdf_obj *trailer; + pdf_ocg_descriptor *ocg; + + int len; + pdf_xref_entry *table; + + int page_len; + int page_cap; + pdf_obj **page_objs; + pdf_obj **page_refs; + + pdf_lexbuf_large lexbuf; +}; + +void pdf_cache_object(pdf_document *doc, int num, int gen); + +fz_stream *pdf_open_inline_stream(pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *chain, pdf_image_params *params); +fz_buffer *pdf_load_image_stream(pdf_document *doc, int num, int gen, pdf_image_params *params); +fz_stream *pdf_open_image_stream(pdf_document *doc, int num, int gen, pdf_image_params *params); +fz_stream *pdf_open_stream_with_offset(pdf_document *doc, int num, int gen, pdf_obj *dict, int stm_ofs); +fz_stream *pdf_open_image_decomp_stream(fz_context *ctx, fz_buffer *, pdf_image_params *params, int *factor); + +void pdf_repair_xref(pdf_document *doc, pdf_lexbuf *buf); +void pdf_repair_obj_stms(pdf_document *doc); +void pdf_debug_xref(pdf_document *); +void pdf_resize_xref(pdf_document *doc, int newcap); + +/* + * Encryption + */ + +pdf_crypt *pdf_new_crypt(fz_context *ctx, pdf_obj *enc, pdf_obj *id); +void pdf_free_crypt(fz_context *ctx, pdf_crypt *crypt); + +void pdf_crypt_obj(fz_context *ctx, pdf_crypt *crypt, pdf_obj *obj, int num, int gen); +fz_stream *pdf_open_crypt(fz_stream *chain, pdf_crypt *crypt, int num, int gen); +fz_stream *pdf_open_crypt_with_filter(fz_stream *chain, pdf_crypt *crypt, char *name, int num, int gen); + +int pdf_get_crypt_revision(pdf_document *doc); +char *pdf_get_crypt_method(pdf_document *doc); +int pdf_get_crypt_length(pdf_document *doc); +unsigned char *pdf_get_crypt_key(pdf_document *doc); + +void pdf_debug_crypt(pdf_crypt *crypt); + +/* + * Functions, Colorspaces, Shadings and Images + */ + +typedef struct pdf_function_s pdf_function; + +pdf_function *pdf_load_function(pdf_document *doc, pdf_obj *ref); +void pdf_eval_function(fz_context *ctx, pdf_function *func, float *in, int inlen, float *out, int outlen); +pdf_function *pdf_keep_function(fz_context *ctx, pdf_function *func); +void pdf_drop_function(fz_context *ctx, pdf_function *func); +unsigned int pdf_function_size(pdf_function *func); + +fz_colorspace *pdf_load_colorspace(pdf_document *doc, pdf_obj *obj); +fz_pixmap *pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src); + +fz_shade *pdf_load_shading(pdf_document *doc, pdf_obj *obj); + +fz_image *pdf_load_inline_image(pdf_document *doc, pdf_obj *rdb, pdf_obj *dict, fz_stream *file); +int pdf_is_jpx_image(fz_context *ctx, pdf_obj *dict); + +/* + * Pattern + */ + +typedef struct pdf_pattern_s pdf_pattern; + +struct pdf_pattern_s +{ + fz_storable storable; + int ismask; + float xstep; + float ystep; + fz_matrix matrix; + fz_rect bbox; + pdf_obj *resources; + fz_buffer *contents; +}; + +pdf_pattern *pdf_load_pattern(pdf_document *doc, pdf_obj *obj); +pdf_pattern *pdf_keep_pattern(fz_context *ctx, pdf_pattern *pat); +void pdf_drop_pattern(fz_context *ctx, pdf_pattern *pat); + +/* + * XObject + */ + +typedef struct pdf_xobject_s pdf_xobject; + +struct pdf_xobject_s +{ + fz_storable storable; + fz_matrix matrix; + fz_rect bbox; + int isolated; + int knockout; + int transparency; + fz_colorspace *colorspace; + pdf_obj *resources; + fz_buffer *contents; + pdf_obj *me; +}; + +pdf_xobject *pdf_load_xobject(pdf_document *doc, pdf_obj *obj); +pdf_xobject *pdf_keep_xobject(fz_context *ctx, pdf_xobject *xobj); +void pdf_drop_xobject(fz_context *ctx, pdf_xobject *xobj); + +/* + * CMap + */ + +typedef struct pdf_cmap_s pdf_cmap; +typedef struct pdf_range_s pdf_range; + +enum { PDF_CMAP_SINGLE, PDF_CMAP_RANGE, PDF_CMAP_TABLE, PDF_CMAP_MULTI }; + +struct pdf_range_s +{ + unsigned short low; + /* Next, we pack 2 fields into the same unsigned short. Top 14 bits + * are the extent, bottom 2 bits are flags: single, range, table, + * multi */ + unsigned short extent_flags; + unsigned short offset; /* range-delta or table-index */ +}; + +struct pdf_cmap_s +{ + fz_storable storable; + char cmap_name[32]; + + char usecmap_name[32]; + pdf_cmap *usecmap; + + int wmode; + + int codespace_len; + struct + { + unsigned short n; + unsigned short low; + unsigned short high; + } codespace[40]; + + int rlen, rcap; + pdf_range *ranges; + + int tlen, tcap; + unsigned short *table; +}; + +pdf_cmap *pdf_new_cmap(fz_context *ctx); +pdf_cmap *pdf_keep_cmap(fz_context *ctx, pdf_cmap *cmap); +void pdf_drop_cmap(fz_context *ctx, pdf_cmap *cmap); +void pdf_free_cmap_imp(fz_context *ctx, fz_storable *cmap); +unsigned int pdf_cmap_size(fz_context *ctx, pdf_cmap *cmap); + +void pdf_debug_cmap(fz_context *ctx, pdf_cmap *cmap); +int pdf_get_wmode(fz_context *ctx, pdf_cmap *cmap); +void pdf_set_wmode(fz_context *ctx, pdf_cmap *cmap, int wmode); +void pdf_set_usecmap(fz_context *ctx, pdf_cmap *cmap, pdf_cmap *usecmap); + +void pdf_add_codespace(fz_context *ctx, pdf_cmap *cmap, int low, int high, int n); +void pdf_map_range_to_table(fz_context *ctx, pdf_cmap *cmap, int low, int *map, int len); +void pdf_map_range_to_range(fz_context *ctx, pdf_cmap *cmap, int srclo, int srchi, int dstlo); +void pdf_map_one_to_many(fz_context *ctx, pdf_cmap *cmap, int one, int *many, int len); +void pdf_sort_cmap(fz_context *ctx, pdf_cmap *cmap); + +int pdf_lookup_cmap(pdf_cmap *cmap, int cpt); +int pdf_lookup_cmap_full(pdf_cmap *cmap, int cpt, int *out); +int pdf_decode_cmap(pdf_cmap *cmap, unsigned char *s, int *cpt); + +pdf_cmap *pdf_new_identity_cmap(fz_context *ctx, int wmode, int bytes); +pdf_cmap *pdf_load_cmap(fz_context *ctx, fz_stream *file); +pdf_cmap *pdf_load_system_cmap(fz_context *ctx, char *name); +pdf_cmap *pdf_load_builtin_cmap(fz_context *ctx, char *name); +pdf_cmap *pdf_load_embedded_cmap(pdf_document *doc, pdf_obj *ref); + +/* + * Font + */ + +enum +{ + PDF_FD_FIXED_PITCH = 1 << 0, + PDF_FD_SERIF = 1 << 1, + PDF_FD_SYMBOLIC = 1 << 2, + PDF_FD_SCRIPT = 1 << 3, + PDF_FD_NONSYMBOLIC = 1 << 5, + PDF_FD_ITALIC = 1 << 6, + PDF_FD_ALL_CAP = 1 << 16, + PDF_FD_SMALL_CAP = 1 << 17, + PDF_FD_FORCE_BOLD = 1 << 18 +}; + +enum { PDF_ROS_CNS, PDF_ROS_GB, PDF_ROS_JAPAN, PDF_ROS_KOREA }; + +void pdf_load_encoding(char **estrings, char *encoding); +int pdf_lookup_agl(char *name); +const char **pdf_lookup_agl_duplicates(int ucs); + +extern const unsigned short pdf_doc_encoding[256]; +extern const char * const pdf_mac_roman[256]; +extern const char * const pdf_mac_expert[256]; +extern const char * const pdf_win_ansi[256]; +extern const char * const pdf_standard[256]; + +typedef struct pdf_font_desc_s pdf_font_desc; +typedef struct pdf_hmtx_s pdf_hmtx; +typedef struct pdf_vmtx_s pdf_vmtx; + +struct pdf_hmtx_s +{ + unsigned short lo; + unsigned short hi; + int w; /* type3 fonts can be big! */ +}; + +struct pdf_vmtx_s +{ + unsigned short lo; + unsigned short hi; + short x; + short y; + short w; +}; + +struct pdf_font_desc_s +{ + fz_storable storable; + unsigned int size; + + fz_font *font; + + /* FontDescriptor */ + int flags; + float italic_angle; + float ascent; + float descent; + float cap_height; + float x_height; + float missing_width; + + /* Encoding (CMap) */ + pdf_cmap *encoding; + pdf_cmap *to_ttf_cmap; + int cid_to_gid_len; + unsigned short *cid_to_gid; + + /* ToUnicode */ + pdf_cmap *to_unicode; + int cid_to_ucs_len; + unsigned short *cid_to_ucs; + + /* Metrics (given in the PDF file) */ + int wmode; + + int hmtx_len, hmtx_cap; + pdf_hmtx dhmtx; + pdf_hmtx *hmtx; + + int vmtx_len, vmtx_cap; + pdf_vmtx dvmtx; + pdf_vmtx *vmtx; + + int is_embedded; +}; + +void pdf_set_font_wmode(fz_context *ctx, pdf_font_desc *font, int wmode); +void pdf_set_default_hmtx(fz_context *ctx, pdf_font_desc *font, int w); +void pdf_set_default_vmtx(fz_context *ctx, pdf_font_desc *font, int y, int w); +void pdf_add_hmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int w); +void pdf_add_vmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int x, int y, int w); +void pdf_end_hmtx(fz_context *ctx, pdf_font_desc *font); +void pdf_end_vmtx(fz_context *ctx, pdf_font_desc *font); +pdf_hmtx pdf_get_hmtx(fz_context *ctx, pdf_font_desc *font, int cid); +pdf_vmtx pdf_get_vmtx(fz_context *ctx, pdf_font_desc *font, int cid); + +void pdf_load_to_unicode(pdf_document *doc, pdf_font_desc *font, char **strings, char *collection, pdf_obj *cmapstm); + +int pdf_font_cid_to_gid(fz_context *ctx, pdf_font_desc *fontdesc, int cid); + +unsigned char *pdf_find_builtin_font(char *name, unsigned int *len); +unsigned char *pdf_find_substitute_font(int mono, int serif, int bold, int italic, unsigned int *len); +unsigned char *pdf_find_substitute_cjk_font(int ros, int serif, unsigned int *len); + +pdf_font_desc *pdf_load_type3_font(pdf_document *doc, pdf_obj *rdb, pdf_obj *obj); +pdf_font_desc *pdf_load_font(pdf_document *doc, pdf_obj *rdb, pdf_obj *obj); + +pdf_font_desc *pdf_new_font_desc(fz_context *ctx); +pdf_font_desc *pdf_keep_font(fz_context *ctx, pdf_font_desc *fontdesc); +void pdf_drop_font(fz_context *ctx, pdf_font_desc *font); + +void pdf_debug_font(fz_context *ctx, pdf_font_desc *fontdesc); + +/* + * Interactive features + */ + +typedef struct pdf_annot_s pdf_annot; + +struct pdf_annot_s +{ + pdf_obj *obj; + fz_rect rect; + pdf_xobject *ap; + fz_matrix matrix; + pdf_annot *next; +}; + +fz_link_dest pdf_parse_link_dest(pdf_document *doc, pdf_obj *dest); +fz_link_dest pdf_parse_action(pdf_document *doc, pdf_obj *action); +pdf_obj *pdf_lookup_dest(pdf_document *doc, pdf_obj *needle); +pdf_obj *pdf_lookup_name(pdf_document *doc, char *which, pdf_obj *needle); +pdf_obj *pdf_load_name_tree(pdf_document *doc, char *which); + +fz_link *pdf_load_link_annots(pdf_document *, pdf_obj *annots, fz_matrix page_ctm); + +pdf_annot *pdf_load_annots(pdf_document *, pdf_obj *annots); +void pdf_free_annot(fz_context *ctx, pdf_annot *link); + +/* + * Page tree, pages and related objects + */ + +struct pdf_page_s +{ + fz_matrix ctm; /* calculated from mediabox and rotate */ + fz_rect mediabox; + int rotate; + int transparency; + pdf_obj *resources; + fz_buffer *contents; + fz_link *links; + pdf_annot *annots; +}; + +/* + * Content stream parsing + */ + +void pdf_run_glyph(pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate); + +/* + * PDF interface to store + */ + +void pdf_store_item(fz_context *ctx, pdf_obj *key, void *val, unsigned int itemsize); +void *pdf_find_item(fz_context *ctx, fz_store_free_fn *free, pdf_obj *key); +void pdf_remove_item(fz_context *ctx, fz_store_free_fn *free, pdf_obj *key); + +#endif diff --git a/pdf/mupdf.h b/pdf/mupdf.h index 5d775044..7566bc36 100644 --- a/pdf/mupdf.h +++ b/pdf/mupdf.h @@ -1,9 +1,9 @@ -#ifndef _MUPDF_H_ -#define _MUPDF_H_ +#ifndef MUPDF_H +#define MUPDF_H -#ifndef _FITZ_H_ -#error "fitz.h must be included before mupdf.h" -#endif +#include "fitz.h" + +typedef struct pdf_document_s pdf_document; /* * Dynamic objects. @@ -39,6 +39,7 @@ int pdf_is_string(pdf_obj *obj); int pdf_is_array(pdf_obj *obj); int pdf_is_dict(pdf_obj *obj); int pdf_is_indirect(pdf_obj *obj); +int pdf_is_stream(pdf_document *doc, int num, int gen); int pdf_objcmp(pdf_obj *a, pdf_obj *b); @@ -81,220 +82,27 @@ int pdf_fprint_obj(FILE *fp, pdf_obj *obj, int tight); void pdf_debug_obj(pdf_obj *obj); void pdf_debug_ref(pdf_obj *obj); -void pdf_set_str_len(pdf_obj *obj, int newlen); /* private */ -void *pdf_get_indirect_document(pdf_obj *obj); /* private */ - -/* - * PDF Images - */ - -typedef struct pdf_image_params_s pdf_image_params; - -struct pdf_image_params_s -{ - int type; - fz_colorspace *colorspace; - union - { - struct - { - int columns; - int rows; - int k; - int eol; - int eba; - int eob; - int bi1; - } - fax; - struct - { - int ct; - } - jpeg; - struct - { - int columns; - int colors; - int predictor; - int bpc; - } - flate; - struct - { - int columns; - int colors; - int predictor; - int bpc; - int ec; - } - lzw; - } - u; -}; - - -typedef struct pdf_image_s pdf_image; - -struct pdf_image_s -{ - fz_image base; - fz_pixmap *tile; - int n, bpc; - pdf_image_params params; - fz_buffer *buffer; - int colorkey[FZ_MAX_COLORS * 2]; - float decode[FZ_MAX_COLORS * 2]; - int imagemask; - int interpolate; - int usecolorkey; -}; - -enum -{ - PDF_IMAGE_RAW, - PDF_IMAGE_FAX, - PDF_IMAGE_JPEG, - PDF_IMAGE_RLD, - PDF_IMAGE_FLATE, - PDF_IMAGE_LZW, - PDF_IMAGE_JPX -}; - -typedef struct pdf_document_s pdf_document; - -/* - * tokenizer and low-level object parser - */ - -enum -{ - PDF_TOK_ERROR, PDF_TOK_EOF, - PDF_TOK_OPEN_ARRAY, PDF_TOK_CLOSE_ARRAY, - PDF_TOK_OPEN_DICT, PDF_TOK_CLOSE_DICT, - PDF_TOK_OPEN_BRACE, PDF_TOK_CLOSE_BRACE, - PDF_TOK_NAME, PDF_TOK_INT, PDF_TOK_REAL, PDF_TOK_STRING, PDF_TOK_KEYWORD, - PDF_TOK_R, PDF_TOK_TRUE, PDF_TOK_FALSE, PDF_TOK_NULL, - PDF_TOK_OBJ, PDF_TOK_ENDOBJ, - PDF_TOK_STREAM, PDF_TOK_ENDSTREAM, - PDF_TOK_XREF, PDF_TOK_TRAILER, PDF_TOK_STARTXREF, - PDF_NUM_TOKENS -}; - -enum -{ - PDF_LEXBUF_SMALL = 256, - PDF_LEXBUF_LARGE = 65536 -}; - - - -typedef struct pdf_lexbuf_s pdf_lexbuf; -typedef struct pdf_lexbuf_large_s pdf_lexbuf_large; - -struct pdf_lexbuf_s -{ - int size; - int len; - int i; - float f; - char scratch[PDF_LEXBUF_SMALL]; -}; - -struct pdf_lexbuf_large_s -{ - pdf_lexbuf base; - char scratch[PDF_LEXBUF_LARGE - PDF_LEXBUF_SMALL]; -}; - - - -int pdf_lex(fz_stream *f, pdf_lexbuf *lexbuf); - -pdf_obj *pdf_parse_array(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf); -pdf_obj *pdf_parse_dict(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf); -pdf_obj *pdf_parse_stm_obj(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf); -pdf_obj *pdf_parse_ind_obj(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf, int *num, int *gen, int *stm_ofs); - -fz_rect pdf_to_rect(fz_context *ctx, pdf_obj *array); -fz_matrix pdf_to_matrix(fz_context *ctx, pdf_obj *array); char *pdf_to_utf8(fz_context *ctx, pdf_obj *src); -unsigned short *pdf_to_ucs2(fz_context *ctx, pdf_obj *src); +unsigned short *pdf_to_ucs2(fz_context *ctx, pdf_obj *src); /* sumatrapdf */ pdf_obj *pdf_to_utf8_name(fz_context *ctx, pdf_obj *src); char *pdf_from_ucs2(fz_context *ctx, unsigned short *str); -/* - * xref and object / stream api - */ - -typedef struct pdf_xref_entry_s pdf_xref_entry; -typedef struct pdf_crypt_s pdf_crypt; -typedef struct pdf_ocg_descriptor_s pdf_ocg_descriptor; -typedef struct pdf_ocg_entry_s pdf_ocg_entry; - -struct pdf_xref_entry_s -{ - int ofs; /* file offset / objstm object number */ - int gen; /* generation / objstm index */ - int stm_ofs; /* on-disk stream */ - pdf_obj *obj; /* stored/cached object */ - int type; /* 0=unset (f)ree i(n)use (o)bjstm */ -}; - -struct pdf_ocg_entry_s -{ - int num; - int gen; - int state; -}; - -struct pdf_ocg_descriptor_s -{ - int len; - pdf_ocg_entry *ocgs; - pdf_obj *intent; -}; - -struct pdf_document_s -{ - fz_document super; - - fz_context *ctx; - fz_stream *file; - - int version; - int startxref; - int file_size; - pdf_crypt *crypt; - pdf_obj *trailer; - pdf_ocg_descriptor *ocg; - - int len; - pdf_xref_entry *table; - - int page_len; - int page_cap; - pdf_obj **page_objs; - pdf_obj **page_refs; - - pdf_lexbuf_large lexbuf; -}; +fz_rect pdf_to_rect(fz_context *ctx, pdf_obj *array); +fz_matrix pdf_to_matrix(fz_context *ctx, pdf_obj *array); +int pdf_count_objects(pdf_document *doc); pdf_obj *pdf_resolve_indirect(pdf_obj *ref); -void pdf_cache_object(pdf_document *doc, int num, int gen); pdf_obj *pdf_load_object(pdf_document *doc, int num, int gen); void pdf_update_object(pdf_document *doc, int num, int gen, pdf_obj *newobj); -int pdf_is_stream(pdf_document *doc, int num, int gen); -fz_stream *pdf_open_inline_stream(pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *chain, pdf_image_params *params); fz_buffer *pdf_load_raw_stream(pdf_document *doc, int num, int gen); fz_buffer *pdf_load_stream(pdf_document *doc, int num, int gen); -fz_buffer *pdf_load_image_stream(pdf_document *doc, int num, int gen, pdf_image_params *params); fz_stream *pdf_open_raw_stream(pdf_document *doc, int num, int gen); -fz_stream *pdf_open_image_stream(pdf_document *doc, int num, int gen, pdf_image_params *params); fz_stream *pdf_open_stream(pdf_document *doc, int num, int gen); -fz_stream *pdf_open_stream_with_offset(pdf_document *doc, int num, int gen, pdf_obj *dict, int stm_ofs); -fz_stream *pdf_open_image_decomp_stream(fz_context *ctx, fz_buffer *, pdf_image_params *params, int *factor); + +fz_image *pdf_load_image(pdf_document *doc, pdf_obj *obj); + +fz_outline *pdf_load_outline(pdf_document *doc); /* pdf_open_document: Open a PDF document. @@ -336,15 +144,8 @@ pdf_document *pdf_open_document_with_stream(fz_stream *file); */ void pdf_close_document(pdf_document *doc); -/* private */ -void pdf_repair_xref(pdf_document *doc, pdf_lexbuf *buf); -void pdf_repair_obj_stms(pdf_document *doc); -void pdf_debug_xref(pdf_document *); -void pdf_resize_xref(pdf_document *doc, int newcap); - -/* - * Encryption - */ +int pdf_needs_password(pdf_document *doc); +int pdf_authenticate_password(pdf_document *doc, char *pw); enum { @@ -359,325 +160,10 @@ enum PDF_DEFAULT_PERM_FLAGS = 0xfffc }; -pdf_crypt *pdf_new_crypt(fz_context *ctx, pdf_obj *enc, pdf_obj *id); -void pdf_free_crypt(fz_context *ctx, pdf_crypt *crypt); - -void pdf_crypt_obj(fz_context *ctx, pdf_crypt *crypt, pdf_obj *obj, int num, int gen); -fz_stream *pdf_open_crypt(fz_stream *chain, pdf_crypt *crypt, int num, int gen); -fz_stream *pdf_open_crypt_with_filter(fz_stream *chain, pdf_crypt *crypt, char *name, int num, int gen); - -int pdf_needs_password(pdf_document *doc); -int pdf_authenticate_password(pdf_document *doc, char *pw); int pdf_has_permission(pdf_document *doc, int p); -int pdf_get_crypt_revision(pdf_document *doc); -char *pdf_get_crypt_method(pdf_document *doc); -int pdf_get_crypt_length(pdf_document *doc); -unsigned char *pdf_get_crypt_key(pdf_document *doc); - -void pdf_debug_crypt(pdf_crypt *crypt); - -/* - * Functions, Colorspaces, Shadings and Images - */ - -typedef struct pdf_function_s pdf_function; - -pdf_function *pdf_load_function(pdf_document *doc, pdf_obj *ref); -void pdf_eval_function(fz_context *ctx, pdf_function *func, float *in, int inlen, float *out, int outlen); -pdf_function *pdf_keep_function(fz_context *ctx, pdf_function *func); -void pdf_drop_function(fz_context *ctx, pdf_function *func); -unsigned int pdf_function_size(pdf_function *func); - -fz_colorspace *pdf_load_colorspace(pdf_document *doc, pdf_obj *obj); -fz_pixmap *pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src); - -fz_shade *pdf_load_shading(pdf_document *doc, pdf_obj *obj); - -fz_image *pdf_load_inline_image(pdf_document *doc, pdf_obj *rdb, pdf_obj *dict, fz_stream *file); -fz_image *pdf_load_image(pdf_document *doc, pdf_obj *obj); -int pdf_is_jpx_image(fz_context *ctx, pdf_obj *dict); - -/* - * Pattern - */ - -typedef struct pdf_pattern_s pdf_pattern; - -struct pdf_pattern_s -{ - fz_storable storable; - int ismask; - float xstep; - float ystep; - fz_matrix matrix; - fz_rect bbox; - pdf_obj *resources; - fz_buffer *contents; -}; - -pdf_pattern *pdf_load_pattern(pdf_document *doc, pdf_obj *obj); -pdf_pattern *pdf_keep_pattern(fz_context *ctx, pdf_pattern *pat); -void pdf_drop_pattern(fz_context *ctx, pdf_pattern *pat); - -/* - * XObject - */ - -typedef struct pdf_xobject_s pdf_xobject; - -struct pdf_xobject_s -{ - fz_storable storable; - fz_matrix matrix; - fz_rect bbox; - int isolated; - int knockout; - int transparency; - fz_colorspace *colorspace; - pdf_obj *resources; - fz_buffer *contents; - pdf_obj *me; -}; - -pdf_xobject *pdf_load_xobject(pdf_document *doc, pdf_obj *obj); -pdf_xobject *pdf_keep_xobject(fz_context *ctx, pdf_xobject *xobj); -void pdf_drop_xobject(fz_context *ctx, pdf_xobject *xobj); - -/* - * CMap - */ - -typedef struct pdf_cmap_s pdf_cmap; -typedef struct pdf_range_s pdf_range; - -enum { PDF_CMAP_SINGLE, PDF_CMAP_RANGE, PDF_CMAP_TABLE, PDF_CMAP_MULTI }; - -struct pdf_range_s -{ - unsigned short low; - /* Next, we pack 2 fields into the same unsigned short. Top 14 bits - * are the extent, bottom 2 bits are flags: single, range, table, - * multi */ - unsigned short extent_flags; - unsigned short offset; /* range-delta or table-index */ -}; - -struct pdf_cmap_s -{ - fz_storable storable; - char cmap_name[32]; - - char usecmap_name[32]; - pdf_cmap *usecmap; - - int wmode; - - int codespace_len; - struct - { - unsigned short n; - unsigned short low; - unsigned short high; - } codespace[40]; - - int rlen, rcap; - pdf_range *ranges; - - int tlen, tcap; - unsigned short *table; -}; - -pdf_cmap *pdf_new_cmap(fz_context *ctx); -pdf_cmap *pdf_keep_cmap(fz_context *ctx, pdf_cmap *cmap); -void pdf_drop_cmap(fz_context *ctx, pdf_cmap *cmap); -void pdf_free_cmap_imp(fz_context *ctx, fz_storable *cmap); -unsigned int pdf_cmap_size(fz_context *ctx, pdf_cmap *cmap); - -void pdf_debug_cmap(fz_context *ctx, pdf_cmap *cmap); -int pdf_get_wmode(fz_context *ctx, pdf_cmap *cmap); -void pdf_set_wmode(fz_context *ctx, pdf_cmap *cmap, int wmode); -void pdf_set_usecmap(fz_context *ctx, pdf_cmap *cmap, pdf_cmap *usecmap); - -void pdf_add_codespace(fz_context *ctx, pdf_cmap *cmap, int low, int high, int n); -void pdf_map_range_to_table(fz_context *ctx, pdf_cmap *cmap, int low, int *map, int len); -void pdf_map_range_to_range(fz_context *ctx, pdf_cmap *cmap, int srclo, int srchi, int dstlo); -void pdf_map_one_to_many(fz_context *ctx, pdf_cmap *cmap, int one, int *many, int len); -void pdf_sort_cmap(fz_context *ctx, pdf_cmap *cmap); - -int pdf_lookup_cmap(pdf_cmap *cmap, int cpt); -int pdf_lookup_cmap_full(pdf_cmap *cmap, int cpt, int *out); -int pdf_decode_cmap(pdf_cmap *cmap, unsigned char *s, int *cpt); - -pdf_cmap *pdf_new_identity_cmap(fz_context *ctx, int wmode, int bytes); -pdf_cmap *pdf_load_cmap(fz_context *ctx, fz_stream *file); -pdf_cmap *pdf_load_system_cmap(fz_context *ctx, char *name); -pdf_cmap *pdf_load_builtin_cmap(fz_context *ctx, char *name); -pdf_cmap *pdf_load_embedded_cmap(pdf_document *doc, pdf_obj *ref); - -/* - * Font - */ - -enum -{ - PDF_FD_FIXED_PITCH = 1 << 0, - PDF_FD_SERIF = 1 << 1, - PDF_FD_SYMBOLIC = 1 << 2, - PDF_FD_SCRIPT = 1 << 3, - PDF_FD_NONSYMBOLIC = 1 << 5, - PDF_FD_ITALIC = 1 << 6, - PDF_FD_ALL_CAP = 1 << 16, - PDF_FD_SMALL_CAP = 1 << 17, - PDF_FD_FORCE_BOLD = 1 << 18 -}; - -enum { PDF_ROS_CNS, PDF_ROS_GB, PDF_ROS_JAPAN, PDF_ROS_KOREA }; - -void pdf_load_encoding(char **estrings, char *encoding); -int pdf_lookup_agl(char *name); -const char **pdf_lookup_agl_duplicates(int ucs); - -extern const unsigned short pdf_doc_encoding[256]; -extern const char * const pdf_mac_roman[256]; -extern const char * const pdf_mac_expert[256]; -extern const char * const pdf_win_ansi[256]; -extern const char * const pdf_standard[256]; - -typedef struct pdf_font_desc_s pdf_font_desc; -typedef struct pdf_hmtx_s pdf_hmtx; -typedef struct pdf_vmtx_s pdf_vmtx; - -struct pdf_hmtx_s -{ - unsigned short lo; - unsigned short hi; - int w; /* type3 fonts can be big! */ -}; - -struct pdf_vmtx_s -{ - unsigned short lo; - unsigned short hi; - short x; - short y; - short w; -}; - -struct pdf_font_desc_s -{ - fz_storable storable; - unsigned int size; - - fz_font *font; - - /* FontDescriptor */ - int flags; - float italic_angle; - float ascent; - float descent; - float cap_height; - float x_height; - float missing_width; - - /* Encoding (CMap) */ - pdf_cmap *encoding; - pdf_cmap *to_ttf_cmap; - int cid_to_gid_len; - unsigned short *cid_to_gid; - - /* ToUnicode */ - pdf_cmap *to_unicode; - int cid_to_ucs_len; - unsigned short *cid_to_ucs; - - /* Metrics (given in the PDF file) */ - int wmode; - - int hmtx_len, hmtx_cap; - pdf_hmtx dhmtx; - pdf_hmtx *hmtx; - - int vmtx_len, vmtx_cap; - pdf_vmtx dvmtx; - pdf_vmtx *vmtx; - - int is_embedded; -}; - -void pdf_set_font_wmode(fz_context *ctx, pdf_font_desc *font, int wmode); -void pdf_set_default_hmtx(fz_context *ctx, pdf_font_desc *font, int w); -void pdf_set_default_vmtx(fz_context *ctx, pdf_font_desc *font, int y, int w); -void pdf_add_hmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int w); -void pdf_add_vmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int x, int y, int w); -void pdf_end_hmtx(fz_context *ctx, pdf_font_desc *font); -void pdf_end_vmtx(fz_context *ctx, pdf_font_desc *font); -pdf_hmtx pdf_get_hmtx(fz_context *ctx, pdf_font_desc *font, int cid); -pdf_vmtx pdf_get_vmtx(fz_context *ctx, pdf_font_desc *font, int cid); - -void pdf_load_to_unicode(pdf_document *doc, pdf_font_desc *font, char **strings, char *collection, pdf_obj *cmapstm); - -int pdf_font_cid_to_gid(fz_context *ctx, pdf_font_desc *fontdesc, int cid); - -unsigned char *pdf_find_builtin_font(char *name, unsigned int *len); -unsigned char *pdf_find_substitute_font(int mono, int serif, int bold, int italic, unsigned int *len); -unsigned char *pdf_find_substitute_cjk_font(int ros, int serif, unsigned int *len); - -pdf_font_desc *pdf_load_type3_font(pdf_document *doc, pdf_obj *rdb, pdf_obj *obj); -pdf_font_desc *pdf_load_font(pdf_document *doc, pdf_obj *rdb, pdf_obj *obj); - -pdf_font_desc *pdf_new_font_desc(fz_context *ctx); -pdf_font_desc *pdf_keep_font(fz_context *ctx, pdf_font_desc *fontdesc); -void pdf_drop_font(fz_context *ctx, pdf_font_desc *font); - -void pdf_debug_font(fz_context *ctx, pdf_font_desc *fontdesc); - -/* - * Interactive features - */ - -typedef struct pdf_annot_s pdf_annot; - -struct pdf_annot_s -{ - pdf_obj *obj; - fz_rect rect; - pdf_xobject *ap; - fz_matrix matrix; - pdf_annot *next; -}; - -fz_link_dest pdf_parse_link_dest(pdf_document *doc, pdf_obj *dest); -fz_link_dest pdf_parse_action(pdf_document *doc, pdf_obj *action); -pdf_obj *pdf_lookup_dest(pdf_document *doc, pdf_obj *needle); -pdf_obj *pdf_lookup_name(pdf_document *doc, char *which, pdf_obj *needle); -pdf_obj *pdf_load_name_tree(pdf_document *doc, char *which); - -fz_outline *pdf_load_outline(pdf_document *doc); - -fz_link *pdf_load_link_annots(pdf_document *, pdf_obj *annots, fz_matrix page_ctm); - -pdf_annot *pdf_load_annots(pdf_document *, pdf_obj *annots); -void pdf_free_annot(fz_context *ctx, pdf_annot *link); - -/* - * Page tree, pages and related objects - */ - typedef struct pdf_page_s pdf_page; -struct pdf_page_s -{ - fz_matrix ctm; /* calculated from mediabox and rotate */ - fz_rect mediabox; - int rotate; - int transparency; - pdf_obj *resources; - fz_buffer *contents; - fz_link *links; - pdf_annot *annots; -}; - int pdf_find_page_number(pdf_document *doc, pdf_obj *pageobj); int pdf_count_pages(pdf_document *doc); @@ -715,10 +201,6 @@ fz_rect pdf_bound_page(pdf_document *doc, pdf_page *page); void pdf_free_page(pdf_document *doc, pdf_page *page); /* - * Content stream parsing - */ - -/* pdf_run_page: Interpret a loaded page and render it on a device. page: A page loaded by pdf_load_page. @@ -731,14 +213,5 @@ void pdf_free_page(pdf_document *doc, pdf_page *page); void pdf_run_page(pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie); void pdf_run_page_with_usage(pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie); -void pdf_run_glyph(pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate); - -/* - * PDF interface to store - */ - -void pdf_store_item(fz_context *ctx, pdf_obj *key, void *val, unsigned int itemsize); -void *pdf_find_item(fz_context *ctx, fz_store_free_fn *free, pdf_obj *key); -void pdf_remove_item(fz_context *ctx, fz_store_free_fn *free, pdf_obj *key); #endif diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c index 81e5d887..bd0ad808 100644 --- a/pdf/pdf_annot.c +++ b/pdf/pdf_annot.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" static pdf_obj * resolve_dest_rec(pdf_document *xref, pdf_obj *dest, int depth) diff --git a/pdf/pdf_cmap.c b/pdf/pdf_cmap.c index 987da592..712ebfe7 100644 --- a/pdf/pdf_cmap.c +++ b/pdf/pdf_cmap.c @@ -15,8 +15,8 @@ * or can trust the parser to give us optimal mappings. */ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" /* Macros for accessing the combined extent_flags field */ #define pdf_range_high(r) ((r)->low + ((r)->extent_flags >> 2)) diff --git a/pdf/pdf_cmap_load.c b/pdf/pdf_cmap_load.c index d4e161c8..6867d845 100644 --- a/pdf/pdf_cmap_load.c +++ b/pdf/pdf_cmap_load.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" unsigned int pdf_cmap_size(fz_context *ctx, pdf_cmap *cmap) diff --git a/pdf/pdf_cmap_parse.c b/pdf/pdf_cmap_parse.c index 4933dea5..3396e3ae 100644 --- a/pdf/pdf_cmap_parse.c +++ b/pdf/pdf_cmap_parse.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" /* * CMap parser diff --git a/pdf/pdf_cmap_table.c b/pdf/pdf_cmap_table.c index fbe528e0..21dfe5fa 100644 --- a/pdf/pdf_cmap_table.c +++ b/pdf/pdf_cmap_table.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" #ifndef NOCJK #include "../generated/cmap_cns.h" diff --git a/pdf/pdf_colorspace.c b/pdf/pdf_colorspace.c index 05d0c135..5bf84535 100644 --- a/pdf/pdf_colorspace.c +++ b/pdf/pdf_colorspace.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" /* ICCBased */ diff --git a/pdf/pdf_crypt.c b/pdf/pdf_crypt.c index 510acc7b..2927527e 100644 --- a/pdf/pdf_crypt.c +++ b/pdf/pdf_crypt.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" enum { diff --git a/pdf/pdf_encoding.c b/pdf/pdf_encoding.c index 9a42a1c1..eb36ed96 100644 --- a/pdf/pdf_encoding.c +++ b/pdf/pdf_encoding.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" #include "data_encodings.h" #include "data_glyphlist.h" diff --git a/pdf/pdf_font.c b/pdf/pdf_font.c index 5e54e0bb..11c97d37 100644 --- a/pdf/pdf_font.c +++ b/pdf/pdf_font.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" #include <ft2build.h> #include FT_FREETYPE_H diff --git a/pdf/pdf_fontfile.c b/pdf/pdf_fontfile.c index 543ce763..4dbbe91c 100644 --- a/pdf/pdf_fontfile.c +++ b/pdf/pdf_fontfile.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" #ifdef NOCJK #define NOCJKFONT diff --git a/pdf/pdf_function.c b/pdf/pdf_function.c index 681c0157..e1c53beb 100644 --- a/pdf/pdf_function.c +++ b/pdf/pdf_function.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" enum { diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c index 4cdd374a..17996a74 100644 --- a/pdf/pdf_image.c +++ b/pdf/pdf_image.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" typedef struct pdf_image_key_s pdf_image_key; diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c index ca957d09..1c2a11f3 100644 --- a/pdf/pdf_interpret.c +++ b/pdf/pdf_interpret.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" #define TILE diff --git a/pdf/pdf_lex.c b/pdf/pdf_lex.c index 322d945c..6774167a 100644 --- a/pdf/pdf_lex.c +++ b/pdf/pdf_lex.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" #define IS_NUMBER \ '+':case'-':case'.':case'0':case'1':case'2':case'3':\ diff --git a/pdf/pdf_metrics.c b/pdf/pdf_metrics.c index fc888257..ae4405ed 100644 --- a/pdf/pdf_metrics.c +++ b/pdf/pdf_metrics.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" void pdf_set_font_wmode(fz_context *ctx, pdf_font_desc *font, int wmode) diff --git a/pdf/pdf_nametree.c b/pdf/pdf_nametree.c index 98a10241..b24d2c24 100644 --- a/pdf/pdf_nametree.c +++ b/pdf/pdf_nametree.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" static pdf_obj * pdf_lookup_name_imp(fz_context *ctx, pdf_obj *node, pdf_obj *needle) diff --git a/pdf/pdf_outline.c b/pdf/pdf_outline.c index 793b5f77..d4bea75a 100644 --- a/pdf/pdf_outline.c +++ b/pdf/pdf_outline.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" static fz_outline * pdf_load_outline_imp(pdf_document *xref, pdf_obj *dict) diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c index ca38aacf..5b9106d1 100644 --- a/pdf/pdf_page.c +++ b/pdf/pdf_page.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" struct info { diff --git a/pdf/pdf_parse.c b/pdf/pdf_parse.c index 57ba1d6f..fe9db368 100644 --- a/pdf/pdf_parse.c +++ b/pdf/pdf_parse.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" fz_rect pdf_to_rect(fz_context *ctx, pdf_obj *array) @@ -45,7 +45,7 @@ pdf_to_utf8(fz_context *ctx, pdf_obj *src) for (i = 2; i + 1 < srclen; i += 2) { ucs = srcptr[i] << 8 | srcptr[i+1]; - dstlen += runelen(ucs); + dstlen += fz_runelen(ucs); } dstptr = dst = fz_malloc(ctx, dstlen + 1); @@ -53,7 +53,7 @@ pdf_to_utf8(fz_context *ctx, pdf_obj *src) for (i = 2; i + 1 < srclen; i += 2) { ucs = srcptr[i] << 8 | srcptr[i+1]; - dstptr += runetochar(dstptr, &ucs); + dstptr += fz_runetochar(dstptr, ucs); } } else if (srclen >= 2 && srcptr[0] == 255 && srcptr[1] == 254) @@ -61,7 +61,7 @@ pdf_to_utf8(fz_context *ctx, pdf_obj *src) for (i = 2; i + 1 < srclen; i += 2) { ucs = srcptr[i] | srcptr[i+1] << 8; - dstlen += runelen(ucs); + dstlen += fz_runelen(ucs); } dstptr = dst = fz_malloc(ctx, dstlen + 1); @@ -69,20 +69,20 @@ pdf_to_utf8(fz_context *ctx, pdf_obj *src) for (i = 2; i + 1 < srclen; i += 2) { ucs = srcptr[i] | srcptr[i+1] << 8; - dstptr += runetochar(dstptr, &ucs); + dstptr += fz_runetochar(dstptr, ucs); } } else { for (i = 0; i < srclen; i++) - dstlen += runelen(pdf_doc_encoding[srcptr[i]]); + dstlen += fz_runelen(pdf_doc_encoding[srcptr[i]]); dstptr = dst = fz_malloc(ctx, dstlen + 1); for (i = 0; i < srclen; i++) { ucs = pdf_doc_encoding[srcptr[i]]; - dstptr += runetochar(dstptr, &ucs); + dstptr += fz_runetochar(dstptr, ucs); } } diff --git a/pdf/pdf_pattern.c b/pdf/pdf_pattern.c index 00e4b8fb..14175670 100644 --- a/pdf/pdf_pattern.c +++ b/pdf/pdf_pattern.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" pdf_pattern * pdf_keep_pattern(fz_context *ctx, pdf_pattern *pat) diff --git a/pdf/pdf_repair.c b/pdf/pdf_repair.c index f42198eb..fda1e6b5 100644 --- a/pdf/pdf_repair.c +++ b/pdf/pdf_repair.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" /* Scan file for objects and reconstruct xref table */ diff --git a/pdf/pdf_shade.c b/pdf/pdf_shade.c index c3bddcbc..589b7613 100644 --- a/pdf/pdf_shade.c +++ b/pdf/pdf_shade.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" #define HUGENUM 32000 /* how far to extend axial/radial shadings */ #define FUNSEGS 32 /* size of sampled mesh for function-based shadings */ diff --git a/pdf/pdf_store.c b/pdf/pdf_store.c index 38abe10b..ae8eac9a 100644 --- a/pdf/pdf_store.c +++ b/pdf/pdf_store.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" static int pdf_make_hash_key(fz_store_hash *hash, void *key_) diff --git a/pdf/pdf_stream.c b/pdf/pdf_stream.c index 6afb2cdb..84f966ec 100644 --- a/pdf/pdf_stream.c +++ b/pdf/pdf_stream.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" /* * Check if an object is a stream or not. diff --git a/pdf/pdf_type3.c b/pdf/pdf_type3.c index dc931e22..6603fc8b 100644 --- a/pdf/pdf_type3.c +++ b/pdf/pdf_type3.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" static void pdf_run_glyph_func(void *doc, void *rdb_, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate) diff --git a/pdf/pdf_unicode.c b/pdf/pdf_unicode.c index edfda708..c94a6683 100644 --- a/pdf/pdf_unicode.c +++ b/pdf/pdf_unicode.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" /* Load or synthesize ToUnicode map for fonts */ diff --git a/pdf/pdf_xobject.c b/pdf/pdf_xobject.c index 36c5c483..ffa86184 100644 --- a/pdf/pdf_xobject.c +++ b/pdf/pdf_xobject.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" pdf_xobject * pdf_keep_xobject(fz_context *ctx, pdf_xobject *xobj) diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c index f0dbde96..9e60955c 100644 --- a/pdf/pdf_xref.c +++ b/pdf/pdf_xref.c @@ -1,5 +1,5 @@ -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" static inline int iswhite(int ch) { @@ -1074,6 +1074,11 @@ pdf_resolve_indirect(pdf_obj *ref) return ref; } +int pdf_count_objects(pdf_document *doc) +{ + return doc->len; +} + /* Replace numbered object -- for use by pdfclean and similar tools */ void pdf_update_object(pdf_document *xref, int num, int gen, pdf_obj *newobj) diff --git a/scripts/cmapdump.c b/scripts/cmapdump.c index db250382..53247339 100644 --- a/scripts/cmapdump.c +++ b/scripts/cmapdump.c @@ -6,8 +6,8 @@ /* We never want to build memento versions of the cmapdump util */ #undef MEMENTO -#include "fitz.h" -#include "mupdf.h" +#include "fitz-internal.h" +#include "mupdf-internal.h" #include "../fitz/base_context.c" #include "../fitz/base_error.c" @@ -181,6 +181,10 @@ void fz_free_aa_context(fz_context *ctx) { } +void fz_copy_aa_context(fz_context *dst, fz_context *src) +{ +} + void *fz_keep_storable(fz_context *ctx, fz_storable *s) { return s; diff --git a/win32/libmupdf.vcproj b/win32/libmupdf.vcproj index f37349a5..543cac48 100644 --- a/win32/libmupdf.vcproj +++ b/win32/libmupdf.vcproj @@ -222,6 +222,10 @@ > </File> <File + RelativePath="..\pdf\mupdf-internal.h" + > + </File> + <File RelativePath="..\pdf\mupdf.h" > </File> @@ -450,6 +454,10 @@ > </File> <File + RelativePath="..\fitz\fitz-internal.h" + > + </File> + <File RelativePath="..\fitz\fitz.h" > </File> @@ -462,10 +470,18 @@ > </File> <File + RelativePath="..\fitz\image_md5.c" + > + </File> + <File RelativePath="..\fitz\image_png.c" > </File> <File + RelativePath="..\fitz\image_save.c" + > + </File> + <File RelativePath="..\fitz\image_tiff.c" > </File> diff --git a/xps/muxps.h b/xps/muxps.h index c90d92ba..caba3322 100644 --- a/xps/muxps.h +++ b/xps/muxps.h @@ -1,9 +1,7 @@ #ifndef _MUXPS_H_ #define _MUXPS_H_ -#ifndef _FITZ_H_ -#error "fitz.h must be included before muxps.h" -#endif +#include "fitz-internal.h" typedef unsigned char byte; diff --git a/xps/xps_common.c b/xps/xps_common.c index 32ea3fdc..c8464459 100644 --- a/xps/xps_common.c +++ b/xps/xps_common.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" static inline int unhex(int a) diff --git a/xps/xps_doc.c b/xps/xps_doc.c index d8ab7bf4..5515b47a 100644 --- a/xps/xps_doc.c +++ b/xps/xps_doc.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" static void diff --git a/xps/xps_glyphs.c b/xps/xps_glyphs.c index f7098ed1..6cdf420b 100644 --- a/xps/xps_glyphs.c +++ b/xps/xps_glyphs.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" #include <ft2build.h> @@ -307,7 +307,7 @@ xps_parse_glyphs_imp(xps_document *doc, fz_matrix ctm, { if (us && un > 0) { - int t = chartorune(&char_code, us); + int t = fz_chartorune(&char_code, us); us += t; un -= t; } } diff --git a/xps/xps_gradient.c b/xps/xps_gradient.c index f0ad0104..580a9cb6 100644 --- a/xps/xps_gradient.c +++ b/xps/xps_gradient.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" #define MAX_STOPS 256 @@ -61,7 +61,7 @@ xps_parse_gradient_stops(xps_document *doc, char *base_uri, xml_element *node, xps_parse_color(doc, base_uri, color, &colorspace, sample); - fz_convert_color(doc->ctx, colorspace, sample + 1, fz_device_rgb, rgb); + fz_convert_color(doc->ctx, fz_device_rgb, rgb, colorspace, sample + 1); stops[count].r = rgb[0]; stops[count].g = rgb[1]; diff --git a/xps/xps_image.c b/xps/xps_image.c index a2021223..665b6d11 100644 --- a/xps/xps_image.c +++ b/xps/xps_image.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" typedef struct xps_image_s xps_image; diff --git a/xps/xps_outline.c b/xps/xps_outline.c index 30357491..577cdb6b 100644 --- a/xps/xps_outline.c +++ b/xps/xps_outline.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" /* diff --git a/xps/xps_path.c b/xps/xps_path.c index 76b9bb21..b3dda187 100644 --- a/xps/xps_path.c +++ b/xps/xps_path.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" char * diff --git a/xps/xps_resource.c b/xps/xps_resource.c index dcf3717d..c65893a1 100644 --- a/xps/xps_resource.c +++ b/xps/xps_resource.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" static xml_element * diff --git a/xps/xps_tile.c b/xps/xps_tile.c index e87d76f7..93783ee1 100644 --- a/xps/xps_tile.c +++ b/xps/xps_tile.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" #define TILE diff --git a/xps/xps_util.c b/xps/xps_util.c index b79927ba..aed6c19f 100644 --- a/xps/xps_util.c +++ b/xps/xps_util.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" static inline int xps_tolower(int c) diff --git a/xps/xps_xml.c b/xps/xps_xml.c index 15c510a6..aee1568e 100644 --- a/xps/xps_xml.c +++ b/xps/xps_xml.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" struct attribute @@ -185,7 +185,7 @@ static void xml_emit_att_value(struct parser *parser, char *a, char *b) while (a < b) { if (*a == '&') { a += xml_parse_entity(&c, a); - s += runetochar(s, &c); + s += fz_runetochar(s, c); } else { *s++ = *a++; @@ -340,7 +340,7 @@ static char *convert_to_utf8(fz_context *doc, unsigned char *s, int n) dst = d = fz_malloc(doc, n * 2); while (s + 1 < e) { c = s[0] << 8 | s[1]; - d += runetochar(d, &c); + d += fz_runetochar(d, c); s += 2; } *d = 0; @@ -351,7 +351,7 @@ static char *convert_to_utf8(fz_context *doc, unsigned char *s, int n) dst = d = fz_malloc(doc, n * 2); while (s + 1 < e) { c = s[0] | s[1] << 8; - d += runetochar(d, &c); + d += fz_runetochar(d, c); s += 2; } *d = 0; diff --git a/xps/xps_zip.c b/xps/xps_zip.c index 08d9832a..a2182d5c 100644 --- a/xps/xps_zip.c +++ b/xps/xps_zip.c @@ -1,4 +1,4 @@ -#include "fitz.h" +#include "fitz-internal.h" #include "muxps.h" #include <zlib.h> |