1#include "mupdf/fitz.h"
2
3#include <string.h>
4
5/*
6 FIXME: Currently transitions only work with alpha. Our app only
7 uses alpha.
8*/
9
10static int
11fade(fz_pixmap *tpix, const fz_pixmap *opix, const fz_pixmap *npix, int time)
12{
13 unsigned char *t, *o, *n;
14 int size;
15 int h;
16 int tstride, ostride, nstride;
17
18 if (!tpix || !opix || !npix || tpix->w != opix->w || opix->w != npix->w || tpix->h != opix->h || opix->h != npix->h || tpix->n != opix->n || opix->n != npix->n)
19 return 0;
20 h = tpix->h;
21 size = tpix->w * tpix->n;
22 ostride = opix->stride - size;
23 nstride = npix->stride - size;
24 tstride = tpix->stride - size;
25 t = tpix->samples;
26 o = opix->samples;
27 n = npix->samples;
28 while (h--)
29 {
30 int ww = size;
31 while (ww-- > 0)
32 {
33 int op = *o++;
34 int np = *n++;
35 *t++ = ((op<<8) + ((np-op) * time) + 0x80)>>8;
36 }
37 o += ostride;
38 n += nstride;
39 t += tstride;
40 }
41 return 1;
42}
43
44static int
45blind_horiz(fz_pixmap *tpix, fz_pixmap *opix, fz_pixmap *npix, int time)
46{
47 unsigned char *t, *o, *n;
48 int blind_height, size, position, y;
49 int tstride, ostride, nstride;
50
51 if (!tpix || !opix || !npix || tpix->w != opix->w || opix->w != npix->w || tpix->h != opix->h || opix->h != npix->h || tpix->n != opix->n || opix->n != npix->n)
52 return 0;
53 size = tpix->w * tpix->n;
54 blind_height = (tpix->h+7) / 8;
55 position = blind_height * time / 256;
56 ostride = opix->stride;
57 nstride = npix->stride;
58 tstride = tpix->stride;
59 t = tpix->samples;
60 o = opix->samples;
61 n = npix->samples;
62 for (y = 0; y < tpix->h; y++)
63 {
64 memcpy(t, ((y % blind_height) <= position ? n : o), size);
65 t += tstride;
66 o += ostride;
67 n += nstride;
68 }
69 return 1;
70}
71
72static int
73blind_vertical(fz_pixmap *tpix, fz_pixmap *opix, fz_pixmap *npix, int time)
74{
75 unsigned char *t, *o, *n;
76 int blind_width, size, position, y;
77 int tstride, ostride, nstride;
78
79 if (!tpix || !opix || !npix || tpix->w != opix->w || opix->w != npix->w || tpix->h != opix->h || opix->h != npix->h || tpix->n != opix->n || opix->n != npix->n)
80 return 0;
81 size = tpix->w * tpix->n;
82 blind_width = (tpix->w+7) / 8;
83 position = blind_width * time / 256;
84 blind_width *= tpix->n;
85 position *= tpix->n;
86 ostride = opix->stride - size;
87 nstride = npix->stride - size;
88 tstride = tpix->stride - size;
89 t = tpix->samples;
90 o = opix->samples;
91 n = npix->samples;
92 for (y = 0; y < tpix->h; y++)
93 {
94 int w, x;
95 x = 0;
96 while ((w = size - x) > 0)
97 {
98 int p;
99 if (w > blind_width)
100 w = blind_width;
101 p = position;
102 if (p > w)
103 p = w;
104 memcpy(t, n, p);
105 memcpy(t+position, o+position, w - p);
106 x += blind_width;
107 t += w;
108 o += w;
109 n += w;
110 }
111 o += ostride;
112 n += nstride;
113 t += tstride;
114 }
115 return 1;
116}
117
118static int
119wipe_tb(fz_pixmap *tpix, fz_pixmap *opix, fz_pixmap *npix, int time)
120{
121 unsigned char *t, *o, *n;
122 int size, position, y;
123 int tstride, ostride, nstride;
124
125 if (!tpix || !opix || !npix || tpix->w != opix->w || opix->w != npix->w || tpix->h != opix->h || opix->h != npix->h || tpix->n != opix->n || opix->n != npix->n)
126 return 0;
127 size = tpix->w * tpix->n;
128 position = tpix->h * time / 256;
129 ostride = opix->stride;
130 nstride = npix->stride;
131 tstride = tpix->stride;
132 t = tpix->samples;
133 o = opix->samples;
134 n = npix->samples;
135 for (y = 0; y < position; y++)
136 {
137 memcpy(t, n, size);
138 t += tstride;
139 o += ostride;
140 n += nstride;
141 }
142 for (; y < tpix->h; y++)
143 {
144 memcpy(t, o, size);
145 t += tstride;
146 o += ostride;
147 n += nstride;
148 }
149 return 1;
150}
151
152static int
153wipe_lr(fz_pixmap *tpix, fz_pixmap *opix, fz_pixmap *npix, int time)
154{
155 unsigned char *t, *o, *n;
156 int size, position, y;
157 int tstride, ostride, nstride;
158
159 if (!tpix || !opix || !npix || tpix->w != opix->w || opix->w != npix->w || tpix->h != opix->h || opix->h != npix->h || tpix->n != opix->n || opix->n != npix->n)
160 return 0;
161 size = tpix->w * tpix->n;
162 position = tpix->w * time / 256;
163 position *= tpix->n;
164 ostride = opix->stride;
165 nstride = npix->stride;
166 tstride = tpix->stride;
167 t = tpix->samples;
168 o = opix->samples + position;
169 n = npix->samples;
170 for (y = 0; y < tpix->h; y++)
171 {
172 memcpy(t, n, position);
173 memcpy(t+position, o, size-position);
174 t += tstride;
175 o += ostride;
176 n += nstride;
177 }
178 return 1;
179}
180
181/*
182 Generate a frame of a transition.
183
184 tpix: Target pixmap
185 opix: Old pixmap
186 npix: New pixmap
187 time: Position within the transition (0 to 256)
188 trans: Transition details
189
190 Returns 1 if successfully generated a frame.
191*/
192int fz_generate_transition(fz_context *ctx, fz_pixmap *tpix, fz_pixmap *opix, fz_pixmap *npix, int time, fz_transition *trans)
193{
194 switch (trans->type)
195 {
196 default:
197 case FZ_TRANSITION_FADE:
198 return fade(tpix, opix, npix, time);
199 case FZ_TRANSITION_BLINDS:
200 if (trans->vertical)
201 return blind_vertical(tpix, opix, npix, time);
202 else
203 return blind_horiz(tpix, opix, npix, time);
204 case FZ_TRANSITION_WIPE:
205 switch (((trans->direction + 45 + 360) % 360) / 90)
206 {
207 default:
208 case 0: return wipe_lr(tpix, opix, npix, time);
209 case 1: return wipe_tb(tpix, npix, opix, 256-time);
210 case 2: return wipe_lr(tpix, npix, opix, 256-time);
211 case 3: return wipe_tb(tpix, opix, npix, time);
212 }
213 }
214}
215