2016-04-13 94 views
0
// 
// main.c 
// cbp 
// 
// Created by Zhan on 16/4/13. 
// Copyright © 2016年 Zhan. All rights reserved. 
// 
#include <stdio.h> 
#include <stdlib.h> 
#include<math.h> 

#pragma pack(2) 

typedef unsigned short int WORD; 
typedef unsigned int DWORD; 

typedef struct BMP_FILE_HEADER 
{ 
    WORD bType; 
    DWORD bSize; 
    WORD bReserved1; 
    WORD bReserved2; 
    DWORD bOffset; 
} BMPFILEHEADER; 

typedef struct BMP_INFO 
{ 
    DWORD bInfoSize; 
    DWORD bWidth; 
    DWORD bHeight; 
    WORD bPlanes; 
    WORD bBitCount; 
    DWORD bCompression; 
    DWORD bmpImageSize; 
    DWORD bXPelsPerMeter; 
    DWORD bYPelsPerMeter; 
    DWORD bClrUsed; 
    DWORD bClrImportant; 
} BMPINF; 

/*彩色表*/ 
typedef struct RGB_QUAD 
{ 
    WORD rgbBlue; 
    WORD rgbGreen; 
    WORD rgbRed; 
    WORD rgbReversed; 
} RGBQUAD; 

int main() 
{ 
    FILE *fp,*fpout; 
    BMPFILEHEADER fileHeader; 
    BMPINF infoHeader; 
    int width, height; 
    //WORD c; 
    int s; 
    float s1,s2; 
    unsigned char **image; 

    if((fp = fopen("XG.bmp", "rb")) == NULL) 
    { 
     printf("Cann't open the file!\n"); 
    } 


    fseek(fp, 0, 0); 
    fread(&fileHeader, sizeof(fileHeader), 1, fp); 
    fread(&infoHeader, sizeof(infoHeader), 1, fp); 

    printf("size fileHeader == %ld\n",sizeof(fileHeader)); 
    printf("size infoHader == %ld\n",sizeof(infoHeader)); 

    width = infoHeader.bWidth; 
    height = abs(infoHeader.bHeight); 

    printf("infoHeader.bWidth == %d\n",width); 
    printf("infoHeader.bheight == %d\n",height); 

    image = (unsigned char **)malloc(sizeof(unsigned char *) * width); 
    image[0] = (unsigned char *)malloc(sizeof(unsigned char) * width * height); 

    // unsigned char **image1 =(unsigned char**) malloc (width*sizeof(int*)); 
    // for(int i=0;i<width;i++) 
    //  *image1++=(unsigned char*) malloc (height*sizeof(int)); 

    fseek(fp,(sizeof(fileHeader)+sizeof(infoHeader)),SEEK_SET); 
    for(int i=0;i<width;i++) 
    { 
     for(int j=0;j<height;j++){ 
      fread(&image[i][j],1,1,fp); }}  //Memory leak ? 
    for(int i=1;i<width;i++){ 
     for(int j=1;j<height;j++) 
     { 
      s1=image[i-1][j+1]+2*image[i][j+1]+image[i+1][j+1]; 
      s1=s1-image[i-1][j-1]-2*image[i][j-1]-image[i+1][j-1]; 
      s2=image[i-1][j-1]+2*image[i-1][j]+image[i-1][j+1]; 
      s2=s2-image[i+1][j-1]-2*image[i+1][j]-image[i+1][j+1]; 
      s=fabs(s1)+fabs(s2); 
      if(s>80) 
       image[i][j]=255; 
      else 
       image[i][j]=0; 
     } 
    } 
    if((fpout=fopen("za.bmp","wb"))==NULL){ 
     printf("cannot open outfile!\n"); 
     free(image[0]); 
     free(image); 
     return 0; 
    } 
    printf("intoWrite\n"); 
    fwrite(&fileHeader,sizeof(fileHeader),1,fpout); 
    fwrite(&infoHeader,sizeof(infoHeader),1,fpout); 
    for(int i=0;i<width;i++) 
    { 
     for(int j=0;j<height;j++){ 
      printf("forWrite\n"); 
      fwrite(&image[i][j],1,1,fpout);}} 
    // c = fgetc(fp); 
    // int mi=0,mj=0; 
    // while (!feof(fp)) 
    // { 
    //  fwrite(&c,1,1,fpout); 
    //  mi++;mj++; 
    // c = fgetc(fp); 
    // } 
    free(image[0]); 
    free(image); 
    printf("OK!\n"); 
    fclose(fp); 
    fclose(fpout); 
    return 0; 
} 

这是我的bmp边缘detection.I代码中使用的Xcode来运行该代码时,它总是提示“线程1:EXC_BAD_ACCESS(码= 1,地址=为0x0)”或“函数调用参数是一个未初始化的值“at”fread(& image [i] [j],1,1,fp)“为什么我用静态二维数组没有错误,但动态二维数组是错误的?的C代码的指针

回答

0
image=(WORD **)calloc(width,sizeof(WORD*)); 
     if (NULL==image) return 1; 
      for (a=0;a<width;a++) { 
       image[a]=(WORD*)calloc(height,sizeof(WORD)); 
       if (NULL==image[a]){ 
        printf("free image\n"); 
        free(image); 
        return 2;} 
      } 

我用calloc函数,这个函数是分配内存和初始化的。

0
image[0] = (unsigned char *)malloc(sizeof(unsigned char) * width * height); 

您只为一个数组而不是整个查找表分配空间,其中每个指针都指向一个已分配的数组。

但是,首先绝对不需要使用一些不明显的查找表。相反,使用二维数组:

width = ...; 
height = ....; 
unsigned char (*image)[][height]; 
image = malloc(sizeof(unsigned char[width][height])); 

... 

free(image); 

而现在,因为你有一个真正的二维数组,而不是一些零碎的东西,你可以一次读取整个数组,如果你想:

fread(image, sizeof(unsigned[width][height]), 1, fp); 

意义:进入我的二维数组,从fp中读取一个二维数组。你可以跳过循环。

+0

我在Visual Studio上使用了这种方式,并得到了这个:IntelliSense:表达式必须是指向完整对象类型的指针 –

+0

@MichaelZhan您必须使用现代标准C编译器来编译它。 Visual Studio的“2015”编译器完全过时了,它包含了1989年的技术和1999年的一些技术。 – Lundin

+0

HAHA。最后我使用了calloc函数。实际上,我喜欢Xcode来编写代码。 –