1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
#include <fitz.h>
static void
scalerow(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
{
int x, left, k;
int sum[32];
left = 0;
for (k = 0; k < ncomp; k++)
sum[k] = 0;
for (x = 0; x < w; x++)
{
for (k = 0; k < ncomp; k++)
sum[k] += src[x * ncomp + k];
if (++left == denom)
{
left = 0;
for (k = 0; k < ncomp; k++)
{
dst[k] = sum[k] / denom;
sum[k] = 0;
}
dst += ncomp;
}
}
/* left overs */
if (left)
for (k = 0; k < ncomp; k++)
dst[k] = sum[k] / left;
}
static void
scalecols(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
{
int x, y, k;
unsigned char *s;
int sum[32];
for (x = 0; x < w; x++)
{
s = src + (x * ncomp);
for (k = 0; k < ncomp; k++)
sum[k] = 0;
for (y = 0; y < denom; y++)
for (k = 0; k < ncomp; k++)
sum[k] += s[y * w * ncomp + k];
for (k = 0; k < ncomp; k++)
dst[k] = sum[k] / denom;
dst += ncomp;
}
}
fz_error *
fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom)
{
fz_error *error;
fz_pixmap *dst;
unsigned char *buf;
int y, iy, oy;
int ow, oh, n;
ow = (src->w + xdenom - 1) / xdenom;
oh = (src->h + ydenom - 1) / ydenom;
n = src->n;
buf = fz_malloc(ow * n * ydenom);
if (!buf)
return fz_outofmem;
error = fz_newpixmap(&dst, 0, 0, ow, oh, src->n);
if (error)
{
fz_free(buf);
return error;
}
for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++)
{
for (iy = 0; iy < ydenom; iy++)
scalerow(src->samples + (y + iy) * src->w * n,
buf + iy * ow * n,
src->w, n, xdenom);
scalecols(buf, dst->samples + oy * dst->w * n, dst->w, n, ydenom);
}
ydenom = src->h - y;
if (ydenom)
{
for (iy = 0; iy < ydenom; iy++)
scalerow(src->samples + (y + iy) * src->w * n,
buf + iy * ow * n,
src->w, n, xdenom);
scalecols(buf, dst->samples + oy * dst->w * n, dst->w, n, ydenom);
}
fz_free(buf);
*dstp = dst;
return nil;
}
|