使用struct变量和struct array读取bmp图像的代码。 请建议我对malloc进行类型转换的正确方法(代码下面列出的错误):
#include<stdio.h>
#include<stdlib.h>
typedef struct bands{
/* .bmp image store pixel colors in "bgr" sequence */
unsigned char b,g,r; //in 24bit bmp, we need to use 8bit datatype for each color
}bands;
int main()
{
FILE *bmpimage; //ptr to read image file
FILE *redpix,*greenpix,*bluepix; //ptr to create band/color wise file
unsigned short pix_x=223,pix_y=197; /*pix_x: no. of pixels in a row, pix_y: no. of pixels in a column of input image*/
unsigned short n_pix=pix_x*pix_y; /*variable to count total no. of pixels*/
bmpimage=fopen("blocks223x197.bmp","r"); //24 bit bmpimage
redpix=fopen("redpixels.txt","w");
greenpix=fopen("greenpixels.txt","w");
bluepix=fopen("bluepixels.txt","w");
/* Define a pointer to a memory block,'*readbuffer',
that has 'n_pix' no. of memory blocks each of size same as struct bands */
bands *readbuffer=(char*)malloc(n_pix*sizeof(*readbuffer));
int n;
//Create memory for each of 'n_pix' no. of pixel array of each color
for(n=0;n<n_pix;n++){
unsigned char *readbuffer[n].b = (char*) malloc(sizeof(readbuffer[n].b));
unsigned char *readbuffer[n].g = (char*) malloc(sizeof(readbuffer[n].g));
unsigned char *readbuffer[n].r = (char*) malloc(sizeof(readbuffer[n].r));
}
if(!bmpimage){printf("Error reading bmpimage!");return 1;}
if(readbuffer==NULL){printf("NULL buffer"); exit(1);}
/* Go to 54th byte to access pixelvalue data (since, 24bit bmp format) */
fseek(bmpimage,54,SEEK_SET);
/* Read 'n_pix' no. of 'bgr' blocks each of which are of the size same as "struct bands" */
fread(readbuffer,sizeof(bands),n_pix,bmpimage); /*read 'n_pix' no. of 'bgr' blocks each of which are of the size same as "struct bands" to the memory address, 'readbuffer' or '&readbuffer[0]' */
int n_blocks=(sizeof(readbuffer)/sizeof(bands));
printf("no. of blocks read= %d, n_pix=%d",n_blocks,n_pix);
int i,j; int count; count=0;
/* logic to print pixel values in correct order*/
for(i=pix_y;i>0;i--){ /*for accessing row data. Choose to print from bottom to top*/
for(j=1;j<=pix_x;j++){ /*for accessing column data. Print from left to right*/
if(j!=pix_x){
fprintf(redpix,"%d,",readbuffer[(i-1)*pix_x + j].r);
fprintf(greenpix,"%d,",readbuffer[(i-1)*pix_x + j].g);
fprintf(bluepix,"%d,",readbuffer[(i-1)*pix_x + j].b);
}
else{
count++;
fprintf(redpix,"%d\n",readbuffer[(i-1)*pix_x + j].r);
fprintf(greenpix,"%d\n",readbuffer[(i-1)*pix_x + j].g);
fprintf(bluepix,"%d\n",readbuffer[(i-1)*pix_x + j].b);
}
}
}
// free allocated memory
for(n=0;n<n_pix;n++){
free(readbuffer[n].b) ;
free(readbuffer[n].g) ;
free(readbuffer[n].r) ;
}
fclose(bmpimage);fclose(redpix);fclose(bluepix);fclose(greenpix);
return 0;
}
参考文献: How to properly malloc for array of struct in C
malloc an array of struct pointers vs array of structs
错误列表:
bmpread_check.c:在函数&#39; main&#39;: bmpread_check.c:24:19:警告:从不兼容的指针类型初始化&gt; [默认启用] band readbuffer =(char )malloc(n_pix * sizeof(* readbuffer)); ^ bmpread_check.c:29:33:错误:预期&#39; =&#39;,&#39;,&#39;,&#39 ;;&#39;,&#39; asm&#39;或&#39; 属性&#39; &gt;之前&#39;。&#39;代币 unsigned char readbuffer [n] .b =(char )malloc(sizeof(readbuffer [n] .b)); ^ bmpread_check.c:29:33:错误:在&#39;之前的预期表达式。&#39;代币 bmpread_check.c:30:33:错误:预期&#39; =&#39;,&#39;,&#39;,&#39 ;;&#39;,&#39; asm&#39;或&#39; 属性&#39; &gt;之前&#39;。&#39;代币 unsigned char readbuffer [n] .g =(char )malloc(sizeof(readbuffer [n] .g)); ^ bmpread_check.c:30:33:错误:在&#39;之前的预期表达。&#39;代币 bmpread_check.c:31:33:错误:预期&#39; =&#39;,&#39;,&#39;,&#39 ;;&#39;,&#39; asm&#39;或&#39; 属性&#39; &gt;之前&#39;。&#39;令牌
unsigned char readbuffer [n] .r =(char )malloc(sizeof(readbuffer [n] .r)); ^ bmpread_check.c:31:33:错误:在&#39;之前的预期表达式。&#39;代币 bmpread_check.c:69:5:警告:传递&#39; free&#39;使用&gt;整数制作指针而不使用强制转换[默认启用] free(readbuffer [n] .b); ^ 在bmpread_check.c中包含的文件中:3:0: c:\ mingw \ include \ stdlib.h:357:38:注意:预期&#39; void &#39;但是参数是&gt;类型&#39; unsigned char&#39; _CRTIMP void __cdecl __MINGW_NOTHROW free(void ); ^ bmpread_check.c:70:5:警告:传递&#39; free&#39;使用&gt;整数制作指针而不使用强制转换[默认启用] free(readbuffer [n] .g); ^ 在bmpread_check.c中包含的文件中:3:0: c:\ mingw \ include \ stdlib.h:357:38:注意:预期&#39; void &#39;但是参数是&gt;类型&#39; unsigned char&#39; _CRTIMP void __cdecl __MINGW_NOTHROW free(void ); ^ bmpread_check.c:71:5:警告:传递&#39; free&#39;使用&gt;整数制作指针而不使用强制转换[默认启用] free(readbuffer [n] .r); ^ 在bmpread_check.c中包含的文件中:3:0: c:\ mingw \ include \ stdlib.h:357:38:注意:预期&#39; void &#39;但是参数的类型是&gt;&#39; unsigned char&#39; _CRTIMP void __cdecl __MINGW_NOTHROW free(void ); ^
答案 0 :(得分:1)
此:
bands *readbuffer=(bands*)malloc(n_pix*sizeof(bands));
(注意:不是*readbuffer
。它是bands
)
已经为所有n_pix
个频段分配了内存。
没有必要为b, g, r
分配内存,因为它们不是指针。
所以,
//Create memory for each of 'n_pix' no. of pixel array of each color
// And allocating using for loop
不需要。
答案 1 :(得分:1)
变量b
,g
&amp; r
不是指针,而是无符号的8位变量。因此,为这种情况分配内存的正确方法是分配一个具有总像素数的结构的数组,即宽度乘以图像的高度。
这可以通过动态分配结构指针bands*
来实现,如下所示。
bands *readbuffer = malloc(n_pix * sizeof(bands));
该语句会将结构分配n_pix次,以便您可以初始化和访问像素值b
,g
&amp; r
位于每个像素位置,如下所示。
readbuffer[i]-> b = 20;
readbuffer[i]-> g = 80;
readbuffer[i]-> r = 40;
i
可以是0
到n_pix-1