BMP_Image *BMP_load(const char *filename) { // read the header from the file FILE *input_file = fopen(filename,"rb");//use rb to read binary file if (input_file == NULL)//check if it's opened { return NULL; } BMP_Header input_header;//input header file if (fread(&input_header, sizeof(BMP_Header), 1, input_file) != 1)//check if the input file has been successfully read or not { fclose(input_file); return NULL; } // print the header information (use BMP_printHeader) BMP_printHeader(&input_header);//print the header information to the screen // make sure the header is valid before proceeding (use BMP_checkValid) if(BMP_checkValid(&input_header) != 1)//check if the header information is valid or not { return NULL; } // create the image structure (BMP_create) BMP_Image *input_image = BMP_create(&input_header);//use BMP_create to create a output_image structure // read all of the image data if(fread(input_image -> data, sizeof(char), input_image -> data_size, input_file) != input_image -> data_size)//use fread to read all the image data { fclose(input_file);//if not successful, close the file return NULL; } // return the image fclose(input_file); return input_image; }
Image * Image_loadbmp(const char * filename) { FILE * fp = NULL; size_t read; BMP_Header header; Image * tmp_im = NULL, * im = NULL; size_t n_bytes = 0; int err = FALSE; if(!err) { // Open filename fp = fopen(filename, "rb"); if(!fp) { fprintf(stderr, "Failed to open file '%s'\n", filename); err = TRUE; } } if(!err) { // Read the header read = fread(&header, sizeof(BMP_Header), 1, fp); if(read != 1) { fprintf(stderr, "Failed to read header from '%s'\n", filename); err = TRUE; } } if(!err) { // Print the header BMP_printHeader(&header); } if(!err) { // We're only interested in a subset of valid bmp files if(!BMP_checkValid(&header)) { fprintf(stderr, "Invalid header in '%s'\n", filename); err = TRUE; } } if(!err) { // Allocate Image struct tmp_im = malloc(sizeof(Image)); if(tmp_im == NULL) { fprintf(stderr, "Failed to allocate im structure\n"); err = TRUE; } } if(!err) { // Init the Image struct tmp_im->width = header.width; tmp_im->height = header.height; // Handle the comment char * filename_cpy = strdup(filename); // we want to call basename char * file_basename = basename(filename_cpy); // requires editable str const char * prefix = "Original BMP file: "; n_bytes = sizeof(char) * (strlen(prefix) + strlen(file_basename) + 1); tmp_im->comment = malloc(n_bytes); if(tmp_im->comment == NULL) { fprintf(stderr, "Failed to allocate %zd bytes for comment\n", n_bytes); err = TRUE; } else { sprintf(tmp_im->comment, "%s%s", prefix, file_basename); } free(filename_cpy); // this also takes care of file_basename // Handle image data n_bytes = sizeof(uint8_t) * header.width * header.height; tmp_im->data = malloc(n_bytes); if(tmp_im->data == NULL) { fprintf(stderr, "Failed to allocate %zd bytes for image data\n", n_bytes); err = TRUE; } } if(!err) { // Seek the start of the pixel data if(fseek(fp, header.offset, SEEK_SET) != 0) { fprintf(stderr, "Failed to seek %d, the data of the image data\n", header.offset); err = TRUE; } } if(!err) { // Read pixel data size_t bytes_per_row = ((header.bits * header.width + 31)/32) * 4; n_bytes = bytes_per_row * header.height; uint8_t * rawbmp = malloc(n_bytes); if(rawbmp == NULL) { fprintf(stderr, "Could not allocate %zd bytes of image data\n", n_bytes); err = TRUE; } else { read = fread(rawbmp, sizeof(uint8_t), n_bytes, fp); if(n_bytes != read) { fprintf(stderr, "Only read %zd of %zd bytes of image data\n", read, n_bytes); err = TRUE; } else { // Must convert RGB to grayscale uint8_t * write_ptr = tmp_im->data; uint8_t * read_ptr; int intensity; int row, col; // row and column for(row = 0; row < header.height; ++row) { read_ptr = &rawbmp[row * bytes_per_row]; for(col = 0; col < header.width; ++col) { intensity = *read_ptr++; // blue intensity += *read_ptr++; // green intensity += *read_ptr++; // red *write_ptr++ = intensity / 3; // now grayscale } } } } free(rawbmp); } if(!err) { // We should be at the end of the file now uint8_t byte; read = fread(&byte, sizeof(uint8_t), 1, fp); if(read != 0) { fprintf(stderr, "Stray bytes at the end of bmp file '%s'\n", filename); err = TRUE; } } if(!err) { // We're winners... im = tmp_im; // bmp will be returned tmp_im = NULL; // and not cleaned up } // Cleanup if(tmp_im != NULL) { free(tmp_im->comment); // Remember, you can always free(NULL) free(tmp_im->data); free(tmp_im); } if(fp) { fclose(fp); } return im; }
Image * Image_load(const char * filename) { FILE * fp = NULL; ImageHeader header; size_t read; Image * tmp_im = NULL, * im = NULL; int err = FALSE; if(!err){ fp = fopen(filename, "rb"); if(!fp){ fprintf(stderr, "Failed to open file '%s'\n",filename); err = TRUE; } } if(!err){ read = fread(&header, sizeof(ImageHeader), 1, fp); if(read != 1){ fprintf(stderr, "Failed to read header from '%s'\n", filename); err = TRUE; } } if(!err){ if(!BMP_checkValid(&header)) { fprintf(stderr, "Invalid header in '%s'\n", filename); err = TRUE; } } if(!err){ tmp_im = malloc(sizeof(Image)); tmp_im->comment = NULL; tmp_im->data = NULL; if(tmp_im == NULL){ fprintf(stderr, "Failed to allocate im structure\n"); err = TRUE; } } if(!err){ tmp_im->width = header.width; tmp_im->height = header.height; tmp_im->comment = malloc(sizeof(char*) *header.comment_len); if(tmp_im->comment == NULL){ fprintf(stderr, "Fail to allocate comment\n"); err = TRUE; } } if(!err){ read = fread(tmp_im->comment, sizeof(char), header.comment_len, fp); if(read != header.comment_len || tmp_im->comment[header.comment_len-1] != '\0'){ fprintf(stderr, "Comment does not end with null byte\n"); err = TRUE; } } if(!err){ tmp_im-> data = malloc(sizeof(uint8_t) * header.width * header.height); if(tmp_im-> data == NULL){ fprintf(stderr, "Fail to allocate memory to data\n"); err = TRUE; } } if(!err) { read = fread(tmp_im-> data, sizeof(uint8_t), header.width * header.height,fp); if(read != header.width * header.height){ fprintf(stderr, "could not read all image data\n"); err = TRUE; } } if(!err){ if(fgetc(fp) != EOF){ fprintf(stderr, "Have not reach the end of file\n"); err = TRUE; } } if(!err){ im = tmp_im; tmp_im = NULL; } Image_free(tmp_im); if(fp != NULL) fclose(fp); if(err) return NULL; else return im; }