2010-02-26 6 views
-2

나는 내 프로젝트에 약간의 어려움이있다. 256x256 bmp 이미지에서 RGB 값을 얻었습니다. 그러나, 나는 그 RGB 값을 압축하는 허프만 코딩을 사용하여 계속하는 방법을 모르겠다. 아무도 도와 줄 수 있습니까? 당신의 도움을 주셔서 감사합니다.허프만 코딩을 사용한 이미지 압축

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

/*-------PROTOTYPES-------*/ 
long getImageInfo(FILE*, long, int); 
void copyImageInfo(FILE* inputFile, FILE* outputFile); 
void copyColorTable(FILE* inputFile, FILE* outputFile, int nColors); 
//void bmpsave (FILE*, unsigned char , int , int); 

/*------STRUCTURES--------*/ 
typedef struct {int rows; int cols; unsigned char* data;} sImage; 

int main(int argc, char* argv[]) 
{ 



    FILE *bmpInput, *rasterOutput, *bmpOutput,*RedText,*GreenText,*BlueText,*ErrorRedText,*ErrorBlueText,*ErrorGreenText; 
    FILE     *entroGreen,*entroBlue,*entroRed; 
    sImage originalImage; 
    unsigned char someChar; 
    unsigned char *pChar; 
    long fileSize; 
    int vectorSize, nColors; 
    int     totalGCount=0, totalBCount=0,totalRCount=0; 
    int r, c, i,j,k=0; 
    int redValue, greenValue, blueValue; 
    int     dummyRed=0 ,dummyGreen=0, dummyBlue=0; 
    int     count[256] = {0},countRed[256]= {0},countBlue[256]= {0},countGreen[256]= {0}; 
    double    EntropyGreen, EntropyBlue, EntropyRed; 
    //int     error[414720]; 
    //int     Red[400][720]; 
    //int     Green[400][720]; 
    //int     Blue[400][720]; 


    unsigned int uint1; 
    short   word1; 
    unsigned char byte1, byte2; 
    FILE   *imdata; 

    int **errorGreen; 
    int **errorRed; 
    int **errorBlue; 
    int **Red; 
    int **Blue; 
    int **Green; 
    int **b; 


    b = malloc (256 * sizeof (int)); 
    for (i = 0; i < 256; ++i) 
    b[i] = malloc (256 * sizeof (int)); 

    errorGreen = malloc (256 * sizeof (int)); 
    for (i = 0; i < 256; ++i) 
    errorGreen[i] = malloc (256 * sizeof (int)); 

    errorRed = malloc (256 * sizeof (int)); 
    for (i = 0; i < 256; ++i) 
    errorRed[i] = malloc (256 * sizeof (int)); 

    errorBlue = malloc (256 * sizeof (int)); 
    for (i = 0; i < 256; ++i) 
    errorBlue[i] = malloc (256 * sizeof (int)); 
    //error = (int *) malloc (414720 * sizeof (int)); //Dynamic Memmory Allocation of 1D Array 
    Red = malloc (256 * sizeof (int)); 
    for (i = 0; i < 256; ++i) 
    Red[i] = malloc (256 * sizeof (int)); 

    Green = malloc (256 * sizeof (int)); 
    for (i = 0; i < 256; ++i) 
    Green[i] = malloc (256 * sizeof (int)); 

    Blue = malloc (256 * sizeof (int)); 
    for (i = 0; i < 256; ++i) 
    Blue[i] = malloc (256 * sizeof (int)); 






    /*--------INITIALIZE POINTER----------*/ 
    someChar = '0'; 
    pChar = &someChar; 

    if(argc < 2) 
    { 
    printf("Usage: %s bmpInput.bmp\n", argv[0]); 
    exit(0); 
    } 

    printf("Reading file %s\n", "Kirschen_256.bmp"); 

    /*----DECLARE INPUT AND OUTPUT FILES----*/ 
    bmpInput = fopen("Kirschen_256.bmp", "rb"); 
    /*RedText = fopen("Red.txt", "w"); 
    BlueText = fopen("Blue.txt", "w"); 
    GreenText = fopen("Green.txt", "w");*/ 
    entroGreen = fopen("entroGreen.txt", "w"); 
    entroRed = fopen("entroRed.txt", "w"); 
    entroBlue = fopen("entroBlue.txt", "w"); 
    ErrorRedText = fopen("ErrorRed.txt", "w"); 
    ErrorBlueText = fopen("ErrorBlue.txt", "w"); 
    ErrorGreenText = fopen("ErrorGreen.txt", "w"); 
    rasterOutput = fopen("Kirschen_256.txt", "w"); 
    bmpOutput = fopen("Kirschen_256().bmp", "wb"); 

    fseek(bmpInput , 0L , SEEK_END); 
    //fseek is a C function belonging to the ANSI C standard library, 
    //and included in the file stdio.h. Its purpose is to change the file position indicator for the specified stream. 
    /*-----GET BMP DATA-----*/ 
    originalImage.cols = (int)getImageInfo(bmpInput, 18, 4); 
    originalImage.rows = (int)getImageInfo(bmpInput, 22, 4); 
    fileSize = getImageInfo(bmpInput, 2, 4); 
    nColors = getImageInfo(bmpInput, 46, 4); 
    //vectorSize = fileSize - (14 + 40 + 4*nColors); 

    /*----PRINT DATA TO SCREEN-----*/ 
    printf("Width: %d\n", originalImage.cols); 
    printf("Height: %d\n", originalImage.rows); 
    printf("File size: %ld\n", fileSize); 
    printf("Bits/pixel: %d\n", getImageInfo(bmpInput, 28, 4)); 
    printf("No. colors: %d\n", nColors); 
    //printf("Vector size: %d\n", vectorSize); 

    copyImageInfo(bmpInput, bmpOutput); 
    //copyColorTable(bmpInput, bmpOutput, nColors); 


    /*----FOR 24-BIT BMP, THERE IS NO COLOR TABLE-----*/ 
    fseek(bmpInput , 54 , SEEK_SET); 
    fseek(bmpOutput , 54 , SEEK_SET); 
    /*-----------READ RASTER DATA-----------*/ 

    for(r=0; r<=originalImage.rows-1; r++) 
    { 
    for(c=0; c<=originalImage.cols-1; c++) 
    { 
     /*----READ FIRST BYTE TO GET BLUE VALUE-----*/ 
    fread(pChar, sizeof(char), 1, bmpInput); 
     blueValue = *pChar; 
     Blue[r][c]=*pChar; 
     if (r==0||c==0){ 
      errorBlue[r][c]=abs(dummyBlue-blueValue); 
      countBlue[abs(dummyBlue-blueValue)]++; 
      count[abs(dummyBlue-blueValue)]++; 
      totalBCount++; 
     } 
     else{ 
      errorBlue[r][c]=abs(((dummyBlue+Blue[r-1][c]+Blue[r-1][c-1])/3)-blueValue); 
      countBlue[abs(((dummyBlue+Blue[r-1][c]+Blue[r-1][c-1])/3)-blueValue)]++; 
      count[abs(((dummyBlue+Blue[r-1][c]+Blue[r-1][c-1])/3)-blueValue)]++; 
      totalBCount++; 
    } 
     //error[k]=abs(dummyBlue-blueValue); 
     //k++; 
     *pChar=dummyBlue; 
     fwrite(pChar, sizeof(char), 1, bmpOutput); 
     dummyBlue=blueValue; 


     /*-----READ NEXT BYTE TO GET GREEN VALUE-----*/ 
    fread(pChar, sizeof(char), 1, bmpInput); 
     greenValue = *pChar; 
     Green[r][c]=*pChar; 
     if (r==0||c==0){ 
      errorGreen[r][c]=abs(dummyGreen-greenValue); 
      countGreen[abs(dummyGreen-greenValue)]++; 
      count[abs(dummyGreen-greenValue)]++; 
      totalGCount++; 
     } 
     else{ 
      errorGreen[r][c]=abs(((dummyGreen+Green[r-1][c]+Green[r-1][c-1])/3)-greenValue); 
      countGreen[abs(((dummyGreen+Green[r-1][c]+Green[r-1][c-1])/3)-greenValue)]++; 
      count[abs(((dummyGreen+Green[r-1][c]+Green[r-1][c-1])/3)-greenValue)]++; 
      totalGCount++; 
    } 
     *pChar=dummyGreen; 
     fwrite(pChar, sizeof(char), 1, bmpOutput); 
     dummyGreen=greenValue; 


     /*-----READ NEXT BYTE TO GET RED VALUE-----*/ 
     fread(pChar, sizeof(char), 1, bmpInput); 
     redValue = *pChar; 
     Red[r][c]=*pChar; 
     if (r==0||c==0){ 
      errorRed[r][c]=abs(dummyRed-redValue); 
      countRed[abs(dummyRed-redValue)]++; 
      count[abs(dummyRed-redValue)]++; 
      totalRCount++; 
     } 
     else{ 
      errorRed[r][c]=abs(((dummyRed+Red[r-1][c]+Red[r-1][c-1])/3)-redValue); 
      countRed[abs(((dummyRed+Red[r-1][c]+Red[r-1][c-1])/3)-redValue)]++; 
      count[abs(((dummyRed+Red[r-1][c]+Red[r-1][c-1])/3)-redValue)]++; 
      totalRCount++; 
    } 
     *pChar=dummyRed; 
     fwrite(pChar, sizeof(char), 1, bmpOutput); 
     dummyRed=redValue; 


     /*---------PRINT TO TEXT FILE---------*/ 
     fprintf(rasterOutput, "(%d %d) = \tRed \t%d", r, c, redValue); 
     fprintf(rasterOutput, "\tGreen \t%d \tBlue \t%d\n", greenValue, blueValue); 

     /*-----read data, reflect and write to output file----*/ 

     //fseek(bmpOutput, 54 , SEEK_SET); 
     //fwrite(pChar, sizeof(char), 1, bmpOutput); 
    } 
    } 
    for (j=0; j<256; j++) { 
      for (i=255; i>=0; i--) { 
        if(i>=256-(count[j]/16)) 
        b[i][j] = 0x00; 
        else 
        b[i][j] = 0xFF; 
      } 
    } 


    imdata = fopen("Kirschen_256after4", "wb"); 
/* if (imdata == NULL) { 
    printf("%s open error.\n", imname); exit(0); 
    } 
*/ 
    byte1 = 'B'; byte2 = 'M'; 
    fwrite(&byte1, 1, 1, imdata); fwrite(&byte2, 1, 1, imdata); 
    uint1 = 54 + 4*256 + originalImage.cols*originalImage.rows; fwrite(&uint1, 4, 1, imdata); 
    word1 = 0; fwrite(&word1, 2, 1, imdata); fwrite(&word1, 2, 1, imdata); 
    uint1 = 54 + 4*256; fwrite(&uint1, 4, 1, imdata); 
    uint1 = 40; fwrite(&uint1, 4, 1, imdata); 
    fwrite(&originalImage.cols, 4, 1, imdata); fwrite(&originalImage.rows, 4, 1, imdata); 
    word1 = 1; fwrite(&word1, 2, 1, imdata); 
    word1 = 8; fwrite(&word1, 2, 1, imdata); 
    uint1 = 0; fwrite(&uint1, 4, 1, imdata); 
    uint1 = originalImage.cols*originalImage.rows; fwrite(&uint1, 4, 1, imdata); 
    j = 11811; fwrite(&j, 4, 1, imdata); fwrite(&j, 4, 1, imdata); 
    uint1 = 256; fwrite(&uint1, 4, 1, imdata); 
    uint1 = 0;  fwrite(&uint1, 4, 1, imdata); 

    for (i=0; i<256; i++) { 
    byte1 = i; 
    fwrite(&byte1, 1, 1, imdata); fwrite(&byte1, 1, 1, imdata); 
    fwrite(&byte1, 1, 1, imdata); fwrite(&byte1, 1, 1, imdata); 
    } 

    for (i=originalImage.rows-1; i>=0; i--) { 
    for (j=0; j<originalImage.cols; j++) { 
     fwrite(&b[i][j], 1, 1, imdata); 
    } 
    } 

    fclose(imdata); 

    for (i=0; i<256; i++) { 
     if (countGreen[i]==0) 
      EntropyGreen += 0; 
     else 
      EntropyGreen += ((double)countGreen[i]/(double)totalGCount) * (log2 ((double)1/((double)countGreen[i]/(double)totalGCount))); 

     if (countRed[i]==0) 
      EntropyRed += 0; 
     else 
      EntropyRed += ((double)countRed[i]/(double)totalRCount) * (log2 ((double)1/((double)countRed[i]/(double)totalRCount))); 

     if (countBlue[i]==0) 
      EntropyBlue +=0; 
     else 
      EntropyBlue += ((double)countBlue[i]/(double)totalBCount) * (log2 ((double)1/((double)countBlue[i]/(double)totalBCount))); 


    } 


     fprintf(entroGreen, "Entropy= %f", EntropyGreen); 
     fprintf(entroRed, "Entropy= %f", EntropyRed); 
     fprintf(entroBlue, "Entropy= %f", EntropyBlue); 

    for (i = 0; i < 256; i++) { 
    for (j = 0; j < 256; j++) { 
     fprintf(ErrorRedText, "[%d][%d] = %2d\n", i, j, errorRed[i][j]); 
     fprintf(ErrorGreenText, "[%d][%d] = %2d\n", i, j, errorGreen[i][j]); 
     fprintf(ErrorBlueText, "[%d][%d] = %2d\n", i, j, errorBlue[i][j]); 

    fprintf (ErrorRedText,"\n"); 
    fprintf (ErrorBlueText,"\n"); 
    fprintf (ErrorGreenText,"\n"); 
    } 
    } 
    /*for (i = 0; i < 768; i++) { 
    for (j = 0; j < 1024; j++) { 
     fprintf(RedText, "a[%d][%d] = %2d\n", i, j, Red[i][j]); 
     fprintf(GreenText, "a[%d][%d] = %2d\n", i, j, Green[i][j]); 
     fprintf(BlueText, "a[%d][%d] = %2d\n", i, j, Blue[i][j]); 
    } 
    fprintf (RedText,"\n"); 
    fprintf (BlueText,"\n"); 
    fprintf (GreenText,"\n"); 
    }*/ 
    /*for (i = 0; i < 414720; i++){ 
     fprintf(ErrorText, "error[%d] = %d\n",i,error[i]); 
     fprintf (ErrorText,"\n"); 
    }*/ 
// PrintHistogram(freq_array, NUM_RANGE); 


    fclose(bmpInput); 
    /*fclose(RedText); 
    fclose(GreenText); 
    fclose(BlueText);*/ 
    fclose(ErrorRedText); 
    fclose(ErrorGreenText); 
    fclose(ErrorBlueText); 
    fclose(rasterOutput); 
    fclose(bmpOutput); 
    fclose(entroGreen); 
    fclose(entroRed); 
    fclose(entroBlue); 


    return 0; 



} 

/*----GET IMAGE INFO SUBPROGRAM------*/ 

long getImageInfo(FILE* inputFile, long offset, int numberOfChars) 
{ 
    unsigned char *ptrC; 
    long value=0L; 
    int i; 
    unsigned char dummy; 


    dummy = '0'; 
    ptrC = &dummy; 

    fseek(inputFile, offset, SEEK_SET); 

    for(i=1; i<=numberOfChars; i++) 
    { 
    fread(ptrC, sizeof(char), 1, inputFile); 
    /* calculate value based on adding bytes */ 
    value = (long)(value + (*ptrC)*(pow(256, (i-1)))); 
    } 

    return(value); 
} 

/*-------------COPIES HEADER AND INFO HEADER----------------*/ 
void copyImageInfo(FILE* inputFile, FILE* outputFile) 
{ 
    unsigned char *ptrC; 
    unsigned char dummy; 
    int i; 

    dummy = '0'; 
    ptrC = &dummy; 

    fseek(inputFile, 0L, SEEK_SET); 
    fseek(outputFile, 0L, SEEK_SET); 

    for(i=0; i<=50; i++) 
    { 
    fread(ptrC, sizeof(char), 1, inputFile); 
    fwrite(ptrC, sizeof(char), 1, outputFile); 
    } 

} 

/*----------------COPIES COLOR TABLE-----------------------------*/ 
void copyColorTable(FILE* inputFile, FILE* outputFile, int nColors) 
{ 
    unsigned char *ptrC; 
    unsigned char dummy; 
    int i; 

    dummy = '0'; 
    ptrC = &dummy; 

    fseek(inputFile, 54L, SEEK_SET); 
    fseek(outputFile, 54L, SEEK_SET); 

    for(i=0; i<=(4*nColors); i++) /* there are (4*nColors) bytesin color table */ 
    { 
    fread(ptrC, sizeof(char), 1, inputFile); 
    fwrite(ptrC, sizeof(char), 1, outputFile); 
    } 

} 
+0

어떤 비트에 붙어 있습니까? 귀하의 코드는 huffman과 관련된 것을 작성하기 시작한 것으로 보이지 않습니다. 개념에 대해 혼란 스러우면 이해하지 못하는 개념에 대해 구체적인 질문을하고 관련성없는 코드를 게시하지 마십시오. huffman이 코드로 작업하는 방법을 혼동하는 경우 문제를 나타내는 최소한의 컴파일 가능한 예제를 게시하십시오. –

+0

이 숙제가 있습니까? 그렇다면 숙제 레이블을 추가하십시오. – bta

답변

1

나는 매우 에 StackOverflow의을 요청하기 전에 Google과 같은 검색 엔진을 사용하는 것이 좋습니다. 이것은 대표적인 예입니다. 내 Google Search이고은 C와 C++ 모두에서 나타납니다.

프로그램에 어려움이 있으시면 여기에 관련 코드를 보여주십시오.