Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

idct.c

Go to the documentation of this file.
00001 /*
00002  * idct.c
00003  * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
00004  * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
00005  *
00006  * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
00007  * See http://libmpeg2.sourceforge.net/ for updates.
00008  *
00009  * mpeg2dec is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * mpeg2dec is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  */
00023 
00024 #include "config.h"
00025 
00026 #include <stdlib.h>
00027 #include <inttypes.h>
00028 
00029 #include "mpeg2.h"
00030 #include "mpeg2_internal.h"
00031 #include "attributes.h"
00032 
00033 #define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
00034 #define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
00035 #define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
00036 #define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
00037 #define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
00038 #define W7 565  /* 2048*sqrt (2)*cos (7*pi/16) */
00039 
00040 /* idct main entry point  */
00041 void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride);
00042 void (* mpeg2_idct_add) (int last, int16_t * block,
00043                          uint8_t * dest, int stride);
00044 
00045 static uint8_t clip_lut[1024];
00046 #define CLIP(i) ((clip_lut+384)[(i)])
00047 
00048 #if 0
00049 #define BUTTERFLY(t0,t1,W0,W1,d0,d1)    \
00050 do {                                    \
00051     t0 = W0*d0 + W1*d1;                 \
00052     t1 = W0*d1 - W1*d0;                 \
00053 } while (0)
00054 #else
00055 #define BUTTERFLY(t0,t1,W0,W1,d0,d1)    \
00056 do {                                    \
00057     int tmp = W0 * (d0 + d1);           \
00058     t0 = tmp + (W1 - W0) * d1;          \
00059     t1 = tmp - (W1 + W0) * d0;          \
00060 } while (0)
00061 #endif
00062 
00063 static void inline idct_row (int16_t * const block)
00064 {
00065     int d0, d1, d2, d3;
00066     int a0, a1, a2, a3, b0, b1, b2, b3;
00067     int t0, t1, t2, t3;
00068 
00069     /* shortcut */
00070     if (likely (!(block[1] | ((int32_t *)block)[1] | ((int32_t *)block)[2] |
00071                   ((int32_t *)block)[3]))) {
00072         uint32_t tmp = (uint16_t) (block[0] << 3);
00073         tmp |= tmp << 16;
00074         ((int32_t *)block)[0] = tmp;
00075         ((int32_t *)block)[1] = tmp;
00076         ((int32_t *)block)[2] = tmp;
00077         ((int32_t *)block)[3] = tmp;
00078         return;
00079     }
00080 
00081     d0 = (block[0] << 11) + 128;
00082     d1 = block[1];
00083     d2 = block[2] << 11;
00084     d3 = block[3];
00085     t0 = d0 + d2;
00086     t1 = d0 - d2;
00087     BUTTERFLY (t2, t3, W6, W2, d3, d1);
00088     a0 = t0 + t2;
00089     a1 = t1 + t3;
00090     a2 = t1 - t3;
00091     a3 = t0 - t2;
00092 
00093     d0 = block[4];
00094     d1 = block[5];
00095     d2 = block[6];
00096     d3 = block[7];
00097     BUTTERFLY (t0, t1, W7, W1, d3, d0);
00098     BUTTERFLY (t2, t3, W3, W5, d1, d2);
00099     b0 = t0 + t2;
00100     b3 = t1 + t3;
00101     t0 -= t2;
00102     t1 -= t3;
00103     b1 = ((t0 + t1) * 181) >> 8;
00104     b2 = ((t0 - t1) * 181) >> 8;
00105 
00106     block[0] = (a0 + b0) >> 8;
00107     block[1] = (a1 + b1) >> 8;
00108     block[2] = (a2 + b2) >> 8;
00109     block[3] = (a3 + b3) >> 8;
00110     block[4] = (a3 - b3) >> 8;
00111     block[5] = (a2 - b2) >> 8;
00112     block[6] = (a1 - b1) >> 8;
00113     block[7] = (a0 - b0) >> 8;
00114 }
00115 
00116 static void inline idct_col (int16_t * const block)
00117 {
00118     int d0, d1, d2, d3;
00119     int a0, a1, a2, a3, b0, b1, b2, b3;
00120     int t0, t1, t2, t3;
00121 
00122     d0 = (block[8*0] << 11) + 65536;
00123     d1 = block[8*1];
00124     d2 = block[8*2] << 11;
00125     d3 = block[8*3];
00126     t0 = d0 + d2;
00127     t1 = d0 - d2;
00128     BUTTERFLY (t2, t3, W6, W2, d3, d1);
00129     a0 = t0 + t2;
00130     a1 = t1 + t3;
00131     a2 = t1 - t3;
00132     a3 = t0 - t2;
00133 
00134     d0 = block[8*4];
00135     d1 = block[8*5];
00136     d2 = block[8*6];
00137     d3 = block[8*7];
00138     BUTTERFLY (t0, t1, W7, W1, d3, d0);
00139     BUTTERFLY (t2, t3, W3, W5, d1, d2);
00140     b0 = t0 + t2;
00141     b3 = t1 + t3;
00142     t0 = (t0 - t2) >> 8;
00143     t1 = (t1 - t3) >> 8;
00144     b1 = (t0 + t1) * 181;
00145     b2 = (t0 - t1) * 181;
00146 
00147     block[8*0] = (a0 + b0) >> 17;
00148     block[8*1] = (a1 + b1) >> 17;
00149     block[8*2] = (a2 + b2) >> 17;
00150     block[8*3] = (a3 + b3) >> 17;
00151     block[8*4] = (a3 - b3) >> 17;
00152     block[8*5] = (a2 - b2) >> 17;
00153     block[8*6] = (a1 - b1) >> 17;
00154     block[8*7] = (a0 - b0) >> 17;
00155 }
00156 
00157 static void mpeg2_idct_copy_c (int16_t * block, uint8_t * dest,
00158                                const int stride)
00159 {
00160     int i;
00161 
00162     for (i = 0; i < 8; i++)
00163         idct_row (block + 8 * i);
00164     for (i = 0; i < 8; i++)
00165         idct_col (block + i);
00166     do {
00167         dest[0] = CLIP (block[0]);
00168         dest[1] = CLIP (block[1]);
00169         dest[2] = CLIP (block[2]);
00170         dest[3] = CLIP (block[3]);
00171         dest[4] = CLIP (block[4]);
00172         dest[5] = CLIP (block[5]);
00173         dest[6] = CLIP (block[6]);
00174         dest[7] = CLIP (block[7]);
00175 
00176         block[0] = 0;   block[1] = 0;   block[2] = 0;   block[3] = 0;
00177         block[4] = 0;   block[5] = 0;   block[6] = 0;   block[7] = 0;
00178 
00179         dest += stride;
00180         block += 8;
00181     } while (--i);
00182 }
00183 
00184 static void mpeg2_idct_add_c (const int last, int16_t * block,
00185                               uint8_t * dest, const int stride)
00186 {
00187     int i;
00188 
00189     if (last != 129 || (block[0] & 7) == 4) {
00190         for (i = 0; i < 8; i++)
00191             idct_row (block + 8 * i);
00192         for (i = 0; i < 8; i++)
00193             idct_col (block + i);
00194         do {
00195             dest[0] = CLIP (block[0] + dest[0]);
00196             dest[1] = CLIP (block[1] + dest[1]);
00197             dest[2] = CLIP (block[2] + dest[2]);
00198             dest[3] = CLIP (block[3] + dest[3]);
00199             dest[4] = CLIP (block[4] + dest[4]);
00200             dest[5] = CLIP (block[5] + dest[5]);
00201             dest[6] = CLIP (block[6] + dest[6]);
00202             dest[7] = CLIP (block[7] + dest[7]);
00203 
00204             block[0] = 0;       block[1] = 0;   block[2] = 0;   block[3] = 0;
00205             block[4] = 0;       block[5] = 0;   block[6] = 0;   block[7] = 0;
00206 
00207             dest += stride;
00208             block += 8;
00209         } while (--i);
00210     } else {
00211         int DC;
00212 
00213         DC = (block[0] + 4) >> 3;
00214         block[0] = block[63] = 0;
00215         i = 8;
00216         do {
00217             dest[0] = CLIP (DC + dest[0]);
00218             dest[1] = CLIP (DC + dest[1]);
00219             dest[2] = CLIP (DC + dest[2]);
00220             dest[3] = CLIP (DC + dest[3]);
00221             dest[4] = CLIP (DC + dest[4]);
00222             dest[5] = CLIP (DC + dest[5]);
00223             dest[6] = CLIP (DC + dest[6]);
00224             dest[7] = CLIP (DC + dest[7]);
00225             dest += stride;
00226         } while (--i);
00227     }
00228 }
00229 
00230 void mpeg2_idct_init (uint32_t accel)
00231 {
00232 #ifdef ARCH_X86
00233     if (accel & MPEG2_ACCEL_X86_MMXEXT) {
00234         mpeg2_idct_copy = mpeg2_idct_copy_mmxext;
00235         mpeg2_idct_add = mpeg2_idct_add_mmxext;
00236         mpeg2_idct_mmx_init ();
00237     } else if (accel & MPEG2_ACCEL_X86_MMX) {
00238         mpeg2_idct_copy = mpeg2_idct_copy_mmx;
00239         mpeg2_idct_add = mpeg2_idct_add_mmx;
00240         mpeg2_idct_mmx_init ();
00241     } else
00242 #endif
00243 #ifdef ARCH_PPC
00244     if (accel & MPEG2_ACCEL_PPC_ALTIVEC) {
00245         mpeg2_idct_copy = mpeg2_idct_copy_altivec;
00246         mpeg2_idct_add = mpeg2_idct_add_altivec;
00247         mpeg2_idct_altivec_init ();
00248     } else
00249 #endif
00250 #ifdef ARCH_ALPHA
00251     if (accel & MPEG2_ACCEL_ALPHA_MVI) {
00252         mpeg2_idct_copy = mpeg2_idct_copy_mvi;
00253         mpeg2_idct_add = mpeg2_idct_add_mvi;
00254         mpeg2_idct_alpha_init (0);
00255     } else if (accel & MPEG2_ACCEL_ALPHA) {
00256         mpeg2_idct_copy = mpeg2_idct_copy_alpha;
00257         mpeg2_idct_add = mpeg2_idct_add_alpha;
00258         mpeg2_idct_alpha_init (1);
00259     } else
00260 #endif
00261 #ifdef LIBMPEG2_MLIB
00262     if (accel & MPEG2_ACCEL_MLIB) {
00263         mpeg2_idct_copy = mpeg2_idct_copy_mlib_non_ieee;
00264         mpeg2_idct_add = (getenv ("MLIB_NON_IEEE") ?
00265                           mpeg2_idct_add_mlib_non_ieee : mpeg2_idct_add_mlib);
00266     } else
00267 #endif
00268     {
00269         extern uint8_t mpeg2_scan_norm[64];
00270         extern uint8_t mpeg2_scan_alt[64];
00271         int i, j;
00272 
00273         mpeg2_idct_copy = mpeg2_idct_copy_c;
00274         mpeg2_idct_add = mpeg2_idct_add_c;
00275         for (i = -384; i < 640; i++)
00276             clip_lut[i+384] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
00277         for (i = 0; i < 64; i++) {
00278             j = mpeg2_scan_norm[i];
00279             mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
00280             j = mpeg2_scan_alt[i];
00281             mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2);
00282         }
00283     }
00284 }
 

Powered by Plone

This site conforms to the following standards: