C中的空指针分配

时间:2019-05-30 18:17:56

标签: c pointers struct

我是C程序的初学者。我正在尝试编写一个程序,该程序读取BMP文件并写入Image文件的副本。但是,当我以较小的代码执行此代码时,它会进行1次迭代,然后显示Null指针分配。请帮我解决这个问题

我正在Turbo C / Windows 7 OS中运行此代码

#define MAX_FILE_NAME_SIZE 100
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>

struct Pixel
{
 unsigned char red;
 unsigned char green;
 unsigned char blue;
};
struct RGB_Image
{
 char file_name[MAX_FILE_NAME_SIZE];
 long height;
 long width;
 long size;
 struct Pixel** pixels;
};

//following functions are used for loading and saving of images
int load_image(struct RGB_Image* image);
int save_image(struct RGB_Image image) ;

/// following function is used free up allcated memories for pixels
void free_pixels(struct RGB_Image image);

// following function is used for re allocate memories for pixels
void re_allocate_pixels(struct RGB_Image* image, int new_height, int new_width);

// following functin are used to manipulate images like
// removing channel, inerting image, quantire image, flip images, etc
void save_copy_image();
void remove_channel_image();
void invert_image();
void quantize_image();
void flip_hrizontal_image();
void change_luminonsity_image();
void print_information_image();
void crop_image();
void change_luminosity();

// following functions are used to manipulate pixels of image
// like invert pixels, flip images, remove pixels, etc
void invert_pixels(struct Pixel** pixels, int height, int width);
void flip_hrizntal_pixels(struct Pixel** pixels, int height, int width);
void quantize_pixels(struct Pixel** pixels, int height, int width, int quantize_level);
void remove_red_pixels(struct Pixel** pixels, int height, int width);
void remove_green_pixels(struct Pixel** pixels, int height, int width);
void remove_blue_pixels(struct Pixel** pixels, int height, int width);
void change_luminosity_pixels(struct Pixel** pixels, int height, int width, int luminosity_level);

void free_pixels(struct RGB_Image image)
{
 long i=0;
 for(;i<image.height;i++)
 {
  free(image.pixels[i]);
 }

}

void print_information_image()
{
 struct RGB_Image image;
 int file_status;
 file_status = load_image(&image);
 if(file_status == 0)
 {
  printf("File name : %s\n", image.file_name);
  printf("Height : %ld\n", image.height);
  printf("Width : %ld\n", image.width);
  printf("Size : %ld\n", image.size);
  free_pixels(image);
 }


}


// loads image to passed pointer variable
int load_image(struct RGB_Image* image_pointer)
{
 // decalre variable for storing file name
 char file_name[MAX_FILE_NAME_SIZE];
 // decalre file pointer
 FILE *file_pointer;
 long i,j;
 //long k=0;

 // read file name and store it in image pointer
 printf("\n Enter the file name : ");
 scanf("%s", image_pointer->file_name);
 // copy file name from pointer to local variables
 strcpy(file_name, image_pointer->file_name);
 // append bmp extension
 strcat(file_name, ".bmp");
 // read a file
 file_pointer = fopen(file_name, "rb");
 // if there is an error, return 1
 if(file_pointer == NULL)
 {
  printf("\n File can not be opened");
  return 1;
 }

 // move the opened file and move 2 bytes
 fseek(file_pointer, 2, SEEK_SET);
 // read the size of file
 fread(&(image_pointer->size), 4, 1, file_pointer);
 // move 12 bytes further
 fseek(file_pointer, 12, SEEK_CUR);
 // read height and width of file
 fread(&(image_pointer->width), 4, 1, file_pointer);
 fread(&(image_pointer->height), 4, 1, file_pointer);
 // move 28 bytes for reading further content
 fseek(file_pointer, 28, SEEK_CUR);
 // printf("dim read finished\n");
 // assign pointers for each row

 image_pointer->pixels = (struct Pixel**) malloc(sizeof(*image_pointer->pixels) * image_pointer->height);
 // printf("craete first pointers finished\n");
 i = 0;
 for(;i<image_pointer->height;i++)
 {
  image_pointer->pixels[i] = (struct Pixel*) malloc(sizeof(struct Pixel*) * image_pointer->width);
 }
  // printf("create indiv pointers finished\n");

 for(i=0;i<image_pointer->height;i++)
 {
  for(j=0;j<image_pointer->width;j++)
  {
   fread(&(image_pointer->pixels[i][j].red), 1, 1, file_pointer);
   fread(&(image_pointer->pixels[i][j].green), 1, 1, file_pointer);
   fread(&(image_pointer->pixels[i][j].blue), 1, 1, file_pointer);
   //k += 3;
  }
 }
  //printf("file is copied \n");
// printf("total value %ld", k);

 fclose(file_pointer);
 printf("\n Image loaded \n \n");
 return 0;
}


void save_copy_image()
{
    struct RGB_Image image;
    int file_status = load_image(&image);
    if (file_status == 0) {
        strcat(image.file_name, "_copy");
        printf("\nImage Copied");
        save_image(image);
        free_pixels(image);
    }
}

int save_image(struct RGB_Image image) {
    long i, j;
    char copy_file_name[MAX_FILE_NAME_SIZE];
    FILE *file_pointer;
    int image_datasize = image.size - 40;
    unsigned char bmp_header[54] = {
        0x42, 0x4D, 0, 0, 0, 0,
        0X00,0X00,0X00,0X00,
        0x36,0x00,0x00,0x00,
        0x28,0x00,0x00,0x00,
        0, 0, 0, 0,
        0, 0, 0, 0,
        0x01,0x00,0x18,0x00,
        0x00,0x00,0x00,0x00,
        0, 0, 0, 0,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0X00,0X00,0X00,0X00
    };
    bmp_header[2] = image.size;
    bmp_header[3] = image.size >> 8;
    bmp_header[4] = image.size >> 16;
    bmp_header[5] = image.size >> 24;

    bmp_header[18] = image.width;
    bmp_header[19] = image.width >> 8;
    bmp_header[20] = image.width >> 16;
    bmp_header[21] = image.width >> 24;

    bmp_header[22] = image.height;
    bmp_header[23] = image.height >> 8;
    bmp_header[24] = image.height >> 16;
    bmp_header[25] = image.height >> 24;

    bmp_header[34] = image_datasize;
    bmp_header[35] = image_datasize >> 8;
    bmp_header[36] = image_datasize >> 16;
    bmp_header[37] = image_datasize >> 24;


    strcpy(copy_file_name, image.file_name);
    strcat(copy_file_name, ".bmp");
    file_pointer = fopen(copy_file_name, "wb");
    if (file_pointer == NULL) {
        printf("\nFile can not be opened.");
        return 1;
    }

    fwrite(bmp_header, 1, 54, file_pointer);
    for (i=0;i < image.height;i++) {
        for (j=0;j < image.width;j++) {
            fwrite(&(image.pixels[i][j].red), 1, 1, file_pointer);
            fwrite(&(image.pixels[i][j].green), 1, 1, file_pointer);
            fwrite(&(image.pixels[i][j].blue), 1, 1, file_pointer);
        }
    }
    fclose(file_pointer);
    printf("\nImage Saved %d", image_datasize);
    return 0;
}

void change_luminosity_pixels(struct Pixel** pixels, int height, int width, int luminosity_level)
{
     int i, j, value_red = 0, value_green = 0, value_blue = 0;
     for (i=0;i < height;i++) {
        for (j=0;j < width;j++) {
            value_red = pixels[i][j].red + luminosity_level;
            if(value_red > 255)
                value_red = 255;
            else if(value_red < 0)
                value_red = 0;
            printf("red value = %d", value_red);
            pixels[i][j].red = value_red;
            //fwrite(&(value_red), 1, 1, file_pointer);

            value_green = pixels[i][j].green + luminosity_level;
            if(value_green > 255)
                value_green = 255;
            else if(value_green < 0)
                value_green = 0;
            printf("green value = %d", value_green);
            pixels[i][j].green = value_green;
            //fwrite(&(value_green), 1, 1, file_pointer);

            value_blue = pixels[i][j].blue + luminosity_level;
            if(value_blue > 255)
                value_blue = 255;
            else if(value_blue < 0)
                value_blue = 0;
            printf("blue value = %d", value_blue);
            pixels[i][j].blue = value_blue;
            //fwrite(&(value_blue), 1, 1, file_pointer);

        }
    }
}

void change_luminosity()
{
    struct RGB_Image image;
    int luminosity_level, file_status;
    file_status = load_image(&image);
    if(file_status == 0)
    {
        printf(" Enter the luminosity: ");
        scanf("%d", &luminosity_level);
        change_luminosity_pixels(image.pixels, image.height, image.width, luminosity_level);
        strcat(image.file_name, "_luminosity_");
        //strcat(image.file_name, luminosity_level);
        save_image(image);
        printf("Image luminosity changed by a level of %d", luminosity_level);
        free_pixels(image);
    }
}

// starts main program
int main()
{

 int choice = -2;
 clrscr();
 while(choice != -1)
 {
  printf("\n\n IMAGE MENU\n");
  printf("0. Print Image Information\n");
  printf("1. Save Copy of Image\n");
  printf("2. Change Luminosity\n");
  printf("3. Remove Image Channel\n");
  printf("4. Invert Image Clours\n");
  printf("5. Quantize Image\n");
  printf("6. Flip Image Horizntally\n");
  printf("7. Crop Image\n");
  printf("-1. Quit\n");
  printf("Enter your choice : ");
  scanf("%d", &choice);
  switch(choice)

  {
    case 0:
    print_information_image();
    break;
    case 1:
       save_copy_image();
    break;
    case 2:
    break;
    case 3:
    break;
    case 4:
    break;
    case 5:
    break;
    case 6:
    break;
    case 7:
    break;
    case -1:
     exit(0);
    break;
    default:
     //continue;
    break;
  }

 }
 printf("\\ Test");
 getch();
 return 0;
}

它应该可以处理所有大小的bmp文件>请帮帮我

0 个答案:

没有答案