Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7640 views
1
#include "mupdf/fitz.h"
2
3
#include <jbig2.h>
4
5
typedef struct fz_jbig2d_s fz_jbig2d;
6
7
struct fz_jbig2_globals_s
8
{
9
fz_storable storable;
10
Jbig2GlobalCtx *gctx;
11
};
12
13
struct fz_jbig2d_s
14
{
15
fz_stream *chain;
16
Jbig2Ctx *ctx;
17
fz_jbig2_globals *gctx;
18
Jbig2Image *page;
19
int idx;
20
unsigned char buffer[4096];
21
};
22
23
static void
24
fz_drop_jbig2_globals(fz_context *ctx, fz_jbig2_globals *globals)
25
{
26
fz_drop_storable(ctx, &globals->storable);
27
}
28
29
static void
30
close_jbig2d(fz_context *ctx, void *state_)
31
{
32
fz_jbig2d *state = (fz_jbig2d *)state_;
33
if (state->page)
34
jbig2_release_page(state->ctx, state->page);
35
if (state->gctx)
36
fz_drop_jbig2_globals(ctx, state->gctx);
37
jbig2_ctx_free(state->ctx);
38
fz_drop_stream(ctx, state->chain);
39
fz_free(ctx, state);
40
}
41
42
static int
43
next_jbig2d(fz_context *ctx, fz_stream *stm, int len)
44
{
45
fz_jbig2d *state = stm->state;
46
unsigned char tmp[4096];
47
unsigned char *buf = state->buffer;
48
unsigned char *p = buf;
49
unsigned char *ep;
50
unsigned char *s;
51
int x, w, n;
52
53
if (len > sizeof(state->buffer))
54
len = sizeof(state->buffer);
55
ep = buf + len;
56
57
if (!state->page)
58
{
59
while (1)
60
{
61
n = fz_read(ctx, state->chain, tmp, sizeof tmp);
62
if (n == 0)
63
break;
64
jbig2_data_in(state->ctx, tmp, n);
65
}
66
67
jbig2_complete_page(state->ctx);
68
69
state->page = jbig2_page_out(state->ctx);
70
if (!state->page)
71
fz_throw(ctx, FZ_ERROR_GENERIC, "jbig2_page_out failed");
72
}
73
74
s = state->page->data;
75
w = state->page->height * state->page->stride;
76
x = state->idx;
77
while (p < ep && x < w)
78
*p++ = s[x++] ^ 0xff;
79
state->idx = x;
80
81
stm->rp = buf;
82
stm->wp = p;
83
if (p == buf)
84
return EOF;
85
stm->pos += p - buf;
86
return *stm->rp++;
87
}
88
89
static int
90
error_callback(void *data, const char *msg, Jbig2Severity severity, int32_t seg_idx)
91
{
92
fz_context *ctx = data;
93
if (severity == JBIG2_SEVERITY_FATAL)
94
fz_warn(ctx, "jbig2dec error: %s (segment %d)", msg, seg_idx);
95
else if (severity == JBIG2_SEVERITY_WARNING)
96
fz_warn(ctx, "jbig2dec warning: %s (segment %d)", msg, seg_idx);
97
return 0;
98
}
99
100
fz_jbig2_globals *
101
fz_load_jbig2_globals(fz_context *ctx, unsigned char *data, int size)
102
{
103
fz_jbig2_globals *globals = fz_malloc_struct(ctx, fz_jbig2_globals);
104
105
Jbig2Ctx *jctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, NULL, error_callback, ctx);
106
jbig2_data_in(jctx, data, size);
107
108
FZ_INIT_STORABLE(globals, 1, fz_drop_jbig2_globals_imp);
109
globals->gctx = jbig2_make_global_ctx(jctx);
110
111
return globals;
112
}
113
114
void
115
fz_drop_jbig2_globals_imp(fz_context *ctx, fz_storable *globals_)
116
{
117
fz_jbig2_globals *globals = (fz_jbig2_globals *)globals_;
118
jbig2_global_ctx_free(globals->gctx);
119
fz_free(ctx, globals);
120
}
121
122
fz_stream *
123
fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals)
124
{
125
fz_jbig2d *state = NULL;
126
127
fz_var(state);
128
129
fz_try(ctx)
130
{
131
state = fz_malloc_struct(ctx, fz_jbig2d);
132
state->ctx = NULL;
133
state->gctx = globals;
134
state->chain = chain;
135
state->ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, globals ? globals->gctx : NULL, error_callback, ctx);
136
state->page = NULL;
137
state->idx = 0;
138
}
139
fz_catch(ctx)
140
{
141
if (state)
142
{
143
fz_drop_jbig2_globals(ctx, state->gctx);
144
if (state->ctx)
145
jbig2_ctx_free(state->ctx);
146
}
147
fz_free(ctx, state);
148
fz_drop_stream(ctx, chain);
149
fz_rethrow(ctx);
150
}
151
152
return fz_new_stream(ctx, state, next_jbig2d, close_jbig2d);
153
}
154
155