本文介绍了解压缩在中间停止,输出文件填充零(黑色PIXELS)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图对bmp(位图)文件应用DCT(离散余弦变换)压缩。我有一个C文件,我运行在Turbo C ++。这不是真正的压缩,但我想实现DCT和IDCT。代码如下:

I am trying to apply DCT(discrete cosine transformation) compression on a bmp(bitmap) file. I have a c file which i am running in Turbo C++. This is not actually compressing but i was trying to implement the DCT and IDCT. The code is as follows:

/*
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<stdlib.h>
#include<stdio.h>
#include<math.h>
#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;
}

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

Here is the image i am using as input

(im srry网站将bmp转换为png你可以将它转换回bmp来使用它)
这是生成的图像:

(im srry the site converted the bmp into png. You may convert it back to bmp to use it)Here is the image that is generated:

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

The file college3.bmp that gets created is of size 200x160 and of 93.8 kB but till quarter of the image it has decoded the coefficients correctly but later the file is filled with black pixels. I have taken a screenshot of the o/p as it was saying not a valid bmp while uploading. I am sitting on this problem since feb,2004. If anyone can say me where there is a bug i would be very thankful. I have analysed the output file and found an EOF right at the place where the pixels are starting to be black. I read some other questions on the topic and found that the conversion factors ci,cj have been used improperly. While coding i had also got confused with the indices x,y,i and j. So i hope this problem i will solve in a few days.

推荐答案

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

Apparently, the problem in the above code is in how you open your files.

这是你的代码应该是什么(注意明确指定的开放模式,二进制和文本):

This is what should be in your code (note the explicitly specified open modes, binary and text):

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");
...
}

/ p>

With that and slightly altered structure definitions:

#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 ++,打开Watcom,gcc),并获得所需的输出图片。

I'm able to compile your program successfully using 3 different compilers (Turbo C++, Open Watcom, gcc) and get the desired output picture.

这篇关于解压缩在中间停止,输出文件填充零(黑色PIXELS)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 04:25