diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | bcb704366cb5e333a626c18c308c7e0448a8e69f (patch) | |
tree | f0d6ab7d78ecdd9207cf46536376b44b91a1ca71 /kopete/protocols/msn/webcam/libmimic/fdct_quant.c | |
download | tdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.tar.gz tdenetwork-bcb704366cb5e333a626c18c308c7e0448a8e69f.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kopete/protocols/msn/webcam/libmimic/fdct_quant.c')
-rw-r--r-- | kopete/protocols/msn/webcam/libmimic/fdct_quant.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/kopete/protocols/msn/webcam/libmimic/fdct_quant.c b/kopete/protocols/msn/webcam/libmimic/fdct_quant.c new file mode 100644 index 00000000..7e8d0bdd --- /dev/null +++ b/kopete/protocols/msn/webcam/libmimic/fdct_quant.c @@ -0,0 +1,181 @@ +/* Copyright (C) 2005 Ole André Vadla Ravnås <oleavr@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "mimic-private.h" + +extern guchar _col_zag[64]; + +void _fdct_quant_block(MimCtx *ctx, gint *block, const guchar *src, + gint stride, gboolean is_chrom, gint num_coeffs) +{ + gint sum1, sum2, sum3, sum4; + gint diff1, diff2, diff3, diff4; + gint ex1, ex2, ex3, ex4, ex5; + gint i, j; + const guchar *p1; + gint *iptr; + + /* + * Forward DCT, first pass (horizontal). + */ + p1 = src; + iptr = block; + + for (i = 0; i < 8; i++) { + sum1 = p1[0] + p1[7]; + sum2 = p1[1] + p1[6]; + sum3 = p1[2] + p1[5]; + sum4 = p1[3] + p1[4]; + + diff1 = p1[0] - p1[7]; + diff2 = p1[1] - p1[6]; + diff3 = p1[2] - p1[5]; + diff4 = p1[3] - p1[4]; + + ex1 = ((diff1 + diff4) * 851) - (diff1 * 282); + ex2 = ((diff2 + diff3) * 1004) - (diff2 * 804); + ex3 = ((diff2 + diff3) * 1004) - (diff3 * 1204); + ex4 = ((diff1 + diff4) * 851) - (diff4 * 1420); + + iptr[0] = sum1 + sum2 + sum3 + sum4; + iptr[2] = (((sum1 - sum4) * 1337) + ((sum2 - sum3) * 554)) >> 10; + iptr[4] = sum1 - sum2 - sum3 + sum4; + + iptr[1] = (ex1 + ex2 + ex3 + ex4) >> 10; + iptr[3] = ((ex4 - ex2) * 181) >> 17; + iptr[5] = ((ex1 - ex3) * 181) >> 17; + + p1 += stride; + iptr += 8; + } + + p1 = src; + iptr = block; + + /* + * Forward DCT, first pass (vertical). + * + * This is only known to be correct for i == 0, though it seems to be ... + */ + for (i = 0; i < 6; i++) { + sum1 = iptr[ 0 + i] + iptr[56 + i]; + sum2 = iptr[ 8 + i] + iptr[48 + i]; + sum3 = iptr[16 + i] + iptr[40 + i]; + sum4 = iptr[24 + i] + iptr[32 + i]; + + diff1 = iptr[ 0 + i] - iptr[56 + i]; + diff2 = iptr[ 8 + i] - iptr[48 + i]; + diff3 = iptr[16 + i] - iptr[40 + i]; + diff4 = iptr[24 + i] - iptr[32 + i]; + + ex1 = ((diff1 + diff4) * 851) - (diff1 * 282); + ex2 = ((diff2 + diff3) * 1004) - (diff2 * 804); + ex3 = ((diff2 + diff3) * 1004) - (diff3 * 1204); + ex4 = ((diff1 + diff4) * 851) - (diff4 * 1420); + + ex5 = (sum1 + sum2 - sum3 - sum4) * 554; + + for (j = 0; j < 7 - i; j++) { + switch (j) { + + case 0: + iptr[ 0 + i] = (16 + sum1 + sum2 + sum3 + sum4) >> 5; + break; + + case 1: + iptr[ 8 + i] = (16384 + ex1 + ex2 + ex3 + ex4) >> 15; + break; + + case 2: + iptr[16 + i] = (16384 + ((sum1 - sum4) * 783) + ex5) >> 15; + break; + + case 3: + iptr[24 + i] = (8192 + (((ex4 - ex2) >> 8) * 181)) >> 14; + break; + + case 4: + iptr[32 + i] = (16 + sum1 - sum2 - sum3 + sum4) >> 5; + break; + + case 5: + iptr[40 + i] = (8192 + (((ex1 - ex3) >> 8) * 181)) >> 14; + break; + + case 6: + iptr[48 + i] = (16384 - ((sum2 - sum3) * 1891) + ex5) >> 15; + break; + } + } + } + + /* + * Quantize. + */ + block[0] /= 2; + block[8] /= 4; + block[1] /= 4; + block[6] = 0; + + if (num_coeffs > 3) { + + gdouble s = (10000 - ctx->quality) * 10.0 * (gfloat) 9.9999997e-5; + + if (s > 10.0) + s = 10.0; + else if (is_chrom != 0 && s < 1.0) + s = 1.0; + else if (s < 2.0) + s = 2.0; + + s = 1.0 / s; + + for (i = 3; i < num_coeffs; i++) { + + gdouble coeff, r; + + coeff = block[_col_zag[i]] * s; + r = coeff - (gint) coeff; + + if (r >= 0.6) + block[_col_zag[i]] = (gint) (coeff + 1.0); + else if (r <= -0.6) + block[_col_zag[i]] = (gint) (coeff - 1.0); + else + block[_col_zag[i]] = (gint) coeff; + + if (block[_col_zag[i]] > 120) + block[_col_zag[i]] = 120; + else if (block[_col_zag[i]] < -120) + block[_col_zag[i]] = -120; + } + } + + if (block[8] > 120) + block[8] = 120; + else if (block[8] < -120) + block[8] = -120; + + if (block[1] > 120) + block[1] = 120; + else if (block[1] < -120) + block[1] = -120; + + for (i = num_coeffs; i < 64; i++) + block[_col_zag[i]] = 0; +} + |