Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- typedef struct {
- unsigned char red,green,blue;
- } PPMPixel;
- typedef struct {
- int x, y;
- PPMPixel *data;
- } PPMImage;
- typedef struct {
- int Y,Cb,Cr;
- } YCbCrPixel;
- typedef struct {
- int x, y;
- YCbCrPixel *data;
- } YCbCrImage;
- //pravljenje tablica za kvantizaciju
- int K1[8][8] = {
- {16, 11, 10, 16, 24, 40, 51, 61},
- {12, 12, 14, 19, 26, 58, 60, 55},
- {14, 13, 16, 24, 40, 57, 69, 56},
- {14, 17, 22, 29, 51, 87, 80, 62},
- {18, 22, 37, 56, 68, 109, 103, 77},
- {24, 35, 55, 64, 81, 104, 113, 92},
- {49, 64, 78, 87, 103, 121, 120, 101},
- {72, 92, 95, 98, 112, 100, 103, 99}
- };
- int K2[8][8] = {
- {17, 18, 24, 47 ,99, 99, 99, 99},
- {18, 21, 26, 66, 99, 99, 99, 99},
- {24, 26, 56, 99, 99, 99, 99, 99},
- {47, 66, 99, 99, 99, 99, 99, 99},
- {99, 99, 99, 99, 99, 99, 99, 99},
- {99, 99, 99, 99, 99, 99, 99, 99},
- {99, 99, 99, 99, 99, 99, 99, 99},
- {99, 99, 99, 99, 99, 99, 99, 99}
- };
- int T[8][8] = {
- {0 ,1 ,8 ,16, 9, 2, 3, 10},
- {17 ,24 ,32 ,25 ,18 ,11 ,4 ,5},
- {12 ,19 ,26 ,33 ,40 ,48, 41, 34},
- {27 ,20 ,13, 6, 7 ,14 ,21 ,28},
- {35 ,42 ,49 ,56 ,57, 50, 43, 36},
- {29 ,22, 15 ,23 ,30 ,37 ,44 ,51},
- {58 ,59 ,52 ,45, 38, 31, 39, 46},
- {53 ,60 ,61 ,54 ,47, 55 ,62 ,63}
- };
- int brojI;
- int brojJ;
- #define RGB_COMPONENT_COLOR 255
- #define PI 3.142857
- #define MAX_HIGHT 8
- #define MAX_WIDTH 8
- static PPMImage *readFile(char *filename){
- char buff[16];
- PPMImage *img;
- FILE *fp;
- int c, rgb_comp_color;
- //dohvaca file
- fp = fopen(filename, "rb");
- //puni buffer sa podatcima
- fgets(buff, sizeof(buff), fp);
- //1. "magical number" mora bit P6
- if (buff[0] != 'P' || buff[1] != '6') {
- fprintf(stderr, "Ovo nije ispravna PPM datoteka (nema P6)\n");
- exit(1);
- }
- //alociranje memorije za sliku
- img = (PPMImage *)malloc(sizeof(PPMImage));
- //rucitavanje dimenzija slike
- fscanf(fp, "%d %d", &img->x, &img->y);
- //provjera rgb komponente (moglo bi se izbaciti)
- //ucitavanje rgb komponente
- fscanf(fp, "%d", &rgb_comp_color);
- //provjera rgb
- if (rgb_comp_color!= RGB_COMPONENT_COLOR){
- fprintf(stderr, "RGB nije 255\n");
- exit(1);
- }
- //procita se prazan redak (ili vise njih)
- while (fgetc(fp) != '\n') ;
- //alociranje memorije za pixel data
- img->data = (PPMPixel*)malloc(img->x * img->y * sizeof(PPMPixel));
- //ucitava podatke o pikselima iz datoteke
- fread(img->data, 3 * img->x, img->y, fp);
- fclose(fp);
- return img;
- }
- static YCbCrImage *RGBToYCbCr(PPMImage *img){
- YCbCrImage *imgYCbCr;
- imgYCbCr = (YCbCrImage *)malloc(sizeof(YCbCrImage));
- //istih su dimenzija
- imgYCbCr->x=img->x;
- imgYCbCr->y=img->y;
- imgYCbCr->data = (YCbCrPixel*)malloc(imgYCbCr->x * imgYCbCr->y * sizeof(YCbCrPixel));
- int i;
- //ode bi odma mogli sve smanjit za 128 samo treba paziti na pretvaranje tipova u c-u
- for(i=0;i<imgYCbCr->x*imgYCbCr->y;++i){
- //printf("%d \n", i);
- int red =(int)img->data[i].red;
- int green =(int)img->data[i].green;
- int blue =(int)img->data[i].blue;
- imgYCbCr->data[i].Y= (0.299*red) + (0.587*green) + (0.114*blue)-128;
- imgYCbCr->data[i].Cb=(-0.1687*red) - (0.3313*green) + (0.5*blue);
- imgYCbCr->data[i].Cr=(0.5*red) - (0.4187*green) - (0.0813*blue);
- }
- return imgYCbCr;
- }
- void writeFile(const char *filename, YCbCrImage *img, int sizeX, int sizeY){
- FILE *fp;
- fp = fopen(filename, "wb");
- fprintf(fp, "%d %d\n",sizeX, sizeY);
- int i;
- int j;
- for(i=0;i<img->x;++i){
- for(j=0;j<img->y;++j){
- fprintf(fp, "%d ",img->data[i*MAX_WIDTH+j].Y);
- }
- fprintf(fp,"\n");
- }
- fprintf(fp,"\n");
- for(i=0;i<img->x;++i){
- for(j=0;j<img->y;++j){
- fprintf(fp, "%d ",img->data[i*MAX_WIDTH+j].Cb);
- }
- fprintf(fp,"\n");
- }
- fprintf(fp,"\n");
- for(i=0;i<img->x;++i){
- for(j=0;j<img->y;++j){
- fprintf(fp, "%d ",img->data[i*MAX_WIDTH+j].Cr);
- }
- fprintf(fp,"\n");
- }
- fprintf(fp,"\n");
- fclose(fp);
- }
- static YCbCrImage *zmijica(YCbCrImage *image3){
- YCbCrImage *imgYCbCr;
- imgYCbCr = (YCbCrImage *)malloc(sizeof(YCbCrImage));
- //istih su dimenzija
- imgYCbCr->x=image3->x;
- imgYCbCr->y=image3->y;
- imgYCbCr->data = (YCbCrPixel*)malloc(imgYCbCr->x * imgYCbCr->y * sizeof(YCbCrPixel));
- //writeFile("prijeZmije.txt", image3, hight, width);
- int brojacI;
- int brojacJ;
- int index;
- for(brojacI=0;brojacI<MAX_HIGHT;++brojacI){
- for(brojacJ=0;brojacJ<MAX_WIDTH;++brojacJ){
- index=T[brojacI][brojacJ];
- imgYCbCr->data[index]=image3->data[brojacI*MAX_WIDTH+brojacJ];
- }
- }
- return imgYCbCr;
- }
- static YCbCrPixel kvantizacija(float dctY,float dctCb,float dctCr, int m, int n){
- int dctYKvantizirano=0;
- int dctCbKvantizirano=0;
- int dctCrKvantizirano=0;
- dctYKvantizirano=round(dctY/(K1[m][n]*1.0));
- dctCbKvantizirano=round(dctCb/(K2[m][n]*1.0));
- dctCrKvantizirano=round(dctCr/(K2[m][n]*1.0));
- YCbCrPixel pomPixel = { .Y = dctYKvantizirano, .Cb = dctCbKvantizirano, .Cr = dctCrKvantizirano };
- return pomPixel;
- }
- int main(int argc, char *argv[]){
- //int a, b, c;
- if (argc < 4 || argc > 5){
- printf("Potrebno je unjeti 3 argumenta");
- return 0;
- }
- char *inputFileName = argv[1];
- int brojBloka = atoi(argv[2]);
- char *outputFileName = argv[3];
- //printf("Broj bloka : %d\n", brojBloka);
- brojJ=brojBloka%MAX_WIDTH;
- brojI=(brojBloka-brojJ)/MAX_WIDTH;
- //printf("i : %d\n", brojI);
- //printf("j : %d\n", brojJ);
- PPMImage *image;
- image = readFile(inputFileName);
- int hight = image->y;
- int width = image->x;
- YCbCrImage *image2;
- image2 = RGBToYCbCr(image);
- //dealociranje
- free(image->data);
- free(image);
- int i;
- int j;
- for(i=0;i<hight/MAX_HIGHT;++i){
- for(j=0;j<width/MAX_WIDTH;++j){
- //odma nakon transformacije se vrsi kvantizacija
- //alociranje nove male slike koja je veclini 8X8 - tj blok je (tu se pohranjuju podatci nakon kosinusne transformacije)
- YCbCrImage *image3;
- image3 = (YCbCrImage *)malloc(sizeof(YCbCrImage));
- image3->x=MAX_WIDTH;
- image3->y=MAX_HIGHT;
- image3->data = (YCbCrPixel*)malloc(image3->x * image3->y * sizeof(YCbCrPixel));
- //alociranje nove male slike koja je veclini 8X8 - tj blok je u koju cemo zapisat podatke nakon zmijice
- YCbCrImage *image4;
- image4 = (YCbCrImage *)malloc(sizeof(YCbCrImage));
- image4->x=MAX_WIDTH;
- image4->y=MAX_HIGHT;
- image4->data = (YCbCrPixel*)malloc(image4->x * image4->y * sizeof(YCbCrPixel));
- float cv;
- float cu;
- int m;
- int n;
- for(m=0;m<MAX_HIGHT;++m){
- for(n=0;n<MAX_WIDTH;++n){
- //kosinusna transformacija
- cv = 1.0;
- cu = 1.0;
- if(m==0){
- cv=0.7071068; //korijen iz 2 korz 2
- }
- if(n==0){
- cu=0.7071068; //korijen iz 2 korz 2
- }
- float sumY = 0;
- float dct1Y = 0;
- float sumCb = 0;
- float dct1Cb = 0;
- float sumCr = 0;
- float dct1Cr= 0;
- float tempConst;
- YCbCrPixel pomPixel;
- int k;
- int l;
- for (k = 0; k < MAX_HIGHT; ++k) {
- for (l = 0; l < MAX_WIDTH; ++l) {
- pomPixel = image2->data[i*MAX_WIDTH*width+j*MAX_WIDTH+k*width+l];
- tempConst = cos((2 * k + 1) * m * PI / 16) * cos((2 * l + 1) * n * PI / 16);
- //if(m==1&&n==1&&k==0&&l==0){
- // printf("TEMP KONST: %f \n", tempConst);
- // printf("pomPixel.Y: %d \n", pomPixel.Y);
- //}
- dct1Y = pomPixel.Y * tempConst;
- sumY = sumY + dct1Y;
- dct1Cb = pomPixel.Cb * tempConst;
- sumCb = sumCb + dct1Cb;
- dct1Cr = pomPixel.Cr * tempConst;
- sumCr = sumCr + dct1Cr;
- }
- }
- float dctY=0;
- float dctCb=0;
- float dctCr=0;
- dctY = 0.25*cv*cu*sumY;
- dctCb = 0.25*cv*cu*sumCb;
- dctCr = 0.25*cv*cu*sumCr;
- YCbCrPixel pomPixe2;
- pomPixe2 = kvantizacija(dctY, dctCb, dctCr, m, n);
- image3->data[m*MAX_WIDTH+n]=pomPixe2;
- }
- }
- image4 = zmijica(image3);
- //kraj zmijice
- //nakon zmicijie mozemo zapisat podatke u datoteku, ako se radi o tom bloku
- if(i==brojI && j==brojJ){
- writeFile(outputFileName, image4, hight, width);
- }
- //zatvaranje dvaju for ptelji od i i j
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement