/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2020 Justine Alexandra Roberts Tunney │ │ │ │ This program is free software; you can redistribute it and/or modify │ │ it under the terms of the GNU General Public License as published by │ │ the Free Software Foundation; version 2 of the License. │ │ │ │ This program is distributed in the hope that it will be useful, but │ │ WITHOUT ANY WARRANTY; without even the implied warranty of │ │ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ │ General Public License for more details. │ │ │ │ You should have received a copy of the GNU General Public License │ │ along with this program; if not, write to the Free Software │ │ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "dsp/core/core.h" #define DCT(A, B, C, D, E, F, G, H, T, C0, C1, C2, C3, C4) \ do { \ T z1, z2, z3, z4, z5, z11, z13; \ T t0, t1, t2, t3, t4, t5, t6, t7, t8, t10, t11, t12, t13; \ t0 = A + H; \ t7 = A - H; \ t1 = B + G; \ t6 = B - G; \ t2 = C + F; \ t5 = C - F; \ t3 = D + E; \ t4 = D - E; \ t10 = t0 + t3; \ t13 = t0 - t3; \ t11 = t1 + t2; \ t12 = t1 - t2; \ A = t10 + t11; \ E = t10 - t11; \ z1 = (t12 + t13) * C0; \ C = t13 + z1; \ G = t13 - z1; \ t10 = t4 + t5; \ t11 = t5 + t6; \ t12 = t6 + t7; \ z5 = (t10 - t12) * C1; \ z2 = t10 * C2 + z5; \ z4 = t12 * C3 + z5; \ z3 = t11 * C4; \ z11 = t7 + z3; \ z13 = t7 - z3; \ F = z13 + z2; \ D = z13 - z2; \ B = z11 + z4; \ H = z11 - z4; \ } while (0) /** * Performs float forward discrete cosine transform. * * This takes a tiny block of image data and shoves the information it * represents into the top left corner. It can be reversed using idct(). * It matters because iterating the result in a serpentine pattern makes * run-length delta encoding super effective. Furthermore, data downward * rightly may be divided away for lossy compression. * * @cost ~100ns */ void *dct(float M[8][8], float c0, float c1, float c2, float c3, float c4) { unsigned y, x; for (y = 0; y < 8; ++y) { DCT(M[y][0], M[y][1], M[y][2], M[y][3], M[y][4], M[y][5], M[y][6], M[y][7], float, c0, c1, c2, c3, c4); } for (x = 0; x < 8; ++x) { DCT(M[0][x], M[1][x], M[2][x], M[3][x], M[4][x], M[5][x], M[6][x], M[7][x], float, c0, c1, c2, c3, c4); } return M; } void *dctjpeg(float M[8][8]) { return dct(M, .707106781f, .382683433f, .541196100f, 1.306562965f, .707106781f); }