解压缩在中间停止,输出文件用零填充(BLACK PIXELS)?

我试图在bmp(位图)文件上应用DCT(离散余弦变换)压缩。 我有一个我在Turbo C ++中运行的ac文件。 这实际上并没有压缩,但我试图实现DCT和IDCT。 代码如下:

/* the image to be compressed is a bmp with 24 bpp and with name "college4.bmp" of dimensions 200*160 ie 25*20- 8*8 blocks o/p is college2.dat format: 8 bit signed integers starting rowwise from 0,0 to 8,8 the coefficients order is blue,green,red for the block no 1 then 2 and soon */ #include #include #include #define WIDTH 25 #define HEIGHT 20 typedef struct { unsigned int type; unsigned long int filesize; unsigned int reserved1,reserved2; unsigned long int offset; } BMPHEAD; typedef struct { unsigned long int infosize; unsigned long int width,height; unsigned int planes,bitsperpixel; unsigned long int compression; unsigned long int sizeimage; long int xpelspermeter,ypelspermeter; unsigned long int colorused,colorimportant; } INFOHEAD; typedef struct { char rgbquad[4]; } colortable; BMPHEAD bmphead; INFOHEAD infohead; FILE *bmp_fp1,*bmp_fp2; int buf[WIDTH][8][8][3],buf1[WIDTH][8][8][3]; float pi=3.14159265,DCTcoeff[8][8][8][8]; void generatedctcoeff() { int y, i, j, x; for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { for (x = 0; x < 8; x++) { for (y = 0; y < 8; y++) { DCTcoeff[i][j][x][y] = cos(((2 * y + 1) * pi * j) / 16) * cos(((2 * x + 1) * i * pi) / 16); } } } } } void outputtofile1() { // Write into college2.dat int i, j, x, y, blockno; // One block at a time, buf contains pixel int redcoef, greencoef, bluecoef; // data of one row of blocks float gijred, gijgreen, gijblue, c, ci, cj; c = 1 / (sqrt(2)); for (blockno = 0; blockno < WIDTH; blockno++) { for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { gijred = 0; gijgreen = 0; gijblue = 0; for (x = 0; x < 8; x++) { for (y = 0; y < 8; y++) { gijblue = gijblue + DCTcoeff[i][j][x][y] * buf[blockno][x][y][0]; gijgreen = gijgreen + DCTcoeff[i][j][x][y] * buf[blockno][x][y][1]; gijred = gijred + DCTcoeff[i][j][x][y] * buf[blockno][x][y][2]; } } ci = cj = 1.0; if (i == 0) ci = c; if (j == 0) cj = c; gijblue = ci * cj * gijblue / 4; gijgreen = ci * cj * gijgreen / 4; gijred = ci * cj * gijred / 4; bluecoef = (int) gijblue; greencoef = (int) gijgreen; redcoef = (int) gijred; fprintf(bmp_fp2, "%d %d %d ", bluecoef, greencoef, redcoef); } } } /* end of one block processing */ } void compressimage() { int rowcount,x,y; bmp_fp1=fopen("college4.bmp","r"); bmp_fp2=fopen("college2.dat","w"); printf("generating coefficients...\n"); generatedctcoeff(); if(bmp_fp1==NULL) { printf("can't open"); return; } printf("compressing....\n"); fread(&bmphead,1,sizeof(bmphead),bmp_fp1); fread(&infohead,1,sizeof(infohead),bmp_fp1); fseek(bmp_fp1,bmphead.offset,SEEK_SET); for(rowcount=0;rowcount<HEIGHT;rowcount++) { for(y=0;y<8;y++) { for(x=0;x<infohead.width;x++) { buf[x/8][x%8][y][0]=(int)fgetc(bmp_fp1); buf[x/8][x%8][y][1]=(int)fgetc(bmp_fp1); buf[x/8][x%8][y][2]=(int)fgetc(bmp_fp1); } } outputtofile1(); //output contents of buf after dct to file } fclose(bmp_fp1); fclose(bmp_fp2); } void outputtofile2() { //output buf to college3.bmp int i, j, x, y, blockno; // buf now contains coefficients float pxyred, pxygreen, pxyblue, c, ci, cj; // a temp buffer buf1 used to c = 1 / (sqrt(2)); // store one row of block of for (blockno = 0; blockno < WIDTH; blockno++) { // decoded pixel values for (x = 0; x < 8; x++) for (y = 0; y < 8; y++) { pxyred = 0; pxygreen = 0; pxyblue = 0; for (j = 0; j < 8; j++) { cj = 1.0; if (j == 0) cj = c; for (i = 0; i < 8; i++) { ci = 1.0; if (i == 0) ci = c; pxyblue = pxyblue + ci * cj * DCTcoeff[i][j][y][x] * buf[blockno][i][j][0]; pxygreen = pxygreen + ci * cj * DCTcoeff[i][j][y][x] * buf[blockno][i][j][1]; pxyred = pxyred + ci * cj * DCTcoeff[i][j][y][x] * buf[blockno][i][j][2]; } } pxyblue /= 4; pxygreen /= 4; pxyred /= 4; buf1[blockno][y][x][0] = pxyblue; buf1[blockno][y][x][1] = pxygreen; buf1[blockno][y][x][2] = pxyred; } } for (y = 0; y < 8; y++) { for (blockno = 0; blockno < WIDTH; blockno++) for (x = 0; x < 8; x++) { fprintf(bmp_fp2, "%c%c%c", (char) buf1[blockno][x][y][0], (char) buf1[blockno][x][y][1], (char) buf1[blockno][x][y][2]); } } } void uncompressimage() { int blue,green,red,rowcount,colcount,i,j; bmp_fp1=fopen("college2.dat","r"); bmp_fp2=fopen("college3.bmp","w"); printf("generating coefficients...\n"); generatedctcoeff(); if (bmp_fp1==NULL) { printf("open failed"); return; } printf("uncompressing....\n"); bmphead.type=0x4d42; bmphead.filesize=30518; bmphead.reserved1=0; bmphead.reserved2=0; bmphead.offset=sizeof(bmphead)+sizeof(infohead); infohead.infosize=sizeof(infohead); infohead.width=200; infohead.height=160; infohead.planes=1; infohead.bitsperpixel=24; infohead.compression=0; infohead.sizeimage=0; infohead.xpelspermeter=3780; infohead.ypelspermeter=3780; infohead.colorused=0; infohead.colorimportant=0; fwrite(&bmphead,sizeof(BMPHEAD),1,bmp_fp2); fwrite(&infohead,sizeof(INFOHEAD),1,bmp_fp2); for(rowcount=0;rowcount<HEIGHT;rowcount++) { for(colcount=0;colcount<WIDTH;colcount++) { for(i=0;i<8;i++) { for(j=0;j<8;j++) { fscanf(bmp_fp1,"%d",&blue); fscanf(bmp_fp1,"%d",&green); fscanf(bmp_fp1,"%d",&red); buf[colcount][i][j][0]=blue; buf[colcount][i][j][1]=green; buf[colcount][i][j][2]=red; } } } outputtofile2(); } fclose(bmp_fp1); fclose(bmp_fp2); } int main() { printf("opening files...\n"); compressimage(); printf("opening files...again\n"); uncompressimage(); printf("successful decompression\nenter any key\n"); return 0; } 

这是我用作输入的图像 输入图像

(即使该网站将bmp转换为png。您可以将其转换回bmp以使用它)以下是生成的图像:

输出不正确

创建的文件college3.bmp的大小为200×160和93.8 kB但是直到图像的四分之一它才正确解码了系数,但之后文件被黑色像素填充。 我已经截取了o / p的截图,因为它在上传时说的不是有效的bmp。 自2004年2月以来,我正坐在这个问题上。 如果有人能说我哪里有错误,我会非常感激。 我已经分析了输出文件,并在像素开始变黑的地方找到了一个EOF。 我读了一些关于这个主题的其他问题,发现转换因子ci,cj使用不当。 虽然编码我也与索引x,y,i和j混淆了。 所以我希望这个问题能在几天后解决。

显然,上面代码中的问题在于如何打开文件。

这是您的代码中应该包含的内容(请注意明确指定的打开模式,二进制文本和文本):

 void compressimage() { ... bmp_fp1=fopen("college4.bmp","rb"); bmp_fp2=fopen("college2.dat","wt"); ... } void uncompressimage() { ... bmp_fp1=fopen("college2.dat","rt"); bmp_fp2=fopen("college3.bmp","wb"); ... } 

随着结构定义略有改变:

 #pragma pack(push,1) typedef struct { unsigned short int type; unsigned long int filesize; unsigned short int reserved1,reserved2; unsigned long int offset; } BMPHEAD; typedef struct { unsigned long int infosize; unsigned long int width,height; unsigned short int planes,bitsperpixel; unsigned long int compression; unsigned long int sizeimage; long int xpelspermeter,ypelspermeter; unsigned long int colorused,colorimportant; } INFOHEAD; typedef struct { char rgbquad[4]; } colortable; #pragma pack(pop) 

我能够使用3种不同的编译器(Turbo C ++,Open Watcom,gcc)成功编译您的程序,并获得所需的输出图片。