/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:4;tab-width:4;coding:utf-8   -*-â
âvi: set et ft=c ts=4 sw=4 fenc=utf-8                                       :viâ
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¡
â  PL_MPEG - MPEG1 Video decoder, MP2 Audio decoder, MPEG-PS demuxer           â
â  Dominic Szablewski - https://phoboslab.org                                  â
â                                                                              â
â  The MIT License(MIT)                                                        â
â  Copyright(c) 2019 Dominic Szablewski                                        â
â                                                                              â
â  Permission is hereby granted, free of charge, to any person obtaining       â
â  a copy of this software and associated documentation files(the              â
â  "Software"), to deal in the Software without restriction, including         â
â  without limitation the rights to use, copy, modify, merge, publish,         â
â  distribute, sublicense, and / or sell copies of the Software, and to        â
â  permit persons to whom the Software is furnished to do so, subject to       â
â  the following conditions:                                                   â
â                                                                              â
â    The above copyright notice and this permission notice shall be            â
â    included in all copies or substantial portions of the Software.           â
â                                                                              â
â  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,             â
â  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF          â
â  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND                       â
â  NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE       â
â  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN             â
â  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN           â
â  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE            â
â  SOFTWARE.                                                                   â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ*/
#include "dsp/core/half.h"

asm(".ident\t\"\\n\\n\
PL_MPEG (MIT License)\\n\
Copyright(c) 2019 Dominic Szablewski\\n\
https://phoboslab.org\"");
asm(".include \"libc/disclaimer.inc\"");

/**
 * Computes Fixed-Point 8x8 Inverse Discrete Cosine Transform.
 *
 * @note discovered by Nasir Ahmed
 */
void plm_video_idct(int block[8][8]) {
  int i, j, t1, t2, m0;
  int b1, b3, b4, b6, b7;
  int y3, y4, y5, y6, y7;
  int x0, x1, x2, x3, x4;

  for (i = 0; i < 8; ++i) {
    b1 = block[4][i];
    b3 = block[2][i] + block[6][i];
    b4 = block[5][i] - block[3][i];
    t1 = block[1][i] + block[7][i];
    t2 = block[3][i] + block[5][i];
    b6 = block[1][i] - block[7][i];
    b7 = t1 + t2;
    m0 = block[0][i];
    x4 = ((b6 * 473 - b4 * 196 + 128) >> 8) - b7;
    x0 = x4 - (((t1 - t2) * 362 + 128) >> 8);
    x1 = m0 - b1;
    x2 = (((block[2][i] - block[6][i]) * 362 + 128) >> 8) - b3;
    x3 = m0 + b1;
    y3 = x1 + x2;
    y4 = x3 + b3;
    y5 = x1 - x2;
    y6 = x3 - b3;
    y7 = -x0 - ((b4 * 473 + b6 * 196 + 128) >> 8);
    block[0][i] = b7 + y4;
    block[1][i] = x4 + y3;
    block[2][i] = y5 - x0;
    block[3][i] = y6 - y7;
    block[4][i] = y6 + y7;
    block[5][i] = x0 + y5;
    block[6][i] = y3 - x4;
    block[7][i] = y4 - b7;
  }

  for (i = 0; i < 8; ++i) {
    b1 = block[i][4];
    b3 = block[i][2] + block[i][6];
    b4 = block[i][5] - block[i][3];
    t1 = block[i][1] + block[i][7];
    t2 = block[i][3] + block[i][5];
    b6 = block[i][1] - block[i][7];
    b7 = t1 + t2;
    m0 = block[i][0];
    x4 = ((b6 * 473 - b4 * 196 + 128) >> 8) - b7;
    x0 = x4 - (((t1 - t2) * 362 + 128) >> 8);
    x1 = m0 - b1;
    x2 = (((block[i][2] - block[i][6]) * 362 + 128) >> 8) - b3;
    x3 = m0 + b1;
    y3 = x1 + x2;
    y4 = x3 + b3;
    y5 = x1 - x2;
    y6 = x3 - b3;
    y7 = -x0 - ((b4 * 473 + b6 * 196 + 128) >> 8);
    block[i][0] = (b7 + y4 + 128) >> 8;
    block[i][1] = (x4 + y3 + 128) >> 8;
    block[i][2] = (y5 - x0 + 128) >> 8;
    block[i][3] = (y6 - y7 + 128) >> 8;
    block[i][4] = (y6 + y7 + 128) >> 8;
    block[i][5] = (x0 + y5 + 128) >> 8;
    block[i][6] = (y3 - x4 + 128) >> 8;
    block[i][7] = (y4 - b7 + 128) >> 8;
  }
}
