Binary Hell's main site

 Главная страница 
 Новости 
 Статьи 
 Продукты 
 Документация 
 Наши проекты 
 О группе 
 
 Пишите нам 
 Опыт ФИДО конференций 
 Доки по ASM-у 
 Учебники 
 Форматы файлов 
 

- DEMO.DESIGN (2:5030/1334.67) ---------------------------------- DEMO.DESIGN -
 Сооб : 5 из 7
 От   : Yura Schapov                        2:5012/28.18    07 Апр 01  22:06:05
 Кому : Stanislav Tihohod                                   09 Апр 01  00:21:33
 Тема : JPEG
-------------------------------------------------------------------------------
Как поживаете, Stanislav ?

 Мои бортовые системы запеленговали, что в Суббота Апрель 07 2001 01:10,
Stanislav Tihohod писал Yura Schapov:

 ST> Кстати, а зачем тебе нужны термы 16х16?

Да вот, сегодня проверил, оказывается не нужны... ;)
Еще пробовал сделать DCT на матрице float-ов 256x256 - эхх... жалко,
не продают пока еще суперкомпьютеры... ;)

Могу исходником поделиться... все-таки почти два дня отлаживал. =)

---cut---

Дискретное косинусное преобразование в JPEG
Специально для DEMO.DESIGN

(c)Д.Мастрюков, журнал "Монитор" 6.94
(c)Ю.Щапов, 2:5012/28.18 =)

Принцип: (работаем с блоком 8x8 - матрица Точки)
encoding: DCT = C * Точки * Ct
decoding: Точки = C * DCT * Ct

Где: C(i,j) = 1/sqrt(N), i=0
     C(i,j) = sqrt(2/N) * cos(((2*j+1)*i*PI)/(2*N)), i<>0
     Ct - транспонированная С.

Для округления коэффициентов (а мы должны все поместить в unsigned char),
используем матрицу округления, считается она таким вот образом:

for (i=0;i<N;i++) for (j=0;j<N;j++) Quantum[i][j]=16+(1+i+j)*quality;

Как ее использовать: просто после кодирования делим на
нее поэлементно, а потом, чтобы восстановить информацию,
поэлементно на нее умножаем. Так как числа в ней возрастают
по диагонали, получается что больше всего информации остается
по низкочастотным компонентам DCT, а высокочастотные обращаются
в ноль. (Там еще некоторые тонкости, например обход по зигзагу
чтобы получились длинные цепочки нулей, но это не суть важно).

Пример DCT-iDCT преобразования 32-х битных текстур 256x256.

//tc.h

#define PI 3.14159265358979323846

#define ROUND(a)    (((a)<0)?(int)((a)-0.5):(int)((a)+0.5))
#define NORMALIZE(n) ((n<0) ? 0 : ((n>255) ? 255 : n));

#define ROWS    256
#define COLS    256
#define N 8

//globals

float C[N][N];
float Ct[N][N];
int Quantum[N][N];
int InputRunLength;
int OutputRunLength;

float input_array[N][N];
float output_array[N][N];


struct zigzag
{
    int row;
    int col;
};

zigzag ZigZag[N*N];

int ZigZag8[8*8]=
{
     0,  1,  5,  6, 14, 15, 27, 28,
     2,  4,  7, 13, 16, 26, 29, 42,
     3,  8, 12, 17, 25, 30, 41, 43,
     9, 11, 18, 24, 31, 40, 44, 53,
    10, 19, 23, 32, 39, 45, 52, 54,
    20, 22, 33, 38, 46, 51, 55, 60,
    21, 34, 37, 47, 50, 56, 59, 61,
    35, 36, 48, 49, 57, 58, 62, 63
};


void Initalise(int quality)
{
    int i,j;

//subsampling matrix
    for (i=0;i<N;i++)
        for (j=0;j<N;j++)
            Quantum[i][j] = 16 + ( 1 + i + j ) * quality;

// define DCT and transposed DCT matrix:
// C(i,j) = 1/sqrt(N), i=0
// C(i,j) = sqrt(2/N) * cos(((2*j+1)*i*PI)/(2*N)), i<>0

    for(j=0;j<N;j++)
    {
        C[0][j]= 1.0 / sqrt((float) N);
        Ct[j][0]=C[0][j];
    }

    for (i=1;i<N;i++)
        for (j=0;j<N;j++)
            {
                C[i][j]= sqrt(2.0/N) * cos( ((2*j+1)*i*PI)/(2.0*N) );
                Ct[j][i]=C[i][j];
            }

    int x,y,dx,dy;
    x,y,dy=0; dx=1;

    for (i=0;i<N*N;i++)
    {
        ZigZag[i].row = ZigZag8[i]%N;
        ZigZag[i].col = ZigZag8[i]/N;
    }

}

void MatrixMul(float input[N][N], float output[N][N],
        float C[N][N],float Ct[N][N])
{
    float temp[N][N];
    float temp1;
    int i,j,k;

    //output = C * input * Ct;

    for (i=0;i<N;i++)
        for (j=0;j<N;j++)
        {
            temp[i][j]=0.0;
            for(k=0;k<N;k++)
                temp[i][j]+=input[i][k] * Ct[k][j];
        }

    for (i=0;i<N;i++)
        for (j=0;j<N;j++)
        {
            temp1=0.0;
            for (k=0;k<N;k++)
                temp1+=C[i][k]*temp[k][j];
                    output[i][j]=temp1;
        }
}


void DCT(float input[N][N],float output[N][N])
{
    int i,row,col;
    MatrixMul(input,output,C,Ct);

    for (i=0;i<(N*N);i++)
    {
        row=ZigZag[i].row;
        col=ZigZag[i].col;
        output[row][col] = ROUND( output[row][col] / Quantum[row][col] );
        //he-he, Beavis, hi says ROUND ;-)
    }

}
void iDCT(float input[N][N],float output[N][N])
{
    int i,j,row,col;
    float result;
    for (i=0;i<(N*N);i++)
    {
        row=ZigZag[i].row;
        col=ZigZag[i].col;
        input[row][col] = (signed char)input[row][col] * Quantum[row][col];
    }

    MatrixMul(input,output,Ct,C);

    for (i=0;i<N;i++)
        for (j=0;j<N;j++)
            output[i][j]=NORMALIZE(output[i][j]);

}


void Read_BOX(int x, int y, byte *input, float array[N][N], int layer)
{
    int i,j;
    for (i=0;i<N;i++)
        for (j=0;j<N;j++)
            array[i][j] = input[ ( (x+i) + (y+j)*256 )*4+layer ];
}

void Write_BOX(int x, int y, byte *output, float array[N][N], int layer)
{
    int i,j;
    for (i=0;i<N;i++)
        for (j=0;j<N;j++)
            output[ ( (x+i) + (y+j)*256 )*4+layer ] =  array[i][j];
}

void CompressTexture(int *input_texture, int *output_texture, int quality)
{
    int i,j,k,layer;

    byte *input=(byte*)input_texture;
    byte *output=(byte*)output_texture;

    Initalise(quality);

    for (layer=0;layer<3;layer++)
    for (i=0;i<256;i+=N)
        for (j=0;j<256;j+=N)
        {
            Read_BOX(i, j, input, input_array, layer);
            DCT(input_array, output_array);
            Write_BOX(i, j, output, output_array, layer);
        }
}

void DeCompressTexture(int *input_texture, int *output_texture, int quality)
{
    int i,j,k,layer;

    byte *input=(byte*)input_texture;
    byte *output=(byte*)output_texture;
    Initalise(quality);

    for (layer=0;layer<3;layer++)
    for (i=0;i<256;i+=N)
        for (j=0;j<256;j+=N)
        {
            Read_BOX(i, j, input, input_array, layer);
            iDCT(input_array, output_array);
            Write_BOX(i, j, output, output_array,layer);
        }

}

---cut---

                C уважением, Yura Schapov.
--- [Team FM-4307]
 * Origin: :nigirO * (2:5012/28.18)

  

Rambler's Top100 Rambler's Top100 NET's Top100