Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <getopt.h>
- #include <string.h>
- #define EXIT_ERROR 40
- #pragma pack(push, 1)
- typedef struct {
- unsigned short int signature;
- unsigned int size;
- unsigned short int reserved1, reserved2;
- unsigned int offset;
- unsigned int info_size;
- int width, height;
- unsigned short int planes;
- unsigned short int bits;
- unsigned int compression;
- unsigned int imagesize;
- int xresolution, yresolution;
- unsigned int ncolours;
- unsigned int importantcolours;
- } BMPHeader;
- typedef struct {
- unsigned char b;
- unsigned char g;
- unsigned char r;
- } RGB;
- typedef struct {
- BMPHeader header;
- RGB **rgb;
- } Image;
- #pragma pack(pop)
- int create_image(Image *image, char *filename)
- {
- FILE *fp = fopen(filename, "rb");
- if (fp == NULL) {
- fputs("Failed to open file\n", stderr);
- return 0;
- }
- fread(&image->header, 1, sizeof(BMPHeader), fp);
- if (image->header.signature != 0x4D42) {
- fputs("Not a BMP file\n", stderr);
- return 0;
- }
- if (image->header.bits != 24 || image->header.compression != 0 || image->header.planes != 1) {
- fputs("Unsupported BMP file", stderr);
- return 0;
- }
- fseek(fp, image->header.offset, SEEK_SET);
- RGB **rgb = calloc(image->header.height, sizeof(RGB*));
- if (rgb == NULL) {
- fputs("Failed to allocate memory", stderr);
- return 0;
- }
- int padd = (4 - (sizeof(RGB) * image->header.width) % 4) % 4;
- for (int i = 0; i < image->header.height; i++) {
- rgb[i] = calloc(image->header.width, sizeof(RGB));
- if (rgb[i] == NULL) {
- for (int j = 0; j < i; j++)
- free(rgb[j]);
- free(rgb);
- fputs("Failed to allocate memory\n", stderr);
- return 0;
- }
- fread(rgb[i], 1, sizeof(RGB) * image->header.width, fp);
- fseek(fp, padd, SEEK_CUR);
- }
- image->rgb = rgb;
- fclose(fp);
- return 1;
- }
- int save_image(Image *image, char *filename)
- {
- FILE *fp = fopen(filename, "wb");
- if (fp == NULL) {
- fputs("Failed to open file\n", stderr);
- return 0;
- }
- fwrite(&image->header, 1, sizeof(BMPHeader), fp);
- fseek(fp, image->header.offset, SEEK_SET);
- int padd = (4 - (sizeof(RGB) * image->header.width) % 4) % 4;
- for (int i = 0; i < image->header.height; i++) {
- fwrite(image->rgb[i], 1, sizeof(RGB) * image->header.width, fp);
- for (int j = 0; j < padd; j++)
- fputc(0, fp);
- }
- fclose(fp);
- return 1;
- }
- void destroy_image(Image *image)
- {
- for (int i = 0; i < image->header.height; i++)
- free(image->rgb[i]);
- free(image->rgb);
- }
- enum {
- OPTION_INVERSE = 1,
- OPTION_COMPONENT_SUM
- };
- enum {
- COMPONENT_UNSET,
- COMPONENT_RED,
- COMPONENT_GREEN,
- COMPONENT_BLUE
- };
- const char *shortopts = "hin:I:O:";
- struct option longopts[] = {
- { "help", no_argument, NULL, 'h' },
- { "info", no_argument, NULL, 'i' },
- { "inverse_image", no_argument, NULL, OPTION_INVERSE },
- { "component_max", no_argument, NULL, OPTION_COMPONENT_SUM },
- { "component_name", required_argument, NULL, 'n' },
- { "input", required_argument, NULL, 'I' },
- { "output", required_argument, NULL, 'O' },
- { NULL, 0, NULL, 0 }
- };
- int get_component_name()
- {
- if (strcmp(optarg, "red") == 0)
- return COMPONENT_RED;
- else if (strcmp(optarg, "green") == 0)
- return COMPONENT_GREEN;
- else if (strcmp(optarg, "blue") == 0)
- return COMPONENT_BLUE;
- return COMPONENT_UNSET;
- }
- void print_help()
- {
- puts(
- "Usage: cw [OPTION]...\n"
- "Options:\n"
- " -h, --help: print this help\n"
- " -i, --info: print image info\n"
- " --inverse_image: inverse image colors\n"
- " --component_max: sum all components and write them to component\n"
- " specified by --component_name, -n\n"
- );
- }
- int print_image_info(Image *image)
- {
- printf("Image info:\n");
- printf(" width: %d\n", (int)image->header.width);
- printf(" height: %d\n", (int)image->header.height);
- printf(" planes: %d\n", (int)image->header.planes);
- printf(" bits: %d\n", (int)image->header.bits);
- printf(" compression: %d\n", (int)image->header.compression);
- printf(" imagesize: %d\n", (int)image->header.imagesize);
- printf(" xresolution: %d\n", (int)image->header.xresolution);
- printf(" yresolution: %d\n", (int)image->header.yresolution);
- printf(" ncolours: %d\n", (int)image->header.ncolours);
- printf(" importantcolours: %d\n", (int)image->header.importantcolours);
- return 1;
- }
- int invert_image(Image *image)
- {
- for (int i = 0; i < image->header.height; i++) {
- for (int j = 0; j < image->header.width; j++) {
- image->rgb[i][j].r = 255 - image->rgb[i][j].r;
- image->rgb[i][j].g = 255 - image->rgb[i][j].g;
- image->rgb[i][j].b = 255 - image->rgb[i][j].b;
- }
- }
- return 1;
- }
- int components_sum(Image *image, int component_name)
- {
- if (component_name == COMPONENT_UNSET) {
- fputs("Component name must be specified\n", stderr);
- return 0;
- }
- for (int i = 0; i < image->header.height; i++) {
- for (int j = 0; j < image->header.width; j++) {
- int sum = image->rgb[i][j].r + image->rgb[i][j].g + image->rgb[i][j].b;
- switch (component_name) {
- case COMPONENT_RED: image->rgb[i][j].r = sum; break;
- case COMPONENT_GREEN: image->rgb[i][j].g = sum; break;
- case COMPONENT_BLUE: image->rgb[i][j].b = sum; break;
- }
- }
- }
- return 1;
- }
- int main(int argc, char **argv)
- {
- puts("Course work for option 3.2, created by Maxim Chernov");
- int function = 0;
- int opt = getopt_long(argc, argv, shortopts, longopts, NULL);
- int component_name = COMPONENT_UNSET;
- char *input = NULL;
- char *output = "out.bmp";
- while (opt != -1) {
- if (opt == '?') {
- fputs("Invalid option or missing argument\n", stderr);
- return EXIT_ERROR;
- }
- switch (opt) {
- case 'h':
- print_help();
- return 0;
- case 'i':
- case OPTION_INVERSE:
- case OPTION_COMPONENT_SUM:
- function = opt;
- break;
- case 'n':
- component_name = get_component_name();
- if (component_name == COMPONENT_UNSET) {
- fputs("Invalid component name\n", stderr);
- return EXIT_ERROR;
- }
- break;
- case 'I':
- input = optarg;
- break;
- case 'O':
- output = optarg;
- break;
- }
- opt = getopt_long(argc, argv, shortopts, longopts, NULL);
- }
- if (function == 0) {
- fputs("No function specified\n", stderr);
- return EXIT_ERROR;
- }
- if (input == NULL) {
- if (optind >= argc) {
- fputs("No input file specified\n", stderr);
- return EXIT_ERROR;
- }
- input = argv[optind];
- }
- Image image;
- if (!create_image(&image, input))
- return EXIT_ERROR;
- int ret;
- switch (function) {
- case 'i':
- ret = print_image_info(&image);
- break;
- case OPTION_INVERSE:
- ret = invert_image(&image);
- break;
- case OPTION_COMPONENT_SUM:
- ret = components_sum(&image, component_name);
- break;
- }
- if (ret == 0) {
- destroy_image(&image);
- return EXIT_ERROR;
- }
- if (function != 'i' && !save_image(&image, output)) {
- destroy_image(&image);
- return EXIT_ERROR;
- }
- destroy_image(&image);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement