我的项目有些困难。我从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 :(得分:0)
我强烈建议您在询问 StackOverflow 之前使用Google等搜索引擎。这是一个很好的例子。我的Google Search会在C和C ++中产生示例。
如果您的程序有问题,请在此处显示相关代码。