src/dctexample.c
author viric@mandarina
Mon, 15 Dec 2008 01:06:43 +0000
changeset 253 e3aa70211aee
parent 227 f2a4f54d3fc8
permissions -rw-r--r--
Afegint coses a la presentació

#include <stdio.h>
#include <math.h>
#include "libjpegrest.h"

#define PI 3.141592657

/* This opens a 8x8 PGM file from argv[1], and stores
 * a 64+7x64+7 PGM file with each DCT-IDCT result, considering
 * only the coefficients from top-left until the concerning
 * DCT-IDCT result. */

static void mydct(float *in, float *out)
{
    int x,y,u,v;

    float Cu, Cv;

    for (u=0; u < 8; ++u)
        for (v=0; v < 8; ++v)
        {
            float *optr;
            float sum;
            optr = out+v*8+u;

            sum = 0.;
            for (x=0; x < 8; ++x)
                for (y=0; y < 8; ++y) {
                    float *iptr;
                    iptr = in+y*8+x;

                    sum += *iptr
                        * cos(((float) ((2*x+1)*u) )*PI/16.)
                        * cos(((float) ((2*y+1)*v) )*PI/16.);
                }

            if (u == 0) Cu = 1. / sqrt(2); else Cu = 1.;
            if (v == 0) Cv = 1. / sqrt(2); else Cv = 1.;
            *optr = 0.25 * Cu * Cv * sum;
        }
}

static void myidct(float *in, float *out)
{
    int x,y,u,v;

    float Cu, Cv;

    for (x=0; x < 8; ++x)
        for (y=0; y < 8; ++y)
        {
            float *optr;
            float sum;
            optr = out+y*8+x;

            sum = 0.;
            for (v=0; v < 8; ++v)
                for (u=0; u < 8; ++u)
                {
                    float *iptr;
                    iptr = in+v*8+u;

                    if (u == 0) Cu = 1. / sqrt(2); else Cu = 1.;
                    if (v == 0) Cv = 1. / sqrt(2); else Cv = 1.;

                    sum += Cu * Cv * *iptr
                        * cos(((float) ((2*x+1)*u) )*PI/16.)
                        * cos(((float) ((2*y+1)*v) )*PI/16.);
                }

            *optr = 0.25 * sum;
        }
}

void zero_block(float *block)
{
    int i;
    for (i=0; i < 64; ++i)
        block[i] = 0.;
}

void prepare_subblock(float *block, int x, int y, const float *input)
{
    /* Fill the subsquare from 0..x and 0..y */
    int i,j;

    zero_block(block);

    for (j=0; j <= y; ++j)
        for (i=0; i <= x; ++i)
        {
            block[j*8+i] = input[j*8+i];
        }
}

void write_block_to_big(struct bitmap *bdest, const float *sub, int x, int y)
{
    int i,j;

    for (j=0; j < 8; ++j)
        for (i=0; i < 8; ++i)
        {
            gsl_matrix *dest = bdest->m[0];
            dest->data[(j+y*9)*dest->tda+x*9+i] = sub[j*8+i];
        }

    if (x < 7)
        for (j=0; j < 8; ++j)
        {
            gsl_matrix *dest = bdest->m[0];
            dest->data[(j+y*9)*dest->tda+x*9+8] = 255;
        }
    if (y < 7)
        for (i=0; i < 8; ++i)
        {
            gsl_matrix *dest = bdest->m[0];
            dest->data[(8+y*9)*dest->tda+x*9+i] = 255;
        }

    if (y < 7 && x < 7)
    {
        gsl_matrix *dest = bdest->m[0];
        dest->data[(8+y*9)*dest->tda+x*9+8] = 255;
    }
}

int main(int argn, char **argv)
{
    struct bitmap bmap;
    float input[64];
    float input_test[64];
    float input_dct[64];
    float output_dct[64];
    float output[64];
    float quantize[64] = {
        20, 14, 13, 20, 30, 50, 64, 76, 
        15, 15, 18, 24, 33, 73, 75, 69, 
        18, 16, 20, 30, 50, 71, 86, 70, 
        18, 21, 28, 36, 64, 109, 100, 78, 
        23, 28, 46, 70, 85, 136, 129, 96, 
        30, 44, 69, 80, 101, 130, 141, 115, 
        61, 80, 98, 109, 129, 151, 150, 126, 
        90, 115, 119, 123, 140, 125, 129, 124 };


    struct bitmap obmap;
    int i,j,k;

    bitmap_pam_init(&argn, argv);

    bitmap_filename_pam_get(argv[1], &bmap);

    if (bmap.nplanes != 1 || bmap.width != 8 || bmap.height != 8)
    {
        fprintf(stderr, "Error: The file should be 8x8 PGM\n");
        return -1;
    }

    k=0;
    for(j=0;j < 8; ++j)
        for(i=0;i < 8; ++i)
        {
            gsl_matrix *mat = bmap.m[0];
            input[k++] = mat->data[j*mat->tda + i];
        }

    mydct(input, input_dct);

    {
        FILE *odct, *ifile, *qtable, *qfile;
        odct = fopen("dct.txt", "wt");
        ifile = fopen("ifile.txt", "wt");
        qtable = fopen("qtable.txt", "wt");
        qfile = fopen("qfile.txt", "wt");
        for(j=0;j < 8; ++j)
        {
            fprintf(odct, "<tr>\n");
            fprintf(ifile, "<tr>\n");
            fprintf(qtable, "<tr>\n");
            fprintf(qfile, "<tr>\n");
            for(i=0;i < 8; ++i)
            {
                fprintf(odct, "<td>%.2f\n", input_dct[j*8+i]);
                fprintf(ifile, "<td>%.0f\n", input[j*8+i]);
                fprintf(qtable, "<td>%.0f\n", quantize[j*8+i]);
                fprintf(qfile, "<td>%i\n", lrint(input_dct[j*8+i]/quantize[j*8+i]));
            }
        }
        fclose(odct);
        fclose(ifile);
        fclose(qtable);
        fclose(qfile);
    }

    myidct(input_dct, input_test);

    obmap = bitmap_alloc(1, 64+7, 64+7);

    for(j=0;j < 8; ++j)
        for(i=0;i < 8; ++i)
        {
            prepare_subblock(output_dct,i,j,input_dct);
            myidct(output_dct, output);
            write_block_to_big(&obmap, output, i, j);
        }

    bitmap_filename_pam_put(argv[2], &obmap);

    bitmap_free(obmap);
    return 0;
}