]>
Commit | Line | Data |
---|---|---|
1 | #[cfg(feature="decoder_smush_video")] | |
2 | enum GlyphEdge { | |
3 | Left, | |
4 | Top, | |
5 | Right, | |
6 | Bottom, | |
7 | None | |
8 | } | |
9 | ||
10 | #[cfg(feature="decoder_smush_video")] | |
11 | impl GlyphEdge { | |
12 | fn get(x: usize, y: usize, size: usize) -> Self { | |
13 | if y == 0 { | |
14 | GlyphEdge::Bottom | |
15 | } else if y == size - 1 { | |
16 | GlyphEdge::Top | |
17 | } else if x == 0 { | |
18 | GlyphEdge::Left | |
19 | } else if x == size - 1 { | |
20 | GlyphEdge::Right | |
21 | } else { | |
22 | GlyphEdge::None | |
23 | } | |
24 | } | |
25 | } | |
26 | ||
27 | #[cfg(feature="decoder_smush_video")] | |
28 | enum GlyphDir { | |
29 | Left, | |
30 | Up, | |
31 | Right, | |
32 | Down, | |
33 | None | |
34 | } | |
35 | ||
36 | #[cfg(feature="decoder_smush_video")] | |
37 | impl GlyphDir { | |
38 | fn get(edge0: GlyphEdge, edge1: GlyphEdge) -> Self { | |
39 | match (edge0, edge1) { | |
40 | (GlyphEdge::Left, GlyphEdge::Right) | | |
41 | (GlyphEdge::Right, GlyphEdge::Left) => GlyphDir::Up, | |
42 | (GlyphEdge::Top, GlyphEdge::Bottom) | | |
43 | (GlyphEdge::Bottom, GlyphEdge::Top) => GlyphDir::Right, | |
44 | (GlyphEdge::Bottom, _) | | |
45 | (_, GlyphEdge::Bottom) => GlyphDir::Up, | |
46 | (GlyphEdge::Top, _) | | |
47 | (_, GlyphEdge::Top) => GlyphDir::Down, | |
48 | (GlyphEdge::Left, _) | | |
49 | (_, GlyphEdge::Left) => GlyphDir::Left, | |
50 | (GlyphEdge::Right, _) | | |
51 | (_, GlyphEdge::Right) => GlyphDir::Right, | |
52 | _ => GlyphDir::None, | |
53 | } | |
54 | } | |
55 | } | |
56 | ||
57 | #[cfg(feature="decoder_smush_video")] | |
58 | const XVEC4: [usize; 16] = [0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 2, 1]; | |
59 | #[cfg(feature="decoder_smush_video")] | |
60 | const YVEC4: [usize; 16] = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2]; | |
61 | #[cfg(feature="decoder_smush_video")] | |
62 | const XVEC8: [usize; 16] = [0, 2, 5, 7, 7, 7, 7, 7, 7, 5, 2, 0, 0, 0, 0, 0]; | |
63 | #[cfg(feature="decoder_smush_video")] | |
64 | const YVEC8: [usize; 16] = [0, 0, 0, 0, 1, 3, 4, 6, 7, 7, 7, 7, 6, 4, 3, 1]; | |
65 | ||
66 | #[cfg(feature="decoder_smush_video")] | |
67 | fn make_glyphs_47(glyphs4: &mut [[u8; 16]; 256], glyphs8: &mut [[u8; 64]; 256]) { | |
68 | for (n, glyph) in glyphs4.iter_mut().enumerate() { | |
69 | let i = n >> 4; | |
70 | let j = n & 0xF; | |
71 | make_glyph_47(glyph, XVEC4[i], YVEC4[i], XVEC4[j], YVEC4[j], 4); | |
72 | } | |
73 | for (n, glyph) in glyphs8.iter_mut().enumerate() { | |
74 | let i = n >> 4; | |
75 | let j = n & 0xF; | |
76 | make_glyph_47(glyph, XVEC8[i], YVEC8[i], XVEC8[j], YVEC8[j], 8); | |
77 | } | |
78 | } | |
79 | #[cfg(feature="decoder_smush_video")] | |
80 | fn make_glyph_47(dst: &mut [u8], xi: usize, yi: usize, xj: usize, yj: usize, size: usize) { | |
81 | let edge0 = GlyphEdge::get(xi, yi, size); | |
82 | let edge1 = GlyphEdge::get(xj, yj, size); | |
83 | let dir = GlyphDir::get(edge0, edge1); | |
84 | let npoints = if xi > xj { xi - xj } else { xj - xi }.max(if yi > yj { yi - yj } else { yj - yi }); | |
85 | for ipoint in 0..=npoints { | |
86 | let (p0, p1) = if npoints > 0 { | |
87 | (interpolate(xi, xj, ipoint, npoints), | |
88 | interpolate(yi, yj, ipoint, npoints)) | |
89 | } else { | |
90 | (xi, yi) | |
91 | }; | |
92 | let off = p0 + p1 * size; | |
93 | match dir { | |
94 | GlyphDir::Up => { | |
95 | for i in 0..=p1 { | |
96 | dst[off - i * size] = 1; | |
97 | } | |
98 | }, | |
99 | GlyphDir::Down => { | |
100 | for i in 0..size-p1 { | |
101 | dst[off + i * size] = 1; | |
102 | } | |
103 | }, | |
104 | GlyphDir::Left => { | |
105 | for i in 0..=p0 { | |
106 | dst[off - i] = 1; | |
107 | } | |
108 | }, | |
109 | GlyphDir::Right => { | |
110 | for i in 0..size-p0 { | |
111 | dst[off + i] = 1; | |
112 | } | |
113 | }, | |
114 | _ => {}, | |
115 | }; | |
116 | } | |
117 | } | |
118 | #[cfg(feature="decoder_smush_video")] | |
119 | fn interpolate(a: usize, b: usize, pos1: usize, range: usize) -> usize { | |
120 | (a * pos1 + b * (range - pos1) + range / 2) / range | |
121 | } | |
122 | ||
123 | #[cfg(feature="decoder_smush_video")] | |
124 | mod v1; | |
125 | #[cfg(feature="decoder_smush_video")] | |
126 | pub use v1::get_decoder_video_v1; | |
127 | #[cfg(feature="decoder_smush_video")] | |
128 | mod v2; | |
129 | #[cfg(feature="decoder_smush_video")] | |
130 | pub use v2::get_decoder_video_v2; | |
131 | ||
132 | #[cfg(feature="decoder_smush_audio")] | |
133 | mod iact; | |
134 | #[cfg(feature="decoder_smush_audio")] | |
135 | pub use iact::get_decoder_iact; | |
136 | #[cfg(feature="decoder_smush_audio")] | |
137 | mod vima; | |
138 | #[cfg(feature="decoder_smush_audio")] | |
139 | pub use vima::get_decoder_vima; |