Декомпрессия останавливается между ними, а выходной файл заполняется нулями (BLACK PIXELS)?

Я пытаюсь применить сжатие DCT (дискретное косинусное преобразование) в файле BMP (bitmap). У меня есть файл ac, который я запускаю в Turbo C ++. На самом деле это не сжатие, но я пытался реализовать 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; } 

Вот изображение, которое я использую в качестве входного Входное изображение

(im srry сайт преобразовал bmp в png. Вы можете преобразовать его обратно в bmp, чтобы использовать его) Вот изображение, которое сгенерировано:

Неправильный вывод

Созданный файл college3.bmp имеет размер 200×160 и 93.8 kB, но до четверти изображения он правильно декодировал коэффициенты, но позже файл заполняется черными пикселями. Я сделал скриншот o / p, поскольку он говорил не действительный BMP при загрузке. Я сижу на этой проблеме с февраля 2004 года. Если кто-нибудь скажет мне, где есть ошибка, я был бы очень благодарен. Я проанализировал выходной файл и нашел 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) 

Я могу скомпилировать вашу программу с помощью трех разных компиляторов (Turbo C ++, Open Watcom, gcc) и получить желаемое изображение вывода.