summaryrefslogtreecommitdiff
path: root/render/scale.c
blob: 1fad5a0bab5def934e7a173b6c9134edd6d343a8 (plain)
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
#include <fitz.h>

static void
scalerow(unsigned char *src, int w, int denom, unsigned char *dst, int ncomp)
{
	int x, left, n;
	int sum[32];

	left = 0;
	for (n = 0; n < ncomp; n++)
		sum[n] = 0;

	for (x = 0; x < w; x++)
	{
		for (n = 0; n < ncomp; n++)
            sum[n] += src[x * ncomp + n];
		if (++left == denom)
		{
			left = 0;
			for (n = 0; n < ncomp; n++)
			{
				dst[n] = sum[n] / denom;
				sum[n] = 0;
			}
			dst += ncomp;
		}
	}

	/* left overs */
	if (left)
		for (n = 0; n < ncomp; n++)
			dst[n] = sum[n] / left;
}

static void
scalecols(unsigned char *src, int stride, int w, int denom, unsigned char *dst, int ncomp)
{
	int x, y, n;
	unsigned char *s;
	int sum[32];

	for (x = 0; x < w; x++)
	{
		s = src + (x * ncomp);
		for (n = 0; n < ncomp; n++)
			sum[n] = 0;
		for (y = 0; y < denom; y++)
			for (n = 0; n < ncomp; n++)
				sum[n] += s[y * stride + n];
		for (n = 0; n < ncomp; n++)
			dst[n] = sum[n] / denom;
		dst += ncomp;
	}
}

fz_error *
fz_scalepixmap(fz_pixmap *src, fz_pixmap *dst, int xdenom, int ydenom)
{
	assert(src->n == dst->n);
	assert(src->a == dst->a);
	assert((src->w + xdenom - 1) / xdenom == dst->w);
	assert((src->h + ydenom - 1) / ydenom == dst->h);

	int ncomp = src->n + src->a;
	unsigned char scratch[dst->stride * ydenom];

	int y, iy, oy;

	for (y = 0, oy = 0; y < (dst->h - 1) * ydenom; y += ydenom, oy++)
	{
		for (iy = 0; iy < ydenom; iy++)
			scalerow(src->samples + (y + iy) * src->stride, src->w, xdenom,
				scratch + iy * dst->stride, ncomp);
		scalecols(scratch, ncomp * dst->w, dst->w, ydenom,
			dst->samples + (oy * dst->stride), ncomp);
	}

	ydenom = src->h - y;
	if (ydenom)
	{
		for (iy = 0; iy < ydenom; iy++)
			scalerow(src->samples + (y + iy) * src->stride, src->w, xdenom,
				scratch + iy * (ncomp * dst->w), ncomp);
		scalecols(scratch, ncomp * dst->w, dst->w, ydenom,
			dst->samples + (oy * dst->stride), ncomp);
	}

//printf("unscaled image ");fz_debugpixmap(src);getchar();
//printf("scaled image ");fz_debugpixmap(dst);getchar();

	return nil;
}