Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4679 → Rev 4680

/contrib/media/updf/fitz/base_error.c
0,0 → 1,159
#include "fitz.h"
 
enum { LINE_LEN = 160, LINE_COUNT = 25 };
 
static char warn_message[LINE_LEN] = "";
static int warn_count = 0;
 
void fz_flush_warnings(void)
{
if (warn_count > 1)
fprintf(stderr, "warning: ... repeated %d times ...\n", warn_count);
warn_message[0] = 0;
warn_count = 0;
}
 
void fz_warn(char *fmt, ...)
{
va_list ap;
char buf[LINE_LEN];
 
va_start(ap, fmt);
vsnprintf(buf, sizeof buf, fmt, ap);
va_end(ap);
 
if (!strcmp(buf, warn_message))
{
warn_count++;
}
else
{
fz_flush_warnings();
fprintf(stderr, "warning: %s\n", buf);
fz_strlcpy(warn_message, buf, sizeof warn_message);
warn_count = 1;
}
}
 
static char error_message[LINE_COUNT][LINE_LEN];
static int error_count = 0;
 
static void
fz_emit_error(char what, char *location, char *message)
{
fz_flush_warnings();
 
fprintf(stderr, "%c %s%s\n", what, location, message);
 
if (error_count < LINE_COUNT)
{
fz_strlcpy(error_message[error_count], location, LINE_LEN);
fz_strlcat(error_message[error_count], message, LINE_LEN);
error_count++;
}
}
 
int
fz_get_error_count(void)
{
return error_count;
}
 
char *
fz_get_error_line(int n)
{
return error_message[n];
}
 
fz_error
fz_throw_imp(const char *file, int line, const char *func, char *fmt, ...)
{
va_list ap;
char one[LINE_LEN], two[LINE_LEN];
 
error_count = 0;
 
snprintf(one, sizeof one, "%s:%d: %s(): ", file, line, func);
va_start(ap, fmt);
vsnprintf(two, sizeof two, fmt, ap);
va_end(ap);
 
fz_emit_error('+', one, two);
 
return -1;
}
 
fz_error
fz_rethrow_imp(const char *file, int line, const char *func, fz_error cause, char *fmt, ...)
{
va_list ap;
char one[LINE_LEN], two[LINE_LEN];
 
snprintf(one, sizeof one, "%s:%d: %s(): ", file, line, func);
va_start(ap, fmt);
vsnprintf(two, sizeof two, fmt, ap);
va_end(ap);
 
fz_emit_error('|', one, two);
 
return cause;
}
 
void
fz_catch_imp(const char *file, int line, const char *func, fz_error cause, char *fmt, ...)
{
va_list ap;
char one[LINE_LEN], two[LINE_LEN];
 
snprintf(one, sizeof one, "%s:%d: %s(): ", file, line, func);
va_start(ap, fmt);
vsnprintf(two, sizeof two, fmt, ap);
va_end(ap);
 
fz_emit_error('\\', one, two);
}
 
fz_error
fz_throw_impx(char *fmt, ...)
{
va_list ap;
char buf[LINE_LEN];
 
error_count = 0;
 
va_start(ap, fmt);
vsnprintf(buf, sizeof buf, fmt, ap);
va_end(ap);
 
fz_emit_error('+', "", buf);
 
return -1;
}
 
fz_error
fz_rethrow_impx(fz_error cause, char *fmt, ...)
{
va_list ap;
char buf[LINE_LEN];
 
va_start(ap, fmt);
vsnprintf(buf, sizeof buf, fmt, ap);
va_end(ap);
 
fz_emit_error('|', "", buf);
 
return cause;
}
 
void
fz_catch_impx(fz_error cause, char *fmt, ...)
{
va_list ap;
char buf[LINE_LEN];
 
va_start(ap, fmt);
vsnprintf(buf, sizeof buf, fmt, ap);
va_end(ap);
 
fz_emit_error('\\', "", buf);
}
/contrib/media/updf/fitz/base_geometry.c
0,0 → 1,268
#include "fitz.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))
 
/* Matrices, points and affine transformations */
 
const fz_matrix fz_identity = { 1, 0, 0, 1, 0, 0 };
 
fz_matrix
fz_concat(fz_matrix one, fz_matrix two)
{
fz_matrix dst;
dst.a = one.a * two.a + one.b * two.c;
dst.b = one.a * two.b + one.b * two.d;
dst.c = one.c * two.a + one.d * two.c;
dst.d = one.c * two.b + one.d * two.d;
dst.e = one.e * two.a + one.f * two.c + two.e;
dst.f = one.e * two.b + one.f * two.d + two.f;
return dst;
}
 
fz_matrix
fz_scale(float sx, float sy)
{
fz_matrix m;
m.a = sx; m.b = 0;
m.c = 0; m.d = sy;
m.e = 0; m.f = 0;
return m;
}
 
fz_matrix
fz_shear(float h, float v)
{
fz_matrix m;
m.a = 1; m.b = v;
m.c = h; m.d = 1;
m.e = 0; m.f = 0;
return m;
}
 
fz_matrix
fz_rotate(float theta)
{
fz_matrix m;
float s;
float c;
 
while (theta < 0)
theta += 360;
while (theta >= 360)
theta -= 360;
 
if (fabsf(0 - theta) < FLT_EPSILON)
{
s = 0;
c = 1;
}
else if (fabsf(90.0f - theta) < FLT_EPSILON)
{
s = 1;
c = 0;
}
else if (fabsf(180.0f - theta) < FLT_EPSILON)
{
s = 0;
c = -1;
}
else if (fabsf(270.0f - theta) < FLT_EPSILON)
{
s = -1;
c = 0;
}
else
{
s = sinf(theta * (float)M_PI / 180);
c = cosf(theta * (float)M_PI / 180);
}
 
m.a = c; m.b = s;
m.c = -s; m.d = c;
m.e = 0; m.f = 0;
return m;
}
 
fz_matrix
fz_translate(float tx, float ty)
{
fz_matrix m;
m.a = 1; m.b = 0;
m.c = 0; m.d = 1;
m.e = tx; m.f = ty;
return m;
}
 
fz_matrix
fz_invert_matrix(fz_matrix src)
{
fz_matrix dst;
float rdet = 1 / (src.a * src.d - src.b * src.c);
dst.a = src.d * rdet;
dst.b = -src.b * rdet;
dst.c = -src.c * rdet;
dst.d = src.a * rdet;
dst.e = -src.e * dst.a - src.f * dst.c;
dst.f = -src.e * dst.b - src.f * dst.d;
return dst;
}
 
int
fz_is_rectilinear(fz_matrix m)
{
return (fabsf(m.b) < FLT_EPSILON && fabsf(m.c) < FLT_EPSILON) ||
(fabsf(m.a) < FLT_EPSILON && fabsf(m.d) < FLT_EPSILON);
}
 
float
fz_matrix_expansion(fz_matrix m)
{
return sqrtf(fabsf(m.a * m.d - m.b * m.c));
}
 
fz_point
fz_transform_point(fz_matrix m, fz_point p)
{
fz_point t;
t.x = p.x * m.a + p.y * m.c + m.e;
t.y = p.x * m.b + p.y * m.d + m.f;
return t;
}
 
fz_point
fz_transform_vector(fz_matrix m, fz_point p)
{
fz_point t;
t.x = p.x * m.a + p.y * m.c;
t.y = p.x * m.b + p.y * m.d;
return t;
}
 
/* Rectangles and bounding boxes */
 
const fz_rect fz_infinite_rect = { 1, 1, -1, -1 };
const fz_rect fz_empty_rect = { 0, 0, 0, 0 };
const fz_rect fz_unit_rect = { 0, 0, 1, 1 };
 
const fz_bbox fz_infinite_bbox = { 1, 1, -1, -1 };
const fz_bbox fz_empty_bbox = { 0, 0, 0, 0 };
const fz_bbox fz_unit_bbox = { 0, 0, 1, 1 };
 
fz_bbox
fz_round_rect(fz_rect f)
{
fz_bbox i;
i.x0 = floorf(f.x0 + 0.001f); /* adjust by 0.001 to compensate for precision errors */
i.y0 = floorf(f.y0 + 0.001f);
i.x1 = ceilf(f.x1 - 0.001f);
i.y1 = ceilf(f.y1 - 0.001f);
return i;
}
 
fz_rect
fz_intersect_rect(fz_rect a, fz_rect b)
{
fz_rect r;
if (fz_is_infinite_rect(a)) return b;
if (fz_is_infinite_rect(b)) return a;
if (fz_is_empty_rect(a)) return fz_empty_rect;
if (fz_is_empty_rect(b)) return fz_empty_rect;
r.x0 = MAX(a.x0, b.x0);
r.y0 = MAX(a.y0, b.y0);
r.x1 = MIN(a.x1, b.x1);
r.y1 = MIN(a.y1, b.y1);
return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_rect : r;
}
 
fz_rect
fz_union_rect(fz_rect a, fz_rect b)
{
fz_rect r;
if (fz_is_infinite_rect(a)) return a;
if (fz_is_infinite_rect(b)) return b;
if (fz_is_empty_rect(a)) return b;
if (fz_is_empty_rect(b)) return a;
r.x0 = MIN(a.x0, b.x0);
r.y0 = MIN(a.y0, b.y0);
r.x1 = MAX(a.x1, b.x1);
r.y1 = MAX(a.y1, b.y1);
return r;
}
 
fz_bbox
fz_intersect_bbox(fz_bbox a, fz_bbox b)
{
fz_bbox r;
if (fz_is_infinite_rect(a)) return b;
if (fz_is_infinite_rect(b)) return a;
if (fz_is_empty_rect(a)) return fz_empty_bbox;
if (fz_is_empty_rect(b)) return fz_empty_bbox;
r.x0 = MAX(a.x0, b.x0);
r.y0 = MAX(a.y0, b.y0);
r.x1 = MIN(a.x1, b.x1);
r.y1 = MIN(a.y1, b.y1);
return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_bbox : r;
}
 
fz_bbox
fz_union_bbox(fz_bbox a, fz_bbox b)
{
fz_bbox r;
if (fz_is_infinite_rect(a)) return a;
if (fz_is_infinite_rect(b)) return b;
if (fz_is_empty_rect(a)) return b;
if (fz_is_empty_rect(b)) return a;
r.x0 = MIN(a.x0, b.x0);
r.y0 = MIN(a.y0, b.y0);
r.x1 = MAX(a.x1, b.x1);
r.y1 = MAX(a.y1, b.y1);
return r;
}
 
fz_rect
fz_transform_rect(fz_matrix m, fz_rect r)
{
fz_point s, t, u, v;
 
if (fz_is_infinite_rect(r))
return r;
 
s.x = r.x0; s.y = r.y0;
t.x = r.x0; t.y = r.y1;
u.x = r.x1; u.y = r.y1;
v.x = r.x1; v.y = r.y0;
s = fz_transform_point(m, s);
t = fz_transform_point(m, t);
u = fz_transform_point(m, u);
v = fz_transform_point(m, v);
r.x0 = MIN4(s.x, t.x, u.x, v.x);
r.y0 = MIN4(s.y, t.y, u.y, v.y);
r.x1 = MAX4(s.x, t.x, u.x, v.x);
r.y1 = MAX4(s.y, t.y, u.y, v.y);
return r;
}
 
fz_bbox
fz_transform_bbox(fz_matrix m, fz_bbox b)
{
fz_point s, t, u, v;
 
if (fz_is_infinite_bbox(b))
return b;
 
s.x = b.x0; s.y = b.y0;
t.x = b.x0; t.y = b.y1;
u.x = b.x1; u.y = b.y1;
v.x = b.x1; v.y = b.y0;
s = fz_transform_point(m, s);
t = fz_transform_point(m, t);
u = fz_transform_point(m, u);
v = fz_transform_point(m, v);
b.x0 = MIN4(s.x, t.x, u.x, v.x);
b.y0 = MIN4(s.y, t.y, u.y, v.y);
b.x1 = MAX4(s.x, t.x, u.x, v.x);
b.y1 = MAX4(s.y, t.y, u.y, v.y);
return b;
 
}
/contrib/media/updf/fitz/base_getopt.c
0,0 → 1,66
/*
* This is a version of the public domain getopt implementation by
* Henry Spencer originally posted to net.sources.
*
* This file is in the public domain.
*/
 
#include <stdio.h>
#include <string.h>
 
#define getopt fz_getopt
#define optarg fz_optarg
#define optind fz_optind
 
char *optarg; /* Global argument pointer. */
int optind = 0; /* Global argv index. */
 
static char *scan = NULL; /* Private scan pointer. */
 
int
getopt(int argc, char *argv[], char *optstring)
{
char c;
char *place;
 
optarg = NULL;
 
if (scan == NULL || *scan == '\0') {
if (optind == 0)
optind++;
 
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
return EOF;
if (argv[optind][1] == '-' && argv[optind][2] == '\0') {
optind++;
return EOF;
}
 
scan = argv[optind]+1;
optind++;
}
 
c = *scan++;
place = strchr(optstring, c);
 
if (place == NULL || c == ':') {
fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
return '?';
}
 
place++;
if (*place == ':') {
if (*scan != '\0') {
optarg = scan;
scan = NULL;
} else if( optind < argc ) {
optarg = argv[optind];
optind++;
} else {
fprintf(stderr, "%s: option requires argument -%c\n", argv[0], c);
return ':';
}
}
 
return c;
}
/contrib/media/updf/fitz/base_hash.c
0,0 → 1,241
#include "fitz.h"
 
/*
Simple hashtable with open adressing linear probe.
Unlike text book examples, removing entries works
correctly in this implementation, so it wont start
exhibiting bad behaviour if entries are inserted
and removed frequently.
*/
 
enum { MAX_KEY_LEN = 48 };
typedef struct fz_hash_entry_s fz_hash_entry;
 
struct fz_hash_entry_s
{
unsigned char key[MAX_KEY_LEN];
void *val;
};
 
struct fz_hash_table_s
{
int keylen;
int size;
int load;
fz_hash_entry *ents;
};
 
static unsigned hash(unsigned char *s, int len)
{
unsigned val = 0;
int i;
for (i = 0; i < len; i++)
{
val += s[i];
val += (val << 10);
val ^= (val >> 6);
}
val += (val << 3);
val ^= (val >> 11);
val += (val << 15);
return val;
}
 
fz_hash_table *
fz_new_hash_table(int initialsize, int keylen)
{
fz_hash_table *table;
 
assert(keylen <= MAX_KEY_LEN);
 
table = fz_malloc(sizeof(fz_hash_table));
table->keylen = keylen;
table->size = initialsize;
table->load = 0;
table->ents = fz_calloc(table->size, sizeof(fz_hash_entry));
memset(table->ents, 0, sizeof(fz_hash_entry) * table->size);
 
return table;
}
 
void
fz_empty_hash(fz_hash_table *table)
{
table->load = 0;
memset(table->ents, 0, sizeof(fz_hash_entry) * table->size);
}
 
int
fz_hash_len(fz_hash_table *table)
{
return table->size;
}
 
void *
fz_hash_get_key(fz_hash_table *table, int idx)
{
return table->ents[idx].key;
}
 
void *
fz_hash_get_val(fz_hash_table *table, int idx)
{
return table->ents[idx].val;
}
 
void
fz_free_hash(fz_hash_table *table)
{
fz_free(table->ents);
fz_free(table);
}
 
static void
fz_resize_hash(fz_hash_table *table, int newsize)
{
fz_hash_entry *oldents = table->ents;
int oldsize = table->size;
int oldload = table->load;
int i;
 
if (newsize < oldload * 8 / 10)
{
fz_throw("assert: resize hash too small");
return;
}
 
table->ents = fz_calloc(newsize, sizeof(fz_hash_entry));
memset(table->ents, 0, sizeof(fz_hash_entry) * newsize);
table->size = newsize;
table->load = 0;
 
for (i = 0; i < oldsize; i++)
{
if (oldents[i].val)
{
fz_hash_insert(table, oldents[i].key, oldents[i].val);
}
}
 
fz_free(oldents);
}
 
void *
fz_hash_find(fz_hash_table *table, void *key)
{
fz_hash_entry *ents = table->ents;
unsigned size = table->size;
unsigned pos = hash(key, table->keylen) % size;
 
while (1)
{
if (!ents[pos].val)
return NULL;
 
if (memcmp(key, ents[pos].key, table->keylen) == 0)
return ents[pos].val;
 
pos = (pos + 1) % size;
}
}
 
void
fz_hash_insert(fz_hash_table *table, void *key, void *val)
{
fz_hash_entry *ents;
unsigned size;
unsigned pos;
 
if (table->load > table->size * 8 / 10)
{
fz_resize_hash(table, table->size * 2);
}
 
ents = table->ents;
size = table->size;
pos = hash(key, table->keylen) % size;
 
while (1)
{
if (!ents[pos].val)
{
memcpy(ents[pos].key, key, table->keylen);
ents[pos].val = val;
table->load ++;
return;
}
 
if (memcmp(key, ents[pos].key, table->keylen) == 0)
fz_warn("assert: overwrite hash slot");
 
pos = (pos + 1) % size;
}
}
 
void
fz_hash_remove(fz_hash_table *table, void *key)
{
fz_hash_entry *ents = table->ents;
unsigned size = table->size;
unsigned pos = hash(key, table->keylen) % size;
unsigned hole, look, code;
 
while (1)
{
if (!ents[pos].val)
{
fz_warn("assert: remove inexistant hash entry");
return;
}
 
if (memcmp(key, ents[pos].key, table->keylen) == 0)
{
ents[pos].val = NULL;
 
hole = pos;
look = (hole + 1) % size;
 
while (ents[look].val)
{
code = hash(ents[look].key, table->keylen) % size;
if ((code <= hole && hole < look) ||
(look < code && code <= hole) ||
(hole < look && look < code))
{
ents[hole] = ents[look];
ents[look].val = NULL;
hole = look;
}
 
look = (look + 1) % size;
}
 
table->load --;
 
return;
}
 
pos = (pos + 1) % size;
}
}
 
void
fz_debug_hash(fz_hash_table *table)
{
int i, k;
 
printf("cache load %d / %d\n", table->load, table->size);
 
for (i = 0; i < table->size; i++)
{
if (!table->ents[i].val)
printf("table % 4d: empty\n", i);
else
{
printf("table % 4d: key=", i);
for (k = 0; k < MAX_KEY_LEN; k++)
printf("%02x", ((char*)table->ents[i].key)[k]);
printf(" val=$%p\n", table->ents[i].val);
}
}
}
/contrib/media/updf/fitz/base_memory.c
0,0 → 1,77
#include "fitz.h"
 
void *
fz_malloc(int size)
{
void *p = malloc(size);
if (!p)
{
fprintf(stderr, "fatal error: out of memory\n");
abort();
}
return p;
}
 
void *
fz_calloc(int count, int size)
{
void *p;
 
if (count == 0 || size == 0)
return 0;
 
if (count < 0 || size < 0 || count > INT_MAX / size)
{
fprintf(stderr, "fatal error: out of memory (integer overflow)\n");
abort();
}
 
p = malloc(count * size);
if (!p)
{
fprintf(stderr, "fatal error: out of memory\n");
abort();
}
return p;
}
 
void *
fz_realloc(void *p, int count, int size)
{
void *np;
 
if (count == 0 || size == 0)
{
fz_free(p);
return 0;
}
 
if (count < 0 || size < 0 || count > INT_MAX / size)
{
fprintf(stderr, "fatal error: out of memory (integer overflow)\n");
abort();
}
 
np = realloc(p, count * size);
if (np == NULL)
{
fprintf(stderr, "fatal error: out of memory\n");
abort();
}
return np;
}
 
void
fz_free(void *p)
{
free(p);
}
 
char *
fz_strdup(char *s)
{
int len = strlen(s) + 1;
char *ns = fz_malloc(len);
memcpy(ns, s, len);
return ns;
}
/contrib/media/updf/fitz/base_object.c
0,0 → 1,802
#include "fitz.h"
 
typedef enum fz_objkind_e
{
FZ_NULL,
FZ_BOOL,
FZ_INT,
FZ_REAL,
FZ_STRING,
FZ_NAME,
FZ_ARRAY,
FZ_DICT,
FZ_INDIRECT
} fz_objkind;
 
struct keyval
{
fz_obj *k;
fz_obj *v;
};
 
struct fz_obj_s
{
int refs;
fz_objkind kind;
union
{
int b;
int i;
float f;
struct {
unsigned short len;
char buf[1];
} s;
char n[1];
struct {
int len;
int cap;
fz_obj **items;
} a;
struct {
char sorted;
int len;
int cap;
struct keyval *items;
} d;
struct {
int num;
int gen;
struct pdf_xref_s *xref;
} r;
} u;
};
 
static fz_obj *fz_resolve_indirect_null(fz_obj *ref)
{
return ref;
}
 
fz_obj* (*fz_resolve_indirect)(fz_obj*) = fz_resolve_indirect_null;
 
fz_obj *
fz_new_null(void)
{
fz_obj *obj = fz_malloc(sizeof(fz_obj));
obj->refs = 1;
obj->kind = FZ_NULL;
return obj;
}
 
fz_obj *
fz_new_bool(int b)
{
fz_obj *obj = fz_malloc(sizeof(fz_obj));
obj->refs = 1;
obj->kind = FZ_BOOL;
obj->u.b = b;
return obj;
}
 
fz_obj *
fz_new_int(int i)
{
fz_obj *obj = fz_malloc(sizeof(fz_obj));
obj->refs = 1;
obj->kind = FZ_INT;
obj->u.i = i;
return obj;
}
 
fz_obj *
fz_new_real(float f)
{
fz_obj *obj = fz_malloc(sizeof(fz_obj));
obj->refs = 1;
obj->kind = FZ_REAL;
obj->u.f = f;
return obj;
}
 
fz_obj *
fz_new_string(char *str, int len)
{
fz_obj *obj = fz_malloc(offsetof(fz_obj, u.s.buf) + len + 1);
obj->refs = 1;
obj->kind = FZ_STRING;
obj->u.s.len = len;
memcpy(obj->u.s.buf, str, len);
obj->u.s.buf[len] = '\0';
return obj;
}
 
fz_obj *
fz_new_name(char *str)
{
fz_obj *obj = fz_malloc(offsetof(fz_obj, u.n) + strlen(str) + 1);
obj->refs = 1;
obj->kind = FZ_NAME;
strcpy(obj->u.n, str);
return obj;
}
 
fz_obj *
fz_new_indirect(int num, int gen, void *xref)
{
fz_obj *obj = fz_malloc(sizeof(fz_obj));
obj->refs = 1;
obj->kind = FZ_INDIRECT;
obj->u.r.num = num;
obj->u.r.gen = gen;
obj->u.r.xref = xref;
return obj;
}
 
fz_obj *
fz_keep_obj(fz_obj *obj)
{
assert(obj != NULL);
obj->refs ++;
return obj;
}
 
int fz_is_indirect(fz_obj *obj)
{
return obj ? obj->kind == FZ_INDIRECT : 0;
}
 
int fz_is_null(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
return obj ? obj->kind == FZ_NULL : 0;
}
 
int fz_is_bool(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
return obj ? obj->kind == FZ_BOOL : 0;
}
 
int fz_is_int(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
return obj ? obj->kind == FZ_INT : 0;
}
 
int fz_is_real(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
return obj ? obj->kind == FZ_REAL : 0;
}
 
int fz_is_string(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
return obj ? obj->kind == FZ_STRING : 0;
}
 
int fz_is_name(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
return obj ? obj->kind == FZ_NAME : 0;
}
 
int fz_is_array(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
return obj ? obj->kind == FZ_ARRAY : 0;
}
 
int fz_is_dict(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
return obj ? obj->kind == FZ_DICT : 0;
}
 
int fz_to_bool(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
if (fz_is_bool(obj))
return obj->u.b;
return 0;
}
 
int fz_to_int(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
if (fz_is_int(obj))
return obj->u.i;
if (fz_is_real(obj))
return obj->u.f;
return 0;
}
 
float fz_to_real(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
if (fz_is_real(obj))
return obj->u.f;
if (fz_is_int(obj))
return obj->u.i;
return 0;
}
 
char *fz_to_name(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
if (fz_is_name(obj))
return obj->u.n;
return "";
}
 
char *fz_to_str_buf(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
if (fz_is_string(obj))
return obj->u.s.buf;
return "";
}
 
int fz_to_str_len(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
if (fz_is_string(obj))
return obj->u.s.len;
return 0;
}
 
/* for use by pdf_crypt_obj_imp to decrypt AES string in place */
void fz_set_str_len(fz_obj *obj, int newlen)
{
obj = fz_resolve_indirect(obj);
if (fz_is_string(obj))
if (newlen < obj->u.s.len)
obj->u.s.len = newlen;
}
 
int fz_to_num(fz_obj *obj)
{
if (fz_is_indirect(obj))
return obj->u.r.num;
return 0;
}
 
int fz_to_gen(fz_obj *obj)
{
if (fz_is_indirect(obj))
return obj->u.r.gen;
return 0;
}
 
void *fz_get_indirect_xref(fz_obj *obj)
{
if (fz_is_indirect(obj))
return obj->u.r.xref;
return NULL;
}
 
int
fz_objcmp(fz_obj *a, fz_obj *b)
{
int i;
 
if (a == b)
return 0;
 
if (!a || !b)
return 1;
 
if (a->kind != b->kind)
return 1;
 
switch (a->kind)
{
case FZ_NULL:
return 0;
 
case FZ_BOOL:
return a->u.b - b->u.b;
 
case FZ_INT:
return a->u.i - b->u.i;
 
case FZ_REAL:
if (a->u.f < b->u.f)
return -1;
if (a->u.f > b->u.f)
return 1;
return 0;
 
case FZ_STRING:
if (a->u.s.len < b->u.s.len)
{
if (memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len) <= 0)
return -1;
return 1;
}
if (a->u.s.len > b->u.s.len)
{
if (memcmp(a->u.s.buf, b->u.s.buf, b->u.s.len) >= 0)
return 1;
return -1;
}
return memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len);
 
case FZ_NAME:
return strcmp(a->u.n, b->u.n);
 
case FZ_INDIRECT:
if (a->u.r.num == b->u.r.num)
return a->u.r.gen - b->u.r.gen;
return a->u.r.num - b->u.r.num;
 
case FZ_ARRAY:
if (a->u.a.len != b->u.a.len)
return a->u.a.len - b->u.a.len;
for (i = 0; i < a->u.a.len; i++)
if (fz_objcmp(a->u.a.items[i], b->u.a.items[i]))
return 1;
return 0;
 
case FZ_DICT:
if (a->u.d.len != b->u.d.len)
return a->u.d.len - b->u.d.len;
for (i = 0; i < a->u.d.len; i++)
{
if (fz_objcmp(a->u.d.items[i].k, b->u.d.items[i].k))
return 1;
if (fz_objcmp(a->u.d.items[i].v, b->u.d.items[i].v))
return 1;
}
return 0;
 
}
return 1;
}
 
static char *
fz_objkindstr(fz_obj *obj)
{
if (obj == NULL)
return "<NULL>";
switch (obj->kind)
{
case FZ_NULL: return "null";
case FZ_BOOL: return "boolean";
case FZ_INT: return "integer";
case FZ_REAL: return "real";
case FZ_STRING: return "string";
case FZ_NAME: return "name";
case FZ_ARRAY: return "array";
case FZ_DICT: return "dictionary";
case FZ_INDIRECT: return "reference";
}
return "<unknown>";
}
 
fz_obj *
fz_new_array(int initialcap)
{
fz_obj *obj;
int i;
 
obj = fz_malloc(sizeof(fz_obj));
obj->refs = 1;
obj->kind = FZ_ARRAY;
 
obj->u.a.len = 0;
obj->u.a.cap = initialcap > 1 ? initialcap : 6;
 
obj->u.a.items = fz_calloc(obj->u.a.cap, sizeof(fz_obj*));
for (i = 0; i < obj->u.a.cap; i++)
obj->u.a.items[i] = NULL;
 
return obj;
}
 
fz_obj *
fz_copy_array(fz_obj *obj)
{
fz_obj *new;
int i;
 
if (fz_is_indirect(obj) || !fz_is_array(obj))
fz_warn("assert: not an array (%s)", fz_objkindstr(obj));
 
new = fz_new_array(fz_array_len(obj));
for (i = 0; i < fz_array_len(obj); i++)
fz_array_push(new, fz_array_get(obj, i));
 
return new;
}
 
int
fz_array_len(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
if (!fz_is_array(obj))
return 0;
return obj->u.a.len;
}
 
fz_obj *
fz_array_get(fz_obj *obj, int i)
{
obj = fz_resolve_indirect(obj);
 
if (!fz_is_array(obj))
return NULL;
 
if (i < 0 || i >= obj->u.a.len)
return NULL;
 
return obj->u.a.items[i];
}
 
void
fz_array_put(fz_obj *obj, int i, fz_obj *item)
{
obj = fz_resolve_indirect(obj);
 
if (!fz_is_array(obj))
fz_warn("assert: not an array (%s)", fz_objkindstr(obj));
else if (i < 0)
fz_warn("assert: index %d < 0", i);
else if (i >= obj->u.a.len)
fz_warn("assert: index %d > length %d", i, obj->u.a.len);
else
{
if (obj->u.a.items[i])
fz_drop_obj(obj->u.a.items[i]);
obj->u.a.items[i] = fz_keep_obj(item);
}
}
 
void
fz_array_push(fz_obj *obj, fz_obj *item)
{
obj = fz_resolve_indirect(obj);
 
if (!fz_is_array(obj))
fz_warn("assert: not an array (%s)", fz_objkindstr(obj));
else
{
if (obj->u.a.len + 1 > obj->u.a.cap)
{
int i;
obj->u.a.cap = (obj->u.a.cap * 3) / 2;
obj->u.a.items = fz_realloc(obj->u.a.items, obj->u.a.cap, sizeof(fz_obj*));
for (i = obj->u.a.len ; i < obj->u.a.cap; i++)
obj->u.a.items[i] = NULL;
}
obj->u.a.items[obj->u.a.len] = fz_keep_obj(item);
obj->u.a.len++;
}
}
 
void
fz_array_insert(fz_obj *obj, fz_obj *item)
{
obj = fz_resolve_indirect(obj);
 
if (!fz_is_array(obj))
fz_warn("assert: not an array (%s)", fz_objkindstr(obj));
else
{
if (obj->u.a.len + 1 > obj->u.a.cap)
{
int i;
obj->u.a.cap = (obj->u.a.cap * 3) / 2;
obj->u.a.items = fz_realloc(obj->u.a.items, obj->u.a.cap, sizeof(fz_obj*));
for (i = obj->u.a.len ; i < obj->u.a.cap; i++)
obj->u.a.items[i] = NULL;
}
memmove(obj->u.a.items + 1, obj->u.a.items, obj->u.a.len * sizeof(fz_obj*));
obj->u.a.items[0] = fz_keep_obj(item);
obj->u.a.len++;
}
}
 
/* dicts may only have names as keys! */
 
static int keyvalcmp(const void *ap, const void *bp)
{
const struct keyval *a = ap;
const struct keyval *b = bp;
return strcmp(fz_to_name(a->k), fz_to_name(b->k));
}
 
fz_obj *
fz_new_dict(int initialcap)
{
fz_obj *obj;
int i;
 
obj = fz_malloc(sizeof(fz_obj));
obj->refs = 1;
obj->kind = FZ_DICT;
 
obj->u.d.sorted = 1;
obj->u.d.len = 0;
obj->u.d.cap = initialcap > 1 ? initialcap : 10;
 
obj->u.d.items = fz_calloc(obj->u.d.cap, sizeof(struct keyval));
for (i = 0; i < obj->u.d.cap; i++)
{
obj->u.d.items[i].k = NULL;
obj->u.d.items[i].v = NULL;
}
 
return obj;
}
 
fz_obj *
fz_copy_dict(fz_obj *obj)
{
fz_obj *new;
int i;
 
if (fz_is_indirect(obj) || !fz_is_dict(obj))
fz_throw("assert: not a dict (%s)", fz_objkindstr(obj));
 
new = fz_new_dict(fz_dict_len(obj));
for (i = 0; i < fz_dict_len(obj); i++)
fz_dict_put(new, fz_dict_get_key(obj, i), fz_dict_get_val(obj, i));
 
return new;
}
 
int
fz_dict_len(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
if (!fz_is_dict(obj))
return 0;
return obj->u.d.len;
}
 
fz_obj *
fz_dict_get_key(fz_obj *obj, int i)
{
obj = fz_resolve_indirect(obj);
 
if (!fz_is_dict(obj))
return NULL;
 
if (i < 0 || i >= obj->u.d.len)
return NULL;
 
return obj->u.d.items[i].k;
}
 
fz_obj *
fz_dict_get_val(fz_obj *obj, int i)
{
obj = fz_resolve_indirect(obj);
 
if (!fz_is_dict(obj))
return NULL;
 
if (i < 0 || i >= obj->u.d.len)
return NULL;
 
return obj->u.d.items[i].v;
}
 
static int
fz_dict_finds(fz_obj *obj, char *key)
{
if (obj->u.d.sorted)
{
int l = 0;
int r = obj->u.d.len - 1;
while (l <= r)
{
int m = (l + r) >> 1;
int c = -strcmp(fz_to_name(obj->u.d.items[m].k), key);
if (c < 0)
r = m - 1;
else if (c > 0)
l = m + 1;
else
return m;
}
}
 
else
{
int i;
for (i = 0; i < obj->u.d.len; i++)
if (strcmp(fz_to_name(obj->u.d.items[i].k), key) == 0)
return i;
}
 
return -1;
}
 
fz_obj *
fz_dict_gets(fz_obj *obj, char *key)
{
int i;
 
obj = fz_resolve_indirect(obj);
 
if (!fz_is_dict(obj))
return NULL;
 
i = fz_dict_finds(obj, key);
if (i >= 0)
return obj->u.d.items[i].v;
 
return NULL;
}
 
fz_obj *
fz_dict_get(fz_obj *obj, fz_obj *key)
{
if (fz_is_name(key))
return fz_dict_gets(obj, fz_to_name(key));
return NULL;
}
 
fz_obj *
fz_dict_getsa(fz_obj *obj, char *key, char *abbrev)
{
fz_obj *v;
v = fz_dict_gets(obj, key);
if (v)
return v;
return fz_dict_gets(obj, abbrev);
}
 
void
fz_dict_put(fz_obj *obj, fz_obj *key, fz_obj *val)
{
char *s;
int i;
 
obj = fz_resolve_indirect(obj);
 
if (!fz_is_dict(obj))
{
fz_warn("assert: not a dict (%s)", fz_objkindstr(obj));
return;
}
 
if (fz_is_name(key))
s = fz_to_name(key);
else
{
fz_warn("assert: key is not a name (%s)", fz_objkindstr(obj));
return;
}
 
if (!val)
{
fz_warn("assert: val does not exist for key (%s)", s);
return;
}
 
i = fz_dict_finds(obj, s);
if (i >= 0)
{
fz_drop_obj(obj->u.d.items[i].v);
obj->u.d.items[i].v = fz_keep_obj(val);
return;
}
 
if (obj->u.d.len + 1 > obj->u.d.cap)
{
obj->u.d.cap = (obj->u.d.cap * 3) / 2;
obj->u.d.items = fz_realloc(obj->u.d.items, obj->u.d.cap, sizeof(struct keyval));
for (i = obj->u.d.len; i < obj->u.d.cap; i++)
{
obj->u.d.items[i].k = NULL;
obj->u.d.items[i].v = NULL;
}
}
 
/* borked! */
if (obj->u.d.len)
if (strcmp(fz_to_name(obj->u.d.items[obj->u.d.len - 1].k), s) > 0)
obj->u.d.sorted = 0;
 
obj->u.d.items[obj->u.d.len].k = fz_keep_obj(key);
obj->u.d.items[obj->u.d.len].v = fz_keep_obj(val);
obj->u.d.len ++;
}
 
void
fz_dict_puts(fz_obj *obj, char *key, fz_obj *val)
{
fz_obj *keyobj = fz_new_name(key);
fz_dict_put(obj, keyobj, val);
fz_drop_obj(keyobj);
}
 
void
fz_dict_dels(fz_obj *obj, char *key)
{
obj = fz_resolve_indirect(obj);
 
if (!fz_is_dict(obj))
fz_warn("assert: not a dict (%s)", fz_objkindstr(obj));
else
{
int i = fz_dict_finds(obj, key);
if (i >= 0)
{
fz_drop_obj(obj->u.d.items[i].k);
fz_drop_obj(obj->u.d.items[i].v);
obj->u.d.sorted = 0;
obj->u.d.items[i] = obj->u.d.items[obj->u.d.len-1];
obj->u.d.len --;
}
}
}
 
void
fz_dict_del(fz_obj *obj, fz_obj *key)
{
if (fz_is_name(key))
fz_dict_dels(obj, fz_to_name(key));
else
fz_warn("assert: key is not a name (%s)", fz_objkindstr(obj));
}
 
void
fz_sort_dict(fz_obj *obj)
{
obj = fz_resolve_indirect(obj);
if (!fz_is_dict(obj))
return;
if (!obj->u.d.sorted)
{
qsort(obj->u.d.items, obj->u.d.len, sizeof(struct keyval), keyvalcmp);
obj->u.d.sorted = 1;
}
}
 
static void
fz_free_array(fz_obj *obj)
{
int i;
 
for (i = 0; i < obj->u.a.len; i++)
if (obj->u.a.items[i])
fz_drop_obj(obj->u.a.items[i]);
 
fz_free(obj->u.a.items);
fz_free(obj);
}
 
static void
fz_free_dict(fz_obj *obj)
{
int i;
 
for (i = 0; i < obj->u.d.len; i++) {
if (obj->u.d.items[i].k)
fz_drop_obj(obj->u.d.items[i].k);
if (obj->u.d.items[i].v)
fz_drop_obj(obj->u.d.items[i].v);
}
 
fz_free(obj->u.d.items);
fz_free(obj);
}
 
void
fz_drop_obj(fz_obj *obj)
{
assert(obj != NULL);
if (--obj->refs == 0)
{
if (obj->kind == FZ_ARRAY)
fz_free_array(obj);
else if (obj->kind == FZ_DICT)
fz_free_dict(obj);
else
fz_free(obj);
}
}
/contrib/media/updf/fitz/base_string.c
0,0 → 1,265
#include "fitz.h"
 
int
fz_is_big_endian(void)
{
static const int one = 1;
return *(char*)&one == 0;
}
 
char *
fz_strsep(char **stringp, const char *delim)
{
char *ret = *stringp;
if (ret == NULL) return NULL;
if ((*stringp = strpbrk(*stringp, delim)) != NULL)
*((*stringp)++) = '\0';
return ret;
}
 
int
fz_strlcpy(char *dst, const char *src, int siz)
{
register char *d = dst;
register const char *s = src;
register int n = siz;
 
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
 
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
 
return(s - src - 1); /* count does not include NUL */
}
 
int
fz_strlcat(char *dst, const char *src, int siz)
{
register char *d = dst;
register const char *s = src;
register int n = siz;
int dlen;
 
/* Find the end of dst and adjust bytes left but don't go past end */
while (*d != '\0' && n-- != 0)
d++;
dlen = d - dst;
n = siz - dlen;
 
if (n == 0)
return dlen + strlen(s);
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
 
return dlen + (s - src); /* count does not include NUL */
}
 
enum
{
UTFmax = 4, /* maximum bytes per rune */
Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */
Runeself = 0x80, /* rune and UTF sequences are the same (<) */
Runeerror = 0xFFFD, /* decoding error in UTF */
Runemax = 0x10FFFF, /* maximum rune value */
};
 
enum
{
Bit1 = 7,
Bitx = 6,
Bit2 = 5,
Bit3 = 4,
Bit4 = 3,
Bit5 = 2,
 
T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */
Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */
T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */
T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */
T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */
T5 = ((1<<(Bit5+1))-1) ^ 0xFF, /* 1111 1000 */
 
Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */
Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */
Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */
Rune4 = (1<<(Bit4+3*Bitx))-1, /* 0001 1111 1111 1111 1111 1111 */
 
Maskx = (1<<Bitx)-1, /* 0011 1111 */
Testx = Maskx ^ 0xFF, /* 1100 0000 */
 
Bad = Runeerror,
};
 
int
chartorune(int *rune, char *str)
{
int c, c1, c2, c3;
long l;
 
/*
* one character sequence
* 00000-0007F => T1
*/
c = *(unsigned char*)str;
if(c < Tx) {
*rune = c;
return 1;
}
 
/*
* two character sequence
* 0080-07FF => T2 Tx
*/
c1 = *(unsigned char*)(str+1) ^ Tx;
if(c1 & Testx)
goto bad;
if(c < T3) {
if(c < T2)
goto bad;
l = ((c << Bitx) | c1) & Rune2;
if(l <= Rune1)
goto bad;
*rune = l;
return 2;
}
 
/*
* three character sequence
* 0800-FFFF => T3 Tx Tx
*/
c2 = *(unsigned char*)(str+2) ^ Tx;
if(c2 & Testx)
goto bad;
if(c < T4) {
l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
if(l <= Rune2)
goto bad;
*rune = l;
return 3;
}
 
/*
* four character sequence (21-bit value)
* 10000-1FFFFF => T4 Tx Tx Tx
*/
c3 = *(unsigned char*)(str+3) ^ Tx;
if (c3 & Testx)
goto bad;
if (c < T5) {
l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4;
if (l <= Rune3)
goto bad;
*rune = l;
return 4;
}
/*
* Support for 5-byte or longer UTF-8 would go here, but
* since we don't have that, we'll just fall through to bad.
*/
 
/*
* bad decoding
*/
bad:
*rune = Bad;
return 1;
}
 
int
runetochar(char *str, int *rune)
{
/* Runes are signed, so convert to unsigned for range check. */
unsigned long c;
 
/*
* one character sequence
* 00000-0007F => 00-7F
*/
c = *rune;
if(c <= Rune1) {
str[0] = c;
return 1;
}
 
/*
* two character sequence
* 0080-07FF => T2 Tx
*/
if(c <= Rune2) {
str[0] = T2 | (c >> 1*Bitx);
str[1] = Tx | (c & Maskx);
return 2;
}
 
/*
* If the Rune is out of range, convert it to the error rune.
* Do this test here because the error rune encodes to three bytes.
* Doing it earlier would duplicate work, since an out of range
* Rune wouldn't have fit in one or two bytes.
*/
if (c > Runemax)
c = Runeerror;
 
/*
* three character sequence
* 0800-FFFF => T3 Tx Tx
*/
if (c <= Rune3) {
str[0] = T3 | (c >> 2*Bitx);
str[1] = Tx | ((c >> 1*Bitx) & Maskx);
str[2] = Tx | (c & Maskx);
return 3;
}
 
/*
* four character sequence (21-bit value)
* 10000-1FFFFF => T4 Tx Tx Tx
*/
str[0] = T4 | (c >> 3*Bitx);
str[1] = Tx | ((c >> 2*Bitx) & Maskx);
str[2] = Tx | ((c >> 1*Bitx) & Maskx);
str[3] = Tx | (c & Maskx);
return 4;
}
 
int
runelen(int c)
{
char str[10];
return runetochar(str, &c);
}
 
float fz_atof(const char *s)
{
double d;
 
/* The errno voodoo here checks for us reading numbers that are too
* big to fit into a double. The checks for FLT_MAX ensure that we
* don't read a number that's OK as a double and then become invalid
* as we convert to a float. */
errno = 0;
d = strtod(s, NULL);
if (errno == ERANGE || d > FLT_MAX || d < -FLT_MAX) {
/* Return 1.0, as it's a small known value that won't cause a
* divide by 0. */
return 1.0;
}
return (float)d;
}
/contrib/media/updf/fitz/base_time.c
0,0 → 1,42
#ifdef _WIN32
 
#include <time.h>
#include <winsock2.h>
#include <windows.h>
 
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
 
struct timeval;
 
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
FILETIME ft;
unsigned __int64 tmpres = 0;
 
if (tv)
{
GetSystemTimeAsFileTime(&ft);
 
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
 
tmpres /= 10; /*convert into microseconds*/
/*converting file time to unix epoch*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
 
return 0;
}
 
#else
 
void fz_gettimeofday_dummy() { }
 
#endif
/contrib/media/updf/fitz/crypt_aes.c
0,0 → 1,565
/*
* FIPS-197 compliant AES implementation
*
* Copyright (C) 2006-2007 Christophe Devine
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code _must_ retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form may or may not reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of XySSL nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
*
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/
 
#include "fitz.h"
 
#define aes_context fz_aes
 
/* AES block cipher implementation from XYSSL */
 
/*
* 32-bit integer manipulation macros (little endian)
*/
#ifndef GET_ULONG_LE
#define GET_ULONG_LE(n,b,i) \
{ \
(n) = ( (unsigned long) (b)[(i)] ) \
| ( (unsigned long) (b)[(i) + 1] << 8 ) \
| ( (unsigned long) (b)[(i) + 2] << 16 ) \
| ( (unsigned long) (b)[(i) + 3] << 24 ); \
}
#endif
 
#ifndef PUT_ULONG_LE
#define PUT_ULONG_LE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
}
#endif
 
/*
* Forward S-box & tables
*/
static unsigned char FSb[256];
static unsigned long FT0[256];
static unsigned long FT1[256];
static unsigned long FT2[256];
static unsigned long FT3[256];
 
/*
* Reverse S-box & tables
*/
static unsigned char RSb[256];
static unsigned long RT0[256];
static unsigned long RT1[256];
static unsigned long RT2[256];
static unsigned long RT3[256];
 
/*
* Round constants
*/
static unsigned long RCON[10];
 
/*
* Tables generation code
*/
#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
 
static int aes_init_done = 0;
 
static void aes_gen_tables( void )
{
int i, x, y, z;
int pow[256];
int log[256];
 
/*
* compute pow and log tables over GF(2^8)
*/
for( i = 0, x = 1; i < 256; i++ )
{
pow[i] = x;
log[x] = i;
x = ( x ^ XTIME( x ) ) & 0xFF;
}
 
/*
* calculate the round constants
*/
for( i = 0, x = 1; i < 10; i++ )
{
RCON[i] = (unsigned long) x;
x = XTIME( x ) & 0xFF;
}
 
/*
* generate the forward and reverse S-boxes
*/
FSb[0x00] = 0x63;
RSb[0x63] = 0x00;
 
for( i = 1; i < 256; i++ )
{
x = pow[255 - log[i]];
 
y = x; y = ( (y << 1) | (y >> 7) ) & 0xFF;
x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
x ^= y ^ 0x63;
 
FSb[i] = (unsigned char) x;
RSb[x] = (unsigned char) i;
}
 
/*
* generate the forward and reverse tables
*/
for( i = 0; i < 256; i++ )
{
x = FSb[i];
y = XTIME( x ) & 0xFF;
z = ( y ^ x ) & 0xFF;
 
FT0[i] = ( (unsigned long) y ) ^
( (unsigned long) x << 8 ) ^
( (unsigned long) x << 16 ) ^
( (unsigned long) z << 24 );
 
FT1[i] = ROTL8( FT0[i] );
FT2[i] = ROTL8( FT1[i] );
FT3[i] = ROTL8( FT2[i] );
 
x = RSb[i];
 
RT0[i] = ( (unsigned long) MUL( 0x0E, x ) ) ^
( (unsigned long) MUL( 0x09, x ) << 8 ) ^
( (unsigned long) MUL( 0x0D, x ) << 16 ) ^
( (unsigned long) MUL( 0x0B, x ) << 24 );
 
RT1[i] = ROTL8( RT0[i] );
RT2[i] = ROTL8( RT1[i] );
RT3[i] = ROTL8( RT2[i] );
}
}
 
/*
* AES key schedule (encryption)
*/
void aes_setkey_enc( aes_context *ctx, const unsigned char *key, int keysize )
{
int i;
unsigned long *RK;
 
#if !defined(XYSSL_AES_ROM_TABLES)
if( aes_init_done == 0 )
{
aes_gen_tables();
aes_init_done = 1;
}
#endif
 
switch( keysize )
{
case 128: ctx->nr = 10; break;
case 192: ctx->nr = 12; break;
case 256: ctx->nr = 14; break;
default : return;
}
 
#if defined(PADLOCK_ALIGN16)
ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
#else
ctx->rk = RK = ctx->buf;
#endif
 
for( i = 0; i < (keysize >> 5); i++ )
{
GET_ULONG_LE( RK[i], key, i << 2 );
}
 
switch( ctx->nr )
{
case 10:
 
for( i = 0; i < 10; i++, RK += 4 )
{
RK[4] = RK[0] ^ RCON[i] ^
( FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
( FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
( FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
( FSb[ ( RK[3] ) & 0xFF ] << 24 );
 
RK[5] = RK[1] ^ RK[4];
RK[6] = RK[2] ^ RK[5];
RK[7] = RK[3] ^ RK[6];
}
break;
 
case 12:
 
for( i = 0; i < 8; i++, RK += 6 )
{
RK[6] = RK[0] ^ RCON[i] ^
( FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
( FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
( FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
( FSb[ ( RK[5] ) & 0xFF ] << 24 );
 
RK[7] = RK[1] ^ RK[6];
RK[8] = RK[2] ^ RK[7];
RK[9] = RK[3] ^ RK[8];
RK[10] = RK[4] ^ RK[9];
RK[11] = RK[5] ^ RK[10];
}
break;
 
case 14:
 
for( i = 0; i < 7; i++, RK += 8 )
{
RK[8] = RK[0] ^ RCON[i] ^
( FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
( FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
( FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
( FSb[ ( RK[7] ) & 0xFF ] << 24 );
 
RK[9] = RK[1] ^ RK[8];
RK[10] = RK[2] ^ RK[9];
RK[11] = RK[3] ^ RK[10];
 
RK[12] = RK[4] ^
( FSb[ ( RK[11] ) & 0xFF ] ) ^
( FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
( FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
( FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
 
RK[13] = RK[5] ^ RK[12];
RK[14] = RK[6] ^ RK[13];
RK[15] = RK[7] ^ RK[14];
}
break;
 
default:
 
break;
}
}
 
/*
* AES key schedule (decryption)
*/
void aes_setkey_dec( aes_context *ctx, const unsigned char *key, int keysize )
{
int i, j;
aes_context cty;
unsigned long *RK;
unsigned long *SK;
 
switch( keysize )
{
case 128: ctx->nr = 10; break;
case 192: ctx->nr = 12; break;
case 256: ctx->nr = 14; break;
default : return;
}
 
#if defined(PADLOCK_ALIGN16)
ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
#else
ctx->rk = RK = ctx->buf;
#endif
 
aes_setkey_enc( &cty, key, keysize );
SK = cty.rk + cty.nr * 4;
 
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
 
for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
{
for( j = 0; j < 4; j++, SK++ )
{
*RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^
RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^
RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
}
}
 
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
*RK++ = *SK++;
 
memset( &cty, 0, sizeof( aes_context ) );
}
 
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
{ \
X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \
FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y3 >> 24 ) & 0xFF ]; \
\
X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \
FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y0 >> 24 ) & 0xFF ]; \
\
X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \
FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y1 >> 24 ) & 0xFF ]; \
\
X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \
FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y2 >> 24 ) & 0xFF ]; \
}
 
#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
{ \
X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \
RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
RT3[ ( Y1 >> 24 ) & 0xFF ]; \
\
X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \
RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
RT3[ ( Y2 >> 24 ) & 0xFF ]; \
\
X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \
RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
RT3[ ( Y3 >> 24 ) & 0xFF ]; \
\
X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \
RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
RT3[ ( Y0 >> 24 ) & 0xFF ]; \
}
 
/*
* AES-ECB block encryption/decryption
*/
void aes_crypt_ecb( aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
int i;
unsigned long *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
 
#if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86)
if( padlock_supports( PADLOCK_ACE ) )
{
if( padlock_xcryptecb( ctx, mode, input, output ) == 0 )
return;
}
#endif
 
RK = ctx->rk;
 
GET_ULONG_LE( X0, input, 0 ); X0 ^= *RK++;
GET_ULONG_LE( X1, input, 4 ); X1 ^= *RK++;
GET_ULONG_LE( X2, input, 8 ); X2 ^= *RK++;
GET_ULONG_LE( X3, input, 12 ); X3 ^= *RK++;
 
if( mode == AES_DECRYPT )
{
for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
{
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
}
 
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
 
X0 = *RK++ ^ ( RSb[ ( Y0 ) & 0xFF ] ) ^
( RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
( RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
( RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
 
X1 = *RK++ ^ ( RSb[ ( Y1 ) & 0xFF ] ) ^
( RSb[ ( Y0 >>8 ) & 0xFF ] << 8 ) ^
( RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
( RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
 
X2 = *RK++ ^ ( RSb[ ( Y2 ) & 0xFF ] ) ^
( RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
( RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
( RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
 
X3 = *RK++ ^ ( RSb[ ( Y3 ) & 0xFF ] ) ^
( RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
( RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
( RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
}
else /* AES_ENCRYPT */
{
for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
{
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
}
 
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
 
X0 = *RK++ ^ ( FSb[ ( Y0 ) & 0xFF ] ) ^
( FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
( FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
( FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
 
X1 = *RK++ ^ ( FSb[ ( Y1 ) & 0xFF ] ) ^
( FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
( FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
( FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
 
X2 = *RK++ ^ ( FSb[ ( Y2 ) & 0xFF ] ) ^
( FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
( FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
( FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
 
X3 = *RK++ ^ ( FSb[ ( Y3 ) & 0xFF ] ) ^
( FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
( FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
( FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
}
 
PUT_ULONG_LE( X0, output, 0 );
PUT_ULONG_LE( X1, output, 4 );
PUT_ULONG_LE( X2, output, 8 );
PUT_ULONG_LE( X3, output, 12 );
}
 
/*
* AES-CBC buffer encryption/decryption
*/
void aes_crypt_cbc( aes_context *ctx,
int mode,
int length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[16];
 
#if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86)
if( padlock_supports( PADLOCK_ACE ) )
{
if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
return;
}
#endif
 
if( mode == AES_DECRYPT )
{
while( length > 0 )
{
memcpy( temp, input, 16 );
aes_crypt_ecb( ctx, mode, input, output );
 
for( i = 0; i < 16; i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
 
memcpy( iv, temp, 16 );
 
input += 16;
output += 16;
length -= 16;
}
}
else
{
while( length > 0 )
{
for( i = 0; i < 16; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
 
aes_crypt_ecb( ctx, mode, output, output );
memcpy( iv, output, 16 );
 
input += 16;
output += 16;
length -= 16;
}
}
}
 
/*
* AES-CFB buffer encryption/decryption
*/
void aes_crypt_cfb( aes_context *ctx,
int mode,
int length,
int *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int c, n = *iv_off;
 
if( mode == AES_DECRYPT )
{
while( length-- )
{
if( n == 0 )
aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
 
c = *input++;
*output++ = (unsigned char)( c ^ iv[n] );
iv[n] = (unsigned char) c;
 
n = (n + 1) & 0x0F;
}
}
else
{
while( length-- )
{
if( n == 0 )
aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
 
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
 
n = (n + 1) & 0x0F;
}
}
 
*iv_off = n;
}
/contrib/media/updf/fitz/crypt_arc4.c
0,0 → 1,98
/* This code illustrates a sample implementation
* of the Arcfour algorithm
* Copyright (c) April 29, 1997 Kalle Kaukonen.
* All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that this copyright
* notice and disclaimer are retained.
*
* THIS SOFTWARE IS PROVIDED BY KALLE KAUKONEN AND CONTRIBUTORS ``AS
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KALLE
* KAUKONEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include "fitz.h"
 
void
fz_arc4_init(fz_arc4 *arc4, const unsigned char *key, const unsigned keylen)
{
unsigned int t, u;
unsigned int keyindex;
unsigned int stateindex;
unsigned char *state;
unsigned int counter;
 
state = arc4->state;
 
arc4->x = 0;
arc4->y = 0;
 
for (counter = 0; counter < 256; counter++)
{
state[counter] = counter;
}
 
keyindex = 0;
stateindex = 0;
 
for (counter = 0; counter < 256; counter++)
{
t = state[counter];
stateindex = (stateindex + key[keyindex] + t) & 0xff;
u = state[stateindex];
 
state[stateindex] = t;
state[counter] = u;
 
if (++keyindex >= keylen)
{
keyindex = 0;
}
}
}
 
static unsigned char
fz_arc4_next(fz_arc4 *arc4)
{
unsigned int x;
unsigned int y;
unsigned int sx, sy;
unsigned char *state;
 
state = arc4->state;
 
x = (arc4->x + 1) & 0xff;
sx = state[x];
y = (sx + arc4->y) & 0xff;
sy = state[y];
 
arc4->x = x;
arc4->y = y;
 
state[y] = sx;
state[x] = sy;
 
return state[(sx + sy) & 0xff];
}
 
void
fz_arc4_encrypt(fz_arc4 *arc4, unsigned char *dest, const unsigned char *src, const unsigned len)
{
unsigned int i;
for (i = 0; i < len; i++)
{
unsigned char x;
x = fz_arc4_next(arc4);
dest[i] = src[i] ^ x;
}
}
/contrib/media/updf/fitz/crypt_md5.c
0,0 → 1,272
/*
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
 
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
All rights reserved.
 
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
 
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
 
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
 
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
 
#include "fitz.h"
 
/* Constants for MD5Transform routine */
enum
{
S11 = 7, S12 = 12, S13 = 17, S14 = 22,
S21 = 5, S22 = 9, S23 = 14, S24 = 20,
S31 = 4, S32 = 11, S33 = 16, S34 = 23,
S41 = 6, S42 = 10, S43 = 15, S44 = 21
};
 
static void encode(unsigned char *, const unsigned int *, const unsigned);
static void decode(unsigned int *, const unsigned char *, const unsigned);
static void transform(unsigned int state[4], const unsigned char block[64]);
 
static unsigned char padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
 
/* F, G, H and I are basic MD5 functions */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
 
/* ROTATE rotates x left n bits */
#define ROTATE(x, n) (((x) << (n)) | ((x) >> (32-(n))))
 
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
* Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (unsigned int)(ac); \
(a) = ROTATE ((a), (s)); \
(a) += (b); \
}
 
static void encode(unsigned char *output, const unsigned int *input, const unsigned len)
{
unsigned i, j;
 
for (i = 0, j = 0; j < len; i++, j += 4)
{
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
 
static void decode(unsigned int *output, const unsigned char *input, const unsigned len)
{
unsigned i, j;
 
for (i = 0, j = 0; j < len; i++, j += 4)
{
output[i] = ((unsigned int)input[j]) |
(((unsigned int)input[j+1]) << 8) |
(((unsigned int)input[j+2]) << 16) |
(((unsigned int)input[j+3]) << 24);
}
}
 
static void transform(unsigned int state[4], const unsigned char block[64])
{
unsigned int a = state[0];
unsigned int b = state[1];
unsigned int c = state[2];
unsigned int d = state[3];
unsigned int x[16];
 
decode(x, block, 64);
 
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
 
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x02441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
 
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x04881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
 
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
 
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
 
/* Zeroize sensitive information */
memset(x, 0, sizeof (x));
}
 
/* MD5 initialization. Begins an MD5 operation, writing a new context. */
void fz_md5_init(fz_md5 *context)
{
context->count[0] = context->count[1] = 0;
 
/* Load magic initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
 
/* MD5 block update operation. Continues an MD5 message-digest operation,
* processing another message block, and updating the context.
*/
void fz_md5_update(fz_md5 *context, const unsigned char *input, const unsigned inlen)
{
unsigned i, index, partlen;
 
/* Compute number of bytes mod 64 */
index = (unsigned)((context->count[0] >> 3) & 0x3F);
 
/* Update number of bits */
context->count[0] += (unsigned int) inlen << 3;
if (context->count[0] < (unsigned int) inlen << 3)
context->count[1] ++;
context->count[1] += (unsigned int) inlen >> 29;
 
partlen = 64 - index;
 
/* Transform as many times as possible. */
if (inlen >= partlen)
{
memcpy(context->buffer + index, input, partlen);
transform(context->state, context->buffer);
 
for (i = partlen; i + 63 < inlen; i += 64)
transform(context->state, input + i);
 
index = 0;
}
else
{
i = 0;
}
 
/* Buffer remaining input */
memcpy(context->buffer + index, input + i, inlen - i);
}
 
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
* the message digest and zeroizing the context.
*/
void fz_md5_final(fz_md5 *context, unsigned char digest[16])
{
unsigned char bits[8];
unsigned index, padlen;
 
/* Save number of bits */
encode(bits, context->count, 8);
 
/* Pad out to 56 mod 64 */
index = (unsigned)((context->count[0] >> 3) & 0x3f);
padlen = index < 56 ? 56 - index : 120 - index;
fz_md5_update(context, padding, padlen);
 
/* Append length (before padding) */
fz_md5_update(context, bits, 8);
 
/* Store state in digest */
encode(digest, context->state, 16);
 
/* Zeroize sensitive information */
memset(context, 0, sizeof(fz_md5));
}
/contrib/media/updf/fitz/crypt_sha2.c
0,0 → 1,182
/*
This code is based on the code found from 7-Zip, which has a modified
version of the SHA-256 found from Crypto++ <http://www.cryptopp.com/>.
The code was modified a little to fit into liblzma and fitz.
 
This file has been put into the public domain.
You can do whatever you want with this file.
*/
 
#include "fitz.h"
 
static inline int isbigendian(void)
{
static const int one = 1;
return *(char*)&one == 0;
}
 
static inline unsigned int bswap32(unsigned int num)
{
if (!isbigendian())
{
return ( (((num) << 24))
| (((num) << 8) & 0x00FF0000)
| (((num) >> 8) & 0x0000FF00)
| (((num) >> 24)) );
}
return num;
}
 
/* At least on x86, GCC is able to optimize this to a rotate instruction. */
#define rotr_32(num, amount) ((num) >> (amount) | (num) << (32 - (amount)))
 
#define blk0(i) (W[i] = data[i])
#define blk2(i) (W[i & 15] += s1(W[(i - 2) & 15]) + W[(i - 7) & 15] \
+ s0(W[(i - 15) & 15]))
 
#define Ch(x, y, z) (z ^ (x & (y ^ z)))
#define Maj(x, y, z) ((x & y) | (z & (x | y)))
 
#define a(i) T[(0 - i) & 7]
#define b(i) T[(1 - i) & 7]
#define c(i) T[(2 - i) & 7]
#define d(i) T[(3 - i) & 7]
#define e(i) T[(4 - i) & 7]
#define f(i) T[(5 - i) & 7]
#define g(i) T[(6 - i) & 7]
#define h(i) T[(7 - i) & 7]
 
#define R(i) \
h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + SHA256_K[i + j] \
+ (j ? blk2(i) : blk0(i)); \
d(i) += h(i); \
h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
 
#define S0(x) (rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22))
#define S1(x) (rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25))
#define s0(x) (rotr_32(x, 7) ^ rotr_32(x, 18) ^ (x >> 3))
#define s1(x) (rotr_32(x, 17) ^ rotr_32(x, 19) ^ (x >> 10))
 
static const unsigned int SHA256_K[64] = {
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
};
 
static void
transform(unsigned int state[8], const unsigned int data_xe[16])
{
unsigned int data[16];
unsigned int W[16];
unsigned int T[8];
unsigned int j;
 
/* ensure big-endian integers */
for (j = 0; j < 16; j++)
data[j] = bswap32(data_xe[j]);
 
/* Copy state[] to working vars. */
memcpy(T, state, sizeof(T));
 
/* 64 operations, partially loop unrolled */
for (j = 0; j < 64; j += 16) {
R( 0); R( 1); R( 2); R( 3);
R( 4); R( 5); R( 6); R( 7);
R( 8); R( 9); R(10); R(11);
R(12); R(13); R(14); R(15);
}
 
/* Add the working vars back into state[]. */
state[0] += a(0);
state[1] += b(0);
state[2] += c(0);
state[3] += d(0);
state[4] += e(0);
state[5] += f(0);
state[6] += g(0);
state[7] += h(0);
}
 
void fz_sha256_init(fz_sha256 *context)
{
context->count[0] = context->count[1] = 0;
 
context->state[0] = 0x6A09E667;
context->state[1] = 0xBB67AE85;
context->state[2] = 0x3C6EF372;
context->state[3] = 0xA54FF53A;
context->state[4] = 0x510E527F;
context->state[5] = 0x9B05688C;
context->state[6] = 0x1F83D9AB;
context->state[7] = 0x5BE0CD19;
}
 
void fz_sha256_update(fz_sha256 *context, const unsigned char *input, unsigned int inlen)
{
/* Copy the input data into a properly aligned temporary buffer.
* This way we can be called with arbitrarily sized buffers
* (no need to be multiple of 64 bytes), and the code works also
* on architectures that don't allow unaligned memory access. */
while (inlen > 0)
{
const unsigned int copy_start = context->count[0] & 0x3F;
unsigned int copy_size = 64 - copy_start;
if (copy_size > inlen)
copy_size = inlen;
 
memcpy(context->buffer.u8 + copy_start, input, copy_size);
 
input += copy_size;
inlen -= copy_size;
context->count[0] += copy_size;
/* carry overflow from low to high */
if (context->count[0] < copy_size)
context->count[1]++;
 
if ((context->count[0] & 0x3F) == 0)
transform(context->state, context->buffer.u32);
}
}
 
void fz_sha256_final(fz_sha256 *context, unsigned char digest[32])
{
/* Add padding as described in RFC 3174 (it describes SHA-1 but
* the same padding style is used for SHA-256 too). */
unsigned int j = context->count[0] & 0x3F;
context->buffer.u8[j++] = 0x80;
 
while (j != 56)
{
if (j == 64)
{
transform(context->state, context->buffer.u32);
j = 0;
}
context->buffer.u8[j++] = 0x00;
}
 
/* Convert the message size from bytes to bits. */
context->count[1] = (context->count[1] << 3) + (context->count[0] >> 29);
context->count[0] = context->count[0] << 3;
 
context->buffer.u32[14] = bswap32(context->count[1]);
context->buffer.u32[15] = bswap32(context->count[0]);
transform(context->state, context->buffer.u32);
 
for (j = 0; j < 8; j++)
((unsigned int *)digest)[j] = bswap32(context->state[j]);
memset(context, 0, sizeof(fz_sha256));
}
/contrib/media/updf/fitz/dev_bbox.c
0,0 → 1,82
#include "fitz.h"
 
/* TODO: add clip stack and use to intersect bboxes */
 
static void
fz_bbox_fill_path(void *user, fz_path *path, int even_odd, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_bbox *result = user;
fz_bbox bbox = fz_round_rect(fz_bound_path(path, NULL, ctm));
*result = fz_union_bbox(*result, bbox);
}
 
static void
fz_bbox_stroke_path(void *user, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_bbox *result = user;
fz_bbox bbox = fz_round_rect(fz_bound_path(path, stroke, ctm));
*result = fz_union_bbox(*result, bbox);
}
 
static void
fz_bbox_fill_text(void *user, fz_text *text, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_bbox *result = user;
fz_bbox bbox = fz_round_rect(fz_bound_text(text, ctm));
*result = fz_union_bbox(*result, bbox);
}
 
static void
fz_bbox_stroke_text(void *user, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_bbox *result = user;
fz_bbox bbox = fz_round_rect(fz_bound_text(text, ctm));
*result = fz_union_bbox(*result, bbox);
}
 
static void
fz_bbox_fill_shade(void *user, fz_shade *shade, fz_matrix ctm, float alpha)
{
fz_bbox *result = user;
fz_bbox bbox = fz_round_rect(fz_bound_shade(shade, ctm));
*result = fz_union_bbox(*result, bbox);
}
 
static void
fz_bbox_fill_image(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
{
fz_bbox *result = user;
fz_bbox bbox = fz_round_rect(fz_transform_rect(ctm, fz_unit_rect));
*result = fz_union_bbox(*result, bbox);
}
 
static void
fz_bbox_fill_image_mask(void *user, fz_pixmap *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_bbox_fill_image(user, image, ctm, alpha);
}
 
fz_device *
fz_new_bbox_device(fz_bbox *result)
{
fz_device *dev;
 
dev = fz_new_device(result);
 
dev->fill_path = fz_bbox_fill_path;
dev->stroke_path = fz_bbox_stroke_path;
dev->fill_text = fz_bbox_fill_text;
dev->stroke_text = fz_bbox_stroke_text;
dev->fill_shade = fz_bbox_fill_shade;
dev->fill_image = fz_bbox_fill_image;
dev->fill_image_mask = fz_bbox_fill_image_mask;
 
*result = fz_empty_bbox;
 
return dev;
}
/contrib/media/updf/fitz/dev_list.c
0,0 → 1,660
#include "fitz.h"
 
typedef struct fz_display_node_s fz_display_node;
 
#define STACK_SIZE 96
 
typedef enum fz_display_command_e
{
FZ_CMD_FILL_PATH,
FZ_CMD_STROKE_PATH,
FZ_CMD_CLIP_PATH,
FZ_CMD_CLIP_STROKE_PATH,
FZ_CMD_FILL_TEXT,
FZ_CMD_STROKE_TEXT,
FZ_CMD_CLIP_TEXT,
FZ_CMD_CLIP_STROKE_TEXT,
FZ_CMD_IGNORE_TEXT,
FZ_CMD_FILL_SHADE,
FZ_CMD_FILL_IMAGE,
FZ_CMD_FILL_IMAGE_MASK,
FZ_CMD_CLIP_IMAGE_MASK,
FZ_CMD_POP_CLIP,
FZ_CMD_BEGIN_MASK,
FZ_CMD_END_MASK,
FZ_CMD_BEGIN_GROUP,
FZ_CMD_END_GROUP,
FZ_CMD_BEGIN_TILE,
FZ_CMD_END_TILE
} fz_display_command;
 
struct fz_display_node_s
{
fz_display_command cmd;
fz_display_node *next;
fz_rect rect;
union {
fz_path *path;
fz_text *text;
fz_shade *shade;
fz_pixmap *image;
int blendmode;
} item;
fz_stroke_state *stroke;
int flag; /* even_odd, accumulate, isolated/knockout... */
fz_matrix ctm;
fz_colorspace *colorspace;
float alpha;
float color[FZ_MAX_COLORS];
};
 
struct fz_display_list_s
{
fz_display_node *first;
fz_display_node *last;
 
int top;
struct {
fz_rect *update;
fz_rect rect;
} stack[STACK_SIZE];
int tiled;
};
 
enum { ISOLATED = 1, KNOCKOUT = 2 };
 
static fz_display_node *
fz_new_display_node(fz_display_command cmd, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_display_node *node;
int i;
 
node = fz_malloc(sizeof(fz_display_node));
node->cmd = cmd;
node->next = NULL;
node->rect = fz_empty_rect;
node->item.path = NULL;
node->stroke = NULL;
node->flag = 0;
node->ctm = ctm;
if (colorspace)
{
node->colorspace = fz_keep_colorspace(colorspace);
if (color)
{
for (i = 0; i < node->colorspace->n; i++)
node->color[i] = color[i];
}
}
else
{
node->colorspace = NULL;
}
node->alpha = alpha;
 
return node;
}
 
static fz_stroke_state *
fz_clone_stroke_state(fz_stroke_state *stroke)
{
fz_stroke_state *newstroke = fz_malloc(sizeof(fz_stroke_state));
*newstroke = *stroke;
return newstroke;
}
 
static void
fz_append_display_node(fz_display_list *list, fz_display_node *node)
{
switch (node->cmd)
{
case FZ_CMD_CLIP_PATH:
case FZ_CMD_CLIP_STROKE_PATH:
case FZ_CMD_CLIP_IMAGE_MASK:
if (list->top < STACK_SIZE)
{
list->stack[list->top].update = &node->rect;
list->stack[list->top].rect = fz_empty_rect;
}
list->top++;
break;
case FZ_CMD_END_MASK:
case FZ_CMD_CLIP_TEXT:
case FZ_CMD_CLIP_STROKE_TEXT:
if (list->top < STACK_SIZE)
{
list->stack[list->top].update = NULL;
list->stack[list->top].rect = fz_empty_rect;
}
list->top++;
break;
case FZ_CMD_BEGIN_TILE:
list->tiled++;
if (list->top > 0 && list->top < STACK_SIZE)
{
list->stack[list->top-1].rect = fz_infinite_rect;
}
break;
case FZ_CMD_END_TILE:
list->tiled--;
break;
case FZ_CMD_END_GROUP:
break;
case FZ_CMD_POP_CLIP:
if (list->top > STACK_SIZE)
{
list->top--;
node->rect = fz_infinite_rect;
}
else if (list->top > 0)
{
fz_rect *update;
list->top--;
update = list->stack[list->top].update;
if (list->tiled == 0)
{
if (update != NULL)
{
*update = fz_intersect_rect(*update, list->stack[list->top].rect);
node->rect = *update;
}
else
node->rect = list->stack[list->top].rect;
}
else
node->rect = fz_infinite_rect;
}
/* fallthrough */
default:
if (list->top > 0 && list->tiled == 0 && list->top <= STACK_SIZE)
list->stack[list->top-1].rect = fz_union_rect(list->stack[list->top-1].rect, node->rect);
break;
}
if (!list->first)
{
list->first = node;
list->last = node;
}
else
{
list->last->next = node;
list->last = node;
}
}
 
static void
fz_free_display_node(fz_display_node *node)
{
switch (node->cmd)
{
case FZ_CMD_FILL_PATH:
case FZ_CMD_STROKE_PATH:
case FZ_CMD_CLIP_PATH:
case FZ_CMD_CLIP_STROKE_PATH:
fz_free_path(node->item.path);
break;
case FZ_CMD_FILL_TEXT:
case FZ_CMD_STROKE_TEXT:
case FZ_CMD_CLIP_TEXT:
case FZ_CMD_CLIP_STROKE_TEXT:
case FZ_CMD_IGNORE_TEXT:
fz_free_text(node->item.text);
break;
case FZ_CMD_FILL_SHADE:
fz_drop_shade(node->item.shade);
break;
case FZ_CMD_FILL_IMAGE:
case FZ_CMD_FILL_IMAGE_MASK:
case FZ_CMD_CLIP_IMAGE_MASK:
fz_drop_pixmap(node->item.image);
break;
case FZ_CMD_POP_CLIP:
case FZ_CMD_BEGIN_MASK:
case FZ_CMD_END_MASK:
case FZ_CMD_BEGIN_GROUP:
case FZ_CMD_END_GROUP:
case FZ_CMD_BEGIN_TILE:
case FZ_CMD_END_TILE:
break;
}
if (node->stroke)
fz_free(node->stroke);
if (node->colorspace)
fz_drop_colorspace(node->colorspace);
fz_free(node);
}
 
static void
fz_list_fill_path(void *user, fz_path *path, int even_odd, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_FILL_PATH, ctm, colorspace, color, alpha);
node->rect = fz_bound_path(path, NULL, ctm);
node->item.path = fz_clone_path(path);
node->flag = even_odd;
fz_append_display_node(user, node);
}
 
static void
fz_list_stroke_path(void *user, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_STROKE_PATH, ctm, colorspace, color, alpha);
node->rect = fz_bound_path(path, stroke, ctm);
node->item.path = fz_clone_path(path);
node->stroke = fz_clone_stroke_state(stroke);
fz_append_display_node(user, node);
}
 
static void
fz_list_clip_path(void *user, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_CLIP_PATH, ctm, NULL, NULL, 0);
node->rect = fz_bound_path(path, NULL, ctm);
if (rect != NULL)
node->rect = fz_intersect_rect(node->rect, *rect);
node->item.path = fz_clone_path(path);
node->flag = even_odd;
fz_append_display_node(user, node);
}
 
static void
fz_list_clip_stroke_path(void *user, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_CLIP_STROKE_PATH, ctm, NULL, NULL, 0);
node->rect = fz_bound_path(path, stroke, ctm);
if (rect != NULL)
node->rect = fz_intersect_rect(node->rect, *rect);
node->item.path = fz_clone_path(path);
node->stroke = fz_clone_stroke_state(stroke);
fz_append_display_node(user, node);
}
 
static void
fz_list_fill_text(void *user, fz_text *text, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_FILL_TEXT, ctm, colorspace, color, alpha);
node->rect = fz_bound_text(text, ctm);
node->item.text = fz_clone_text(text);
fz_append_display_node(user, node);
}
 
static void
fz_list_stroke_text(void *user, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_STROKE_TEXT, ctm, colorspace, color, alpha);
node->rect = fz_bound_text(text, ctm);
node->item.text = fz_clone_text(text);
node->stroke = fz_clone_stroke_state(stroke);
fz_append_display_node(user, node);
}
 
static void
fz_list_clip_text(void *user, fz_text *text, fz_matrix ctm, int accumulate)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_CLIP_TEXT, ctm, NULL, NULL, 0);
node->rect = fz_bound_text(text, ctm);
node->item.text = fz_clone_text(text);
node->flag = accumulate;
/* when accumulating, be conservative about culling */
if (accumulate)
node->rect = fz_infinite_rect;
fz_append_display_node(user, node);
}
 
static void
fz_list_clip_stroke_text(void *user, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_CLIP_STROKE_TEXT, ctm, NULL, NULL, 0);
node->rect = fz_bound_text(text, ctm);
node->item.text = fz_clone_text(text);
node->stroke = fz_clone_stroke_state(stroke);
fz_append_display_node(user, node);
}
 
static void
fz_list_ignore_text(void *user, fz_text *text, fz_matrix ctm)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_IGNORE_TEXT, ctm, NULL, NULL, 0);
node->rect = fz_bound_text(text, ctm);
node->item.text = fz_clone_text(text);
fz_append_display_node(user, node);
}
 
static void
fz_list_pop_clip(void *user)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_POP_CLIP, fz_identity, NULL, NULL, 0);
fz_append_display_node(user, node);
}
 
static void
fz_list_fill_shade(void *user, fz_shade *shade, fz_matrix ctm, float alpha)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_FILL_SHADE, ctm, NULL, NULL, alpha);
node->rect = fz_bound_shade(shade, ctm);
node->item.shade = fz_keep_shade(shade);
fz_append_display_node(user, node);
}
 
static void
fz_list_fill_image(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_FILL_IMAGE, ctm, NULL, NULL, alpha);
node->rect = fz_transform_rect(ctm, fz_unit_rect);
node->item.image = fz_keep_pixmap(image);
fz_append_display_node(user, node);
}
 
static void
fz_list_fill_image_mask(void *user, fz_pixmap *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_FILL_IMAGE_MASK, ctm, colorspace, color, alpha);
node->rect = fz_transform_rect(ctm, fz_unit_rect);
node->item.image = fz_keep_pixmap(image);
fz_append_display_node(user, node);
}
 
static void
fz_list_clip_image_mask(void *user, fz_pixmap *image, fz_rect *rect, fz_matrix ctm)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_CLIP_IMAGE_MASK, ctm, NULL, NULL, 0);
node->rect = fz_transform_rect(ctm, fz_unit_rect);
if (rect != NULL)
node->rect = fz_intersect_rect(node->rect, *rect);
node->item.image = fz_keep_pixmap(image);
fz_append_display_node(user, node);
}
 
static void
fz_list_begin_mask(void *user, fz_rect rect, int luminosity, fz_colorspace *colorspace, float *color)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_BEGIN_MASK, fz_identity, colorspace, color, 0);
node->rect = rect;
node->flag = luminosity;
fz_append_display_node(user, node);
}
 
static void
fz_list_end_mask(void *user)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_END_MASK, fz_identity, NULL, NULL, 0);
fz_append_display_node(user, node);
}
 
static void
fz_list_begin_group(void *user, fz_rect rect, int isolated, int knockout, int blendmode, float alpha)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_BEGIN_GROUP, fz_identity, NULL, NULL, alpha);
node->rect = rect;
node->item.blendmode = blendmode;
node->flag |= isolated ? ISOLATED : 0;
node->flag |= knockout ? KNOCKOUT : 0;
fz_append_display_node(user, node);
}
 
static void
fz_list_end_group(void *user)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_END_GROUP, fz_identity, NULL, NULL, 0);
fz_append_display_node(user, node);
}
 
static void
fz_list_begin_tile(void *user, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_BEGIN_TILE, ctm, NULL, NULL, 0);
node->rect = area;
node->color[0] = xstep;
node->color[1] = ystep;
node->color[2] = view.x0;
node->color[3] = view.y0;
node->color[4] = view.x1;
node->color[5] = view.y1;
fz_append_display_node(user, node);
}
 
static void
fz_list_end_tile(void *user)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_END_TILE, fz_identity, NULL, NULL, 0);
fz_append_display_node(user, node);
}
 
fz_device *
fz_new_list_device(fz_display_list *list)
{
fz_device *dev = fz_new_device(list);
 
dev->fill_path = fz_list_fill_path;
dev->stroke_path = fz_list_stroke_path;
dev->clip_path = fz_list_clip_path;
dev->clip_stroke_path = fz_list_clip_stroke_path;
 
dev->fill_text = fz_list_fill_text;
dev->stroke_text = fz_list_stroke_text;
dev->clip_text = fz_list_clip_text;
dev->clip_stroke_text = fz_list_clip_stroke_text;
dev->ignore_text = fz_list_ignore_text;
 
dev->fill_shade = fz_list_fill_shade;
dev->fill_image = fz_list_fill_image;
dev->fill_image_mask = fz_list_fill_image_mask;
dev->clip_image_mask = fz_list_clip_image_mask;
 
dev->pop_clip = fz_list_pop_clip;
 
dev->begin_mask = fz_list_begin_mask;
dev->end_mask = fz_list_end_mask;
dev->begin_group = fz_list_begin_group;
dev->end_group = fz_list_end_group;
 
dev->begin_tile = fz_list_begin_tile;
dev->end_tile = fz_list_end_tile;
 
return dev;
}
 
fz_display_list *
fz_new_display_list(void)
{
fz_display_list *list = fz_malloc(sizeof(fz_display_list));
list->first = NULL;
list->last = NULL;
list->top = 0;
list->tiled = 0;
return list;
}
 
void
fz_free_display_list(fz_display_list *list)
{
fz_display_node *node = list->first;
while (node)
{
fz_display_node *next = node->next;
fz_free_display_node(node);
node = next;
}
fz_free(list);
}
 
void
fz_execute_display_list(fz_display_list *list, fz_device *dev, fz_matrix top_ctm, fz_bbox scissor)
{
fz_display_node *node;
fz_matrix ctm;
fz_rect rect;
fz_bbox bbox;
int clipped = 0;
int tiled = 0;
int empty;
 
if (!fz_is_infinite_bbox(scissor))
{
/* add some fuzz at the edges, as especially glyph rects
* are sometimes not actually completely bounding the glyph */
scissor.x0 -= 20; scissor.y0 -= 20;
scissor.x1 += 20; scissor.y1 += 20;
}
 
for (node = list->first; node; node = node->next)
{
/* cull objects to draw using a quick visibility test */
 
if (tiled || node->cmd == FZ_CMD_BEGIN_TILE || node->cmd == FZ_CMD_END_TILE)
{
empty = 0;
}
else
{
bbox = fz_round_rect(fz_transform_rect(top_ctm, node->rect));
bbox = fz_intersect_bbox(bbox, scissor);
empty = fz_is_empty_bbox(bbox);
}
 
if (clipped || empty)
{
switch (node->cmd)
{
case FZ_CMD_CLIP_PATH:
case FZ_CMD_CLIP_STROKE_PATH:
case FZ_CMD_CLIP_TEXT:
case FZ_CMD_CLIP_STROKE_TEXT:
case FZ_CMD_CLIP_IMAGE_MASK:
case FZ_CMD_BEGIN_MASK:
case FZ_CMD_BEGIN_GROUP:
clipped++;
continue;
case FZ_CMD_POP_CLIP:
case FZ_CMD_END_GROUP:
if (!clipped)
goto visible;
clipped--;
continue;
case FZ_CMD_END_MASK:
if (!clipped)
goto visible;
continue;
default:
continue;
}
}
 
visible:
ctm = fz_concat(node->ctm, top_ctm);
 
switch (node->cmd)
{
case FZ_CMD_FILL_PATH:
fz_fill_path(dev, node->item.path, node->flag, ctm,
node->colorspace, node->color, node->alpha);
break;
case FZ_CMD_STROKE_PATH:
fz_stroke_path(dev, node->item.path, node->stroke, ctm,
node->colorspace, node->color, node->alpha);
break;
case FZ_CMD_CLIP_PATH:
{
fz_rect trect = fz_transform_rect(top_ctm, node->rect);
fz_clip_path(dev, node->item.path, &trect, node->flag, ctm);
break;
}
case FZ_CMD_CLIP_STROKE_PATH:
{
fz_rect trect = fz_transform_rect(top_ctm, node->rect);
fz_clip_stroke_path(dev, node->item.path, &trect, node->stroke, ctm);
break;
}
case FZ_CMD_FILL_TEXT:
fz_fill_text(dev, node->item.text, ctm,
node->colorspace, node->color, node->alpha);
break;
case FZ_CMD_STROKE_TEXT:
fz_stroke_text(dev, node->item.text, node->stroke, ctm,
node->colorspace, node->color, node->alpha);
break;
case FZ_CMD_CLIP_TEXT:
fz_clip_text(dev, node->item.text, ctm, node->flag);
break;
case FZ_CMD_CLIP_STROKE_TEXT:
fz_clip_stroke_text(dev, node->item.text, node->stroke, ctm);
break;
case FZ_CMD_IGNORE_TEXT:
fz_ignore_text(dev, node->item.text, ctm);
break;
case FZ_CMD_FILL_SHADE:
fz_fill_shade(dev, node->item.shade, ctm, node->alpha);
break;
case FZ_CMD_FILL_IMAGE:
fz_fill_image(dev, node->item.image, ctm, node->alpha);
break;
case FZ_CMD_FILL_IMAGE_MASK:
fz_fill_image_mask(dev, node->item.image, ctm,
node->colorspace, node->color, node->alpha);
break;
case FZ_CMD_CLIP_IMAGE_MASK:
{
fz_rect trect = fz_transform_rect(top_ctm, node->rect);
fz_clip_image_mask(dev, node->item.image, &trect, ctm);
break;
}
case FZ_CMD_POP_CLIP:
fz_pop_clip(dev);
break;
case FZ_CMD_BEGIN_MASK:
rect = fz_transform_rect(top_ctm, node->rect);
fz_begin_mask(dev, rect, node->flag, node->colorspace, node->color);
break;
case FZ_CMD_END_MASK:
fz_end_mask(dev);
break;
case FZ_CMD_BEGIN_GROUP:
rect = fz_transform_rect(top_ctm, node->rect);
fz_begin_group(dev, rect,
(node->flag & ISOLATED) != 0, (node->flag & KNOCKOUT) != 0,
node->item.blendmode, node->alpha);
break;
case FZ_CMD_END_GROUP:
fz_end_group(dev);
break;
case FZ_CMD_BEGIN_TILE:
tiled++;
rect.x0 = node->color[2];
rect.y0 = node->color[3];
rect.x1 = node->color[4];
rect.y1 = node->color[5];
fz_begin_tile(dev, node->rect, rect,
node->color[0], node->color[1], ctm);
break;
case FZ_CMD_END_TILE:
tiled--;
fz_end_tile(dev);
break;
}
}
}
/contrib/media/updf/fitz/dev_null.c
0,0 → 1,165
#include "fitz.h"
 
fz_device *
fz_new_device(void *user)
{
fz_device *dev = fz_malloc(sizeof(fz_device));
memset(dev, 0, sizeof(fz_device));
dev->hints = 0;
dev->flags = 0;
dev->user = user;
return dev;
}
 
void
fz_free_device(fz_device *dev)
{
if (dev->free_user)
dev->free_user(dev->user);
fz_free(dev);
}
 
void
fz_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
if (dev->fill_path)
dev->fill_path(dev->user, path, even_odd, ctm, colorspace, color, 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)
{
if (dev->stroke_path)
dev->stroke_path(dev->user, path, stroke, ctm, colorspace, color, alpha);
}
 
void
fz_clip_path(fz_device *dev, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm)
{
if (dev->clip_path)
dev->clip_path(dev->user, path, rect, even_odd, ctm);
}
 
void
fz_clip_stroke_path(fz_device *dev, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm)
{
if (dev->clip_stroke_path)
dev->clip_stroke_path(dev->user, path, rect, stroke, ctm);
}
 
void
fz_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
if (dev->fill_text)
dev->fill_text(dev->user, text, ctm, colorspace, color, 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)
{
if (dev->stroke_text)
dev->stroke_text(dev->user, text, stroke, ctm, colorspace, color, alpha);
}
 
void
fz_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate)
{
if (dev->clip_text)
dev->clip_text(dev->user, text, ctm, accumulate);
}
 
void
fz_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm)
{
if (dev->clip_stroke_text)
dev->clip_stroke_text(dev->user, text, stroke, ctm);
}
 
void
fz_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm)
{
if (dev->ignore_text)
dev->ignore_text(dev->user, text, ctm);
}
 
void
fz_pop_clip(fz_device *dev)
{
if (dev->pop_clip)
dev->pop_clip(dev->user);
}
 
void
fz_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha)
{
if (dev->fill_shade)
dev->fill_shade(dev->user, shade, ctm, alpha);
}
 
void
fz_fill_image(fz_device *dev, fz_pixmap *image, fz_matrix ctm, float alpha)
{
if (dev->fill_image)
dev->fill_image(dev->user, image, ctm, alpha);
}
 
void
fz_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
if (dev->fill_image_mask)
dev->fill_image_mask(dev->user, image, ctm, colorspace, color, alpha);
}
 
void
fz_clip_image_mask(fz_device *dev, fz_pixmap *image, fz_rect *rect, fz_matrix ctm)
{
if (dev->clip_image_mask)
dev->clip_image_mask(dev->user, image, rect, ctm);
}
 
void
fz_begin_mask(fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, float *bc)
{
if (dev->begin_mask)
dev->begin_mask(dev->user, area, luminosity, colorspace, bc);
}
 
void
fz_end_mask(fz_device *dev)
{
if (dev->end_mask)
dev->end_mask(dev->user);
}
 
void
fz_begin_group(fz_device *dev, fz_rect area, int isolated, int knockout, int blendmode, float alpha)
{
if (dev->begin_group)
dev->begin_group(dev->user, area, isolated, knockout, blendmode, alpha);
}
 
void
fz_end_group(fz_device *dev)
{
if (dev->end_group)
dev->end_group(dev->user);
}
 
void
fz_begin_tile(fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm)
{
if (dev->begin_tile)
dev->begin_tile(dev->user, area, view, xstep, ystep, ctm);
}
 
void
fz_end_tile(fz_device *dev)
{
if (dev->end_tile)
dev->end_tile(dev->user);
}
/contrib/media/updf/fitz/dev_text.c
0,0 → 1,418
#include "fitz.h"
 
#define LINE_DIST 0.9f
#define SPACE_DIST 0.2f
 
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_ADVANCES_H
 
typedef struct fz_text_device_s fz_text_device;
 
struct fz_text_device_s
{
fz_point point;
fz_text_span *head;
fz_text_span *span;
};
 
fz_text_span *
fz_new_text_span(void)
{
fz_text_span *span;
span = fz_malloc(sizeof(fz_text_span));
span->font = NULL;
span->wmode = 0;
span->size = 0;
span->len = 0;
span->cap = 0;
span->text = NULL;
span->next = NULL;
span->eol = 0;
return span;
}
 
void
fz_free_text_span(fz_text_span *span)
{
if (span->font)
fz_drop_font(span->font);
if (span->next)
fz_free_text_span(span->next);
fz_free(span->text);
fz_free(span);
}
 
static void
fz_add_text_char_imp(fz_text_span *span, int c, fz_bbox bbox)
{
if (span->len + 1 >= span->cap)
{
span->cap = span->cap > 1 ? (span->cap * 3) / 2 : 80;
span->text = fz_realloc(span->text, span->cap, sizeof(fz_text_char));
}
span->text[span->len].c = c;
span->text[span->len].bbox = bbox;
span->len ++;
}
 
static fz_bbox
fz_split_bbox(fz_bbox bbox, int i, int n)
{
float w = (float)(bbox.x1 - bbox.x0) / n;
float x0 = bbox.x0;
bbox.x0 = x0 + i * w;
bbox.x1 = x0 + (i + 1) * w;
return bbox;
}
 
static void
fz_add_text_char(fz_text_span **last, fz_font *font, float size, int wmode, int c, fz_bbox bbox)
{
fz_text_span *span = *last;
 
if (!span->font)
{
span->font = fz_keep_font(font);
span->size = size;
}
 
if ((span->font != font || span->size != size || span->wmode != wmode) && c != 32)
{
span = fz_new_text_span();
span->font = fz_keep_font(font);
span->size = size;
span->wmode = wmode;
(*last)->next = span;
*last = span;
}
 
switch (c)
{
case -1: /* ignore when one unicode character maps to multiple glyphs */
break;
case 0xFB00: /* ff */
fz_add_text_char_imp(span, 'f', fz_split_bbox(bbox, 0, 2));
fz_add_text_char_imp(span, 'f', fz_split_bbox(bbox, 1, 2));
break;
case 0xFB01: /* fi */
fz_add_text_char_imp(span, 'f', fz_split_bbox(bbox, 0, 2));
fz_add_text_char_imp(span, 'i', fz_split_bbox(bbox, 1, 2));
break;
case 0xFB02: /* fl */
fz_add_text_char_imp(span, 'f', fz_split_bbox(bbox, 0, 2));
fz_add_text_char_imp(span, 'l', fz_split_bbox(bbox, 1, 2));
break;
case 0xFB03: /* ffi */
fz_add_text_char_imp(span, 'f', fz_split_bbox(bbox, 0, 3));
fz_add_text_char_imp(span, 'f', fz_split_bbox(bbox, 1, 3));
fz_add_text_char_imp(span, 'i', fz_split_bbox(bbox, 2, 3));
break;
case 0xFB04: /* ffl */
fz_add_text_char_imp(span, 'f', fz_split_bbox(bbox, 0, 3));
fz_add_text_char_imp(span, 'f', fz_split_bbox(bbox, 1, 3));
fz_add_text_char_imp(span, 'l', fz_split_bbox(bbox, 2, 3));
break;
case 0xFB05: /* long st */
case 0xFB06: /* st */
fz_add_text_char_imp(span, 's', fz_split_bbox(bbox, 0, 2));
fz_add_text_char_imp(span, 't', fz_split_bbox(bbox, 1, 2));
break;
default:
fz_add_text_char_imp(span, c, bbox);
break;
}
}
 
static void
fz_divide_text_chars(fz_text_span **last, int n, fz_bbox bbox)
{
fz_text_span *span = *last;
int i, x;
x = span->len - n;
if (x >= 0)
for (i = 0; i < n; i++)
span->text[x + i].bbox = fz_split_bbox(bbox, i, n);
}
 
static void
fz_add_text_newline(fz_text_span **last, fz_font *font, float size, int wmode)
{
fz_text_span *span;
span = fz_new_text_span();
span->font = fz_keep_font(font);
span->size = size;
span->wmode = wmode;
(*last)->eol = 1;
(*last)->next = span;
*last = span;
}
 
void
fz_debug_text_span_xml(fz_text_span *span)
{
char buf[10];
int c, n, k, i;
 
printf("<span font=\"%s\" size=\"%g\" wmode=\"%d\" eol=\"%d\">\n",
span->font ? span->font->name : "NULL", span->size, span->wmode, span->eol);
 
for (i = 0; i < span->len; i++)
{
printf("\t<char ucs=\"");
c = span->text[i].c;
if (c < 128)
putchar(c);
else
{
n = runetochar(buf, &c);
for (k = 0; k < n; k++)
putchar(buf[k]);
}
printf("\" bbox=\"%d %d %d %d\" />\n",
span->text[i].bbox.x0,
span->text[i].bbox.y0,
span->text[i].bbox.x1,
span->text[i].bbox.y1);
}
 
printf("</span>\n");
 
if (span->next)
fz_debug_text_span_xml(span->next);
}
 
void
fz_debug_text_span(fz_text_span *span)
{
char buf[10];
int c, n, k, i;
 
for (i = 0; i < span->len; i++)
{
c = span->text[i].c;
if (c < 128)
putchar(c);
else
{
n = runetochar(buf, &c);
for (k = 0; k < n; k++)
putchar(buf[k]);
}
}
 
if (span->eol)
putchar('\n');
 
if (span->next)
fz_debug_text_span(span->next);
}
 
static void
fz_text_extract_span(fz_text_span **last, fz_text *text, fz_matrix ctm, fz_point *pen)
{
fz_font *font = text->font;
FT_Face face = font->ft_face;
fz_matrix tm = text->trm;
fz_matrix trm;
float size;
float adv;
fz_rect rect;
fz_point dir, ndir;
fz_point delta, ndelta;
float dist, dot;
float ascender = 1;
float descender = 0;
int multi;
int i, err;
 
if (text->len == 0)
return;
 
if (font->ft_face)
{
err = FT_Set_Char_Size(font->ft_face, 64, 64, 72, 72);
if (err)
fz_warn("freetype set character size: %s", ft_error_string(err));
ascender = (float)face->ascender / face->units_per_EM;
descender = (float)face->descender / face->units_per_EM;
}
 
rect = fz_empty_rect;
 
if (text->wmode == 0)
{
dir.x = 1;
dir.y = 0;
}
else
{
dir.x = 0;
dir.y = 1;
}
 
tm.e = 0;
tm.f = 0;
trm = fz_concat(tm, ctm);
dir = fz_transform_vector(trm, dir);
dist = sqrtf(dir.x * dir.x + dir.y * dir.y);
ndir.x = dir.x / dist;
ndir.y = dir.y / dist;
 
size = fz_matrix_expansion(trm);
 
multi = 1;
 
for (i = 0; i < text->len; i++)
{
if (text->items[i].gid < 0)
{
fz_add_text_char(last, font, size, text->wmode, text->items[i].ucs, fz_round_rect(rect));
multi ++;
fz_divide_text_chars(last, multi, fz_round_rect(rect));
continue;
}
multi = 1;
 
/* Calculate new pen location and delta */
tm.e = text->items[i].x;
tm.f = text->items[i].y;
trm = fz_concat(tm, ctm);
 
delta.x = pen->x - trm.e;
delta.y = pen->y - trm.f;
if (pen->x == -1 && pen->y == -1)
delta.x = delta.y = 0;
 
dist = sqrtf(delta.x * delta.x + delta.y * delta.y);
 
/* Add space and newlines based on pen movement */
if (dist > 0)
{
ndelta.x = delta.x / dist;
ndelta.y = delta.y / dist;
dot = ndelta.x * ndir.x + ndelta.y * ndir.y;
 
if (dist > size * LINE_DIST)
{
fz_add_text_newline(last, font, size, text->wmode);
}
else if (fabsf(dot) > 0.95f && dist > size * SPACE_DIST)
{
if ((*last)->len > 0 && (*last)->text[(*last)->len - 1].c != ' ')
{
fz_rect spacerect;
spacerect.x0 = -0.2f;
spacerect.y0 = 0;
spacerect.x1 = 0;
spacerect.y1 = 1;
spacerect = fz_transform_rect(trm, spacerect);
fz_add_text_char(last, font, size, text->wmode, ' ', fz_round_rect(spacerect));
}
}
}
 
/* Calculate bounding box and new pen position based on font metrics */
if (font->ft_face)
{
FT_Fixed ftadv = 0;
int mask = FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING | FT_LOAD_IGNORE_TRANSFORM;
 
/* TODO: freetype returns broken vertical metrics */
/* if (text->wmode) mask |= FT_LOAD_VERTICAL_LAYOUT; */
 
FT_Get_Advance(font->ft_face, text->items[i].gid, mask, &ftadv);
adv = ftadv / 65536.0f;
 
rect.x0 = 0;
rect.y0 = descender;
rect.x1 = adv;
rect.y1 = ascender;
}
else
{
adv = font->t3widths[text->items[i].gid];
rect.x0 = 0;
rect.y0 = descender;
rect.x1 = adv;
rect.y1 = ascender;
}
 
rect = fz_transform_rect(trm, rect);
pen->x = trm.e + dir.x * adv;
pen->y = trm.f + dir.y * adv;
 
fz_add_text_char(last, font, size, text->wmode, text->items[i].ucs, fz_round_rect(rect));
}
}
 
static void
fz_text_fill_text(void *user, fz_text *text, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_text_device *tdev = user;
fz_text_extract_span(&tdev->span, text, ctm, &tdev->point);
}
 
static void
fz_text_stroke_text(void *user, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_text_device *tdev = user;
fz_text_extract_span(&tdev->span, text, ctm, &tdev->point);
}
 
static void
fz_text_clip_text(void *user, fz_text *text, fz_matrix ctm, int accumulate)
{
fz_text_device *tdev = user;
fz_text_extract_span(&tdev->span, text, ctm, &tdev->point);
}
 
static void
fz_text_clip_stroke_text(void *user, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm)
{
fz_text_device *tdev = user;
fz_text_extract_span(&tdev->span, text, ctm, &tdev->point);
}
 
static void
fz_text_ignore_text(void *user, fz_text *text, fz_matrix ctm)
{
fz_text_device *tdev = user;
fz_text_extract_span(&tdev->span, text, ctm, &tdev->point);
}
 
static void
fz_text_free_user(void *user)
{
fz_text_device *tdev = user;
 
tdev->span->eol = 1;
 
/* TODO: unicode NFC normalization */
/* TODO: bidi logical reordering */
 
fz_free(tdev);
}
 
fz_device *
fz_new_text_device(fz_text_span *root)
{
fz_device *dev;
fz_text_device *tdev = fz_malloc(sizeof(fz_text_device));
tdev->head = root;
tdev->span = root;
tdev->point.x = -1;
tdev->point.y = -1;
 
dev = fz_new_device(tdev);
dev->hints = FZ_IGNORE_IMAGE | FZ_IGNORE_SHADE;
dev->free_user = fz_text_free_user;
dev->fill_text = fz_text_fill_text;
dev->stroke_text = fz_text_stroke_text;
dev->clip_text = fz_text_clip_text;
dev->clip_stroke_text = fz_text_clip_stroke_text;
dev->ignore_text = fz_text_ignore_text;
return dev;
}
/contrib/media/updf/fitz/dev_trace.c
0,0 → 1,305
#include "fitz.h"
 
static void
fz_trace_matrix(fz_matrix ctm)
{
printf("matrix=\"%g %g %g %g %g %g\" ",
ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f);
}
 
static void
fz_trace_color(fz_colorspace *colorspace, float *color, float alpha)
{
int i;
printf("colorspace=\"%s\" color=\"", colorspace->name);
for (i = 0; i < colorspace->n; i++)
printf("%s%g", i == 0 ? "" : " ", color[i]);
printf("\" ");
if (alpha < 1)
printf("alpha=\"%g\" ", alpha);
}
 
static void
fz_trace_path(fz_path *path, int indent)
{
float x, y;
int i = 0;
int n;
while (i < path->len)
{
for (n = 0; n < indent; n++)
putchar(' ');
switch (path->items[i++].k)
{
case FZ_MOVETO:
x = path->items[i++].v;
y = path->items[i++].v;
printf("<moveto x=\"%g\" y=\"%g\" />\n", x, y);
break;
case FZ_LINETO:
x = path->items[i++].v;
y = path->items[i++].v;
printf("<lineto x=\"%g\" y=\"%g\" />\n", x, y);
break;
case FZ_CURVETO:
x = path->items[i++].v;
y = path->items[i++].v;
printf("<curveto x1=\"%g\" y1=\"%g\" ", x, y);
x = path->items[i++].v;
y = path->items[i++].v;
printf("x2=\"%g\" y2=\"%g\" ", x, y);
x = path->items[i++].v;
y = path->items[i++].v;
printf("x3=\"%g\" y3=\"%g\" />\n", x, y);
break;
case FZ_CLOSE_PATH:
printf("<closepath />\n");
break;
}
}
}
 
static void
fz_trace_fill_path(void *user, fz_path *path, int even_odd, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
printf("<fill_path ");
if (even_odd)
printf("winding=\"eofill\" ");
else
printf("winding=\"nonzero\" ");
fz_trace_color(colorspace, color, alpha);
fz_trace_matrix(ctm);
printf(">\n");
fz_trace_path(path, 0);
printf("</fill_path>\n");
}
 
static void
fz_trace_stroke_path(void *user, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
int i;
 
printf("<stroke_path ");
printf("linewidth=\"%g\" ", stroke->linewidth);
printf("miterlimit=\"%g\" ", stroke->miterlimit);
printf("linecap=\"%d,%d,%d\" ", stroke->start_cap, stroke->dash_cap, stroke->end_cap);
printf("linejoin=\"%d\" ", stroke->linejoin);
 
if (stroke->dash_len)
{
printf("dash_phase=\"%g\" dash=\"", stroke->dash_phase);
for (i = 0; i < stroke->dash_len; i++)
printf("%g ", stroke->dash_list[i]);
printf("\"");
}
 
fz_trace_color(colorspace, color, alpha);
fz_trace_matrix(ctm);
printf(">\n");
 
fz_trace_path(path, 0);
 
printf("</stroke_path>\n");
}
 
static void
fz_trace_clip_path(void *user, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm)
{
printf("<clip_path ");
if (even_odd)
printf("winding=\"eofill\" ");
else
printf("winding=\"nonzero\" ");
fz_trace_matrix(ctm);
printf("contentbbox=\"%g %g %g %g\">\n",
rect->x0, rect->y0, rect->x1, rect->y1);
fz_trace_path(path, 0);
printf("</clip_path>\n");
}
 
static void
fz_trace_clip_stroke_path(void *user, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm)
{
printf("<clip_stroke_path ");
fz_trace_matrix(ctm);
printf(">\n");
fz_trace_path(path, 0);
printf("</clip_stroke_path>\n");
}
 
static void
fz_trace_fill_text(void *user, fz_text *text, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
printf("<fill_text font=\"%s\" wmode=\"%d\" ", text->font->name, text->wmode);
fz_trace_color(colorspace, color, alpha);
fz_trace_matrix(fz_concat(ctm, text->trm));
printf(">\n");
fz_debug_text(text, 0);
printf("</fill_text>\n");
}
 
static void
fz_trace_stroke_text(void *user, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
printf("<stroke_text font=\"%s\" wmode=\"%d\" ", text->font->name, text->wmode);
fz_trace_color(colorspace, color, alpha);
fz_trace_matrix(fz_concat(ctm, text->trm));
printf(">\n");
fz_debug_text(text, 0);
printf("</stroke_text>\n");
}
 
static void
fz_trace_clip_text(void *user, fz_text *text, fz_matrix ctm, int accumulate)
{
printf("<clip_text font=\"%s\" wmode=\"%d\" ", text->font->name, text->wmode);
printf("accumulate=\"%d\" ", accumulate);
fz_trace_matrix(fz_concat(ctm, text->trm));
printf(">\n");
fz_debug_text(text, 0);
printf("</clip_text>\n");
}
 
static void
fz_trace_clip_stroke_text(void *user, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm)
{
printf("<clip_stroke_text font=\"%s\" wmode=\"%d\" ", text->font->name, text->wmode);
fz_trace_matrix(fz_concat(ctm, text->trm));
printf(">\n");
fz_debug_text(text, 0);
printf("</clip_stroke_text>\n");
}
 
static void
fz_trace_ignore_text(void *user, fz_text *text, fz_matrix ctm)
{
printf("<ignore_text font=\"%s\" wmode=\"%d\" ", text->font->name, text->wmode);
fz_trace_matrix(fz_concat(ctm, text->trm));
printf(">\n");
fz_debug_text(text, 0);
printf("</ignore_text>\n");
}
 
static void
fz_trace_fill_image(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
{
printf("<fill_image alpha=\"%g\" ", alpha);
fz_trace_matrix(ctm);
printf("/>\n");
}
 
static void
fz_trace_fill_shade(void *user, fz_shade *shade, fz_matrix ctm, float alpha)
{
printf("<fill_shade alpha=\"%g\" ", alpha);
fz_trace_matrix(ctm);
printf("/>\n");
}
 
static void
fz_trace_fill_image_mask(void *user, fz_pixmap *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
printf("<fill_image_mask ");
fz_trace_matrix(ctm);
fz_trace_color(colorspace, color, alpha);
printf("/>\n");
}
 
static void
fz_trace_clip_image_mask(void *user, fz_pixmap *image, fz_rect *rect, fz_matrix ctm)
{
printf("<clip_image_mask ");
fz_trace_matrix(ctm);
printf("/>\n");
}
 
static void
fz_trace_pop_clip(void *user)
{
printf("<pop_clip />\n");
}
 
static void
fz_trace_begin_mask(void *user, fz_rect bbox, int luminosity, fz_colorspace *colorspace, float *color)
{
printf("<mask bbox=\"%g %g %g %g\" s=\"%s\" ",
bbox.x0, bbox.y0, bbox.x1, bbox.y1,
luminosity ? "luminosity" : "alpha");
// fz_trace_color(colorspace, color, 1);
printf(">\n");
}
 
static void
fz_trace_end_mask(void *user)
{
printf("</mask>\n");
}
 
static void
fz_trace_begin_group(void *user, fz_rect bbox, int isolated, int knockout, int blendmode, float alpha)
{
printf("<group bbox=\"%g %g %g %g\" isolated=\"%d\" knockout=\"%d\" blendmode=\"%s\" alpha=\"%g\">\n",
bbox.x0, bbox.y0, bbox.x1, bbox.y1,
isolated, knockout, fz_blendmode_name(blendmode), alpha);
}
 
static void
fz_trace_end_group(void *user)
{
printf("</group>\n");
}
 
static void
fz_trace_begin_tile(void *user, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm)
{
printf("<tile ");
printf("area=\"%g %g %g %g\" ", area.x0, area.y0, area.x1, area.y1);
printf("view=\"%g %g %g %g\" ", view.x0, view.y0, view.x1, view.y1);
printf("xstep=\"%g\" ystep=\"%g\" ", xstep, ystep);
fz_trace_matrix(ctm);
printf(">\n");
}
 
static void
fz_trace_end_tile(void *user)
{
printf("</tile>\n");
}
 
fz_device *fz_new_trace_device(void)
{
fz_device *dev = fz_new_device(NULL);
 
dev->fill_path = fz_trace_fill_path;
dev->stroke_path = fz_trace_stroke_path;
dev->clip_path = fz_trace_clip_path;
dev->clip_stroke_path = fz_trace_clip_stroke_path;
 
dev->fill_text = fz_trace_fill_text;
dev->stroke_text = fz_trace_stroke_text;
dev->clip_text = fz_trace_clip_text;
dev->clip_stroke_text = fz_trace_clip_stroke_text;
dev->ignore_text = fz_trace_ignore_text;
 
dev->fill_shade = fz_trace_fill_shade;
dev->fill_image = fz_trace_fill_image;
dev->fill_image_mask = fz_trace_fill_image_mask;
dev->clip_image_mask = fz_trace_clip_image_mask;
 
dev->pop_clip = fz_trace_pop_clip;
 
dev->begin_mask = fz_trace_begin_mask;
dev->end_mask = fz_trace_end_mask;
dev->begin_group = fz_trace_begin_group;
dev->end_group = fz_trace_end_group;
 
dev->begin_tile = fz_trace_begin_tile;
dev->end_tile = fz_trace_end_tile;
 
return dev;
}
/contrib/media/updf/fitz/filt_basic.c
0,0 → 1,504
#include "fitz.h"
 
/* Pretend we have a filter that just copies data forever */
 
fz_stream *
fz_open_copy(fz_stream *chain)
{
return fz_keep_stream(chain);
}
 
/* Null filter copies a specified amount of data */
 
struct null_filter
{
fz_stream *chain;
int remain;
};
 
static int
read_null(fz_stream *stm, unsigned char *buf, int len)
{
struct null_filter *state = stm->state;
int amount = MIN(len, state->remain);
int n = fz_read(state->chain, buf, amount);
if (n < 0)
return fz_rethrow(n, "read error in null filter");
state->remain -= n;
return n;
}
 
static void
close_null(fz_stream *stm)
{
struct null_filter *state = stm->state;
fz_close(state->chain);
fz_free(state);
}
 
fz_stream *
fz_open_null(fz_stream *chain, int len)
{
struct null_filter *state;
 
state = fz_malloc(sizeof(struct null_filter));
state->chain = chain;
state->remain = len;
 
return fz_new_stream(state, read_null, close_null);
}
 
/* ASCII Hex Decode */
 
typedef struct fz_ahxd_s fz_ahxd;
 
struct fz_ahxd_s
{
fz_stream *chain;
int eod;
};
 
static inline int iswhite(int a)
{
switch (a) {
case '\n': case '\r': case '\t': case ' ':
case '\0': case '\f': case '\b': case 0177:
return 1;
}
return 0;
}
 
static inline int ishex(int a)
{
return (a >= 'A' && a <= 'F') ||
(a >= 'a' && a <= 'f') ||
(a >= '0' && a <= '9');
}
 
static inline int unhex(int a)
{
if (a >= 'A' && a <= 'F') return a - 'A' + 0xA;
if (a >= 'a' && a <= 'f') return a - 'a' + 0xA;
if (a >= '0' && a <= '9') return a - '0';
return 0;
}
 
static int
read_ahxd(fz_stream *stm, unsigned char *buf, int len)
{
fz_ahxd *state = stm->state;
unsigned char *p = buf;
unsigned char *ep = buf + len;
int a, b, c, odd;
 
odd = 0;
 
while (p < ep)
{
if (state->eod)
return p - buf;
 
c = fz_read_byte(state->chain);
if (c < 0)
return p - buf;
 
if (ishex(c))
{
if (!odd)
{
a = unhex(c);
odd = 1;
}
else
{
b = unhex(c);
*p++ = (a << 4) | b;
odd = 0;
}
}
else if (c == '>')
{
if (odd)
*p++ = (a << 4);
state->eod = 1;
}
else if (!iswhite(c))
{
return fz_throw("bad data in ahxd: '%c'", c);
}
}
 
return p - buf;
}
 
static void
close_ahxd(fz_stream *stm)
{
fz_ahxd *state = stm->state;
fz_close(state->chain);
fz_free(state);
}
 
fz_stream *
fz_open_ahxd(fz_stream *chain)
{
fz_ahxd *state;
 
state = fz_malloc(sizeof(fz_ahxd));
state->chain = chain;
state->eod = 0;
 
return fz_new_stream(state, read_ahxd, close_ahxd);
}
 
/* ASCII 85 Decode */
 
typedef struct fz_a85d_s fz_a85d;
 
struct fz_a85d_s
{
fz_stream *chain;
unsigned char bp[4];
unsigned char *rp, *wp;
int eod;
};
 
static int
read_a85d(fz_stream *stm, unsigned char *buf, int len)
{
fz_a85d *state = stm->state;
unsigned char *p = buf;
unsigned char *ep = buf + len;
int count = 0;
int word = 0;
int c;
 
while (state->rp < state->wp && p < ep)
*p++ = *state->rp++;
 
while (p < ep)
{
if (state->eod)
return p - buf;
 
c = fz_read_byte(state->chain);
if (c < 0)
return p - buf;
 
if (c >= '!' && c <= 'u')
{
if (count == 4)
{
word = word * 85 + (c - '!');
 
state->bp[0] = (word >> 24) & 0xff;
state->bp[1] = (word >> 16) & 0xff;
state->bp[2] = (word >> 8) & 0xff;
state->bp[3] = (word) & 0xff;
state->rp = state->bp;
state->wp = state->bp + 4;
 
word = 0;
count = 0;
}
else
{
word = word * 85 + (c - '!');
count ++;
}
}
 
else if (c == 'z' && count == 0)
{
state->bp[0] = 0;
state->bp[1] = 0;
state->bp[2] = 0;
state->bp[3] = 0;
state->rp = state->bp;
state->wp = state->bp + 4;
}
 
else if (c == '~')
{
c = fz_read_byte(state->chain);
if (c != '>')
fz_warn("bad eod marker in a85d");
 
switch (count) {
case 0:
break;
case 1:
return fz_throw("partial final byte in a85d");
case 2:
word = word * (85 * 85 * 85) + 0xffffff;
state->bp[0] = word >> 24;
state->rp = state->bp;
state->wp = state->bp + 1;
break;
case 3:
word = word * (85 * 85) + 0xffff;
state->bp[0] = word >> 24;
state->bp[1] = word >> 16;
state->rp = state->bp;
state->wp = state->bp + 2;
break;
case 4:
word = word * 85 + 0xff;
state->bp[0] = word >> 24;
state->bp[1] = word >> 16;
state->bp[2] = word >> 8;
state->rp = state->bp;
state->wp = state->bp + 3;
break;
}
state->eod = 1;
}
 
else if (!iswhite(c))
{
return fz_throw("bad data in a85d: '%c'", c);
}
 
while (state->rp < state->wp && p < ep)
*p++ = *state->rp++;
}
 
return p - buf;
}
 
static void
close_a85d(fz_stream *stm)
{
fz_a85d *state = stm->state;
fz_close(state->chain);
fz_free(state);
}
 
fz_stream *
fz_open_a85d(fz_stream *chain)
{
fz_a85d *state;
 
state = fz_malloc(sizeof(fz_a85d));
state->chain = chain;
state->rp = state->bp;
state->wp = state->bp;
state->eod = 0;
 
return fz_new_stream(state, read_a85d, close_a85d);
}
 
/* Run Length Decode */
 
typedef struct fz_rld_s fz_rld;
 
struct fz_rld_s
{
fz_stream *chain;
int run, n, c;
};
 
static int
read_rld(fz_stream *stm, unsigned char *buf, int len)
{
fz_rld *state = stm->state;
unsigned char *p = buf;
unsigned char *ep = buf + len;
 
while (p < ep)
{
if (state->run == 128)
return p - buf;
 
if (state->n == 0)
{
state->run = fz_read_byte(state->chain);
if (state->run < 0)
state->run = 128;
if (state->run < 128)
state->n = state->run + 1;
if (state->run > 128)
{
state->n = 257 - state->run;
state->c = fz_read_byte(state->chain);
if (state->c < 0)
return fz_throw("premature end of data in run length decode");
}
}
 
if (state->run < 128)
{
while (p < ep && state->n)
{
int c = fz_read_byte(state->chain);
if (c < 0)
return fz_throw("premature end of data in run length decode");
*p++ = c;
state->n--;
}
}
 
if (state->run > 128)
{
while (p < ep && state->n)
{
*p++ = state->c;
state->n--;
}
}
}
 
return p - buf;
}
 
static void
close_rld(fz_stream *stm)
{
fz_rld *state = stm->state;
fz_close(state->chain);
fz_free(state);
}
 
fz_stream *
fz_open_rld(fz_stream *chain)
{
fz_rld *state;
 
state = fz_malloc(sizeof(fz_rld));
state->chain = chain;
state->run = 0;
state->n = 0;
state->c = 0;
 
return fz_new_stream(state, read_rld, close_rld);
}
 
/* RC4 Filter */
 
typedef struct fz_arc4c_s fz_arc4c;
 
struct fz_arc4c_s
{
fz_stream *chain;
fz_arc4 arc4;
};
 
static int
read_arc4(fz_stream *stm, unsigned char *buf, int len)
{
fz_arc4c *state = stm->state;
int n;
 
n = fz_read(state->chain, buf, len);
if (n < 0)
return fz_rethrow(n, "read error in arc4 filter");
 
fz_arc4_encrypt(&state->arc4, buf, buf, n);
 
return n;
}
 
static void
close_arc4(fz_stream *stm)
{
fz_arc4c *state = stm->state;
fz_close(state->chain);
fz_free(state);
}
 
fz_stream *
fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen)
{
fz_arc4c *state;
 
state = fz_malloc(sizeof(fz_arc4c));
state->chain = chain;
fz_arc4_init(&state->arc4, key, keylen);
 
return fz_new_stream(state, read_arc4, close_arc4);
}
 
/* AES Filter */
 
typedef struct fz_aesd_s fz_aesd;
 
struct fz_aesd_s
{
fz_stream *chain;
fz_aes aes;
unsigned char iv[16];
int ivcount;
unsigned char bp[16];
unsigned char *rp, *wp;
};
 
static int
read_aesd(fz_stream *stm, unsigned char *buf, int len)
{
fz_aesd *state = stm->state;
unsigned char *p = buf;
unsigned char *ep = buf + len;
 
while (state->ivcount < 16)
{
int c = fz_read_byte(state->chain);
if (c < 0)
return fz_throw("premature end in aes filter");
state->iv[state->ivcount++] = c;
}
 
while (state->rp < state->wp && p < ep)
*p++ = *state->rp++;
 
while (p < ep)
{
int n = fz_read(state->chain, state->bp, 16);
if (n < 0)
return fz_rethrow(n, "read error in aes filter");
else if (n == 0)
return p - buf;
else if (n < 16)
return fz_throw("partial block in aes filter");
 
aes_crypt_cbc(&state->aes, AES_DECRYPT, 16, state->iv, state->bp, state->bp);
state->rp = state->bp;
state->wp = state->bp + 16;
 
/* strip padding at end of file */
if (fz_is_eof(state->chain))
{
int pad = state->bp[15];
if (pad < 1 || pad > 16)
return fz_throw("aes padding out of range: %d", pad);
state->wp -= pad;
}
 
while (state->rp < state->wp && p < ep)
*p++ = *state->rp++;
}
 
return p - buf;
}
 
static void
close_aesd(fz_stream *stm)
{
fz_aesd *state = stm->state;
fz_close(state->chain);
fz_free(state);
}
 
fz_stream *
fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen)
{
fz_aesd *state;
 
state = fz_malloc(sizeof(fz_aesd));
state->chain = chain;
aes_setkey_dec(&state->aes, key, keylen * 8);
state->ivcount = 0;
state->rp = state->bp;
state->wp = state->bp;
 
return fz_new_stream(state, read_aesd, close_aesd);
}
/contrib/media/updf/fitz/filt_dctd.c
0,0 → 1,221
#include "fitz.h"
 
#include <jpeglib.h>
#include <setjmp.h>
 
typedef struct fz_dctd_s fz_dctd;
 
struct fz_dctd_s
{
fz_stream *chain;
int color_transform;
int init;
int stride;
unsigned char *scanline;
unsigned char *rp, *wp;
struct jpeg_decompress_struct cinfo;
struct jpeg_source_mgr srcmgr;
struct jpeg_error_mgr errmgr;
jmp_buf jb;
char msg[JMSG_LENGTH_MAX];
};
 
static void error_exit(j_common_ptr cinfo)
{
fz_dctd *state = cinfo->client_data;
cinfo->err->format_message(cinfo, state->msg);
longjmp(state->jb, 1);
}
 
static void init_source(j_decompress_ptr cinfo)
{
/* nothing to do */
}
 
static void term_source(j_decompress_ptr cinfo)
{
/* nothing to do */
}
 
static boolean fill_input_buffer(j_decompress_ptr cinfo)
{
struct jpeg_source_mgr *src = cinfo->src;
fz_dctd *state = cinfo->client_data;
fz_stream *chain = state->chain;
 
chain->rp = chain->wp;
fz_fill_buffer(chain);
src->next_input_byte = chain->rp;
src->bytes_in_buffer = chain->wp - chain->rp;
 
if (src->bytes_in_buffer == 0)
{
static unsigned char eoi[2] = { 0xFF, JPEG_EOI };
fz_warn("premature end of file in jpeg");
src->next_input_byte = eoi;
src->bytes_in_buffer = 2;
}
 
return 1;
}
 
static void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
struct jpeg_source_mgr *src = cinfo->src;
if (num_bytes > 0)
{
while ((size_t)num_bytes > src->bytes_in_buffer)
{
num_bytes -= src->bytes_in_buffer;
(void) src->fill_input_buffer(cinfo);
}
src->next_input_byte += num_bytes;
src->bytes_in_buffer -= num_bytes;
}
}
 
static int
read_dctd(fz_stream *stm, unsigned char *buf, int len)
{
fz_dctd *state = stm->state;
j_decompress_ptr cinfo = &state->cinfo;
unsigned char *p = buf;
unsigned char *ep = buf + len;
 
if (setjmp(state->jb))
{
if (cinfo->src)
state->chain->rp = state->chain->wp - cinfo->src->bytes_in_buffer;
return fz_throw("jpeg error: %s", state->msg);
}
 
if (!state->init)
{
cinfo->client_data = state;
cinfo->err = &state->errmgr;
jpeg_std_error(cinfo->err);
cinfo->err->error_exit = error_exit;
jpeg_create_decompress(cinfo);
 
cinfo->src = &state->srcmgr;
cinfo->src->init_source = init_source;
cinfo->src->fill_input_buffer = fill_input_buffer;
cinfo->src->skip_input_data = skip_input_data;
cinfo->src->resync_to_restart = jpeg_resync_to_restart;
cinfo->src->term_source = term_source;
cinfo->src->next_input_byte = state->chain->rp;
cinfo->src->bytes_in_buffer = state->chain->wp - state->chain->rp;
 
jpeg_read_header(cinfo, 1);
 
/* speed up jpeg decoding a bit */
cinfo->dct_method = JDCT_FASTEST;
cinfo->do_fancy_upsampling = FALSE;
 
/* default value if ColorTransform is not set */
if (state->color_transform == -1)
{
if (state->cinfo.num_components == 3)
state->color_transform = 1;
else
state->color_transform = 0;
}
 
if (cinfo->saw_Adobe_marker)
state->color_transform = cinfo->Adobe_transform;
 
/* Guess the input colorspace, and set output colorspace accordingly */
switch (cinfo->num_components)
{
case 3:
if (state->color_transform)
cinfo->jpeg_color_space = JCS_YCbCr;
else
cinfo->jpeg_color_space = JCS_RGB;
break;
case 4:
if (state->color_transform)
cinfo->jpeg_color_space = JCS_YCCK;
else
cinfo->jpeg_color_space = JCS_CMYK;
break;
}
 
jpeg_start_decompress(cinfo);
 
state->stride = cinfo->output_width * cinfo->output_components;
state->scanline = fz_malloc(state->stride);
state->rp = state->scanline;
state->wp = state->scanline;
 
state->init = 1;
}
 
while (state->rp < state->wp && p < ep)
*p++ = *state->rp++;
 
while (p < ep)
{
if (cinfo->output_scanline == cinfo->output_height)
break;
 
if (p + state->stride <= ep)
{
jpeg_read_scanlines(cinfo, &p, 1);
p += state->stride;
}
else
{
jpeg_read_scanlines(cinfo, &state->scanline, 1);
state->rp = state->scanline;
state->wp = state->scanline + state->stride;
}
 
while (state->rp < state->wp && p < ep)
*p++ = *state->rp++;
}
 
return p - buf;
}
 
static void
close_dctd(fz_stream *stm)
{
fz_dctd *state = stm->state;
 
if (setjmp(state->jb))
{
state->chain->rp = state->chain->wp - state->cinfo.src->bytes_in_buffer;
fz_warn("jpeg error: %s", state->msg);
goto skip;
}
 
if (state->init)
jpeg_finish_decompress(&state->cinfo);
 
skip:
state->chain->rp = state->chain->wp - state->cinfo.src->bytes_in_buffer;
jpeg_destroy_decompress(&state->cinfo);
fz_free(state->scanline);
fz_close(state->chain);
fz_free(state);
}
 
fz_stream *
fz_open_dctd(fz_stream *chain, fz_obj *params)
{
fz_dctd *state;
fz_obj *obj;
 
state = fz_malloc(sizeof(fz_dctd));
memset(state, 0, sizeof(fz_dctd));
state->chain = chain;
state->color_transform = -1; /* unset */
state->init = 0;
 
obj = fz_dict_gets(params, "ColorTransform");
if (obj)
state->color_transform = fz_to_int(obj);
 
return fz_new_stream(state, read_dctd, close_dctd);
}
/contrib/media/updf/fitz/filt_faxd.c
0,0 → 1,731
#include "fitz.h"
 
/* Fax G3/G4 decoder */
 
/* TODO: uncompressed */
 
/*
<raph> the first 2^(initialbits) entries map bit patterns to decodes
<raph> let's say initial_bits is 8 for the sake of example
<raph> and that the code is 1001
<raph> that means that entries 0x90 .. 0x9f have the entry { val, 4 }
<raph> because those are all the bytes that start with the code
<raph> and the 4 is the length of the code
... if (n_bits > initial_bits) ...
<raph> anyway, in that case, it basically points to a mini table
<raph> the n_bits is the maximum length of all codes beginning with that byte
<raph> so 2^(n_bits - initial_bits) is the size of the mini-table
<raph> peter came up with this, and it makes sense
*/
 
typedef struct cfd_node_s cfd_node;
 
struct cfd_node_s
{
short val;
short nbits;
};
 
enum
{
cfd_white_initial_bits = 8,
cfd_black_initial_bits = 7,
cfd_2d_initial_bits = 7,
cfd_uncompressed_initial_bits = 6 /* must be 6 */
};
 
/* non-run codes in tables */
enum
{
ERROR = -1,
ZEROS = -2, /* EOL follows, possibly with more padding first */
UNCOMPRESSED = -3
};
 
/* semantic codes for cf_2d_decode */
enum
{
P = -4,
H = -5,
VR3 = 0,
VR2 = 1,
VR1 = 2,
V0 = 3,
VL1 = 4,
VL2 = 5,
VL3 = 6
};
 
/* White decoding table. */
const cfd_node cf_white_decode[] = {
{256,12},{272,12},{29,8},{30,8},{45,8},{46,8},{22,7},{22,7},
{23,7},{23,7},{47,8},{48,8},{13,6},{13,6},{13,6},{13,6},{20,7},
{20,7},{33,8},{34,8},{35,8},{36,8},{37,8},{38,8},{19,7},{19,7},
{31,8},{32,8},{1,6},{1,6},{1,6},{1,6},{12,6},{12,6},{12,6},{12,6},
{53,8},{54,8},{26,7},{26,7},{39,8},{40,8},{41,8},{42,8},{43,8},
{44,8},{21,7},{21,7},{28,7},{28,7},{61,8},{62,8},{63,8},{0,8},
{320,8},{384,8},{10,5},{10,5},{10,5},{10,5},{10,5},{10,5},{10,5},
{10,5},{11,5},{11,5},{11,5},{11,5},{11,5},{11,5},{11,5},{11,5},
{27,7},{27,7},{59,8},{60,8},{288,9},{290,9},{18,7},{18,7},{24,7},
{24,7},{49,8},{50,8},{51,8},{52,8},{25,7},{25,7},{55,8},{56,8},
{57,8},{58,8},{192,6},{192,6},{192,6},{192,6},{1664,6},{1664,6},
{1664,6},{1664,6},{448,8},{512,8},{292,9},{640,8},{576,8},{294,9},
{296,9},{298,9},{300,9},{302,9},{256,7},{256,7},{2,4},{2,4},{2,4},
{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},
{2,4},{2,4},{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},
{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},{128,5},{128,5},{128,5},
{128,5},{128,5},{128,5},{128,5},{128,5},{8,5},{8,5},{8,5},{8,5},
{8,5},{8,5},{8,5},{8,5},{9,5},{9,5},{9,5},{9,5},{9,5},{9,5},{9,5},
{9,5},{16,6},{16,6},{16,6},{16,6},{17,6},{17,6},{17,6},{17,6},
{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},
{4,4},{4,4},{4,4},{4,4},{4,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
{14,6},{14,6},{14,6},{14,6},{15,6},{15,6},{15,6},{15,6},{64,5},
{64,5},{64,5},{64,5},{64,5},{64,5},{64,5},{64,5},{6,4},{6,4},
{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},
{6,4},{6,4},{6,4},{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},
{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},{-2,3},{-2,3},
{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},
{-1,0},{-1,0},{-1,0},{-1,0},{-3,4},{1792,3},{1792,3},{1984,4},
{2048,4},{2112,4},{2176,4},{2240,4},{2304,4},{1856,3},{1856,3},
{1920,3},{1920,3},{2368,4},{2432,4},{2496,4},{2560,4},{1472,1},
{1536,1},{1600,1},{1728,1},{704,1},{768,1},{832,1},{896,1},
{960,1},{1024,1},{1088,1},{1152,1},{1216,1},{1280,1},{1344,1},
{1408,1}
};
 
/* Black decoding table. */
const cfd_node cf_black_decode[] = {
{128,12},{160,13},{224,12},{256,12},{10,7},{11,7},{288,12},{12,7},
{9,6},{9,6},{8,6},{8,6},{7,5},{7,5},{7,5},{7,5},{6,4},{6,4},{6,4},
{6,4},{6,4},{6,4},{6,4},{6,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
{5,4},{5,4},{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},
{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},{4,3},{4,3},{4,3},{4,3},
{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},
{4,3},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},
{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},
{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},
{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
{-2,4},{-2,4},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},
{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-3,5},{1792,4},
{1792,4},{1984,5},{2048,5},{2112,5},{2176,5},{2240,5},{2304,5},
{1856,4},{1856,4},{1920,4},{1920,4},{2368,5},{2432,5},{2496,5},
{2560,5},{18,3},{18,3},{18,3},{18,3},{18,3},{18,3},{18,3},{18,3},
{52,5},{52,5},{640,6},{704,6},{768,6},{832,6},{55,5},{55,5},
{56,5},{56,5},{1280,6},{1344,6},{1408,6},{1472,6},{59,5},{59,5},
{60,5},{60,5},{1536,6},{1600,6},{24,4},{24,4},{24,4},{24,4},
{25,4},{25,4},{25,4},{25,4},{1664,6},{1728,6},{320,5},{320,5},
{384,5},{384,5},{448,5},{448,5},{512,6},{576,6},{53,5},{53,5},
{54,5},{54,5},{896,6},{960,6},{1024,6},{1088,6},{1152,6},{1216,6},
{64,3},{64,3},{64,3},{64,3},{64,3},{64,3},{64,3},{64,3},{13,1},
{13,1},{13,1},{13,1},{13,1},{13,1},{13,1},{13,1},{13,1},{13,1},
{13,1},{13,1},{13,1},{13,1},{13,1},{13,1},{23,4},{23,4},{50,5},
{51,5},{44,5},{45,5},{46,5},{47,5},{57,5},{58,5},{61,5},{256,5},
{16,3},{16,3},{16,3},{16,3},{17,3},{17,3},{17,3},{17,3},{48,5},
{49,5},{62,5},{63,5},{30,5},{31,5},{32,5},{33,5},{40,5},{41,5},
{22,4},{22,4},{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},
{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},
{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{128,5},
{192,5},{26,5},{27,5},{28,5},{29,5},{19,4},{19,4},{20,4},{20,4},
{34,5},{35,5},{36,5},{37,5},{38,5},{39,5},{21,4},{21,4},{42,5},
{43,5},{0,3},{0,3},{0,3},{0,3}
};
 
/* 2-D decoding table. */
const cfd_node cf_2d_decode[] = {
{128,11},{144,10},{6,7},{0,7},{5,6},{5,6},{1,6},{1,6},{-4,4},
{-4,4},{-4,4},{-4,4},{-4,4},{-4,4},{-4,4},{-4,4},{-5,3},{-5,3},
{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},
{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},{4,3},{4,3},{4,3},{4,3},{4,3},
{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},
{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},
{2,3},{2,3},{2,3},{2,3},{2,3},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
{3,1},{3,1},{3,1},{-2,4},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},
{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},
{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-3,3}
};
 
/* Uncompresssed decoding table. */
const cfd_node cf_uncompressed_decode[] = {
{64,12},{5,6},{4,5},{4,5},{3,4},{3,4},{3,4},{3,4},{2,3},{2,3},
{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{1,2},{1,2},{1,2},{1,2},{1,2},
{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},
{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},
{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},
{-1,0},{-1,0},{8,6},{9,6},{6,5},{6,5},{7,5},{7,5},{4,4},{4,4},
{4,4},{4,4},{5,4},{5,4},{5,4},{5,4},{2,3},{2,3},{2,3},{2,3},{2,3},
{2,3},{2,3},{2,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
{0,2},{0,2},{0,2},{0,2},{0,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}
};
 
/* bit magic */
 
static inline int getbit(const unsigned char *buf, int x)
{
return ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1;
}
 
static int
find_changing(const unsigned char *line, int x, int w)
{
int a, b;
 
if (!line)
return w;
 
if (x == -1)
{
a = 0;
x = 0;
}
else
{
a = getbit(line, x);
x++;
}
 
while (x < w)
{
b = getbit(line, x);
if (a != b)
break;
x++;
}
 
return x;
}
 
static int
find_changing_color(const unsigned char *line, int x, int w, int color)
{
if (!line)
return w;
 
x = find_changing(line, x, w);
 
if (x < w && getbit(line, x) != color)
x = find_changing(line, x, w);
 
return x;
}
 
static const unsigned char lm[8] = {
0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01
};
 
static const unsigned char rm[8] = {
0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE
};
 
static inline void setbits(unsigned char *line, int x0, int x1)
{
int a0, a1, b0, b1, a;
 
a0 = x0 >> 3;
a1 = x1 >> 3;
 
b0 = x0 & 7;
b1 = x1 & 7;
 
if (a0 == a1)
{
if (b1)
line[a0] |= lm[b0] & rm[b1];
}
else
{
line[a0] |= lm[b0];
for (a = a0 + 1; a < a1; a++)
line[a] = 0xFF;
if (b1)
line[a1] |= rm[b1];
}
}
 
typedef struct fz_faxd_s fz_faxd;
 
enum
{
STATE_NORMAL, /* neutral state, waiting for any code */
STATE_MAKEUP, /* got a 1d makeup code, waiting for terminating code */
STATE_EOL, /* at eol, needs output buffer space */
STATE_H1, STATE_H2, /* in H part 1 and 2 (both makeup and terminating codes) */
STATE_DONE /* all done */
};
 
struct fz_faxd_s
{
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;
 
int stride;
int ridx;
 
int bidx;
unsigned int word;
 
int stage;
 
int a, c, dim, eolc;
unsigned char *ref;
unsigned char *dst;
unsigned char *rp, *wp;
};
 
static inline void eat_bits(fz_faxd *fax, int nbits)
{
fax->word <<= nbits;
fax->bidx += nbits;
}
 
static int
fill_bits(fz_faxd *fax)
{
while (fax->bidx >= 8)
{
int c = fz_read_byte(fax->chain);
if (c == EOF)
return EOF;
fax->bidx -= 8;
fax->word |= c << fax->bidx;
}
return 0;
}
 
static int
get_code(fz_faxd *fax, const cfd_node *table, int initialbits)
{
unsigned int word = fax->word;
int tidx = word >> (32 - initialbits);
int val = table[tidx].val;
int nbits = table[tidx].nbits;
 
if (nbits > initialbits)
{
int mask = (1 << (32 - initialbits)) - 1;
tidx = val + ((word & mask) >> (32 - nbits));
val = table[tidx].val;
nbits = initialbits + table[tidx].nbits;
}
 
eat_bits(fax, nbits);
 
return val;
}
 
/* decode one 1d code */
static fz_error
dec1d(fz_faxd *fax)
{
int code;
 
if (fax->a == -1)
fax->a = 0;
 
if (fax->c)
code = get_code(fax, cf_black_decode, cfd_black_initial_bits);
else
code = get_code(fax, cf_white_decode, cfd_white_initial_bits);
 
if (code == UNCOMPRESSED)
return fz_throw("uncompressed data in faxd");
 
if (code < 0)
return fz_throw("negative code in 1d faxd");
 
if (fax->a + code > fax->columns)
return fz_throw("overflow in 1d faxd");
 
if (fax->c)
setbits(fax->dst, fax->a, fax->a + code);
 
fax->a += code;
 
if (code < 64)
{
fax->c = !fax->c;
fax->stage = STATE_NORMAL;
}
else
fax->stage = STATE_MAKEUP;
 
return fz_okay;
}
 
/* decode one 2d code */
static fz_error
dec2d(fz_faxd *fax)
{
int code, b1, b2;
 
if (fax->stage == STATE_H1 || fax->stage == STATE_H2)
{
if (fax->a == -1)
fax->a = 0;
 
if (fax->c)
code = get_code(fax, cf_black_decode, cfd_black_initial_bits);
else
code = get_code(fax, cf_white_decode, cfd_white_initial_bits);
 
if (code == UNCOMPRESSED)
return fz_throw("uncompressed data in faxd");
 
if (code < 0)
return fz_throw("negative code in 2d faxd");
 
if (fax->a + code > fax->columns)
return fz_throw("overflow in 2d faxd");
 
if (fax->c)
setbits(fax->dst, fax->a, fax->a + code);
 
fax->a += code;
 
if (code < 64)
{
fax->c = !fax->c;
if (fax->stage == STATE_H1)
fax->stage = STATE_H2;
else if (fax->stage == STATE_H2)
fax->stage = STATE_NORMAL;
}
 
return fz_okay;
}
 
code = get_code(fax, cf_2d_decode, cfd_2d_initial_bits);
 
switch (code)
{
case H:
fax->stage = STATE_H1;
break;
 
case P:
b1 = find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
if (b1 >= fax->columns)
b2 = fax->columns;
else
b2 = find_changing(fax->ref, b1, fax->columns);
if (fax->c) setbits(fax->dst, fax->a, b2);
fax->a = b2;
break;
 
case V0:
b1 = find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
if (fax->c) setbits(fax->dst, fax->a, b1);
fax->a = b1;
fax->c = !fax->c;
break;
 
case VR1:
b1 = 1 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
if (b1 >= fax->columns) b1 = fax->columns;
if (fax->c) setbits(fax->dst, fax->a, b1);
fax->a = b1;
fax->c = !fax->c;
break;
 
case VR2:
b1 = 2 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
if (b1 >= fax->columns) b1 = fax->columns;
if (fax->c) setbits(fax->dst, fax->a, b1);
fax->a = b1;
fax->c = !fax->c;
break;
 
case VR3:
b1 = 3 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
if (b1 >= fax->columns) b1 = fax->columns;
if (fax->c) setbits(fax->dst, fax->a, b1);
fax->a = b1;
fax->c = !fax->c;
break;
 
case VL1:
b1 = -1 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
if (b1 < 0) b1 = 0;
if (fax->c) setbits(fax->dst, fax->a, b1);
fax->a = b1;
fax->c = !fax->c;
break;
 
case VL2:
b1 = -2 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
if (b1 < 0) b1 = 0;
if (fax->c) setbits(fax->dst, fax->a, b1);
fax->a = b1;
fax->c = !fax->c;
break;
 
case VL3:
b1 = -3 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
if (b1 < 0) b1 = 0;
if (fax->c) setbits(fax->dst, fax->a, b1);
fax->a = b1;
fax->c = !fax->c;
break;
 
case UNCOMPRESSED:
return fz_throw("uncompressed data in faxd");
 
case ERROR:
return fz_throw("invalid code in 2d faxd");
 
default:
return fz_throw("invalid code in 2d faxd (%d)", code);
}
 
return 0;
}
 
static int
read_faxd(fz_stream *stm, unsigned char *buf, int len)
{
fz_faxd *fax = stm->state;
unsigned char *p = buf;
unsigned char *ep = buf + len;
unsigned char *tmp;
fz_error error;
 
if (fax->stage == STATE_DONE)
return 0;
 
if (fax->stage == STATE_EOL)
goto eol;
 
loop:
 
if (fill_bits(fax))
{
if (fax->bidx > 31)
{
if (fax->a > 0)
goto eol;
goto rtc;
}
}
 
if ((fax->word >> (32 - 12)) == 0)
{
eat_bits(fax, 1);
goto loop;
}
 
if ((fax->word >> (32 - 12)) == 1)
{
eat_bits(fax, 12);
fax->eolc ++;
 
if (fax->k > 0)
{
if (fax->a == -1)
fax->a = 0;
if ((fax->word >> (32 - 1)) == 1)
fax->dim = 1;
else
fax->dim = 2;
eat_bits(fax, 1);
}
}
else if (fax->k > 0 && fax->a == -1)
{
fax->a = 0;
if ((fax->word >> (32 - 1)) == 1)
fax->dim = 1;
else
fax->dim = 2;
eat_bits(fax, 1);
}
else if (fax->dim == 1)
{
fax->eolc = 0;
error = dec1d(fax);
if (error)
return fz_rethrow(error, "cannot decode 1d code");
}
else if (fax->dim == 2)
{
fax->eolc = 0;
error = dec2d(fax);
if (error)
return fz_rethrow(error, "cannot decode 2d code");
}
 
/* no eol check after makeup codes nor in the middle of an H code */
if (fax->stage == STATE_MAKEUP || fax->stage == STATE_H1 || fax->stage == STATE_H2)
goto loop;
 
/* check for eol conditions */
if (fax->eolc || fax->a >= fax->columns)
{
if (fax->a > 0)
goto eol;
if (fax->eolc == (fax->k < 0 ? 2 : 6))
goto rtc;
}
 
goto loop;
 
eol:
fax->stage = STATE_EOL;
 
if (fax->black_is_1)
{
while (fax->rp < fax->wp && p < ep)
*p++ = *fax->rp++;
}
else
{
while (fax->rp < fax->wp && p < ep)
*p++ = *fax->rp++ ^ 0xff;
}
 
if (fax->rp < fax->wp)
return p - buf;
 
tmp = fax->ref;
fax->ref = fax->dst;
fax->dst = tmp;
memset(fax->dst, 0, fax->stride);
 
fax->rp = fax->dst;
fax->wp = fax->dst + fax->stride;
 
fax->stage = STATE_NORMAL;
fax->c = 0;
fax->a = -1;
fax->ridx ++;
 
if (!fax->end_of_block && fax->rows)
{
if (fax->ridx >= fax->rows)
goto rtc;
}
 
/* we have not read dim from eol, make a guess */
if (fax->k > 0 && !fax->eolc && fax->a == -1)
{
if (fax->ridx % fax->k == 0)
fax->dim = 1;
else
fax->dim = 2;
}
 
/* if end_of_line & encoded_byte_align, EOLs are *not* optional */
if (fax->encoded_byte_align)
{
if (fax->end_of_line)
eat_bits(fax, (12 - fax->bidx) & 7);
else
eat_bits(fax, (8 - fax->bidx) & 7);
}
 
/* no more space in output, don't decode the next row yet */
if (p == buf + len)
return p - buf;
 
goto loop;
 
rtc:
fax->stage = STATE_DONE;
return p - buf;
}
 
static void
close_faxd(fz_stream *stm)
{
fz_faxd *fax = stm->state;
int i;
 
/* if we read any extra bytes, try to put them back */
i = (32 - fax->bidx) / 8;
while (i--)
fz_unread_byte(fax->chain);
 
fz_close(fax->chain);
fz_free(fax->ref);
fz_free(fax->dst);
fz_free(fax);
}
 
fz_stream *
fz_open_faxd(fz_stream *chain, fz_obj *params)
{
fz_faxd *fax;
fz_obj *obj;
 
fax = fz_malloc(sizeof(fz_faxd));
fax->chain = chain;
 
fax->ref = NULL;
fax->dst = NULL;
 
fax->k = 0;
fax->end_of_line = 0;
fax->encoded_byte_align = 0;
fax->columns = 1728;
fax->rows = 0;
fax->end_of_block = 1;
fax->black_is_1 = 0;
 
obj = fz_dict_gets(params, "K");
if (obj) fax->k = fz_to_int(obj);
 
obj = fz_dict_gets(params, "EndOfLine");
if (obj) fax->end_of_line = fz_to_bool(obj);
 
obj = fz_dict_gets(params, "EncodedByteAlign");
if (obj) fax->encoded_byte_align = fz_to_bool(obj);
 
obj = fz_dict_gets(params, "Columns");
if (obj) fax->columns = fz_to_int(obj);
 
obj = fz_dict_gets(params, "Rows");
if (obj) fax->rows = fz_to_int(obj);
 
obj = fz_dict_gets(params, "EndOfBlock");
if (obj) fax->end_of_block = fz_to_bool(obj);
 
obj = fz_dict_gets(params, "BlackIs1");
if (obj) fax->black_is_1 = fz_to_bool(obj);
 
fax->stride = ((fax->columns - 1) >> 3) + 1;
fax->ridx = 0;
fax->bidx = 32;
fax->word = 0;
 
fax->stage = STATE_NORMAL;
fax->a = -1;
fax->c = 0;
fax->dim = fax->k < 0 ? 2 : 1;
fax->eolc = 0;
 
fax->ref = fz_malloc(fax->stride);
fax->dst = fz_malloc(fax->stride);
fax->rp = fax->dst;
fax->wp = fax->dst + fax->stride;
 
memset(fax->ref, 0, fax->stride);
memset(fax->dst, 0, fax->stride);
 
return fz_new_stream(fax, read_faxd, close_faxd);
}
/contrib/media/updf/fitz/filt_flate.c
0,0 → 1,103
#include "fitz.h"
 
#include <zlib.h>
 
typedef struct fz_flate_s fz_flate;
 
struct fz_flate_s
{
fz_stream *chain;
z_stream z;
};
 
static void *zalloc(void *opaque, unsigned int items, unsigned int size)
{
return fz_calloc(items, size);
}
 
static void zfree(void *opaque, void *ptr)
{
fz_free(ptr);
}
 
static int
read_flated(fz_stream *stm, unsigned char *outbuf, int outlen)
{
fz_flate *state = stm->state;
fz_stream *chain = state->chain;
z_streamp zp = &state->z;
int code;
 
zp->next_out = outbuf;
zp->avail_out = outlen;
 
while (zp->avail_out > 0)
{
if (chain->rp == chain->wp)
fz_fill_buffer(chain);
 
zp->next_in = chain->rp;
zp->avail_in = chain->wp - chain->rp;
 
code = inflate(zp, Z_SYNC_FLUSH);
 
chain->rp = chain->wp - zp->avail_in;
 
if (code == Z_STREAM_END)
{
return outlen - zp->avail_out;
}
else if (code == Z_BUF_ERROR)
{
fz_warn("premature end of data in flate filter");
return outlen - zp->avail_out;
}
else if (code == Z_DATA_ERROR && zp->avail_in == 0)
{
fz_warn("ignoring zlib error: %s", zp->msg);
return outlen - zp->avail_out;
}
else if (code != Z_OK)
{
return fz_throw("zlib error: %s", zp->msg);
}
}
 
return outlen - zp->avail_out;
}
 
static void
close_flated(fz_stream *stm)
{
fz_flate *state = stm->state;
int code;
 
code = inflateEnd(&state->z);
if (code != Z_OK)
fz_warn("zlib error: inflateEnd: %s", state->z.msg);
 
fz_close(state->chain);
fz_free(state);
}
 
fz_stream *
fz_open_flated(fz_stream *chain)
{
fz_flate *state;
int code;
 
state = fz_malloc(sizeof(fz_flate));
state->chain = chain;
 
state->z.zalloc = zalloc;
state->z.zfree = zfree;
state->z.opaque = NULL;
state->z.next_in = NULL;
state->z.avail_in = 0;
 
code = inflateInit(&state->z);
if (code != Z_OK)
fz_warn("zlib error: inflateInit: %s", state->z.msg);
 
return fz_new_stream(state, read_flated, close_flated);
}
/contrib/media/updf/fitz/filt_jbig2d.c
0,0 → 1,103
#include "fitz.h"
 
#ifdef _WIN32 /* Microsoft Visual C++ */
 
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef __int64 int64_t;
 
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
 
#else
#include <inttypes.h>
#endif
 
#include <jbig2.h>
 
typedef struct fz_jbig2d_s fz_jbig2d;
 
struct fz_jbig2d_s
{
fz_stream *chain;
Jbig2Ctx *ctx;
Jbig2GlobalCtx *gctx;
Jbig2Image *page;
int idx;
};
 
static void
close_jbig2d(fz_stream *stm)
{
fz_jbig2d *state = stm->state;
if (state->page)
jbig2_release_page(state->ctx, state->page);
if (state->gctx)
jbig2_global_ctx_free(state->gctx);
jbig2_ctx_free(state->ctx);
fz_close(state->chain);
fz_free(state);
}
 
static int
read_jbig2d(fz_stream *stm, unsigned char *buf, int len)
{
fz_jbig2d *state = stm->state;
unsigned char tmp[4096];
unsigned char *p = buf;
unsigned char *ep = buf + len;
unsigned char *s;
int x, w, n;
 
if (!state->page)
{
while (1)
{
n = fz_read(state->chain, tmp, sizeof tmp);
if (n < 0)
return fz_rethrow(n, "read error in jbig2 filter");
if (n == 0)
break;
jbig2_data_in(state->ctx, tmp, n);
}
 
jbig2_complete_page(state->ctx);
 
state->page = jbig2_page_out(state->ctx);
if (!state->page)
return fz_throw("jbig2_page_out failed");
}
 
s = state->page->data;
w = state->page->height * state->page->stride;
x = state->idx;
while (p < ep && x < w)
*p++ = s[x++] ^ 0xff;
state->idx = x;
 
return p - buf;
}
 
fz_stream *
fz_open_jbig2d(fz_stream *chain, fz_buffer *globals)
{
fz_jbig2d *state;
 
state = fz_malloc(sizeof(fz_jbig2d));
state->chain = chain;
state->ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, NULL, NULL, NULL);
state->gctx = NULL;
state->page = NULL;
state->idx = 0;
 
if (globals)
{
jbig2_data_in(state->ctx, globals->data, globals->len);
state->gctx = jbig2_make_global_ctx(state->ctx);
state->ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, state->gctx, NULL, NULL);
}
 
return fz_new_stream(state, read_jbig2d, close_jbig2d);
}
/contrib/media/updf/fitz/filt_jpxd.c
0,0 → 1,153
#include "fitz.h"
 
#define OPJ_STATIC
#include <openjpeg.h>
 
static void fz_opj_error_callback(const char *msg, void *client_data)
{
fprintf(stderr, "openjpeg error: %s", msg);
}
 
static void fz_opj_warning_callback(const char *msg, void *client_data)
{
fprintf(stderr, "openjpeg warning: %s", msg);
}
 
static void fz_opj_info_callback(const char *msg, void *client_data)
{
/* fprintf(stderr, "openjpeg info: %s", msg); */
}
 
fz_error
fz_load_jpx_image(fz_pixmap **imgp, unsigned char *data, int size, fz_colorspace *defcs)
{
fz_pixmap *img;
opj_event_mgr_t evtmgr;
opj_dparameters_t params;
opj_dinfo_t *info;
opj_cio_t *cio;
opj_image_t *jpx;
fz_colorspace *colorspace;
unsigned char *p;
int format;
int a, n, w, h, depth, sgnd;
int x, y, k, v;
 
if (size < 2)
return fz_throw("not enough data to determine image format");
 
/* Check for SOC marker -- if found we have a bare J2K stream */
if (data[0] == 0xFF && data[1] == 0x4F)
format = CODEC_J2K;
else
format = CODEC_JP2;
 
memset(&evtmgr, 0, sizeof(evtmgr));
evtmgr.error_handler = fz_opj_error_callback;
evtmgr.warning_handler = fz_opj_warning_callback;
evtmgr.info_handler = fz_opj_info_callback;
 
opj_set_default_decoder_parameters(&params);
 
info = opj_create_decompress(format);
opj_set_event_mgr((opj_common_ptr)info, &evtmgr, stderr);
opj_setup_decoder(info, &params);
 
cio = opj_cio_open((opj_common_ptr)info, data, size);
 
jpx = opj_decode(info, cio);
 
opj_cio_close(cio);
opj_destroy_decompress(info);
 
if (!jpx)
return fz_throw("opj_decode failed");
 
for (k = 1; k < jpx->numcomps; k++)
{
if (jpx->comps[k].w != jpx->comps[0].w)
return fz_throw("image components have different width");
if (jpx->comps[k].h != jpx->comps[0].h)
return fz_throw("image components have different height");
if (jpx->comps[k].prec != jpx->comps[0].prec)
return fz_throw("image components have different precision");
}
 
n = jpx->numcomps;
w = jpx->comps[0].w;
h = jpx->comps[0].h;
depth = jpx->comps[0].prec;
sgnd = jpx->comps[0].sgnd;
 
if (jpx->color_space == CLRSPC_SRGB && n == 4) { n = 3; a = 1; }
else if (jpx->color_space == CLRSPC_SYCC && n == 4) { n = 3; a = 1; }
else if (n == 2) { n = 1; a = 1; }
else if (n > 4) { n = 4; a = 1; }
else { a = 0; }
 
if (defcs)
{
if (defcs->n == n)
{
colorspace = defcs;
}
else
{
fz_warn("jpx file and dict colorspaces do not match");
defcs = NULL;
}
}
 
if (!defcs)
{
switch (n)
{
case 1: colorspace = fz_device_gray; break;
case 3: colorspace = fz_device_rgb; break;
case 4: colorspace = fz_device_cmyk; break;
}
}
 
img = fz_new_pixmap_with_limit(colorspace, w, h);
if (!img)
{
opj_image_destroy(jpx);
return fz_throw("out of memory");
}
 
p = img->samples;
for (y = 0; y < h; y++)
{
for (x = 0; x < w; x++)
{
for (k = 0; k < n + a; k++)
{
v = jpx->comps[k].data[y * w + x];
if (sgnd)
v = v + (1 << (depth - 1));
if (depth > 8)
v = v >> (depth - 8);
*p++ = v;
}
if (!a)
*p++ = 255;
}
}
 
if (a)
{
if (n == 4)
{
fz_pixmap *tmp = fz_new_pixmap(fz_device_rgb, w, h);
fz_convert_pixmap(img, tmp);
fz_drop_pixmap(img);
img = tmp;
}
fz_premultiply_pixmap(img);
}
 
opj_image_destroy(jpx);
 
*imgp = img;
return fz_okay;
}
/contrib/media/updf/fitz/filt_lzwd.c
0,0 → 1,206
#include "fitz.h"
 
/* TODO: error checking */
 
enum
{
MIN_BITS = 9,
MAX_BITS = 12,
NUM_CODES = (1 << MAX_BITS),
LZW_CLEAR = 256,
LZW_EOD = 257,
LZW_FIRST = 258,
MAX_LENGTH = 4097
};
 
typedef struct lzw_code_s lzw_code;
 
struct lzw_code_s
{
int prev; /* prev code (in string) */
unsigned short length; /* string len, including this token */
unsigned char value; /* data value */
unsigned char first_char; /* first token of string */
};
 
typedef struct fz_lzwd_s fz_lzwd;
 
struct fz_lzwd_s
{
fz_stream *chain;
int eod;
 
int early_change;
 
int code_bits; /* num bits/code */
int code; /* current code */
int old_code; /* previously recognized code */
int next_code; /* next free entry */
 
lzw_code table[NUM_CODES];
 
unsigned char bp[MAX_LENGTH];
unsigned char *rp, *wp;
};
 
static int
read_lzwd(fz_stream *stm, unsigned char *buf, int len)
{
fz_lzwd *lzw = stm->state;
lzw_code *table = lzw->table;
unsigned char *p = buf;
unsigned char *ep = buf + len;
unsigned char *s;
int codelen;
 
int code_bits = lzw->code_bits;
int code = lzw->code;
int old_code = lzw->old_code;
int next_code = lzw->next_code;
 
while (lzw->rp < lzw->wp && p < ep)
*p++ = *lzw->rp++;
 
while (p < ep)
{
if (lzw->eod)
return 0;
 
code = fz_read_bits(lzw->chain, code_bits);
 
if (fz_is_eof_bits(lzw->chain))
{
lzw->eod = 1;
break;
}
 
if (code == LZW_EOD)
{
lzw->eod = 1;
break;
}
 
if (code == LZW_CLEAR)
{
code_bits = MIN_BITS;
next_code = LZW_FIRST;
old_code = -1;
continue;
}
 
/* if stream starts without a clear code, old_code is undefined... */
if (old_code == -1)
{
old_code = code;
}
else
{
/* add new entry to the code table */
table[next_code].prev = old_code;
table[next_code].first_char = table[old_code].first_char;
table[next_code].length = table[old_code].length + 1;
if (code < next_code)
table[next_code].value = table[code].first_char;
else if (code == next_code)
table[next_code].value = table[next_code].first_char;
else
fz_warn("out of range code encountered in lzw decode");
 
next_code ++;
 
if (next_code > (1 << code_bits) - lzw->early_change - 1)
{
code_bits ++;
if (code_bits > MAX_BITS)
code_bits = MAX_BITS; /* FIXME */
}
 
old_code = code;
}
 
/* code maps to a string, copy to output (in reverse...) */
if (code > 255)
{
codelen = table[code].length;
lzw->rp = lzw->bp;
lzw->wp = lzw->bp + codelen;
 
assert(codelen < MAX_LENGTH);
 
s = lzw->wp;
do {
*(--s) = table[code].value;
code = table[code].prev;
} while (code >= 0 && s > lzw->bp);
}
 
/* ... or just a single character */
else
{
lzw->bp[0] = code;
lzw->rp = lzw->bp;
lzw->wp = lzw->bp + 1;
}
 
/* copy to output */
while (lzw->rp < lzw->wp && p < ep)
*p++ = *lzw->rp++;
}
 
lzw->code_bits = code_bits;
lzw->code = code;
lzw->old_code = old_code;
lzw->next_code = next_code;
 
return p - buf;
}
 
static void
close_lzwd(fz_stream *stm)
{
fz_lzwd *lzw = stm->state;
fz_close(lzw->chain);
fz_free(lzw);
}
 
fz_stream *
fz_open_lzwd(fz_stream *chain, fz_obj *params)
{
fz_lzwd *lzw;
fz_obj *obj;
int i;
 
lzw = fz_malloc(sizeof(fz_lzwd));
lzw->chain = chain;
lzw->eod = 0;
lzw->early_change = 1;
 
obj = fz_dict_gets(params, "EarlyChange");
if (obj)
lzw->early_change = !!fz_to_int(obj);
 
for (i = 0; i < 256; i++)
{
lzw->table[i].value = i;
lzw->table[i].first_char = i;
lzw->table[i].length = 1;
lzw->table[i].prev = -1;
}
 
for (i = 256; i < NUM_CODES; i++)
{
lzw->table[i].value = 0;
lzw->table[i].first_char = 0;
lzw->table[i].length = 0;
lzw->table[i].prev = -1;
}
 
lzw->code_bits = MIN_BITS;
lzw->code = -1;
lzw->next_code = LZW_FIRST;
lzw->old_code = -1;
lzw->rp = lzw->bp;
lzw->wp = lzw->bp;
 
return fz_new_stream(lzw, read_lzwd, close_lzwd);
}
/contrib/media/updf/fitz/filt_predict.c
0,0 → 1,243
#include "fitz.h"
 
/* TODO: check if this works with 16bpp images */
 
enum { MAXC = 32 };
 
typedef struct fz_predict_s fz_predict;
 
struct fz_predict_s
{
fz_stream *chain;
 
int predictor;
int columns;
int colors;
int bpc;
 
int stride;
int bpp;
unsigned char *in;
unsigned char *out;
unsigned char *ref;
unsigned char *rp, *wp;
};
 
static inline int getcomponent(unsigned char *line, int x, int bpc)
{
switch (bpc)
{
case 1: return (line[x >> 3] >> ( 7 - (x & 7) ) ) & 1;
case 2: return (line[x >> 2] >> ( ( 3 - (x & 3) ) << 1 ) ) & 3;
case 4: return (line[x >> 1] >> ( ( 1 - (x & 1) ) << 2 ) ) & 15;
case 8: return line[x];
}
return 0;
}
 
 
static inline void putcomponent(unsigned char *buf, int x, int bpc, int value)
{
switch (bpc)
{
case 1: buf[x >> 3] |= value << (7 - (x & 7)); break;
case 2: buf[x >> 2] |= value << ((3 - (x & 3)) << 1); break;
case 4: buf[x >> 1] |= value << ((1 - (x & 1)) << 2); break;
case 8: buf[x] = value; break;
}
}
 
static inline int paeth(int a, int b, int c)
{
/* The definitions of ac and bc are correct, not a typo. */
int ac = b - c, bc = a - c, abcc = ac + bc;
int pa = ABS(ac);
int pb = ABS(bc);
int pc = ABS(abcc);
return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
}
 
static void
fz_predict_tiff(fz_predict *state, unsigned char *out, unsigned char *in, int len)
{
int left[MAXC];
int i, k;
 
for (k = 0; k < state->colors; k++)
left[k] = 0;
 
for (i = 0; i < state->columns; i++)
{
for (k = 0; k < state->colors; k++)
{
int a = getcomponent(in, i * state->colors + k, state->bpc);
int b = a + left[k];
int c = b % (1 << state->bpc);
putcomponent(out, i * state->colors + k, state->bpc, c);
left[k] = c;
}
}
}
 
static void
fz_predict_png(fz_predict *state, unsigned char *out, unsigned char *in, int len, int predictor)
{
int bpp = state->bpp;
int i;
unsigned char *ref = state->ref;
 
switch (predictor)
{
case 0:
memcpy(out, in, len);
break;
case 1:
for (i = bpp; i > 0; i--)
{
*out++ = *in++;
}
for (i = len - bpp; i > 0; i--)
{
*out = *in++ + out[-bpp];
out++;
}
break;
case 2:
for (i = bpp; i > 0; i--)
{
*out++ = *in++ + *ref++;
}
for (i = len - bpp; i > 0; i--)
{
*out++ = *in++ + *ref++;
}
break;
case 3:
for (i = bpp; i > 0; i--)
{
*out++ = *in++ + (*ref++) / 2;
}
for (i = len - bpp; i > 0; i--)
{
*out = *in++ + (out[-bpp] + *ref++) / 2;
out++;
}
break;
case 4:
for (i = bpp; i > 0; i--)
{
*out++ = *in++ + paeth(0, *ref++, 0);
}
for (i = len - bpp; i > 0; i --)
{
*out = *in++ + paeth(out[-bpp], *ref, ref[-bpp]);
ref++;
out++;
}
break;
}
}
 
static int
read_predict(fz_stream *stm, unsigned char *buf, int len)
{
fz_predict *state = stm->state;
unsigned char *p = buf;
unsigned char *ep = buf + len;
int ispng = state->predictor >= 10;
int n;
 
while (state->rp < state->wp && p < ep)
*p++ = *state->rp++;
 
while (p < ep)
{
n = fz_read(state->chain, state->in, state->stride + ispng);
if (n < 0)
return fz_rethrow(n, "read error in prediction filter");
if (n == 0)
return p - buf;
 
if (state->predictor == 1)
memcpy(state->out, state->in, n);
else if (state->predictor == 2)
fz_predict_tiff(state, state->out, state->in, n);
else
{
fz_predict_png(state, state->out, state->in + 1, n - 1, state->in[0]);
memcpy(state->ref, state->out, state->stride);
}
 
state->rp = state->out;
state->wp = state->out + n - ispng;
 
while (state->rp < state->wp && p < ep)
*p++ = *state->rp++;
}
 
return p - buf;
}
 
static void
close_predict(fz_stream *stm)
{
fz_predict *state = stm->state;
fz_close(state->chain);
fz_free(state->in);
fz_free(state->out);
fz_free(state->ref);
fz_free(state);
}
 
fz_stream *
fz_open_predict(fz_stream *chain, fz_obj *params)
{
fz_predict *state;
fz_obj *obj;
 
state = fz_malloc(sizeof(fz_predict));
state->chain = chain;
 
state->predictor = 1;
state->columns = 1;
state->colors = 1;
state->bpc = 8;
 
obj = fz_dict_gets(params, "Predictor");
if (obj)
state->predictor = fz_to_int(obj);
 
if (state->predictor != 1 && state->predictor != 2 &&
state->predictor != 10 && state->predictor != 11 &&
state->predictor != 12 && state->predictor != 13 &&
state->predictor != 14 && state->predictor != 15)
{
fz_warn("invalid predictor: %d", state->predictor);
state->predictor = 1;
}
 
obj = fz_dict_gets(params, "Columns");
if (obj)
state->columns = fz_to_int(obj);
 
obj = fz_dict_gets(params, "Colors");
if (obj)
state->colors = fz_to_int(obj);
 
obj = fz_dict_gets(params, "BitsPerComponent");
if (obj)
state->bpc = fz_to_int(obj);
 
state->stride = (state->bpc * state->colors * state->columns + 7) / 8;
state->bpp = (state->bpc * state->colors + 7) / 8;
 
state->in = fz_malloc(state->stride + 1);
state->out = fz_malloc(state->stride);
state->ref = fz_malloc(state->stride);
state->rp = state->out;
state->wp = state->out;
 
memset(state->ref, 0, state->stride);
 
return fz_new_stream(state, read_predict, close_predict);
}
/contrib/media/updf/fitz/fitz.h
0,0 → 1,1120
#ifndef _FITZ_H_
#define _FITZ_H_
 
/*
* Include the standard libc headers.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
 
#include <assert.h>
#include <errno.h>
#include <limits.h> /* INT_MAX & co */
#include <float.h> /* FLT_EPSILON */
#include <fcntl.h> /* O_RDONLY & co */
 
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
 
#define ABS(x) ( (x) < 0 ? -(x) : (x) )
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
#define MAX(a,b) ( (a) > (b) ? (a) : (b) )
#define CLAMP(x,a,b) ( (x) > (b) ? (b) : ( (x) < (a) ? (a) : (x) ) )
 
/*
* Some differences in libc can be smoothed over
*/
 
#ifdef _MSC_VER /* Microsoft Visual C */
 
#pragma warning( disable: 4244 ) /* conversion from X to Y, possible loss of data */
#pragma warning( disable: 4996 ) /* The POSIX name for this item is deprecated */
#pragma warning( disable: 4996 ) /* This function or variable may be unsafe */
 
#include <io.h>
 
int gettimeofday(struct timeval *tv, struct timezone *tz);
 
#define snprintf _snprintf
#define strtoll _strtoi64
 
#else /* Unix or close enough */
 
#include <unistd.h>
 
#ifndef O_BINARY
#define O_BINARY 0
#endif
 
#endif
 
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
 
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880
#endif
 
/*
* Variadic macros, inline and restrict keywords
*/
 
#if __STDC_VERSION__ == 199901L /* C99 */
 
#define fz_throw(...) fz_throw_imp(__FILE__, __LINE__, __func__, __VA_ARGS__)
#define fz_rethrow(cause, ...) fz_rethrow_imp(__FILE__, __LINE__, __func__, cause, __VA_ARGS__)
#define fz_catch(cause, ...) fz_catch_imp(__FILE__, __LINE__, __func__, cause, __VA_ARGS__)
 
#elif _MSC_VER >= 1500 /* MSVC 9 or newer */
 
#define inline __inline
#define restrict __restrict
#define fz_throw(...) fz_throw_imp(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define fz_rethrow(cause, ...) fz_rethrow_imp(__FILE__, __LINE__, __FUNCTION__, cause, __VA_ARGS__)
#define fz_catch(cause, ...) fz_catch_imp(__FILE__, __LINE__, __FUNCTION__, cause, __VA_ARGS__)
 
#elif __GNUC__ >= 3 /* GCC 3 or newer */
 
#define inline __inline
#define restrict __restrict
#define fz_throw(fmt...) fz_throw_imp(__FILE__, __LINE__, __FUNCTION__, fmt)
#define fz_rethrow(cause, fmt...) fz_rethrow_imp(__FILE__, __LINE__, __FUNCTION__, cause, fmt)
#define fz_catch(cause, fmt...) fz_catch_imp(__FILE__, __LINE__, __FUNCTION__, cause, fmt)
 
#else /* Unknown or ancient */
 
#define inline
#define restrict
#define fz_throw fz_throw_impx
#define fz_rethrow fz_rethrow_impx
#define fz_catch fz_catch_impx
 
#endif
 
/*
* GCC can do type checking of printf strings
*/
 
#ifndef __printflike
#if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7
#define __printflike(fmtarg, firstvararg) \
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
#else
#define __printflike(fmtarg, firstvararg)
#endif
#endif
 
/*
* Error handling
*/
 
typedef int fz_error;
 
#define fz_okay ((fz_error)0)
 
void fz_warn(char *fmt, ...) __printflike(1, 2);
void fz_flush_warnings(void);
 
fz_error fz_throw_imp(const char *file, int line, const char *func, char *fmt, ...) __printflike(4, 5);
fz_error fz_rethrow_imp(const char *file, int line, const char *func, fz_error cause, char *fmt, ...) __printflike(5, 6);
void fz_catch_imp(const char *file, int line, const char *func, fz_error cause, char *fmt, ...) __printflike(5, 6);
 
fz_error fz_throw_impx(char *fmt, ...) __printflike(1, 2);
fz_error fz_rethrow_impx(fz_error cause, char *fmt, ...) __printflike(2, 3);
void fz_catch_impx(fz_error cause, char *fmt, ...) __printflike(2, 3);
 
/* extract the last error stack trace */
int fz_get_error_count(void);
char *fz_get_error_line(int n);
 
/*
* Basic runtime and utility functions
*/
 
/* memory allocation */
void *fz_malloc(int size);
void *fz_calloc(int count, int size);
void *fz_realloc(void *p, int count, int size);
void fz_free(void *p);
char *fz_strdup(char *s);
 
/* runtime (hah!) test for endian-ness */
int fz_is_big_endian(void);
 
/* safe string functions */
char *fz_strsep(char **stringp, const char *delim);
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);
 
/* utf-8 encoding and decoding */
int chartorune(int *rune, char *str);
int runetochar(char *str, int *rune);
int runelen(int c);
 
/* getopt */
extern int fz_getopt(int nargc, char * const *nargv, const char *ostr);
extern int fz_optind;
extern char *fz_optarg;
 
/*
* Generic hash-table with fixed-length keys.
*/
 
typedef struct fz_hash_table_s fz_hash_table;
 
fz_hash_table *fz_new_hash_table(int initialsize, int keylen);
void fz_debug_hash(fz_hash_table *table);
void fz_empty_hash(fz_hash_table *table);
void fz_free_hash(fz_hash_table *table);
 
void *fz_hash_find(fz_hash_table *table, void *key);
void fz_hash_insert(fz_hash_table *table, void *key, void *val);
void fz_hash_remove(fz_hash_table *table, void *key);
 
int fz_hash_len(fz_hash_table *table);
void *fz_hash_get_key(fz_hash_table *table, int idx);
void *fz_hash_get_val(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)
 
typedef struct fz_matrix_s fz_matrix;
typedef struct fz_point_s fz_point;
typedef struct fz_rect_s fz_rect;
typedef struct fz_bbox_s fz_bbox;
 
extern const fz_rect fz_unit_rect;
extern const fz_rect fz_empty_rect;
extern const fz_rect fz_infinite_rect;
 
extern const fz_bbox fz_unit_bbox;
extern const fz_bbox fz_empty_bbox;
extern const fz_bbox fz_infinite_bbox;
 
#define fz_is_empty_rect(r) ((r).x0 == (r).x1)
#define fz_is_infinite_rect(r) ((r).x0 > (r).x1)
#define fz_is_empty_bbox(b) ((b).x0 == (b).x1)
#define fz_is_infinite_bbox(b) ((b).x0 > (b).x1)
 
struct fz_matrix_s
{
float a, b, c, d, e, f;
};
 
struct fz_point_s
{
float x, y;
};
 
struct fz_rect_s
{
float x0, y0;
float x1, y1;
};
 
struct fz_bbox_s
{
int x0, y0;
int x1, y1;
};
 
extern const fz_matrix fz_identity;
 
fz_matrix fz_concat(fz_matrix one, fz_matrix two);
fz_matrix fz_scale(float sx, float sy);
fz_matrix fz_shear(float sx, float sy);
fz_matrix fz_rotate(float theta);
fz_matrix fz_translate(float tx, float ty);
fz_matrix fz_invert_matrix(fz_matrix m);
int fz_is_rectilinear(fz_matrix m);
float fz_matrix_expansion(fz_matrix m);
 
fz_bbox fz_round_rect(fz_rect r);
fz_bbox fz_intersect_bbox(fz_bbox a, fz_bbox b);
fz_rect fz_intersect_rect(fz_rect a, fz_rect b);
fz_bbox fz_union_bbox(fz_bbox a, fz_bbox b);
fz_rect fz_union_rect(fz_rect a, fz_rect b);
 
fz_point fz_transform_point(fz_matrix m, fz_point p);
fz_point fz_transform_vector(fz_matrix m, fz_point p);
fz_rect fz_transform_rect(fz_matrix m, fz_rect r);
fz_bbox fz_transform_bbox(fz_matrix m, fz_bbox b);
 
/*
* 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 );
 
/*
* Dynamic objects.
* The same type of objects as found in PDF and PostScript.
* Used by the filters and the mupdf parser.
*/
 
typedef struct fz_obj_s fz_obj;
 
extern fz_obj* (*fz_resolve_indirect)(fz_obj*);
 
fz_obj *fz_new_null(void);
fz_obj *fz_new_bool(int b);
fz_obj *fz_new_int(int i);
fz_obj *fz_new_real(float f);
fz_obj *fz_new_name(char *str);
fz_obj *fz_new_string(char *str, int len);
fz_obj *fz_new_indirect(int num, int gen, void *xref);
 
fz_obj *fz_new_array(int initialcap);
fz_obj *fz_new_dict(int initialcap);
fz_obj *fz_copy_array(fz_obj *array);
fz_obj *fz_copy_dict(fz_obj *dict);
 
fz_obj *fz_keep_obj(fz_obj *obj);
void fz_drop_obj(fz_obj *obj);
 
/* type queries */
int fz_is_null(fz_obj *obj);
int fz_is_bool(fz_obj *obj);
int fz_is_int(fz_obj *obj);
int fz_is_real(fz_obj *obj);
int fz_is_name(fz_obj *obj);
int fz_is_string(fz_obj *obj);
int fz_is_array(fz_obj *obj);
int fz_is_dict(fz_obj *obj);
int fz_is_indirect(fz_obj *obj);
 
int fz_objcmp(fz_obj *a, fz_obj *b);
 
/* safe, silent failure, no error reporting */
int fz_to_bool(fz_obj *obj);
int fz_to_int(fz_obj *obj);
float fz_to_real(fz_obj *obj);
char *fz_to_name(fz_obj *obj);
char *fz_to_str_buf(fz_obj *obj);
int fz_to_str_len(fz_obj *obj);
int fz_to_num(fz_obj *obj);
int fz_to_gen(fz_obj *obj);
 
int fz_array_len(fz_obj *array);
fz_obj *fz_array_get(fz_obj *array, int i);
void fz_array_put(fz_obj *array, int i, fz_obj *obj);
void fz_array_push(fz_obj *array, fz_obj *obj);
void fz_array_insert(fz_obj *array, fz_obj *obj);
 
int fz_dict_len(fz_obj *dict);
fz_obj *fz_dict_get_key(fz_obj *dict, int idx);
fz_obj *fz_dict_get_val(fz_obj *dict, int idx);
fz_obj *fz_dict_get(fz_obj *dict, fz_obj *key);
fz_obj *fz_dict_gets(fz_obj *dict, char *key);
fz_obj *fz_dict_getsa(fz_obj *dict, char *key, char *abbrev);
void fz_dict_put(fz_obj *dict, fz_obj *key, fz_obj *val);
void fz_dict_puts(fz_obj *dict, char *key, fz_obj *val);
void fz_dict_del(fz_obj *dict, fz_obj *key);
void fz_dict_dels(fz_obj *dict, char *key);
void fz_sort_dict(fz_obj *dict);
 
int fz_fprint_obj(FILE *fp, fz_obj *obj, int tight);
void fz_debug_obj(fz_obj *obj);
void fz_debug_ref(fz_obj *obj);
 
void fz_set_str_len(fz_obj *obj, int newlen); /* private */
void *fz_get_indirect_xref(fz_obj *obj); /* private */
 
/*
* Data buffers.
*/
 
typedef struct fz_buffer_s fz_buffer;
 
struct fz_buffer_s
{
int refs;
unsigned char *data;
int cap, len;
};
 
fz_buffer *fz_new_buffer(int size);
fz_buffer *fz_keep_buffer(fz_buffer *buf);
void fz_drop_buffer(fz_buffer *buf);
 
void fz_resize_buffer(fz_buffer *buf, int size);
void fz_grow_buffer(fz_buffer *buf);
 
/*
* Buffered reader.
* Only the data between rp and wp is valid data.
*/
 
typedef struct fz_stream_s fz_stream;
 
struct fz_stream_s
{
int refs;
int error;
int eof;
int pos;
int avail;
int bits;
unsigned char *bp, *rp, *wp, *ep;
void *state;
int (*read)(fz_stream *stm, unsigned char *buf, int len);
void (*close)(fz_stream *stm);
void (*seek)(fz_stream *stm, int offset, int whence);
unsigned char buf[4096];
};
 
fz_stream *fz_open_fd(int file);
fz_stream *fz_open_file(const char *filename);
fz_stream *fz_open_file_w(const wchar_t *filename); /* only on win32 */
fz_stream *fz_open_buffer(fz_buffer *buf);
fz_stream *fz_open_memory(unsigned char *data, int len);
void fz_close(fz_stream *stm);
 
fz_stream *fz_new_stream(void*, int(*)(fz_stream*, unsigned char*, int), void(*)(fz_stream *));
fz_stream *fz_keep_stream(fz_stream *stm);
void fz_fill_buffer(fz_stream *stm);
 
int fz_tell(fz_stream *stm);
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_error fz_read_all(fz_buffer **bufp, fz_stream *stm, int initial);
 
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, fz_obj *param);
fz_stream *fz_open_faxd(fz_stream *chain, fz_obj *param);
fz_stream *fz_open_flated(fz_stream *chain);
fz_stream *fz_open_lzwd(fz_stream *chain, fz_obj *param);
fz_stream *fz_open_predict(fz_stream *chain, fz_obj *param);
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);
 
/*
* Pixmaps have n components per pixel. the last is always alpha.
* premultiplied alpha when rendering, but non-premultiplied for colorspace
* conversions and rescaling.
*/
 
typedef struct fz_pixmap_s fz_pixmap;
typedef struct fz_colorspace_s fz_colorspace;
 
struct fz_pixmap_s
{
int refs;
int x, y, w, h, n;
fz_pixmap *mask; /* explicit soft/image mask */
int interpolate;
int xres, yres;
fz_colorspace *colorspace;
unsigned char *samples;
int free_samples;
};
 
/* will return NULL if soft limit is exceeded */
fz_pixmap *fz_new_pixmap_with_limit(fz_colorspace *colorspace, int w, int h);
 
fz_pixmap *fz_new_pixmap_with_data(fz_colorspace *colorspace, int w, int h, unsigned char *samples);
fz_pixmap *fz_new_pixmap_with_rect(fz_colorspace *, fz_bbox bbox);
fz_pixmap *fz_new_pixmap_with_rect_and_data(fz_colorspace *, fz_bbox bbox, unsigned char *samples);
fz_pixmap *fz_new_pixmap(fz_colorspace *, int w, int h);
fz_pixmap *fz_keep_pixmap(fz_pixmap *pix);
void fz_drop_pixmap(fz_pixmap *pix);
void fz_clear_pixmap(fz_pixmap *pix);
void fz_clear_pixmap_with_color(fz_pixmap *pix, int value);
void fz_clear_pixmap_rect_with_color(fz_pixmap *pix, int value, fz_bbox r);
void fz_copy_pixmap_rect(fz_pixmap *dest, fz_pixmap *src, fz_bbox r);
void fz_premultiply_pixmap(fz_pixmap *pix);
fz_pixmap *fz_alpha_from_gray(fz_pixmap *gray, int luminosity);
fz_bbox fz_bound_pixmap(fz_pixmap *pix);
void fz_invert_pixmap(fz_pixmap *pix);
void fz_gamma_pixmap(fz_pixmap *pix, float gamma);
 
fz_pixmap *fz_scale_pixmap(fz_pixmap *src, float x, float y, float w, float h);
fz_pixmap *fz_scale_pixmap_gridfit(fz_pixmap *src, float x, float y, float w, float h, int gridfit);
 
fz_error fz_write_pnm(fz_pixmap *pixmap, char *filename);
fz_error fz_write_pam(fz_pixmap *pixmap, char *filename, int savealpha);
fz_error fz_write_png(fz_pixmap *pixmap, char *filename, int savealpha);
 
fz_error fz_load_jpx_image(fz_pixmap **imgp, unsigned char *data, int size, fz_colorspace *dcs);
 
/*
* Bitmaps have 1 component per bit. 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;
 
struct fz_bitmap_s
{
int refs;
int w, h, stride, n;
unsigned char *samples;
};
 
fz_bitmap *fz_new_bitmap(int w, int h, int n);
fz_bitmap *fz_keep_bitmap(fz_bitmap *bit);
void fz_clear_bitmap(fz_bitmap *bit);
void fz_drop_bitmap(fz_bitmap *bit);
 
fz_error fz_write_pbm(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.
*/
 
typedef struct fz_halftone_s fz_halftone;
 
struct fz_halftone_s
{
int refs;
int n;
fz_pixmap *comp[1];
};
 
fz_halftone *fz_new_halftone(int num_comps);
fz_halftone *fz_get_default_halftone(int num_comps);
fz_halftone *fz_keep_halftone(fz_halftone *half);
void fz_drop_halftone(fz_halftone *half);
 
fz_bitmap *fz_halftone_pixmap(fz_pixmap *pix, fz_halftone *ht);
 
/*
* Colorspace resources.
*/
 
extern fz_colorspace *fz_device_gray;
extern fz_colorspace *fz_device_rgb;
extern fz_colorspace *fz_device_bgr;
extern fz_colorspace *fz_device_cmyk;
 
struct fz_colorspace_s
{
int refs;
char name[16];
int n;
void (*to_rgb)(fz_colorspace *, float *src, float *rgb);
void (*from_rgb)(fz_colorspace *, float *rgb, float *dst);
void (*free_data)(fz_colorspace *);
void *data;
};
 
fz_colorspace *fz_new_colorspace(char *name, int n);
fz_colorspace *fz_keep_colorspace(fz_colorspace *colorspace);
void fz_drop_colorspace(fz_colorspace *colorspace);
 
void fz_convert_color(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv);
void fz_convert_pixmap(fz_pixmap *src, fz_pixmap *dst);
 
fz_colorspace *fz_find_device_colorspace(char *name);
 
/*
* Fonts come in two variants:
* Regular fonts are handled by FreeType.
* Type 3 fonts have callbacks to the interpreter.
*/
 
struct fz_device_s;
 
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;
fz_obj *t3resources;
fz_buffer **t3procs; /* has 256 entries if used */
float *t3widths; /* has 256 entries if used */
void *t3xref; /* a pdf_xref for the callback */
fz_error (*t3run)(void *xref, fz_obj *resources, fz_buffer *contents,
struct fz_device_s *dev, fz_matrix ctm);
 
fz_rect bbox;
 
/* substitute metrics */
int width_count;
int *width_table;
};
 
fz_font *fz_new_type3_font(char *name, fz_matrix matrix);
 
fz_error fz_new_font_from_memory(fz_font **fontp, unsigned char *data, int len, int index);
fz_error fz_new_font_from_file(fz_font **fontp, char *path, int index);
 
fz_font *fz_keep_font(fz_font *font);
void fz_drop_font(fz_font *font);
 
void fz_debug_font(fz_font *font);
void fz_set_font_bbox(fz_font *font, float xmin, float ymin, float xmax, float ymax);
 
/*
* 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;
 
union fz_path_item_s
{
fz_path_item_kind k;
float v;
};
 
struct fz_path_s
{
int len, cap;
fz_path_item *items;
};
 
struct fz_stroke_state_s
{
int start_cap, dash_cap, end_cap;
int linejoin;
float linewidth;
float miterlimit;
float dash_phase;
int dash_len;
float dash_list[32];
};
 
fz_path *fz_new_path(void);
void fz_moveto(fz_path*, float x, float y);
void fz_lineto(fz_path*, float x, float y);
void fz_curveto(fz_path*, float, float, float, float, float, float);
void fz_curvetov(fz_path*, float, float, float, float);
void fz_curvetoy(fz_path*, float, float, float, float);
void fz_closepath(fz_path*);
void fz_free_path(fz_path *path);
 
void fz_transform_path(fz_path *path, fz_matrix transform);
 
fz_path *fz_clone_path(fz_path *old);
 
fz_rect fz_bound_path(fz_path *path, fz_stroke_state *stroke, fz_matrix ctm);
void fz_debug_path(fz_path *, int indent);
 
/*
* 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_font *face, fz_matrix trm, int wmode);
void fz_add_text(fz_text *text, int gid, int ucs, float x, float y);
void fz_free_text(fz_text *text);
void fz_debug_text(fz_text*, int indent);
fz_rect fz_bound_text(fz_text *text, fz_matrix ctm);
fz_text *fz_clone_text(fz_text *old);
 
/*
* 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
{
int refs;
 
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_shade *shade);
void fz_drop_shade(fz_shade *shade);
void fz_debug_shade(fz_shade *shade);
 
fz_rect fz_bound_shade(fz_shade *shade, fz_matrix ctm);
void fz_paint_shade(fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox);
 
/*
* Glyph cache
*/
 
typedef struct fz_glyph_cache_s fz_glyph_cache;
 
fz_glyph_cache *fz_new_glyph_cache(void);
fz_pixmap *fz_render_ft_glyph(fz_font *font, int cid, fz_matrix trm);
fz_pixmap *fz_render_t3_glyph(fz_font *font, int cid, fz_matrix trm, fz_colorspace *model);
fz_pixmap *fz_render_ft_stroked_glyph(fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state);
fz_pixmap *fz_render_glyph(fz_glyph_cache*, fz_font*, int, fz_matrix, fz_colorspace *model);
fz_pixmap *fz_render_stroked_glyph(fz_glyph_cache*, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke);
void fz_free_glyph_cache(fz_glyph_cache *);
 
/*
* Scan converter
*/
 
int fz_get_aa_level(void);
void fz_set_aa_level(int bits);
 
typedef struct fz_gel_s fz_gel;
 
fz_gel *fz_new_gel(void);
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.
*/
 
enum
{
/* Hints */
FZ_IGNORE_IMAGE = 1,
FZ_IGNORE_SHADE = 2,
 
/* Flags */
FZ_CHARPROC_MASK = 1,
FZ_CHARPROC_COLOR = 2,
};
 
typedef struct fz_device_s fz_device;
 
struct fz_device_s
{
int hints;
int flags;
 
void *user;
void (*free_user)(void *);
 
void (*fill_path)(void *, fz_path *, int even_odd, fz_matrix, fz_colorspace *, float *color, float alpha);
void (*stroke_path)(void *, fz_path *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha);
void (*clip_path)(void *, fz_path *, fz_rect *rect, int even_odd, fz_matrix);
void (*clip_stroke_path)(void *, fz_path *, fz_rect *rect, fz_stroke_state *, fz_matrix);
 
void (*fill_text)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
void (*stroke_text)(void *, fz_text *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha);
void (*clip_text)(void *, fz_text *, fz_matrix, int accumulate);
void (*clip_stroke_text)(void *, fz_text *, fz_stroke_state *, fz_matrix);
void (*ignore_text)(void *, fz_text *, fz_matrix);
 
void (*fill_shade)(void *, fz_shade *shd, fz_matrix ctm, float alpha);
void (*fill_image)(void *, fz_pixmap *img, fz_matrix ctm, float alpha);
void (*fill_image_mask)(void *, fz_pixmap *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha);
void (*clip_image_mask)(void *, fz_pixmap *img, fz_rect *rect, fz_matrix ctm);
 
void (*pop_clip)(void *);
 
void (*begin_mask)(void *, fz_rect, int luminosity, fz_colorspace *, float *bc);
void (*end_mask)(void *);
void (*begin_group)(void *, fz_rect, int isolated, int knockout, int blendmode, float alpha);
void (*end_group)(void *);
 
void (*begin_tile)(void *, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm);
void (*end_tile)(void *);
};
 
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_pixmap *image, fz_matrix ctm, float alpha);
void fz_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
void fz_clip_image_mask(fz_device *dev, fz_pixmap *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(void *user);
void fz_free_device(fz_device *dev);
 
fz_device *fz_new_trace_device(void);
fz_device *fz_new_bbox_device(fz_bbox *bboxp);
fz_device *fz_new_draw_device(fz_glyph_cache *cache, fz_pixmap *dest);
fz_device *fz_new_draw_device_type3(fz_glyph_cache *cache, fz_pixmap *dest);
 
/*
* Text extraction device
*/
 
typedef struct fz_text_span_s fz_text_span;
typedef struct fz_text_char_s fz_text_char;
 
struct fz_text_char_s
{
int c;
fz_bbox bbox;
};
 
struct fz_text_span_s
{
fz_font *font;
float size;
int wmode;
int len, cap;
fz_text_char *text;
fz_text_span *next;
int eol;
};
 
fz_text_span *fz_new_text_span(void);
void fz_free_text_span(fz_text_span *line);
void fz_debug_text_span(fz_text_span *line);
void fz_debug_text_span_xml(fz_text_span *span);
 
fz_device *fz_new_text_device(fz_text_span *text);
 
/*
* Display list device -- record and play back device commands.
*/
 
typedef struct fz_display_list_s fz_display_list;
 
fz_display_list *fz_new_display_list(void);
void fz_free_display_list(fz_display_list *list);
fz_device *fz_new_list_device(fz_display_list *list);
void fz_execute_display_list(fz_display_list *list, fz_device *dev, fz_matrix ctm, fz_bbox area);
 
/*
* Plotting functions.
*/
 
void fz_accelerate(void);
void fz_accelerate_arch(void);
 
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);
 
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
};
 
#endif
/contrib/media/updf/fitz/lrintf.c
0,0 → 1,5
#include <math.h>
 
long long int lrintf(float x) {
return floor(x);
}
/contrib/media/updf/fitz/obj_print.c
0,0 → 1,335
#include "fitz.h"
 
struct fmt
{
char *buf;
int cap;
int len;
int indent;
int tight;
int col;
int sep;
int last;
};
 
static void fmt_obj(struct fmt *fmt, fz_obj *obj);
 
static inline int iswhite(int ch)
{
return
ch == '\000' ||
ch == '\011' ||
ch == '\012' ||
ch == '\014' ||
ch == '\015' ||
ch == '\040';
}
 
static inline int isdelim(int ch)
{
return ch == '(' || ch == ')' ||
ch == '<' || ch == '>' ||
ch == '[' || ch == ']' ||
ch == '{' || ch == '}' ||
ch == '/' ||
ch == '%';
}
 
static inline void fmt_putc(struct fmt *fmt, int c)
{
if (fmt->sep && !isdelim(fmt->last) && !isdelim(c)) {
fmt->sep = 0;
fmt_putc(fmt, ' ');
}
fmt->sep = 0;
 
if (fmt->buf && fmt->len < fmt->cap)
fmt->buf[fmt->len] = c;
 
if (c == '\n')
fmt->col = 0;
else
fmt->col ++;
 
fmt->len ++;
 
fmt->last = c;
}
 
static inline void fmt_indent(struct fmt *fmt)
{
int i = fmt->indent;
while (i--) {
fmt_putc(fmt, ' ');
fmt_putc(fmt, ' ');
}
}
 
static inline void fmt_puts(struct fmt *fmt, char *s)
{
while (*s)
fmt_putc(fmt, *s++);
}
 
static inline void fmt_sep(struct fmt *fmt)
{
fmt->sep = 1;
}
 
static void fmt_str(struct fmt *fmt, fz_obj *obj)
{
char *s = fz_to_str_buf(obj);
int n = fz_to_str_len(obj);
int i, c;
 
fmt_putc(fmt, '(');
for (i = 0; i < n; i++)
{
c = (unsigned char)s[i];
if (c == '\n')
fmt_puts(fmt, "\\n");
else if (c == '\r')
fmt_puts(fmt, "\\r");
else if (c == '\t')
fmt_puts(fmt, "\\t");
else if (c == '\b')
fmt_puts(fmt, "\\b");
else if (c == '\f')
fmt_puts(fmt, "\\f");
else if (c == '(')
fmt_puts(fmt, "\\(");
else if (c == ')')
fmt_puts(fmt, "\\)");
else if (c < 32 || c >= 127) {
char buf[16];
fmt_putc(fmt, '\\');
sprintf(buf, "%03o", c);
fmt_puts(fmt, buf);
}
else
fmt_putc(fmt, c);
}
fmt_putc(fmt, ')');
}
 
static void fmt_hex(struct fmt *fmt, fz_obj *obj)
{
char *s = fz_to_str_buf(obj);
int n = fz_to_str_len(obj);
int i, b, c;
 
fmt_putc(fmt, '<');
for (i = 0; i < n; i++) {
b = (unsigned char) s[i];
c = (b >> 4) & 0x0f;
fmt_putc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA);
c = (b) & 0x0f;
fmt_putc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA);
}
fmt_putc(fmt, '>');
}
 
static void fmt_name(struct fmt *fmt, fz_obj *obj)
{
unsigned char *s = (unsigned char *) fz_to_name(obj);
int i, c;
 
fmt_putc(fmt, '/');
 
for (i = 0; s[i]; i++)
{
if (isdelim(s[i]) || iswhite(s[i]) ||
s[i] == '#' || s[i] < 32 || s[i] >= 127)
{
fmt_putc(fmt, '#');
c = (s[i] >> 4) & 0xf;
fmt_putc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA);
c = s[i] & 0xf;
fmt_putc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA);
}
else
{
fmt_putc(fmt, s[i]);
}
}
}
 
static void fmt_array(struct fmt *fmt, fz_obj *obj)
{
int i;
 
if (fmt->tight) {
fmt_putc(fmt, '[');
for (i = 0; i < fz_array_len(obj); i++) {
fmt_obj(fmt, fz_array_get(obj, i));
fmt_sep(fmt);
}
fmt_putc(fmt, ']');
}
else {
fmt_puts(fmt, "[ ");
for (i = 0; i < fz_array_len(obj); i++) {
if (fmt->col > 60) {
fmt_putc(fmt, '\n');
fmt_indent(fmt);
}
fmt_obj(fmt, fz_array_get(obj, i));
fmt_putc(fmt, ' ');
}
fmt_putc(fmt, ']');
fmt_sep(fmt);
}
}
 
static void fmt_dict(struct fmt *fmt, fz_obj *obj)
{
int i;
fz_obj *key, *val;
 
if (fmt->tight) {
fmt_puts(fmt, "<<");
for (i = 0; i < fz_dict_len(obj); i++) {
fmt_obj(fmt, fz_dict_get_key(obj, i));
fmt_sep(fmt);
fmt_obj(fmt, fz_dict_get_val(obj, i));
fmt_sep(fmt);
}
fmt_puts(fmt, ">>");
}
else {
fmt_puts(fmt, "<<\n");
fmt->indent ++;
for (i = 0; i < fz_dict_len(obj); i++) {
key = fz_dict_get_key(obj, i);
val = fz_dict_get_val(obj, i);
fmt_indent(fmt);
fmt_obj(fmt, key);
fmt_putc(fmt, ' ');
if (!fz_is_indirect(val) && fz_is_array(val))
fmt->indent ++;
fmt_obj(fmt, val);
fmt_putc(fmt, '\n');
if (!fz_is_indirect(val) && fz_is_array(val))
fmt->indent --;
}
fmt->indent --;
fmt_indent(fmt);
fmt_puts(fmt, ">>");
}
}
 
static void fmt_obj(struct fmt *fmt, fz_obj *obj)
{
char buf[256];
 
if (!obj)
fmt_puts(fmt, "<NULL>");
else if (fz_is_indirect(obj))
{
sprintf(buf, "%d %d R", fz_to_num(obj), fz_to_gen(obj));
fmt_puts(fmt, buf);
}
else if (fz_is_null(obj))
fmt_puts(fmt, "null");
else if (fz_is_bool(obj))
fmt_puts(fmt, fz_to_bool(obj) ? "true" : "false");
else if (fz_is_int(obj))
{
sprintf(buf, "%d", fz_to_int(obj));
fmt_puts(fmt, buf);
}
else if (fz_is_real(obj))
{
sprintf(buf, "%g", fz_to_real(obj));
if (strchr(buf, 'e')) /* bad news! */
sprintf(buf, fabsf(fz_to_real(obj)) > 1 ? "%1.1f" : "%1.8f", fz_to_real(obj));
fmt_puts(fmt, buf);
}
else if (fz_is_string(obj))
{
char *str = fz_to_str_buf(obj);
int len = fz_to_str_len(obj);
int added = 0;
int i, c;
for (i = 0; i < len; i++) {
c = (unsigned char)str[i];
if (strchr("()\\\n\r\t\b\f", c))
added ++;
else if (c < 32 || c >= 127)
added += 3;
}
if (added < len)
fmt_str(fmt, obj);
else
fmt_hex(fmt, obj);
}
else if (fz_is_name(obj))
fmt_name(fmt, obj);
else if (fz_is_array(obj))
fmt_array(fmt, obj);
else if (fz_is_dict(obj))
fmt_dict(fmt, obj);
else
fmt_puts(fmt, "<unknown object>");
}
 
static int
fz_sprint_obj(char *s, int n, fz_obj *obj, int tight)
{
struct fmt fmt;
 
fmt.indent = 0;
fmt.col = 0;
fmt.sep = 0;
fmt.last = 0;
 
fmt.tight = tight;
fmt.buf = s;
fmt.cap = n;
fmt.len = 0;
fmt_obj(&fmt, obj);
 
if (fmt.buf && fmt.len < fmt.cap)
fmt.buf[fmt.len] = '\0';
 
return fmt.len;
}
 
int
fz_fprint_obj(FILE *fp, fz_obj *obj, int tight)
{
char buf[1024];
char *ptr;
int n;
 
n = fz_sprint_obj(NULL, 0, obj, tight);
if ((n + 1) < sizeof buf)
{
fz_sprint_obj(buf, sizeof buf, obj, tight);
fputs(buf, fp);
fputc('\n', fp);
}
else
{
ptr = fz_malloc(n + 1);
fz_sprint_obj(ptr, n + 1, obj, tight);
fputs(ptr, fp);
fputc('\n', fp);
fz_free(ptr);
}
return n;
}
 
void
fz_debug_obj(fz_obj *obj)
{
fz_fprint_obj(stdout, obj, 0);
}
 
void
fz_debug_ref(fz_obj *ref)
{
fz_obj *obj;
obj = fz_resolve_indirect(ref);
fz_debug_obj(obj);
}
/contrib/media/updf/fitz/res_bitmap.c
0,0 → 1,76
#include "fitz.h"
 
fz_bitmap *
fz_new_bitmap(int w, int h, int n)
{
fz_bitmap *bit;
 
bit = fz_malloc(sizeof(fz_bitmap));
bit->refs = 1;
bit->w = w;
bit->h = h;
bit->n = n;
/* Span is 32 bit aligned. We may want to make this 64 bit if we
* use SSE2 etc. */
bit->stride = ((n * w + 31) & ~31) >> 3;
 
bit->samples = fz_calloc(h, bit->stride);
 
return bit;
}
 
fz_bitmap *
fz_keep_bitmap(fz_bitmap *pix)
{
pix->refs++;
return pix;
}
 
void
fz_drop_bitmap(fz_bitmap *bit)
{
if (bit && --bit->refs == 0)
{
fz_free(bit->samples);
fz_free(bit);
}
}
 
void
fz_clear_bitmap(fz_bitmap *bit)
{
memset(bit->samples, 0, bit->stride * bit->h);
}
 
/*
* Write bitmap to PBM file
*/
 
fz_error
fz_write_pbm(fz_bitmap *bitmap, char *filename)
{
FILE *fp;
unsigned char *p;
int h, bytestride;
 
fp = fopen(filename, "wb");
if (!fp)
return fz_throw("cannot open file '%s': %s", filename, strerror(errno));
 
assert(bitmap->n == 1);
 
fprintf(fp, "P4\n%d %d\n", bitmap->w, bitmap->h);
 
p = bitmap->samples;
 
h = bitmap->h;
bytestride = (bitmap->w + 7) >> 3;
while (h--)
{
fwrite(p, 1, bytestride, fp);
p += bitmap->stride;
}
 
fclose(fp);
return fz_okay;
}
/contrib/media/updf/fitz/res_colorspace.c
0,0 → 1,685
#include "fitz.h"
 
#define SLOWCMYK
 
fz_colorspace *
fz_new_colorspace(char *name, int n)
{
fz_colorspace *cs = fz_malloc(sizeof(fz_colorspace));
cs->refs = 1;
fz_strlcpy(cs->name, name, sizeof cs->name);
cs->n = n;
cs->to_rgb = NULL;
cs->from_rgb = NULL;
cs->free_data = NULL;
cs->data = NULL;
return cs;
}
 
fz_colorspace *
fz_keep_colorspace(fz_colorspace *cs)
{
if (cs->refs < 0)
return cs;
cs->refs ++;
return cs;
}
 
void
fz_drop_colorspace(fz_colorspace *cs)
{
if (cs && cs->refs < 0)
return;
if (cs && --cs->refs == 0)
{
if (cs->free_data && cs->data)
cs->free_data(cs);
fz_free(cs);
}
}
 
/* Device colorspace definitions */
 
static void gray_to_rgb(fz_colorspace *cs, float *gray, float *rgb)
{
rgb[0] = gray[0];
rgb[1] = gray[0];
rgb[2] = gray[0];
}
 
static void rgb_to_gray(fz_colorspace *cs, float *rgb, float *gray)
{
float r = rgb[0];
float g = rgb[1];
float b = rgb[2];
gray[0] = r * 0.3f + g * 0.59f + b * 0.11f;
}
 
static void rgb_to_rgb(fz_colorspace *cs, float *rgb, float *xyz)
{
xyz[0] = rgb[0];
xyz[1] = rgb[1];
xyz[2] = rgb[2];
}
 
static void bgr_to_rgb(fz_colorspace *cs, float *bgr, float *rgb)
{
rgb[0] = bgr[2];
rgb[1] = bgr[1];
rgb[2] = bgr[0];
}
 
static void rgb_to_bgr(fz_colorspace *cs, float *rgb, float *bgr)
{
bgr[0] = rgb[2];
bgr[1] = rgb[1];
bgr[2] = rgb[0];
}
 
static void cmyk_to_rgb(fz_colorspace *cs, float *cmyk, float *rgb)
{
#ifdef SLOWCMYK /* from poppler */
float c = cmyk[0], m = cmyk[1], y = cmyk[2], k = cmyk[3];
float c1 = 1 - c, m1 = 1 - m, y1 = 1 - y, k1 = 1 - k;
float r, g, b, x;
 
/* this is a matrix multiplication, unrolled for performance */
x = c1 * m1 * y1 * k1; /* 0 0 0 0 */
r = g = b = x;
x = c1 * m1 * y1 * k; /* 0 0 0 1 */
r += 0.1373 * x;
g += 0.1216 * x;
b += 0.1255 * x;
x = c1 * m1 * y * k1; /* 0 0 1 0 */
r += x;
g += 0.9490 * x;
x = c1 * m1 * y * k; /* 0 0 1 1 */
r += 0.1098 * x;
g += 0.1020 * x;
x = c1 * m * y1 * k1; /* 0 1 0 0 */
r += 0.9255 * x;
b += 0.5490 * x;
x = c1 * m * y1 * k; /* 0 1 0 1 */
r += 0.1412 * x;
x = c1 * m * y * k1; /* 0 1 1 0 */
r += 0.9294 * x;
g += 0.1098 * x;
b += 0.1412 * x;
x = c1 * m * y * k; /* 0 1 1 1 */
r += 0.1333 * x;
x = c * m1 * y1 * k1; /* 1 0 0 0 */
g += 0.6784 * x;
b += 0.9373 * x;
x = c * m1 * y1 * k; /* 1 0 0 1 */
g += 0.0588 * x;
b += 0.1412 * x;
x = c * m1 * y * k1; /* 1 0 1 0 */
g += 0.6510 * x;
b += 0.3137 * x;
x = c * m1 * y * k; /* 1 0 1 1 */
g += 0.0745 * x;
x = c * m * y1 * k1; /* 1 1 0 0 */
r += 0.1804 * x;
g += 0.1922 * x;
b += 0.5725 * x;
x = c * m * y1 * k; /* 1 1 0 1 */
b += 0.0078 * x;
x = c * m * y * k1; /* 1 1 1 0 */
r += 0.2118 * x;
g += 0.2119 * x;
b += 0.2235 * x;
 
rgb[0] = CLAMP(r, 0, 1);
rgb[1] = CLAMP(g, 0, 1);
rgb[2] = CLAMP(b, 0, 1);
#else
rgb[0] = 1 - MIN(1, cmyk[0] + cmyk[3]);
rgb[1] = 1 - MIN(1, cmyk[1] + cmyk[3]);
rgb[2] = 1 - MIN(1, cmyk[2] + cmyk[3]);
#endif
}
 
static void rgb_to_cmyk(fz_colorspace *cs, float *rgb, float *cmyk)
{
float c, m, y, k;
c = 1 - rgb[0];
m = 1 - rgb[1];
y = 1 - rgb[2];
k = MIN(c, MIN(m, y));
cmyk[0] = c - k;
cmyk[1] = m - k;
cmyk[2] = y - k;
cmyk[3] = k;
}
 
static fz_colorspace k_device_gray = { -1, "DeviceGray", 1, gray_to_rgb, rgb_to_gray };
static fz_colorspace k_device_rgb = { -1, "DeviceRGB", 3, rgb_to_rgb, rgb_to_rgb };
static fz_colorspace k_device_bgr = { -1, "DeviceRGB", 3, bgr_to_rgb, rgb_to_bgr };
static fz_colorspace k_device_cmyk = { -1, "DeviceCMYK", 4, cmyk_to_rgb, rgb_to_cmyk };
 
fz_colorspace *fz_device_gray = &k_device_gray;
fz_colorspace *fz_device_rgb = &k_device_rgb;
fz_colorspace *fz_device_bgr = &k_device_bgr;
fz_colorspace *fz_device_cmyk = &k_device_cmyk;
 
fz_colorspace *
fz_find_device_colorspace(char *name)
{
if (!strcmp(name, "DeviceGray"))
return fz_device_gray;
if (!strcmp(name, "DeviceRGB"))
return fz_device_rgb;
if (!strcmp(name, "DeviceBGR"))
return fz_device_bgr;
if (!strcmp(name, "DeviceCMYK"))
return fz_device_cmyk;
fz_warn("unknown device colorspace: %s", name);
return NULL;
}
 
/* Fast pixmap color conversions */
 
static void fast_gray_to_rgb(fz_pixmap *src, fz_pixmap *dst)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
while (n--)
{
d[0] = s[0];
d[1] = s[0];
d[2] = s[0];
d[3] = s[1];
s += 2;
d += 4;
}
}
 
static void fast_gray_to_cmyk(fz_pixmap *src, fz_pixmap *dst)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
while (n--)
{
d[0] = 0;
d[1] = 0;
d[2] = 0;
d[3] = s[0];
d[4] = s[1];
s += 2;
d += 5;
}
}
 
static void fast_rgb_to_gray(fz_pixmap *src, fz_pixmap *dst)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
while (n--)
{
d[0] = ((s[0]+1) * 77 + (s[1]+1) * 150 + (s[2]+1) * 28) >> 8;
d[1] = s[3];
s += 4;
d += 2;
}
}
 
static void fast_bgr_to_gray(fz_pixmap *src, fz_pixmap *dst)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
while (n--)
{
d[0] = ((s[0]+1) * 28 + (s[1]+1) * 150 + (s[2]+1) * 77) >> 8;
d[1] = s[3];
s += 4;
d += 2;
}
}
 
static void fast_rgb_to_cmyk(fz_pixmap *src, fz_pixmap *dst)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
while (n--)
{
unsigned char c = 255 - s[0];
unsigned char m = 255 - s[1];
unsigned char y = 255 - s[2];
unsigned char k = MIN(c, MIN(m, y));
d[0] = c - k;
d[1] = m - k;
d[2] = y - k;
d[3] = k;
d[4] = s[3];
s += 4;
d += 5;
}
}
 
static void fast_bgr_to_cmyk(fz_pixmap *src, fz_pixmap *dst)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
while (n--)
{
unsigned char c = 255 - s[2];
unsigned char m = 255 - s[1];
unsigned char y = 255 - s[0];
unsigned char k = MIN(c, MIN(m, y));
d[0] = c - k;
d[1] = m - k;
d[2] = y - k;
d[3] = k;
d[4] = s[3];
s += 4;
d += 5;
}
}
 
static void fast_cmyk_to_gray(fz_pixmap *src, fz_pixmap *dst)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
while (n--)
{
unsigned char c = fz_mul255(s[0], 77);
unsigned char m = fz_mul255(s[1], 150);
unsigned char y = fz_mul255(s[2], 28);
d[0] = 255 - MIN(c + m + y + s[3], 255);
d[1] = s[4];
s += 5;
d += 2;
}
}
 
static void fast_cmyk_to_rgb(fz_pixmap *src, fz_pixmap *dst)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
while (n--)
{
#ifdef SLOWCMYK
float cmyk[4], rgb[3];
cmyk[0] = s[0] / 255.0f;
cmyk[1] = s[1] / 255.0f;
cmyk[2] = s[2] / 255.0f;
cmyk[3] = s[3] / 255.0f;
cmyk_to_rgb(NULL, cmyk, rgb);
d[0] = rgb[0] * 255;
d[1] = rgb[1] * 255;
d[2] = rgb[2] * 255;
#else
d[0] = 255 - MIN(s[0] + s[3], 255);
d[1] = 255 - MIN(s[1] + s[3], 255);
d[2] = 255 - MIN(s[2] + s[3], 255);
#endif
d[3] = s[4];
s += 5;
d += 4;
}
}
 
static void fast_cmyk_to_bgr(fz_pixmap *src, fz_pixmap *dst)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
while (n--)
{
#ifdef SLOWCMYK
float cmyk[4], rgb[3];
cmyk[0] = s[0] / 255.0f;
cmyk[1] = s[1] / 255.0f;
cmyk[2] = s[2] / 255.0f;
cmyk[3] = s[3] / 255.0f;
cmyk_to_rgb(NULL, cmyk, rgb);
d[0] = rgb[2] * 255;
d[1] = rgb[1] * 255;
d[2] = rgb[0] * 255;
#else
d[0] = 255 - MIN(s[2] + s[3], 255);
d[1] = 255 - MIN(s[1] + s[3], 255);
d[2] = 255 - MIN(s[0] + s[3], 255);
#endif
d[3] = s[4];
s += 5;
d += 4;
}
}
 
static void fast_rgb_to_bgr(fz_pixmap *src, fz_pixmap *dst)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
int n = src->w * src->h;
while (n--)
{
d[0] = s[2];
d[1] = s[1];
d[2] = s[0];
d[3] = s[3];
s += 4;
d += 4;
}
}
 
static void
fz_std_conv_pixmap(fz_pixmap *src, fz_pixmap *dst)
{
float srcv[FZ_MAX_COLORS];
float dstv[FZ_MAX_COLORS];
int srcn, dstn;
int y, x, k, i;
 
fz_colorspace *ss = src->colorspace;
fz_colorspace *ds = dst->colorspace;
 
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
 
assert(src->w == dst->w && src->h == dst->h);
assert(src->n == ss->n + 1);
assert(dst->n == ds->n + 1);
 
srcn = ss->n;
dstn = ds->n;
 
/* Special case for Lab colorspace (scaling of components to float) */
if (!strcmp(ss->name, "Lab") && srcn == 3)
{
for (y = 0; y < src->h; y++)
{
for (x = 0; x < src->w; x++)
{
srcv[0] = *s++ / 255.0f * 100;
srcv[1] = *s++ - 128;
srcv[2] = *s++ - 128;
 
fz_convert_color(ss, srcv, ds, dstv);
 
for (k = 0; k < dstn; k++)
*d++ = dstv[k] * 255;
 
*d++ = *s++;
}
}
}
 
/* Brute-force for small images */
else if (src->w * src->h < 256)
{
for (y = 0; y < src->h; y++)
{
for (x = 0; x < src->w; x++)
{
for (k = 0; k < srcn; k++)
srcv[k] = *s++ / 255.0f;
 
fz_convert_color(ss, srcv, ds, dstv);
 
for (k = 0; k < dstn; k++)
*d++ = dstv[k] * 255;
 
*d++ = *s++;
}
}
}
 
/* 1-d lookup table for separation and similar colorspaces */
else if (srcn == 1)
{
unsigned char lookup[FZ_MAX_COLORS * 256];
 
for (i = 0; i < 256; i++)
{
srcv[0] = i / 255.0f;
fz_convert_color(ss, srcv, ds, dstv);
for (k = 0; k < dstn; k++)
lookup[i * dstn + k] = dstv[k] * 255;
}
 
for (y = 0; y < src->h; y++)
{
for (x = 0; x < src->w; x++)
{
i = *s++;
for (k = 0; k < dstn; k++)
*d++ = lookup[i * dstn + k];
*d++ = *s++;
}
}
}
 
/* Memoize colors using a hash table for the general case */
else
{
fz_hash_table *lookup;
unsigned char *color;
 
lookup = fz_new_hash_table(509, srcn);
 
for (y = 0; y < src->h; y++)
{
for (x = 0; x < src->w; x++)
{
color = fz_hash_find(lookup, s);
if (color)
{
memcpy(d, color, dstn);
s += srcn;
d += dstn;
*d++ = *s++;
}
else
{
for (k = 0; k < srcn; k++)
srcv[k] = *s++ / 255.0f;
fz_convert_color(ss, srcv, ds, dstv);
for (k = 0; k < dstn; k++)
*d++ = dstv[k] * 255;
 
fz_hash_insert(lookup, s - srcn, d - dstn);
 
*d++ = *s++;
}
}
}
 
fz_free_hash(lookup);
}
}
 
void
fz_convert_pixmap(fz_pixmap *sp, fz_pixmap *dp)
{
fz_colorspace *ss = sp->colorspace;
fz_colorspace *ds = dp->colorspace;
 
assert(ss && ds);
 
if (sp->mask)
dp->mask = fz_keep_pixmap(sp->mask);
dp->interpolate = sp->interpolate;
 
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(sp, dp);
}
 
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(sp, dp);
}
 
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 */
else if (ds == fz_device_cmyk) fast_bgr_to_cmyk(sp, dp);
else fz_std_conv_pixmap(sp, dp);
}
 
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(sp, dp);
else if (ds == fz_device_rgb) fast_cmyk_to_rgb(sp, dp);
else fz_std_conv_pixmap(sp, dp);
}
 
else fz_std_conv_pixmap(sp, dp);
}
 
/* Convert a single color */
 
static void
fz_std_conv_color(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv)
{
float rgb[3];
int i;
 
if (srcs != dsts)
{
assert(srcs->to_rgb && dsts->from_rgb);
srcs->to_rgb(srcs, srcv, rgb);
dsts->from_rgb(dsts, rgb, dstv);
for (i = 0; i < dsts->n; i++)
dstv[i] = CLAMP(dstv[i], 0, 1);
}
else
{
for (i = 0; i < srcs->n; i++)
dstv[i] = srcv[i];
}
}
 
void
fz_convert_color(fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv)
{
if (ss == fz_device_gray)
{
if ((ds == fz_device_rgb) || (ds == fz_device_bgr))
{
dv[0] = sv[0];
dv[1] = sv[0];
dv[2] = sv[0];
}
else if (ds == fz_device_cmyk)
{
dv[0] = 0;
dv[1] = 0;
dv[2] = 0;
dv[3] = sv[0];
}
else
fz_std_conv_color(ss, sv, ds, dv);
}
 
else if (ss == fz_device_rgb)
{
if (ds == fz_device_gray)
{
dv[0] = sv[0] * 0.3f + sv[1] * 0.59f + sv[2] * 0.11f;
}
else if (ds == fz_device_bgr)
{
dv[0] = sv[2];
dv[1] = sv[1];
dv[2] = sv[0];
}
else if (ds == fz_device_cmyk)
{
float c = 1 - sv[0];
float m = 1 - sv[1];
float y = 1 - sv[2];
float k = MIN(c, MIN(m, y));
dv[0] = c - k;
dv[1] = m - k;
dv[2] = y - k;
dv[3] = k;
}
else
fz_std_conv_color(ss, sv, ds, dv);
}
 
else if (ss == fz_device_bgr)
{
if (ds == fz_device_gray)
{
dv[0] = sv[0] * 0.11f + sv[1] * 0.59f + sv[2] * 0.3f;
}
else if (ds == fz_device_bgr)
{
dv[0] = sv[2];
dv[1] = sv[1];
dv[2] = sv[0];
}
else if (ds == fz_device_cmyk)
{
float c = 1 - sv[2];
float m = 1 - sv[1];
float y = 1 - sv[0];
float k = MIN(c, MIN(m, y));
dv[0] = c - k;
dv[1] = m - k;
dv[2] = y - k;
dv[3] = k;
}
else
fz_std_conv_color(ss, sv, ds, dv);
}
 
else if (ss == fz_device_cmyk)
{
if (ds == fz_device_gray)
{
float c = sv[0] * 0.3f;
float m = sv[1] * 0.59f;
float y = sv[2] * 0.11f;
dv[0] = 1 - MIN(c + m + y + sv[3], 1);
}
else if (ds == fz_device_rgb)
{
#ifdef SLOWCMYK
cmyk_to_rgb(NULL, sv, dv);
#else
dv[0] = 1 - MIN(sv[0] + sv[3], 1);
dv[1] = 1 - MIN(sv[1] + sv[3], 1);
dv[2] = 1 - MIN(sv[2] + sv[3], 1);
#endif
}
else if (ds == fz_device_bgr)
{
#ifdef SLOWCMYK
float rgb[3];
cmyk_to_rgb(NULL, sv, rgb);
dv[0] = rgb[2];
dv[1] = rgb[1];
dv[2] = rgb[0];
#else
dv[0] = 1 - MIN(sv[2] + sv[3], 1);
dv[1] = 1 - MIN(sv[1] + sv[3], 1);
dv[2] = 1 - MIN(sv[0] + sv[3], 1);
#endif
}
else
fz_std_conv_color(ss, sv, ds, dv);
}
 
else
fz_std_conv_color(ss, sv, ds, dv);
}
/contrib/media/updf/fitz/res_font.c
0,0 → 1,609
#include "fitz.h"
 
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_STROKER_H
 
static void fz_finalize_freetype(void);
 
static fz_font *
fz_new_font(char *name)
{
fz_font *font;
 
font = fz_malloc(sizeof(fz_font));
font->refs = 1;
 
if (name)
fz_strlcpy(font->name, name, sizeof font->name);
else
fz_strlcpy(font->name, "(null)", sizeof font->name);
 
font->ft_face = NULL;
font->ft_substitute = 0;
font->ft_bold = 0;
font->ft_italic = 0;
font->ft_hint = 0;
 
font->ft_file = NULL;
font->ft_data = NULL;
font->ft_size = 0;
 
font->t3matrix = fz_identity;
font->t3resources = NULL;
font->t3procs = NULL;
font->t3widths = NULL;
font->t3xref = NULL;
font->t3run = NULL;
 
font->bbox.x0 = 0;
font->bbox.y0 = 0;
font->bbox.x1 = 1000;
font->bbox.y1 = 1000;
 
font->width_count = 0;
font->width_table = NULL;
 
return font;
}
 
fz_font *
fz_keep_font(fz_font *font)
{
font->refs ++;
return font;
}
 
void
fz_drop_font(fz_font *font)
{
int fterr;
int i;
 
if (font && --font->refs == 0)
{
if (font->t3procs)
{
if (font->t3resources)
fz_drop_obj(font->t3resources);
for (i = 0; i < 256; i++)
if (font->t3procs[i])
fz_drop_buffer(font->t3procs[i]);
fz_free(font->t3procs);
fz_free(font->t3widths);
}
 
if (font->ft_face)
{
fterr = FT_Done_Face((FT_Face)font->ft_face);
if (fterr)
fz_warn("freetype finalizing face: %s", ft_error_string(fterr));
fz_finalize_freetype();
}
 
if (font->ft_file)
fz_free(font->ft_file);
if (font->ft_data)
fz_free(font->ft_data);
 
if (font->width_table)
fz_free(font->width_table);
 
fz_free(font);
}
}
 
void
fz_set_font_bbox(fz_font *font, float xmin, float ymin, float xmax, float ymax)
{
font->bbox.x0 = xmin;
font->bbox.y0 = ymin;
font->bbox.x1 = xmax;
font->bbox.y1 = ymax;
}
 
/*
* Freetype hooks
*/
 
static FT_Library fz_ftlib = NULL;
static int fz_ftlib_refs = 0;
 
#undef __FTERRORS_H__
#define FT_ERRORDEF(e, v, s) { (e), (s) },
#define FT_ERROR_START_LIST
#define FT_ERROR_END_LIST { 0, NULL }
 
struct ft_error
{
int err;
char *str;
};
 
static const struct ft_error ft_errors[] =
{
#include FT_ERRORS_H
};
 
char *ft_error_string(int err)
{
const struct ft_error *e;
 
for (e = ft_errors; e->str != NULL; e++)
if (e->err == err)
return e->str;
 
return "Unknown error";
}
 
static fz_error
fz_init_freetype(void)
{
int fterr;
int maj, min, pat;
 
if (fz_ftlib)
{
fz_ftlib_refs++;
return fz_okay;
}
 
fterr = FT_Init_FreeType(&fz_ftlib);
if (fterr)
return fz_throw("cannot init freetype: %s", ft_error_string(fterr));
 
FT_Library_Version(fz_ftlib, &maj, &min, &pat);
if (maj == 2 && min == 1 && pat < 7)
{
fterr = FT_Done_FreeType(fz_ftlib);
if (fterr)
fz_warn("freetype finalizing: %s", ft_error_string(fterr));
return fz_throw("freetype version too old: %d.%d.%d", maj, min, pat);
}
 
fz_ftlib_refs++;
return fz_okay;
}
 
static void
fz_finalize_freetype(void)
{
int fterr;
 
if (--fz_ftlib_refs == 0)
{
fterr = FT_Done_FreeType(fz_ftlib);
if (fterr)
fz_warn("freetype finalizing: %s", ft_error_string(fterr));
fz_ftlib = NULL;
}
}
 
fz_error
fz_new_font_from_file(fz_font **fontp, char *path, int index)
{
FT_Face face;
fz_error error;
fz_font *font;
int fterr;
 
error = fz_init_freetype();
if (error)
return fz_rethrow(error, "cannot init freetype library");
 
fterr = FT_New_Face(fz_ftlib, path, index, &face);
if (fterr)
return fz_throw("freetype: cannot load font: %s", ft_error_string(fterr));
 
font = fz_new_font(face->family_name);
font->ft_face = face;
font->bbox.x0 = face->bbox.xMin * 1000 / face->units_per_EM;
font->bbox.y0 = face->bbox.yMin * 1000 / face->units_per_EM;
font->bbox.x1 = face->bbox.xMax * 1000 / face->units_per_EM;
font->bbox.y1 = face->bbox.yMax * 1000 / face->units_per_EM;
 
*fontp = font;
return fz_okay;
}
 
fz_error
fz_new_font_from_memory(fz_font **fontp, unsigned char *data, int len, int index)
{
FT_Face face;
fz_error error;
fz_font *font;
int fterr;
 
error = fz_init_freetype();
if (error)
return fz_rethrow(error, "cannot init freetype library");
 
fterr = FT_New_Memory_Face(fz_ftlib, data, len, index, &face);
if (fterr)
return fz_throw("freetype: cannot load font: %s", ft_error_string(fterr));
 
font = fz_new_font(face->family_name);
font->ft_face = face;
font->bbox.x0 = face->bbox.xMin * 1000 / face->units_per_EM;
font->bbox.y0 = face->bbox.yMin * 1000 / face->units_per_EM;
font->bbox.x1 = face->bbox.xMax * 1000 / face->units_per_EM;
font->bbox.y1 = face->bbox.yMax * 1000 / face->units_per_EM;
 
*fontp = font;
return fz_okay;
}
 
static fz_matrix
fz_adjust_ft_glyph_width(fz_font *font, int gid, fz_matrix trm)
{
/* Fudge the font matrix to stretch the glyph if we've substituted the font. */
if (font->ft_substitute && gid < font->width_count)
{
FT_Error fterr;
int subw;
int realw;
float scale;
 
/* TODO: use FT_Get_Advance */
fterr = FT_Set_Char_Size(font->ft_face, 1000, 1000, 72, 72);
if (fterr)
fz_warn("freetype setting character size: %s", ft_error_string(fterr));
 
fterr = FT_Load_Glyph(font->ft_face, gid,
FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
if (fterr)
fz_warn("freetype failed to load glyph: %s", ft_error_string(fterr));
 
realw = ((FT_Face)font->ft_face)->glyph->metrics.horiAdvance;
subw = font->width_table[gid];
if (realw)
scale = (float) subw / realw;
else
scale = 1;
 
return fz_concat(fz_scale(scale, 1), trm);
}
 
return trm;
}
 
static fz_pixmap *
fz_copy_ft_bitmap(int left, int top, FT_Bitmap *bitmap)
{
fz_pixmap *pixmap;
int y;
 
pixmap = fz_new_pixmap(NULL, bitmap->width, bitmap->rows);
pixmap->x = left;
pixmap->y = top - bitmap->rows;
 
if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO)
{
for (y = 0; y < pixmap->h; y++)
{
unsigned char *out = pixmap->samples + y * pixmap->w;
unsigned char *in = bitmap->buffer + (pixmap->h - y - 1) * bitmap->pitch;
unsigned char bit = 0x80;
int w = pixmap->w;
while (w--)
{
*out++ = (*in & bit) ? 255 : 0;
bit >>= 1;
if (bit == 0)
{
bit = 0x80;
in++;
}
}
}
}
else
{
for (y = 0; y < pixmap->h; y++)
{
memcpy(pixmap->samples + y * pixmap->w,
bitmap->buffer + (pixmap->h - y - 1) * bitmap->pitch,
pixmap->w);
}
}
 
return pixmap;
}
 
fz_pixmap *
fz_render_ft_glyph(fz_font *font, int gid, fz_matrix trm)
{
FT_Face face = font->ft_face;
FT_Matrix m;
FT_Vector v;
FT_Error fterr;
 
trm = fz_adjust_ft_glyph_width(font, gid, trm);
 
if (font->ft_italic)
trm = fz_concat(fz_shear(0.3f, 0), trm);
 
/*
Freetype mutilates complex glyphs if they are loaded
with FT_Set_Char_Size 1.0. it rounds the coordinates
before applying transformation. to get more precision in
freetype, we shift part of the scale in the matrix
into FT_Set_Char_Size instead
*/
 
m.xx = trm.a * 64; /* should be 65536 */
m.yx = trm.b * 64;
m.xy = trm.c * 64;
m.yy = trm.d * 64;
v.x = trm.e * 64;
v.y = trm.f * 64;
 
fterr = FT_Set_Char_Size(face, 65536, 65536, 72, 72); /* should be 64, 64 */
if (fterr)
fz_warn("freetype setting character size: %s", ft_error_string(fterr));
FT_Set_Transform(face, &m, &v);
 
if (fz_get_aa_level() == 0)
{
/* If you really want grid fitting, enable this code. */
float scale = fz_matrix_expansion(trm);
m.xx = trm.a * 65536 / scale;
m.xy = trm.b * 65536 / scale;
m.yx = trm.c * 65536 / scale;
m.yy = trm.d * 65536 / scale;
v.x = 0;
v.y = 0;
 
fterr = FT_Set_Char_Size(face, 64 * scale, 64 * scale, 72, 72);
if (fterr)
fz_warn("freetype setting character size: %s", ft_error_string(fterr));
FT_Set_Transform(face, &m, &v);
fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_TARGET_MONO);
if (fterr)
fz_warn("freetype load glyph (gid %d): %s", gid, ft_error_string(fterr));
}
else if (font->ft_hint)
{
/*
Enable hinting, but keep the huge char size so that
it is hinted for a character. This will in effect nullify
the effect of grid fitting. This form of hinting should
only be used for DynaLab and similar tricky TrueType fonts,
so that we get the correct outline shape.
*/
fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP);
if (fterr)
fz_warn("freetype load glyph (gid %d): %s", gid, ft_error_string(fterr));
}
else
{
fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
if (fterr)
{
fz_warn("freetype load glyph (gid %d): %s", gid, ft_error_string(fterr));
return NULL;
}
}
 
if (font->ft_bold)
{
float strength = fz_matrix_expansion(trm) * 0.04f;
FT_Outline_Embolden(&face->glyph->outline, strength * 64);
FT_Outline_Translate(&face->glyph->outline, -strength * 32, -strength * 32);
}
 
fterr = FT_Render_Glyph(face->glyph, fz_get_aa_level() > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
if (fterr)
{
fz_warn("freetype render glyph (gid %d): %s", gid, ft_error_string(fterr));
return NULL;
}
 
return fz_copy_ft_bitmap(face->glyph->bitmap_left, face->glyph->bitmap_top, &face->glyph->bitmap);
}
 
fz_pixmap *
fz_render_ft_stroked_glyph(fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state)
{
FT_Face face = font->ft_face;
float expansion = fz_matrix_expansion(ctm);
int linewidth = state->linewidth * expansion * 64 / 2;
FT_Matrix m;
FT_Vector v;
FT_Error fterr;
FT_Stroker stroker;
FT_Glyph glyph;
FT_BitmapGlyph bitmap;
fz_pixmap *pixmap;
 
trm = fz_adjust_ft_glyph_width(font, gid, trm);
 
if (font->ft_italic)
trm = fz_concat(fz_shear(0.3f, 0), trm);
 
m.xx = trm.a * 64; /* should be 65536 */
m.yx = trm.b * 64;
m.xy = trm.c * 64;
m.yy = trm.d * 64;
v.x = trm.e * 64;
v.y = trm.f * 64;
 
fterr = FT_Set_Char_Size(face, 65536, 65536, 72, 72); /* should be 64, 64 */
if (fterr)
{
fz_warn("FT_Set_Char_Size: %s", ft_error_string(fterr));
return NULL;
}
 
FT_Set_Transform(face, &m, &v);
 
fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
if (fterr)
{
fz_warn("FT_Load_Glyph(gid %d): %s", gid, ft_error_string(fterr));
return NULL;
}
 
fterr = FT_Stroker_New(fz_ftlib, &stroker);
if (fterr)
{
fz_warn("FT_Stroker_New: %s", ft_error_string(fterr));
return NULL;
}
 
FT_Stroker_Set(stroker, linewidth, state->start_cap, state->linejoin, state->miterlimit * 65536);
 
fterr = FT_Get_Glyph(face->glyph, &glyph);
if (fterr)
{
fz_warn("FT_Get_Glyph: %s", ft_error_string(fterr));
FT_Stroker_Done(stroker);
return NULL;
}
 
fterr = FT_Glyph_Stroke(&glyph, stroker, 1);
if (fterr)
{
fz_warn("FT_Glyph_Stroke: %s", ft_error_string(fterr));
FT_Done_Glyph(glyph);
FT_Stroker_Done(stroker);
return NULL;
}
 
FT_Stroker_Done(stroker);
 
fterr = FT_Glyph_To_Bitmap(&glyph, fz_get_aa_level() > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
if (fterr)
{
fz_warn("FT_Glyph_To_Bitmap: %s", ft_error_string(fterr));
FT_Done_Glyph(glyph);
return NULL;
}
 
bitmap = (FT_BitmapGlyph)glyph;
pixmap = fz_copy_ft_bitmap(bitmap->left, bitmap->top, &bitmap->bitmap);
FT_Done_Glyph(glyph);
 
return pixmap;
}
 
/*
* Type 3 fonts...
*/
 
fz_font *
fz_new_type3_font(char *name, fz_matrix matrix)
{
fz_font *font;
int i;
 
font = fz_new_font(name);
font->t3procs = fz_calloc(256, sizeof(fz_buffer*));
font->t3widths = fz_calloc(256, sizeof(float));
 
font->t3matrix = matrix;
for (i = 0; i < 256; i++)
{
font->t3procs[i] = NULL;
font->t3widths[i] = 0;
}
 
return font;
}
 
fz_pixmap *
fz_render_t3_glyph(fz_font *font, int gid, fz_matrix trm, fz_colorspace *model)
{
fz_error error;
fz_matrix ctm;
fz_buffer *contents;
fz_bbox bbox;
fz_device *dev;
fz_glyph_cache *cache;
fz_pixmap *glyph;
fz_pixmap *result;
 
if (gid < 0 || gid > 255)
return NULL;
 
contents = font->t3procs[gid];
if (!contents)
return NULL;
 
ctm = fz_concat(font->t3matrix, trm);
dev = fz_new_bbox_device(&bbox);
error = font->t3run(font->t3xref, font->t3resources, contents, dev, ctm);
if (error)
fz_catch(error, "cannot draw type3 glyph");
 
if (dev->flags & FZ_CHARPROC_MASK)
{
if (dev->flags & FZ_CHARPROC_COLOR)
fz_warn("type3 glyph claims to be both masked and colored");
model = NULL;
}
else if (dev->flags & FZ_CHARPROC_COLOR)
{
if (model == NULL)
fz_warn("colored type3 glyph wanted in masked context");
}
else
{
fz_warn("type3 glyph doesn't specify masked or colored");
model = NULL; /* Treat as masked */
}
 
fz_free_device(dev);
 
bbox.x0--;
bbox.y0--;
bbox.x1++;
bbox.y1++;
 
glyph = fz_new_pixmap_with_rect(model ? model : fz_device_gray, bbox);
fz_clear_pixmap(glyph);
 
cache = fz_new_glyph_cache();
dev = fz_new_draw_device_type3(cache, glyph);
error = font->t3run(font->t3xref, font->t3resources, contents, dev, ctm);
if (error)
fz_catch(error, "cannot draw type3 glyph");
fz_free_device(dev);
fz_free_glyph_cache(cache);
 
if (model == NULL)
{
result = fz_alpha_from_gray(glyph, 0);
fz_drop_pixmap(glyph);
}
else
result = glyph;
 
return result;
}
 
void
fz_debug_font(fz_font *font)
{
printf("font '%s' {\n", font->name);
 
if (font->ft_face)
{
printf("\tfreetype face %p\n", font->ft_face);
if (font->ft_substitute)
printf("\tsubstitute font\n");
}
 
if (font->t3procs)
{
printf("\ttype3 matrix [%g %g %g %g]\n",
font->t3matrix.a, font->t3matrix.b,
font->t3matrix.c, font->t3matrix.d);
}
 
printf("\tbbox [%g %g %g %g]\n",
font->bbox.x0, font->bbox.y0,
font->bbox.x1, font->bbox.y1);
 
printf("}\n");
}
/contrib/media/updf/fitz/res_halftone.c
0,0 → 1,190
#include "fitz.h"
 
fz_halftone *
fz_new_halftone(int comps)
{
fz_halftone *ht;
int i;
 
ht = fz_malloc(sizeof(fz_halftone) + (comps-1)*sizeof(fz_pixmap *));
ht->refs = 1;
ht->n = comps;
for (i = 0; i < comps; i++)
ht->comp[i] = NULL;
 
return ht;
}
 
fz_halftone *
fz_keep_halftone(fz_halftone *ht)
{
ht->refs++;
return ht;
}
 
void
fz_drop_halftone(fz_halftone *ht)
{
int i;
 
if (!ht || --ht->refs != 0)
return;
for (i = 0; i < ht->n; i++)
fz_drop_pixmap(ht->comp[i]);
fz_free(ht);
}
 
/* Default mono halftone, lifted from Ghostscript. */
static unsigned char mono_ht[] =
{
0x0E, 0x8E, 0x2E, 0xAE, 0x06, 0x86, 0x26, 0xA6, 0x0C, 0x8C, 0x2C, 0xAC, 0x04, 0x84, 0x24, 0xA4,
0xCE, 0x4E, 0xEE, 0x6E, 0xC6, 0x46, 0xE6, 0x66, 0xCC, 0x4C, 0xEC, 0x6C, 0xC4, 0x44, 0xE4, 0x64,
0x3E, 0xBE, 0x1E, 0x9E, 0x36, 0xB6, 0x16, 0x96, 0x3C, 0xBC, 0x1C, 0x9C, 0x34, 0xB4, 0x14, 0x94,
0xFE, 0x7E, 0xDE, 0x5E, 0xF6, 0x76, 0xD6, 0x56, 0xFC, 0x7C, 0xDC, 0x5C, 0xF4, 0x74, 0xD4, 0x54,
0x01, 0x81, 0x21, 0xA1, 0x09, 0x89, 0x29, 0xA9, 0x03, 0x83, 0x23, 0xA3, 0x0B, 0x8B, 0x2B, 0xAB,
0xC1, 0x41, 0xE1, 0x61, 0xC9, 0x49, 0xE9, 0x69, 0xC3, 0x43, 0xE3, 0x63, 0xCB, 0x4B, 0xEB, 0x6B,
0x31, 0xB1, 0x11, 0x91, 0x39, 0xB9, 0x19, 0x99, 0x33, 0xB3, 0x13, 0x93, 0x3B, 0xBB, 0x1B, 0x9B,
0xF1, 0x71, 0xD1, 0x51, 0xF9, 0x79, 0xD9, 0x59, 0xF3, 0x73, 0xD3, 0x53, 0xFB, 0x7B, 0xDB, 0x5B,
0x0D, 0x8D, 0x2D, 0xAD, 0x05, 0x85, 0x25, 0xA5, 0x0F, 0x8F, 0x2F, 0xAF, 0x07, 0x87, 0x27, 0xA7,
0xCD, 0x4D, 0xED, 0x6D, 0xC5, 0x45, 0xE5, 0x65, 0xCF, 0x4F, 0xEF, 0x6F, 0xC7, 0x47, 0xE7, 0x67,
0x3D, 0xBD, 0x1D, 0x9D, 0x35, 0xB5, 0x15, 0x95, 0x3F, 0xBF, 0x1F, 0x9F, 0x37, 0xB7, 0x17, 0x97,
0xFD, 0x7D, 0xDD, 0x5D, 0xF5, 0x75, 0xD5, 0x55, 0xFF, 0x7F, 0xDF, 0x5F, 0xF7, 0x77, 0xD7, 0x57,
0x02, 0x82, 0x22, 0xA2, 0x0A, 0x8A, 0x2A, 0xAA, 0x00, 0x80, 0x20, 0xA0, 0x08, 0x88, 0x28, 0xA8,
0xC2, 0x42, 0xE2, 0x62, 0xCA, 0x4A, 0xEA, 0x6A, 0xC0, 0x40, 0xE0, 0x60, 0xC8, 0x48, 0xE8, 0x68,
0x32, 0xB2, 0x12, 0x92, 0x3A, 0xBA, 0x1A, 0x9A, 0x30, 0xB0, 0x10, 0x90, 0x38, 0xB8, 0x18, 0x98,
0xF2, 0x72, 0xD2, 0x52, 0xFA, 0x7A, 0xDA, 0x5A, 0xF0, 0x70, 0xD0, 0x50, 0xF8, 0x78, 0xD8, 0x58
};
 
fz_halftone *fz_get_default_halftone(int num_comps)
{
fz_halftone *ht = fz_new_halftone(num_comps);
assert(num_comps == 1); /* Only support 1 component for now */
ht->comp[0] = fz_new_pixmap_with_data(NULL, 16, 16, mono_ht);
return ht;
}
 
/* Finally, code to actually perform halftoning. */
static void make_ht_line(unsigned char *buf, fz_halftone *ht, int x, int y, int w)
{
/* FIXME: There is a potential optimisation here; in the case where
* the LCM of the halftone tile widths is smaller than w, we could
* form just one 'LCM' run, then copy it repeatedly.
*/
int k, n;
n = ht->n;
for (k = 0; k < n; k++)
{
fz_pixmap *tile = ht->comp[k];
unsigned char *b = buf++;
unsigned char *t;
unsigned char *tbase;
int px = x + tile->x;
int py = y + tile->y;
int tw = tile->w;
int th = tile->h;
int w2 = w;
int len;
px = px % tw;
if (px < 0)
px += tw;
py = py % th;
if (py < 0)
py += th;
 
assert(tile->n == 1);
 
/* Left hand section; from x to tile width */
tbase = tile->samples + py * tw;
t = tbase + px;
len = tw - px;
if (len > w2)
len = w2;
w2 -= len;
while (len--)
{
*b = *t++;
b += n;
}
 
/* Centre section - complete copies */
w2 -= tw;
while (w2 >= 0)
{
len = tw;
t = tbase;
while (len--)
{
*b = *t++;
b += n;
}
w2 -= tw;
}
w2 += tw;
 
/* Right hand section - stragglers */
t = tbase;
while (w2--)
{
*b = *t++;
b += n;
}
}
}
 
/* Inner mono thresholding code */
static void do_threshold_1(unsigned char *ht_line, unsigned char *pixmap, unsigned char *out, int w)
{
int bit = 0x80;
int h = 0;
 
do
{
if (*pixmap < *ht_line++)
h |= bit;
pixmap += 2; /* Skip the alpha */
bit >>= 1;
if (bit == 0)
{
*out++ = h;
h = 0;
bit = 0x80;
}
 
}
while (--w);
if (bit != 0x80)
*out++ = h;
}
 
fz_bitmap *fz_halftone_pixmap(fz_pixmap *pix, fz_halftone *ht)
{
fz_bitmap *out;
unsigned char *ht_line, *o, *p;
int w, h, x, y, n, pstride, ostride;
 
if (pix == NULL || ht == NULL)
return NULL;
 
assert(pix->n == 2); /* Mono + Alpha */
 
n = pix->n-1; /* Remove alpha */
ht_line = fz_malloc(pix->w * n);
out = fz_new_bitmap(pix->w, pix->h, n);
o = out->samples;
p = pix->samples;
 
h = pix->h;
x = pix->x;
y = pix->y;
w = pix->w;
ostride = out->stride;
pstride = pix->w * pix->n;
while (h--)
{
make_ht_line(ht_line, ht, x, y++, w);
do_threshold_1(ht_line, p, o, w);
o += ostride;
p += pstride;
}
return out;
}
/contrib/media/updf/fitz/res_path.c
0,0 → 1,262
#include "fitz.h"
 
fz_path *
fz_new_path(void)
{
fz_path *path;
 
path = fz_malloc(sizeof(fz_path));
path->len = 0;
path->cap = 0;
path->items = NULL;
 
return path;
}
 
fz_path *
fz_clone_path(fz_path *old)
{
fz_path *path;
 
path = fz_malloc(sizeof(fz_path));
path->len = old->len;
path->cap = old->len;
path->items = fz_calloc(path->cap, sizeof(fz_path_item));
memcpy(path->items, old->items, sizeof(fz_path_item) * path->len);
 
return path;
}
 
void
fz_free_path(fz_path *path)
{
fz_free(path->items);
fz_free(path);
}
 
static void
grow_path(fz_path *path, int n)
{
if (path->len + n < path->cap)
return;
while (path->len + n > path->cap)
path->cap = path->cap + 36;
path->items = fz_realloc(path->items, path->cap, sizeof(fz_path_item));
}
 
void
fz_moveto(fz_path *path, float x, float y)
{
grow_path(path, 3);
path->items[path->len++].k = FZ_MOVETO;
path->items[path->len++].v = x;
path->items[path->len++].v = y;
}
 
void
fz_lineto(fz_path *path, float x, float y)
{
if (path->len == 0)
{
fz_warn("lineto with no current point");
return;
}
grow_path(path, 3);
path->items[path->len++].k = FZ_LINETO;
path->items[path->len++].v = x;
path->items[path->len++].v = y;
}
 
void
fz_curveto(fz_path *path,
float x1, float y1,
float x2, float y2,
float x3, float y3)
{
if (path->len == 0)
{
fz_warn("curveto with no current point");
return;
}
grow_path(path, 7);
path->items[path->len++].k = FZ_CURVETO;
path->items[path->len++].v = x1;
path->items[path->len++].v = y1;
path->items[path->len++].v = x2;
path->items[path->len++].v = y2;
path->items[path->len++].v = x3;
path->items[path->len++].v = y3;
}
 
void
fz_curvetov(fz_path *path, float x2, float y2, float x3, float y3)
{
float x1, y1;
if (path->len == 0)
{
fz_warn("curvetov with no current point");
return;
}
x1 = path->items[path->len-2].v;
y1 = path->items[path->len-1].v;
fz_curveto(path, x1, y1, x2, y2, x3, y3);
}
 
void
fz_curvetoy(fz_path *path, float x1, float y1, float x3, float y3)
{
fz_curveto(path, x1, y1, x3, y3, x3, y3);
}
 
void
fz_closepath(fz_path *path)
{
if (path->len == 0)
{
fz_warn("closepath with no current point");
return;
}
grow_path(path, 1);
path->items[path->len++].k = FZ_CLOSE_PATH;
}
 
static inline fz_rect bound_expand(fz_rect r, fz_point p)
{
if (p.x < r.x0) r.x0 = p.x;
if (p.y < r.y0) r.y0 = p.y;
if (p.x > r.x1) r.x1 = p.x;
if (p.y > r.y1) r.y1 = p.y;
return r;
}
 
fz_rect
fz_bound_path(fz_path *path, fz_stroke_state *stroke, fz_matrix ctm)
{
fz_point p;
fz_rect r = fz_empty_rect;
int i = 0;
 
if (path->len)
{
p.x = path->items[1].v;
p.y = path->items[2].v;
p = fz_transform_point(ctm, p);
r.x0 = r.x1 = p.x;
r.y0 = r.y1 = p.y;
}
 
while (i < path->len)
{
switch (path->items[i++].k)
{
case FZ_CURVETO:
p.x = path->items[i++].v;
p.y = path->items[i++].v;
r = bound_expand(r, fz_transform_point(ctm, p));
p.x = path->items[i++].v;
p.y = path->items[i++].v;
r = bound_expand(r, fz_transform_point(ctm, p));
p.x = path->items[i++].v;
p.y = path->items[i++].v;
r = bound_expand(r, fz_transform_point(ctm, p));
break;
case FZ_MOVETO:
case FZ_LINETO:
p.x = path->items[i++].v;
p.y = path->items[i++].v;
r = bound_expand(r, fz_transform_point(ctm, p));
break;
case FZ_CLOSE_PATH:
break;
}
}
 
if (stroke)
{
float miterlength = stroke->miterlimit;
float linewidth = stroke->linewidth;
float expand = MAX(miterlength, linewidth) * 0.5f;
r.x0 -= expand;
r.y0 -= expand;
r.x1 += expand;
r.y1 += expand;
}
 
return r;
}
 
void
fz_transform_path(fz_path *path, fz_matrix ctm)
{
fz_point p;
int k, i = 0;
 
while (i < path->len)
{
switch (path->items[i++].k)
{
case FZ_CURVETO:
for (k = 0; k < 3; k++)
{
p.x = path->items[i].v;
p.y = path->items[i+1].v;
p = fz_transform_point(ctm, p);
path->items[i].v = p.x;
path->items[i+1].v = p.y;
i += 2;
}
break;
case FZ_MOVETO:
case FZ_LINETO:
p.x = path->items[i].v;
p.y = path->items[i+1].v;
p = fz_transform_point(ctm, p);
path->items[i].v = p.x;
path->items[i+1].v = p.y;
i += 2;
break;
case FZ_CLOSE_PATH:
break;
}
}
}
 
void
fz_debug_path(fz_path *path, int indent)
{
float x, y;
int i = 0;
int n;
while (i < path->len)
{
for (n = 0; n < indent; n++)
putchar(' ');
switch (path->items[i++].k)
{
case FZ_MOVETO:
x = path->items[i++].v;
y = path->items[i++].v;
printf("%g %g m\n", x, y);
break;
case FZ_LINETO:
x = path->items[i++].v;
y = path->items[i++].v;
printf("%g %g l\n", x, y);
break;
case FZ_CURVETO:
x = path->items[i++].v;
y = path->items[i++].v;
printf("%g %g ", x, y);
x = path->items[i++].v;
y = path->items[i++].v;
printf("%g %g ", x, y);
x = path->items[i++].v;
y = path->items[i++].v;
printf("%g %g c\n", x, y);
break;
case FZ_CLOSE_PATH:
printf("h\n");
break;
}
}
}
/contrib/media/updf/fitz/res_pixmap.c
0,0 → 1,519
#include "fitz.h"
 
static int fz_memory_limit = 256 << 20;
static int fz_memory_used = 0;
 
fz_pixmap *
fz_new_pixmap_with_data(fz_colorspace *colorspace, int w, int h, unsigned char *samples)
{
fz_pixmap *pix;
 
pix = fz_malloc(sizeof(fz_pixmap));
pix->refs = 1;
pix->x = 0;
pix->y = 0;
pix->w = w;
pix->h = h;
pix->mask = NULL;
pix->interpolate = 1;
pix->xres = 96;
pix->yres = 96;
pix->colorspace = NULL;
pix->n = 1;
 
if (colorspace)
{
pix->colorspace = fz_keep_colorspace(colorspace);
pix->n = 1 + colorspace->n;
}
 
if (samples)
{
pix->samples = samples;
pix->free_samples = 0;
}
else
{
fz_memory_used += pix->w * pix->h * pix->n;
pix->samples = fz_calloc(pix->h, pix->w * pix->n);
pix->free_samples = 1;
}
 
return pix;
}
 
fz_pixmap *
fz_new_pixmap_with_limit(fz_colorspace *colorspace, int w, int h)
{
int n = colorspace ? colorspace->n + 1 : 1;
int size = w * h * n;
if (fz_memory_used + size > fz_memory_limit)
{
fz_warn("pixmap memory exceeds soft limit %dM + %dM > %dM",
fz_memory_used/(1<<20), size/(1<<20), fz_memory_limit/(1<<20));
return NULL;
}
return fz_new_pixmap_with_data(colorspace, w, h, NULL);
}
 
fz_pixmap *
fz_new_pixmap(fz_colorspace *colorspace, int w, int h)
{
return fz_new_pixmap_with_data(colorspace, w, h, NULL);
}
 
fz_pixmap *
fz_new_pixmap_with_rect(fz_colorspace *colorspace, fz_bbox r)
{
fz_pixmap *pixmap;
pixmap = fz_new_pixmap(colorspace, r.x1 - r.x0, r.y1 - r.y0);
pixmap->x = r.x0;
pixmap->y = r.y0;
return pixmap;
}
 
fz_pixmap *
fz_new_pixmap_with_rect_and_data(fz_colorspace *colorspace, fz_bbox r, unsigned char *samples)
{
fz_pixmap *pixmap;
pixmap = fz_new_pixmap_with_data(colorspace, r.x1 - r.x0, r.y1 - r.y0, samples);
pixmap->x = r.x0;
pixmap->y = r.y0;
return pixmap;
}
 
fz_pixmap *
fz_keep_pixmap(fz_pixmap *pix)
{
pix->refs++;
return pix;
}
 
void
fz_drop_pixmap(fz_pixmap *pix)
{
if (pix && --pix->refs == 0)
{
fz_memory_used -= pix->w * pix->h * pix->n;
if (pix->mask)
fz_drop_pixmap(pix->mask);
if (pix->colorspace)
fz_drop_colorspace(pix->colorspace);
if (pix->free_samples)
fz_free(pix->samples);
fz_free(pix);
}
}
 
fz_bbox
fz_bound_pixmap(fz_pixmap *pix)
{
fz_bbox bbox;
bbox.x0 = pix->x;
bbox.y0 = pix->y;
bbox.x1 = pix->x + pix->w;
bbox.y1 = pix->y + pix->h;
return bbox;
}
 
void
fz_clear_pixmap(fz_pixmap *pix)
{
memset(pix->samples, 0, pix->w * pix->h * pix->n);
}
 
void
fz_clear_pixmap_with_color(fz_pixmap *pix, int value)
{
if (value == 255)
memset(pix->samples, 255, pix->w * pix->h * pix->n);
else
{
int k, x, y;
unsigned char *s = pix->samples;
for (y = 0; y < pix->h; y++)
{
for (x = 0; x < pix->w; x++)
{
for (k = 0; k < pix->n - 1; k++)
*s++ = value;
*s++ = 255;
}
}
}
}
 
void
fz_copy_pixmap_rect(fz_pixmap *dest, fz_pixmap *src, fz_bbox r)
{
const unsigned char *srcp;
unsigned char *destp;
int y, w, destspan, srcspan;
 
r = fz_intersect_bbox(r, fz_bound_pixmap(dest));
r = fz_intersect_bbox(r, fz_bound_pixmap(src));
w = r.x1 - r.x0;
y = r.y1 - r.y0;
if (w <= 0 || y <= 0)
return;
 
w *= src->n;
srcspan = src->w * src->n;
srcp = src->samples + srcspan * (r.y0 - src->y) + src->n * (r.x0 - src->x);
destspan = dest->w * dest->n;
destp = dest->samples + destspan * (r.y0 - dest->y) + dest->n * (r.x0 - dest->x);
do
{
memcpy(destp, srcp, w);
srcp += srcspan;
destp += destspan;
}
while (--y);
}
 
void
fz_clear_pixmap_rect_with_color(fz_pixmap *dest, int value, fz_bbox r)
{
unsigned char *destp;
int x, y, w, k, destspan;
 
r = fz_intersect_bbox(r, fz_bound_pixmap(dest));
w = r.x1 - r.x0;
y = r.y1 - r.y0;
if (w <= 0 || y <= 0)
return;
 
destspan = dest->w * dest->n;
destp = dest->samples + destspan * (r.y0 - dest->y) + dest->n * (r.x0 - dest->x);
if (value == 255)
do
{
memset(destp, 255, w * dest->n);
destp += destspan;
}
while (--y);
else
do
{
unsigned char *s = destp;
for (x = 0; x < w; x++)
{
for (k = 0; k < dest->n - 1; k++)
*s++ = value;
*s++ = 255;
}
destp += destspan;
}
while (--y);
}
 
void
fz_premultiply_pixmap(fz_pixmap *pix)
{
unsigned char *s = pix->samples;
unsigned char a;
int k, x, y;
 
for (y = 0; y < pix->h; y++)
{
for (x = 0; x < pix->w; x++)
{
a = s[pix->n - 1];
for (k = 0; k < pix->n - 1; k++)
s[k] = fz_mul255(s[k], a);
s += pix->n;
}
}
}
 
fz_pixmap *
fz_alpha_from_gray(fz_pixmap *gray, int luminosity)
{
fz_pixmap *alpha;
unsigned char *sp, *dp;
int len;
 
assert(gray->n == 2);
 
alpha = fz_new_pixmap_with_rect(NULL, fz_bound_pixmap(gray));
dp = alpha->samples;
sp = gray->samples;
if (!luminosity)
sp ++;
 
len = gray->w * gray->h;
while (len--)
{
*dp++ = sp[0];
sp += 2;
}
 
return alpha;
}
 
void
fz_invert_pixmap(fz_pixmap *pix)
{
unsigned char *s = pix->samples;
int k, x, y;
 
for (y = 0; y < pix->h; y++)
{
for (x = 0; x < pix->w; x++)
{
for (k = 0; k < pix->n - 1; k++)
s[k] = 255 - s[k];
s += pix->n;
}
}
}
 
void
fz_gamma_pixmap(fz_pixmap *pix, float gamma)
{
unsigned char gamma_map[256];
unsigned char *s = pix->samples;
int k, x, y;
 
for (k = 0; k < 256; k++)
gamma_map[k] = pow(k / 255.0f, gamma) * 255;
 
for (y = 0; y < pix->h; y++)
{
for (x = 0; x < pix->w; x++)
{
for (k = 0; k < pix->n - 1; k++)
s[k] = gamma_map[s[k]];
s += pix->n;
}
}
}
 
/*
* Write pixmap to PNM file (without alpha channel)
*/
 
fz_error
fz_write_pnm(fz_pixmap *pixmap, char *filename)
{
FILE *fp;
unsigned char *p;
int len;
 
if (pixmap->n != 1 && pixmap->n != 2 && pixmap->n != 4)
return fz_throw("pixmap must be grayscale or rgb to write as pnm");
 
fp = fopen(filename, "wb");
if (!fp)
return fz_throw("cannot open file '%s': %s", filename, strerror(errno));
 
if (pixmap->n == 1 || pixmap->n == 2)
fprintf(fp, "P5\n");
if (pixmap->n == 4)
fprintf(fp, "P6\n");
fprintf(fp, "%d %d\n", pixmap->w, pixmap->h);
fprintf(fp, "255\n");
 
len = pixmap->w * pixmap->h;
p = pixmap->samples;
 
switch (pixmap->n)
{
case 1:
fwrite(p, 1, len, fp);
break;
case 2:
while (len--)
{
putc(p[0], fp);
p += 2;
}
break;
case 4:
while (len--)
{
putc(p[0], fp);
putc(p[1], fp);
putc(p[2], fp);
p += 4;
}
}
 
fclose(fp);
return fz_okay;
}
 
/*
* Write pixmap to PAM file (with or without alpha channel)
*/
 
fz_error
fz_write_pam(fz_pixmap *pixmap, char *filename, int savealpha)
{
unsigned char *sp;
int y, w, k;
FILE *fp;
 
int sn = pixmap->n;
int dn = pixmap->n;
if (!savealpha && dn > 1)
dn--;
 
fp = fopen(filename, "wb");
if (!fp)
return fz_throw("cannot open file '%s': %s", filename, strerror(errno));
 
fprintf(fp, "P7\n");
fprintf(fp, "WIDTH %d\n", pixmap->w);
fprintf(fp, "HEIGHT %d\n", pixmap->h);
fprintf(fp, "DEPTH %d\n", dn);
fprintf(fp, "MAXVAL 255\n");
if (pixmap->colorspace)
fprintf(fp, "# COLORSPACE %s\n", pixmap->colorspace->name);
switch (dn)
{
case 1: fprintf(fp, "TUPLTYPE GRAYSCALE\n"); break;
case 2: if (sn == 2) fprintf(fp, "TUPLTYPE GRAYSCALE_ALPHA\n"); break;
case 3: if (sn == 4) fprintf(fp, "TUPLTYPE RGB\n"); break;
case 4: if (sn == 4) fprintf(fp, "TUPLTYPE RGB_ALPHA\n"); break;
}
fprintf(fp, "ENDHDR\n");
 
sp = pixmap->samples;
for (y = 0; y < pixmap->h; y++)
{
w = pixmap->w;
while (w--)
{
for (k = 0; k < dn; k++)
putc(sp[k], fp);
sp += sn;
}
}
 
fclose(fp);
 
return fz_okay;
}
 
/*
* Write pixmap to PNG file (with or without alpha channel)
*/
 
#include <zlib.h>
 
static inline void big32(unsigned char *buf, unsigned int v)
{
buf[0] = (v >> 24) & 0xff;
buf[1] = (v >> 16) & 0xff;
buf[2] = (v >> 8) & 0xff;
buf[3] = (v) & 0xff;
}
 
static inline void put32(unsigned int v, FILE *fp)
{
putc(v >> 24, fp);
putc(v >> 16, fp);
putc(v >> 8, fp);
putc(v, fp);
}
 
static void putchunk(char *tag, unsigned char *data, int size, FILE *fp)
{
unsigned int sum;
put32(size, fp);
fwrite(tag, 1, 4, fp);
fwrite(data, 1, size, fp);
sum = crc32(0, NULL, 0);
sum = crc32(sum, (unsigned char*)tag, 4);
sum = crc32(sum, data, size);
put32(sum, fp);
}
 
fz_error
fz_write_png(fz_pixmap *pixmap, char *filename, int savealpha)
{
static const unsigned char pngsig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
FILE *fp;
unsigned char head[13];
unsigned char *udata, *cdata, *sp, *dp;
uLong usize, csize;
int y, x, k, sn, dn;
int color;
int err;
 
if (pixmap->n != 1 && pixmap->n != 2 && pixmap->n != 4)
return fz_throw("pixmap must be grayscale or rgb to write as png");
 
sn = pixmap->n;
dn = pixmap->n;
if (!savealpha && dn > 1)
dn--;
 
switch (dn)
{
default:
case 1: color = 0; break;
case 2: color = 4; break;
case 3: color = 2; break;
case 4: color = 6; break;
}
 
usize = (pixmap->w * dn + 1) * pixmap->h;
csize = compressBound(usize);
udata = fz_malloc(usize);
cdata = fz_malloc(csize);
 
sp = pixmap->samples;
dp = udata;
for (y = 0; y < pixmap->h; y++)
{
*dp++ = 1; /* sub prediction filter */
for (x = 0; x < pixmap->w; x++)
{
for (k = 0; k < dn; k++)
{
if (x == 0)
dp[k] = sp[k];
else
dp[k] = sp[k] - sp[k-sn];
}
sp += sn;
dp += dn;
}
}
 
err = compress(cdata, &csize, udata, usize);
if (err != Z_OK)
{
fz_free(udata);
fz_free(cdata);
return fz_throw("cannot compress image data");
}
 
fp = fopen(filename, "wb");
if (!fp)
{
fz_free(udata);
fz_free(cdata);
return fz_throw("cannot open file '%s': %s", filename, strerror(errno));
}
 
big32(head+0, pixmap->w);
big32(head+4, pixmap->h);
head[8] = 8; /* depth */
head[9] = color;
head[10] = 0; /* compression */
head[11] = 0; /* filter */
head[12] = 0; /* interlace */
 
fwrite(pngsig, 1, 8, fp);
putchunk("IHDR", head, 13, fp);
putchunk("IDAT", cdata, csize, fp);
putchunk("IEND", head, 0, fp);
fclose(fp);
 
fz_free(udata);
fz_free(cdata);
return fz_okay;
}
/contrib/media/updf/fitz/res_shade.c
0,0 → 1,127
#include "fitz.h"
 
fz_shade *
fz_keep_shade(fz_shade *shade)
{
shade->refs ++;
return shade;
}
 
void
fz_drop_shade(fz_shade *shade)
{
if (shade && --shade->refs == 0)
{
if (shade->colorspace)
fz_drop_colorspace(shade->colorspace);
fz_free(shade->mesh);
fz_free(shade);
}
}
 
fz_rect
fz_bound_shade(fz_shade *shade, fz_matrix ctm)
{
float *v;
fz_rect r;
fz_point p;
int i, ncomp, nvert;
 
ctm = fz_concat(shade->matrix, ctm);
ncomp = shade->use_function ? 3 : 2 + shade->colorspace->n;
nvert = shade->mesh_len / ncomp;
v = shade->mesh;
 
if (shade->type == FZ_LINEAR)
return fz_infinite_rect;
if (shade->type == FZ_RADIAL)
return fz_infinite_rect;
 
if (nvert == 0)
return fz_empty_rect;
 
p.x = v[0];
p.y = v[1];
v += ncomp;
p = fz_transform_point(ctm, p);
r.x0 = r.x1 = p.x;
r.y0 = r.y1 = p.y;
 
for (i = 1; i < nvert; i++)
{
p.x = v[0];
p.y = v[1];
p = fz_transform_point(ctm, p);
v += ncomp;
if (p.x < r.x0) r.x0 = p.x;
if (p.y < r.y0) r.y0 = p.y;
if (p.x > r.x1) r.x1 = p.x;
if (p.y > r.y1) r.y1 = p.y;
}
 
return r;
}
 
void
fz_debug_shade(fz_shade *shade)
{
int i, j, n;
float *vertex;
int triangle;
 
printf("shading {\n");
 
switch (shade->type)
{
case FZ_LINEAR: printf("\ttype linear\n"); break;
case FZ_RADIAL: printf("\ttype radial\n"); break;
case FZ_MESH: printf("\ttype mesh\n"); break;
}
 
printf("\tbbox [%g %g %g %g]\n",
shade->bbox.x0, shade->bbox.y0,
shade->bbox.x1, shade->bbox.y1);
 
printf("\tcolorspace %s\n", shade->colorspace->name);
 
printf("\tmatrix [%g %g %g %g %g %g]\n",
shade->matrix.a, shade->matrix.b, shade->matrix.c,
shade->matrix.d, shade->matrix.e, shade->matrix.f);
 
if (shade->use_background)
{
printf("\tbackground [");
for (i = 0; i < shade->colorspace->n; i++)
printf("%s%g", i == 0 ? "" : " ", shade->background[i]);
printf("]\n");
}
 
if (shade->use_function)
{
printf("\tfunction\n");
n = 3;
}
else
n = 2 + shade->colorspace->n;
 
printf("\tvertices: %d\n", shade->mesh_len);
 
vertex = shade->mesh;
triangle = 0;
i = 0;
while (i < shade->mesh_len)
{
printf("\t%d:(%g, %g): ", triangle, vertex[0], vertex[1]);
 
for (j = 2; j < n; j++)
printf("%s%g", j == 2 ? "" : " ", vertex[j]);
printf("\n");
 
vertex += n;
i++;
if (i % 3 == 0)
triangle++;
}
 
printf("}\n");
}
/contrib/media/updf/fitz/res_text.c
0,0 → 1,133
#include "fitz.h"
 
fz_text *
fz_new_text(fz_font *font, fz_matrix trm, int wmode)
{
fz_text *text;
 
text = fz_malloc(sizeof(fz_text));
text->font = fz_keep_font(font);
text->trm = trm;
text->wmode = wmode;
text->len = 0;
text->cap = 0;
text->items = NULL;
 
return text;
}
 
void
fz_free_text(fz_text *text)
{
fz_drop_font(text->font);
fz_free(text->items);
fz_free(text);
}
 
fz_text *
fz_clone_text(fz_text *old)
{
fz_text *text;
 
text = fz_malloc(sizeof(fz_text));
text->font = fz_keep_font(old->font);
text->trm = old->trm;
text->wmode = old->wmode;
text->len = old->len;
text->cap = text->len;
text->items = fz_calloc(text->len, sizeof(fz_text_item));
memcpy(text->items, old->items, text->len * sizeof(fz_text_item));
 
return text;
}
 
fz_rect
fz_bound_text(fz_text *text, fz_matrix ctm)
{
fz_matrix trm;
fz_rect bbox;
fz_rect fbox;
int i;
 
if (text->len == 0)
return fz_empty_rect;
 
/* find bbox of glyph origins in ctm space */
 
bbox.x0 = bbox.x1 = text->items[0].x;
bbox.y0 = bbox.y1 = text->items[0].y;
 
for (i = 1; i < text->len; i++)
{
bbox.x0 = MIN(bbox.x0, text->items[i].x);
bbox.y0 = MIN(bbox.y0, text->items[i].y);
bbox.x1 = MAX(bbox.x1, text->items[i].x);
bbox.y1 = MAX(bbox.y1, text->items[i].y);
}
 
bbox = fz_transform_rect(ctm, bbox);
 
/* find bbox of font in trm * ctm space */
 
trm = fz_concat(text->trm, ctm);
trm.e = 0;
trm.f = 0;
 
fbox.x0 = text->font->bbox.x0 * 0.001f;
fbox.y0 = text->font->bbox.y0 * 0.001f;
fbox.x1 = text->font->bbox.x1 * 0.001f;
fbox.y1 = text->font->bbox.y1 * 0.001f;
 
fbox = fz_transform_rect(trm, fbox);
 
/* expand glyph origin bbox by font bbox */
 
bbox.x0 += fbox.x0;
bbox.y0 += fbox.y0;
bbox.x1 += fbox.x1;
bbox.y1 += fbox.y1;
 
return bbox;
}
 
static void
fz_grow_text(fz_text *text, int n)
{
if (text->len + n < text->cap)
return;
while (text->len + n > text->cap)
text->cap = text->cap + 36;
text->items = fz_realloc(text->items, text->cap, sizeof(fz_text_item));
}
 
void
fz_add_text(fz_text *text, int gid, int ucs, float x, float y)
{
fz_grow_text(text, 1);
text->items[text->len].ucs = ucs;
text->items[text->len].gid = gid;
text->items[text->len].x = x;
text->items[text->len].y = y;
text->len++;
}
 
static int isxmlmeta(int c)
{
return c < 32 || c >= 128 || c == '&' || c == '<' || c == '>' || c == '\'' || c == '"';
}
 
void fz_debug_text(fz_text *text, int indent)
{
int i, n;
for (i = 0; i < text->len; i++)
{
for (n = 0; n < indent; n++)
putchar(' ');
if (!isxmlmeta(text->items[i].ucs))
printf("<g ucs=\"%c\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n",
text->items[i].ucs, text->items[i].gid, text->items[i].x, text->items[i].y);
else
printf("<g ucs=\"U+%04X\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n",
text->items[i].ucs, text->items[i].gid, text->items[i].x, text->items[i].y);
}
}
/contrib/media/updf/fitz/stm_buffer.c
0,0 → 1,49
#include "fitz.h"
 
fz_buffer *
fz_new_buffer(int size)
{
fz_buffer *b;
 
size = size > 1 ? size : 16;
 
b = fz_malloc(sizeof(fz_buffer));
b->refs = 1;
b->data = fz_malloc(size);
b->cap = size;
b->len = 0;
 
return b;
}
 
fz_buffer *
fz_keep_buffer(fz_buffer *buf)
{
buf->refs ++;
return buf;
}
 
void
fz_drop_buffer(fz_buffer *buf)
{
if (--buf->refs == 0)
{
fz_free(buf->data);
fz_free(buf);
}
}
 
void
fz_resize_buffer(fz_buffer *buf, int size)
{
buf->data = fz_realloc(buf->data, size, 1);
buf->cap = size;
if (buf->len > buf->cap)
buf->len = buf->cap;
}
 
void
fz_grow_buffer(fz_buffer *buf)
{
fz_resize_buffer(buf, (buf->cap * 3) / 2);
}
/contrib/media/updf/fitz/stm_open.c
0,0 → 1,174
#include "fitz.h"
 
fz_stream *
fz_new_stream(void *state,
int(*read)(fz_stream *stm, unsigned char *buf, int len),
void(*close)(fz_stream *stm))
{
fz_stream *stm;
 
stm = fz_malloc(sizeof(fz_stream));
 
stm->refs = 1;
stm->error = 0;
stm->eof = 0;
stm->pos = 0;
 
stm->bits = 0;
stm->avail = 0;
 
stm->bp = stm->buf;
stm->rp = stm->bp;
stm->wp = stm->bp;
stm->ep = stm->buf + sizeof stm->buf;
 
stm->state = state;
stm->read = read;
stm->close = close;
stm->seek = NULL;
 
return stm;
}
 
fz_stream *
fz_keep_stream(fz_stream *stm)
{
stm->refs ++;
return stm;
}
 
void
fz_close(fz_stream *stm)
{
stm->refs --;
if (stm->refs == 0)
{
if (stm->close)
stm->close(stm);
fz_free(stm);
}
}
 
/* File stream */
 
static int read_file(fz_stream *stm, unsigned char *buf, int len)
{
int n = read(*(int*)stm->state, buf, len);
if (n < 0)
return fz_throw("read error: %s", strerror(errno));
return n;
}
 
static void seek_file(fz_stream *stm, int offset, int whence)
{
int n = lseek(*(int*)stm->state, offset, whence);
if (n < 0)
fz_warn("cannot lseek: %s", strerror(errno));
stm->pos = n;
stm->rp = stm->bp;
stm->wp = stm->bp;
}
 
static void close_file(fz_stream *stm)
{
int n = close(*(int*)stm->state);
if (n < 0)
fz_warn("close error: %s", strerror(errno));
fz_free(stm->state);
}
 
fz_stream *
fz_open_fd(int fd)
{
fz_stream *stm;
int *state;
 
state = fz_malloc(sizeof(int));
*state = fd;
 
stm = fz_new_stream(state, read_file, close_file);
stm->seek = seek_file;
 
return stm;
}
 
fz_stream *
fz_open_file(const char *name)
{
int fd = open(name, O_BINARY | O_RDONLY, 0);
if (fd == -1)
return NULL;
return fz_open_fd(fd);
}
 
#ifdef _WIN32
fz_stream *
fz_open_file_w(const wchar_t *name)
{
int fd = _wopen(name, O_BINARY | O_RDONLY, 0);
if (fd == -1)
return NULL;
return fz_open_fd(fd);
}
#endif
 
/* Memory stream */
 
static int read_buffer(fz_stream *stm, unsigned char *buf, int len)
{
return 0;
}
 
static void seek_buffer(fz_stream *stm, int offset, int whence)
{
if (whence == 0)
stm->rp = stm->bp + offset;
if (whence == 1)
stm->rp += offset;
if (whence == 2)
stm->rp = stm->ep - offset;
stm->rp = CLAMP(stm->rp, stm->bp, stm->ep);
stm->wp = stm->ep;
}
 
static void close_buffer(fz_stream *stm)
{
if (stm->state)
fz_drop_buffer(stm->state);
}
 
fz_stream *
fz_open_buffer(fz_buffer *buf)
{
fz_stream *stm;
 
stm = fz_new_stream(fz_keep_buffer(buf), read_buffer, close_buffer);
stm->seek = seek_buffer;
 
stm->bp = buf->data;
stm->rp = buf->data;
stm->wp = buf->data + buf->len;
stm->ep = buf->data + buf->len;
 
stm->pos = buf->len;
 
return stm;
}
 
fz_stream *
fz_open_memory(unsigned char *data, int len)
{
fz_stream *stm;
 
stm = fz_new_stream(NULL, read_buffer, close_buffer);
stm->seek = seek_buffer;
 
stm->bp = data;
stm->rp = data;
stm->wp = data + len;
stm->ep = data + len;
 
stm->pos = len;
 
return stm;
}
/contrib/media/updf/fitz/stm_read.c
0,0 → 1,201
#include "fitz.h"
 
int
fz_read(fz_stream *stm, unsigned char *buf, int len)
{
int count, n;
 
count = MIN(len, stm->wp - stm->rp);
if (count)
{
memcpy(buf, stm->rp, count);
stm->rp += count;
}
 
if (count == len || stm->error || stm->eof)
return count;
 
assert(stm->rp == stm->wp);
 
if (len - count < stm->ep - stm->bp)
{
n = stm->read(stm, stm->bp, stm->ep - stm->bp);
if (n < 0)
{
stm->error = 1;
return fz_rethrow(n, "read error");
}
else if (n == 0)
{
stm->eof = 1;
}
else if (n > 0)
{
stm->rp = stm->bp;
stm->wp = stm->bp + n;
stm->pos += n;
}
 
n = MIN(len - count, stm->wp - stm->rp);
if (n)
{
memcpy(buf + count, stm->rp, n);
stm->rp += n;
count += n;
}
}
else
{
n = stm->read(stm, buf + count, len - count);
if (n < 0)
{
stm->error = 1;
return fz_rethrow(n, "read error");
}
else if (n == 0)
{
stm->eof = 1;
}
else if (n > 0)
{
stm->pos += n;
count += n;
}
}
 
return count;
}
 
void
fz_fill_buffer(fz_stream *stm)
{
int n;
 
assert(stm->rp == stm->wp);
 
if (stm->error || stm->eof)
return;
 
n = stm->read(stm, stm->bp, stm->ep - stm->bp);
if (n < 0)
{
stm->error = 1;
fz_catch(n, "read error; treating as end of file");
}
else if (n == 0)
{
stm->eof = 1;
}
else if (n > 0)
{
stm->rp = stm->bp;
stm->wp = stm->bp + n;
stm->pos += n;
}
}
 
fz_error
fz_read_all(fz_buffer **bufp, fz_stream *stm, int initial)
{
fz_buffer *buf;
int n;
 
if (initial < 1024)
initial = 1024;
 
buf = fz_new_buffer(initial);
 
while (1)
{
if (buf->len == buf->cap)
fz_grow_buffer(buf);
 
if (buf->len / 200 > initial)
{
fz_drop_buffer(buf);
return fz_throw("compression bomb detected");
}
 
n = fz_read(stm, buf->data + buf->len, buf->cap - buf->len);
if (n < 0)
{
fz_drop_buffer(buf);
return fz_rethrow(n, "read error");
}
if (n == 0)
break;
 
buf->len += n;
}
 
*bufp = buf;
return fz_okay;
}
 
void
fz_read_line(fz_stream *stm, char *mem, int n)
{
char *s = mem;
int c = EOF;
while (n > 1)
{
c = fz_read_byte(stm);
if (c == EOF)
break;
if (c == '\r') {
c = fz_peek_byte(stm);
if (c == '\n')
fz_read_byte(stm);
break;
}
if (c == '\n')
break;
*s++ = c;
n--;
}
if (n)
*s = '\0';
}
 
int
fz_tell(fz_stream *stm)
{
return stm->pos - (stm->wp - stm->rp);
}
 
void
fz_seek(fz_stream *stm, int offset, int whence)
{
if (stm->seek)
{
if (whence == 1)
{
offset = fz_tell(stm) + offset;
whence = 0;
}
if (whence == 0)
{
unsigned char *p = stm->wp - (stm->pos - offset);
if (p >= stm->bp && p <= stm->wp)
{
stm->rp = p;
stm->eof = 0;
return;
}
}
stm->seek(stm, offset, whence);
stm->eof = 0;
}
else if (whence != 2)
{
if (whence == 0)
offset -= fz_tell(stm);
if (offset < 0)
fz_warn("cannot seek backwards");
/* dog slow, but rare enough */
while (offset-- > 0)
fz_read_byte(stm);
}
else
fz_warn("cannot seek");
}
/contrib/media/updf/fitz/strtoll.c
0,0 → 1,30
#include <ctype.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <inttypes.h>
 
long long int strtoll(const char *nptr, char **endptr, int base)
{
int neg=0;
unsigned long long int v;
const char*orig=nptr;
 
while(isspace(*nptr)) nptr++;
 
if (*nptr == '-' && isalnum(nptr[1])) { neg=-1; nptr++; }
v=strtoull(nptr,endptr,base);
if (endptr && *endptr==nptr) *endptr=(char *)orig;
if (v>LLONG_MAX) {
if (v==0x8000000000000000ull && neg) {
errno=0;
return v;
}
errno=ERANGE;
return (neg?LLONG_MIN:LLONG_MAX);
}
return (neg?-v:v);
}
 
intmax_t strtoimax(const char *nptr, char **endptr, int base)
__attribute__((alias("strtoll")));
/contrib/media/updf/fitz/strtoull.c
0,0 → 1,68
#include <ctype.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <inttypes.h>
 
#define __expect(foo,bar) (foo)
#define __likely(foo) __expect((foo),1)
#define __unlikely(foo) __expect((foo),0)
 
unsigned long long int strtoull(const char *ptr, char **endptr, int base)
{
int neg = 0, overflow = 0;
long long int v=0;
const char* orig;
const char* nptr=ptr;
 
while(isspace(*nptr)) ++nptr;
 
if (*nptr == '-') { neg=1; nptr++; }
else if (*nptr == '+') ++nptr;
orig=nptr;
if (base==16 && nptr[0]=='0') goto skip0x;
if (base) {
register unsigned int b=base-2;
if (__unlikely(b>34)) { errno=EINVAL; return 0; }
} else {
if (*nptr=='0') {
base=8;
skip0x:
if (((*(nptr+1)=='x')||(*(nptr+1)=='X')) && isxdigit(nptr[2])) {
nptr+=2;
base=16;
}
} else
base=10;
}
while(__likely(*nptr)) {
register unsigned char c=*nptr;
c=(c>='a'?c-'a'+10:c>='A'?c-'A'+10:c<='9'?c-'0':0xff);
if (__unlikely(c>=base)) break; /* out of base */
{
register unsigned long x=(v&0xff)*base+c;
register unsigned long long w=(v>>8)*base+(x>>8);
if (w>(ULLONG_MAX>>8)) overflow=1;
v=(w<<8)+(x&0xff);
}
++nptr;
}
if (__unlikely(nptr==orig)) { /* no conversion done */
nptr=ptr;
errno=EINVAL;
v=0;
}
if (endptr) *endptr=(char *)nptr;
if (overflow) {
errno=ERANGE;
return ULLONG_MAX;
}
return (neg?-v:v);
}
 
/* die, BSD, die!!! */
unsigned long long int strtouq(const char *nptr, char **endptr, int base)
__attribute__((alias("strtoull")));
 
uintmax_t strtoumax(const char *nptr, char **endptr, int base)
__attribute__((alias("strtoull")));