dylanm312

filter.c (main entry point)

Dec 18th, 2023 (edited)
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.50 KB | None | 0 0
  1. #include <getopt.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. #include "helpers.h"
  6.  
  7. int main(int argc, char *argv[])
  8. {
  9.     // Define allowable filters
  10.     char *filters = "begr";
  11.  
  12.     // Get filter flag and check validity
  13.     char filter = getopt(argc, argv, filters);
  14.     if (filter == '?')
  15.     {
  16.         printf("Invalid filter.\n");
  17.         return 1;
  18.     }
  19.  
  20.     // Ensure only one filter
  21.     if (getopt(argc, argv, filters) != -1)
  22.     {
  23.         printf("Only one filter allowed.\n");
  24.         return 2;
  25.     }
  26.  
  27.     // Ensure proper usage
  28.     if (argc != optind + 2)
  29.     {
  30.         printf("Usage: ./filter [flag] infile outfile\n");
  31.         return 3;
  32.     }
  33.  
  34.     // Remember filenames
  35.     char *infile = argv[optind];
  36.     char *outfile = argv[optind + 1];
  37.  
  38.     // Open input file
  39.     FILE *inptr = fopen(infile, "r");
  40.     if (inptr == NULL)
  41.     {
  42.         printf("Could not open %s.\n", infile);
  43.         return 4;
  44.     }
  45.  
  46.     // Open output file
  47.     FILE *outptr = fopen(outfile, "w");
  48.     if (outptr == NULL)
  49.     {
  50.         fclose(inptr);
  51.         printf("Could not create %s.\n", outfile);
  52.         return 5;
  53.     }
  54.  
  55.     // Read infile's BITMAPFILEHEADER
  56.     BITMAPFILEHEADER bf;
  57.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  58.  
  59.     // Read infile's BITMAPINFOHEADER
  60.     BITMAPINFOHEADER bi;
  61.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  62.  
  63.     // Ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  64.     if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  65.         bi.biBitCount != 24 || bi.biCompression != 0)
  66.     {
  67.         fclose(outptr);
  68.         fclose(inptr);
  69.         printf("Unsupported file format.\n");
  70.         return 6;
  71.     }
  72.  
  73.     // Get image's dimensions
  74.     int height = abs(bi.biHeight);
  75.     int width = bi.biWidth;
  76.  
  77.     // Allocate memory for image
  78.     RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
  79.     if (image == NULL)
  80.     {
  81.         printf("Not enough memory to store image.\n");
  82.         fclose(outptr);
  83.         fclose(inptr);
  84.         return 7;
  85.     }
  86.  
  87.     // Determine padding for scanlines
  88.     int padding = (4 - (width * sizeof(RGBTRIPLE)) % 4) % 4;
  89.  
  90.     // Iterate over infile's scanlines
  91.     for (int i = 0; i < height; i++)
  92.     {
  93.         // Read row into pixel array
  94.         fread(image[i], sizeof(RGBTRIPLE), width, inptr);
  95.  
  96.         // Skip over padding
  97.         fseek(inptr, padding, SEEK_CUR);
  98.     }
  99.  
  100.     // Filter image
  101.     switch (filter)
  102.     {
  103.         // Blur
  104.         case 'b':
  105.             blur(height, width, image);
  106.             break;
  107.  
  108.         // Edges
  109.         case 'e':
  110.             edges(height, width, image);
  111.             break;
  112.  
  113.         // Grayscale
  114.         case 'g':
  115.             grayscale(height, width, image);
  116.             break;
  117.  
  118.         // Reflect
  119.         case 'r':
  120.             reflect(height, width, image);
  121.             break;
  122.     }
  123.  
  124.     // Write outfile's BITMAPFILEHEADER
  125.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  126.  
  127.     // Write outfile's BITMAPINFOHEADER
  128.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  129.  
  130.     // Write new pixels to outfile
  131.     for (int i = 0; i < height; i++)
  132.     {
  133.         // Write row to outfile
  134.         fwrite(image[i], sizeof(RGBTRIPLE), width, outptr);
  135.  
  136.         // Write padding at end of row
  137.         for (int k = 0; k < padding; k++)
  138.         {
  139.             fputc(0x00, outptr);
  140.         }
  141.     }
  142.  
  143.     // Free memory for image
  144.     free(image);
  145.  
  146.     // Close files
  147.     fclose(inptr);
  148.     fclose(outptr);
  149.     return 0;
  150. }
  151.  
Add Comment
Please, Sign In to add comment