| 1 | /* |
| 2 | fdct is a Rust translation of jfdctint.c from the |
| 3 | Independent JPEG Group's libjpeg version 9a |
| 4 | obtained from http://www.ijg.org/files/jpegsr9a.zip |
| 5 | It 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 | |
| 54 | static CONST_BITS: i32 = 13; |
| 55 | static PASS1_BITS: i32 = 2; |
| 56 | |
| 57 | static FIX_0_298631336: i32 = 2446; |
| 58 | static FIX_0_390180644: i32 = 3196; |
| 59 | static FIX_0_541196100: i32 = 4433; |
| 60 | static FIX_0_765366865: i32 = 6270; |
| 61 | static FIX_0_899976223: i32 = 7373; |
| 62 | static FIX_1_175875602: i32 = 9633; |
| 63 | static FIX_1_501321110: i32 = 12_299; |
| 64 | static FIX_1_847759065: i32 = 15_137; |
| 65 | static FIX_1_961570560: i32 = 16_069; |
| 66 | static FIX_2_053119869: i32 = 16_819; |
| 67 | static FIX_2_562915447: i32 = 20_995; |
| 68 | static FIX_3_072711026: i32 = 25_172; |
| 69 | |
| 70 | pub(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 | |