1/*
2fdct is a Rust translation of jfdctint.c from the
3Independent JPEG Group's libjpeg version 9a
4obtained from http://www.ijg.org/files/jpegsr9a.zip
5It comes with the following conditions of distribution and use:
6
7 In plain English:
8
9 1. We don't promise that this software works. (But if you find any bugs,
10 please let us know!)
11 2. You can use this software for whatever you want. You don't have to pay us.
12 3. You may not pretend that you wrote this software. If you use it in a
13 program, you must acknowledge somewhere in your documentation that
14 you've used the IJG code.
15
16 In legalese:
17
18 The authors make NO WARRANTY or representation, either express or implied,
19 with respect to this software, its quality, accuracy, merchantability, or
20 fitness for a particular purpose. This software is provided "AS IS", and you,
21 its user, assume the entire risk as to its quality and accuracy.
22
23 This software is copyright (C) 1991-2014, Thomas G. Lane, Guido Vollbeding.
24 All Rights Reserved except as specified below.
25
26 Permission is hereby granted to use, copy, modify, and distribute this
27 software (or portions thereof) for any purpose, without fee, subject to these
28 conditions:
29 (1) If any part of the source code for this software is distributed, then this
30 README file must be included, with this copyright and no-warranty notice
31 unaltered; and any additions, deletions, or changes to the original files
32 must be clearly indicated in accompanying documentation.
33 (2) If only executable code is distributed, then the accompanying
34 documentation must state that "this software is based in part on the work of
35 the Independent JPEG Group".
36 (3) Permission for use of this software is granted only if the user accepts
37 full responsibility for any undesirable consequences; the authors accept
38 NO LIABILITY for damages of any kind.
39
40 These conditions apply to any software derived from or based on the IJG code,
41 not just to the unmodified library. If you use our work, you ought to
42 acknowledge us.
43
44 Permission is NOT granted for the use of any IJG author's name or company name
45 in advertising or publicity relating to this software or products derived from
46 it. This software may be referred to only as "the Independent JPEG Group's
47 software".
48
49 We specifically permit and encourage the use of this software as the basis of
50 commercial products, provided that all warranty or liability claims are
51 assumed by the product vendor.
52*/
53
54static CONST_BITS: i32 = 13;
55static PASS1_BITS: i32 = 2;
56
57static FIX_0_298631336: i32 = 2446;
58static FIX_0_390180644: i32 = 3196;
59static FIX_0_541196100: i32 = 4433;
60static FIX_0_765366865: i32 = 6270;
61static FIX_0_899976223: i32 = 7373;
62static FIX_1_175875602: i32 = 9633;
63static FIX_1_501321110: i32 = 12_299;
64static FIX_1_847759065: i32 = 15_137;
65static FIX_1_961570560: i32 = 16_069;
66static FIX_2_053119869: i32 = 16_819;
67static FIX_2_562915447: i32 = 20_995;
68static FIX_3_072711026: i32 = 25_172;
69
70pub(crate) fn fdct(samples: &[u8; 64], coeffs: &mut [i32; 64]) {
71 // Pass 1: process rows.
72 // Results are scaled by sqrt(8) compared to a true DCT
73 // furthermore we scale the results by 2**PASS1_BITS
74 for y in 0usize..8 {
75 let y0 = y * 8;
76
77 // Even part
78 let t0 = i32::from(samples[y0]) + i32::from(samples[y0 + 7]);
79 let t1 = i32::from(samples[y0 + 1]) + i32::from(samples[y0 + 6]);
80 let t2 = i32::from(samples[y0 + 2]) + i32::from(samples[y0 + 5]);
81 let t3 = i32::from(samples[y0 + 3]) + i32::from(samples[y0 + 4]);
82
83 let t10 = t0 + t3;
84 let t12 = t0 - t3;
85 let t11 = t1 + t2;
86 let t13 = t1 - t2;
87
88 let t0 = i32::from(samples[y0]) - i32::from(samples[y0 + 7]);
89 let t1 = i32::from(samples[y0 + 1]) - i32::from(samples[y0 + 6]);
90 let t2 = i32::from(samples[y0 + 2]) - i32::from(samples[y0 + 5]);
91 let t3 = i32::from(samples[y0 + 3]) - i32::from(samples[y0 + 4]);
92
93 // Apply unsigned -> signed conversion
94 coeffs[y0] = (t10 + t11 - 8 * 128) << PASS1_BITS as usize;
95 coeffs[y0 + 4] = (t10 - t11) << PASS1_BITS as usize;
96
97 let mut z1 = (t12 + t13) * FIX_0_541196100;
98 // Add fudge factor here for final descale
99 z1 += 1 << (CONST_BITS - PASS1_BITS - 1) as usize;
100
101 coeffs[y0 + 2] = (z1 + t12 * FIX_0_765366865) >> (CONST_BITS - PASS1_BITS) as usize;
102 coeffs[y0 + 6] = (z1 - t13 * FIX_1_847759065) >> (CONST_BITS - PASS1_BITS) as usize;
103
104 // Odd part
105 let t12 = t0 + t2;
106 let t13 = t1 + t3;
107
108 let mut z1 = (t12 + t13) * FIX_1_175875602;
109 // Add fudge factor here for final descale
110 z1 += 1 << (CONST_BITS - PASS1_BITS - 1) as usize;
111
112 let mut t12 = t12 * (-FIX_0_390180644);
113 let mut t13 = t13 * (-FIX_1_961570560);
114 t12 += z1;
115 t13 += z1;
116
117 let z1 = (t0 + t3) * (-FIX_0_899976223);
118 let mut t0 = t0 * FIX_1_501321110;
119 let mut t3 = t3 * FIX_0_298631336;
120 t0 += z1 + t12;
121 t3 += z1 + t13;
122
123 let z1 = (t1 + t2) * (-FIX_2_562915447);
124 let mut t1 = t1 * FIX_3_072711026;
125 let mut t2 = t2 * FIX_2_053119869;
126 t1 += z1 + t13;
127 t2 += z1 + t12;
128
129 coeffs[y0 + 1] = t0 >> (CONST_BITS - PASS1_BITS) as usize;
130 coeffs[y0 + 3] = t1 >> (CONST_BITS - PASS1_BITS) as usize;
131 coeffs[y0 + 5] = t2 >> (CONST_BITS - PASS1_BITS) as usize;
132 coeffs[y0 + 7] = t3 >> (CONST_BITS - PASS1_BITS) as usize;
133 }
134
135 // Pass 2: process columns
136 // We remove the PASS1_BITS scaling but leave the results scaled up an
137 // overall factor of 8
138 for x in (0usize..8).rev() {
139 // Even part
140 let t0 = coeffs[x] + coeffs[x + 8 * 7];
141 let t1 = coeffs[x + 8] + coeffs[x + 8 * 6];
142 let t2 = coeffs[x + 8 * 2] + coeffs[x + 8 * 5];
143 let t3 = coeffs[x + 8 * 3] + coeffs[x + 8 * 4];
144
145 // Add fudge factor here for final descale
146 let t10 = t0 + t3 + (1 << (PASS1_BITS - 1) as usize);
147 let t12 = t0 - t3;
148 let t11 = t1 + t2;
149 let t13 = t1 - t2;
150
151 let t0 = coeffs[x] - coeffs[x + 8 * 7];
152 let t1 = coeffs[x + 8] - coeffs[x + 8 * 6];
153 let t2 = coeffs[x + 8 * 2] - coeffs[x + 8 * 5];
154 let t3 = coeffs[x + 8 * 3] - coeffs[x + 8 * 4];
155
156 coeffs[x] = (t10 + t11) >> PASS1_BITS as usize;
157 coeffs[x + 8 * 4] = (t10 - t11) >> PASS1_BITS as usize;
158
159 let mut z1 = (t12 + t13) * FIX_0_541196100;
160 // Add fudge factor here for final descale
161 z1 += 1 << (CONST_BITS + PASS1_BITS - 1) as usize;
162
163 coeffs[x + 8 * 2] = (z1 + t12 * FIX_0_765366865) >> (CONST_BITS + PASS1_BITS) as usize;
164 coeffs[x + 8 * 6] = (z1 - t13 * FIX_1_847759065) >> (CONST_BITS + PASS1_BITS) as usize;
165
166 // Odd part
167 let t12 = t0 + t2;
168 let t13 = t1 + t3;
169
170 let mut z1 = (t12 + t13) * FIX_1_175875602;
171 // Add fudge factor here for final descale
172 z1 += 1 << (CONST_BITS - PASS1_BITS - 1) as usize;
173
174 let mut t12 = t12 * (-FIX_0_390180644);
175 let mut t13 = t13 * (-FIX_1_961570560);
176 t12 += z1;
177 t13 += z1;
178
179 let z1 = (t0 + t3) * (-FIX_0_899976223);
180 let mut t0 = t0 * FIX_1_501321110;
181 let mut t3 = t3 * FIX_0_298631336;
182 t0 += z1 + t12;
183 t3 += z1 + t13;
184
185 let z1 = (t1 + t2) * (-FIX_2_562915447);
186 let mut t1 = t1 * FIX_3_072711026;
187 let mut t2 = t2 * FIX_2_053119869;
188 t1 += z1 + t13;
189 t2 += z1 + t12;
190
191 coeffs[x + 8] = t0 >> (CONST_BITS + PASS1_BITS) as usize;
192 coeffs[x + 8 * 3] = t1 >> (CONST_BITS + PASS1_BITS) as usize;
193 coeffs[x + 8 * 5] = t2 >> (CONST_BITS + PASS1_BITS) as usize;
194 coeffs[x + 8 * 7] = t3 >> (CONST_BITS + PASS1_BITS) as usize;
195 }
196}
197