Advertisement
Guest User

Untitled

a guest
May 25th, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.23 KB | None | 0 0
  1. // Copies a BMP file
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6.  
  7. #include "bmp.h"
  8.  
  9. int main(int argc, char *argv[])
  10. {
  11.     // ensure proper usage
  12.     if (argc != 4)
  13.     {
  14.         fprintf(stderr, "Usage: ./resize n infile outfile\n");
  15.         return 1;
  16.     }
  17.     if (isdigit(argv[1][0]) == 0)
  18.     {
  19.  
  20.         fprintf(stderr, "n is not an integer\n");
  21.         return 1;
  22.     }
  23.  
  24.     int n = atoi(argv[1]);
  25.     printf("Scaling factor is: %i\n", n);
  26.  
  27.     if (n < 1 || n > 100)
  28.     {
  29.         fprintf(stderr, "1 < n < 101\n");
  30.         return 1;
  31.     }
  32.  
  33.     // remember filenames
  34.     char *infile = argv[2];
  35.     char *outfile = argv[3];
  36.  
  37.     // open input file
  38.     FILE *inptr = fopen(infile, "r");
  39.     if (inptr == NULL)
  40.     {
  41.         fprintf(stderr, "Could not open %s.\n", infile);
  42.         return 2;
  43.     }
  44.  
  45.     // open output file
  46.     FILE *outptr = fopen(outfile, "w");
  47.     if (outptr == NULL)
  48.     {
  49.         fclose(inptr);
  50.         fprintf(stderr, "Could not create %s.\n", outfile);
  51.         return 3;
  52.     }
  53.  
  54.     // read infile's BITMAPFILEHEADER
  55.     BITMAPFILEHEADER bf;
  56.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  57.  
  58.     // read infile's BITMAPINFOHEADER
  59.     BITMAPINFOHEADER bi;
  60.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  61.  
  62.     // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  63.     if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  64.         bi.biBitCount != 24 || bi.biCompression != 0)
  65.     {
  66.         fclose(outptr);
  67.         fclose(inptr);
  68.         fprintf(stderr, "Unsupported file format.\n");
  69.         return 4;
  70.     }
  71.  
  72.     // stores initial header and file values
  73.     int biWidth0 = bi.biWidth;
  74.     int biHeight0 = bi.biHeight;
  75.     int padding0 = (4 - ((biWidth0) * sizeof(RGBTRIPLE)) % 4) % 4;
  76.     int biSizeImage0 = ((sizeof(RGBTRIPLE) * biWidth0) + padding0) * abs(biHeight0);
  77.     int bfSize0 = biSizeImage0 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  78.  
  79.     // makes an update of header and file values
  80.     bi.biWidth *= n;
  81.     bi.biHeight *= n;
  82.     int padding = (4 - ((bi.biWidth) * sizeof(RGBTRIPLE)) % 4) % 4;
  83.     bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + padding) * abs(bi.biHeight);
  84.     bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  85.  
  86.     // write outfile's BITMAPFILEHEADER
  87.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  88.  
  89.     // write outfile's BITMAPINFOHEADER
  90.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  91.  
  92.     // iterate over infile's scanlines
  93.     for (int i = 0; i < abs(biHeight0); i++)
  94.     {
  95.         // iterate over rows
  96.         for (int r = 0 ; r < n - 1; r++)
  97.         {
  98.             // iterate over pixels in scanline
  99.             for (int j = 0; j < biWidth0; j++)
  100.             {
  101.                 // temporary storage
  102.                 RGBTRIPLE triple;
  103.  
  104.                 // read RGB triple from infile
  105.                 fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  106.  
  107.                 // attempts to resize horizontally
  108.                 for (int k = 0; k < n; k++)
  109.                 {
  110.                     fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  111.                 }
  112.             }
  113.             // adds padding to outfile
  114.             for (int q = 0; q < padding; q++)
  115.             {
  116.                 fputc(0x00, outptr);
  117.             }
  118.             // sends infile cursor to the start of scanline
  119.             fseek(inptr, -(biWidth0)*sizeof(RGBTRIPLE), SEEK_CUR);
  120.         }
  121.  
  122.         // one last step in vertical scaling
  123.         for (int a = 0; a < biWidth0; a++)
  124.         {
  125.             // temporary storage
  126.             RGBTRIPLE triple;
  127.             // read RGB triple from infile
  128.             fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  129.  
  130.             // attempts to resize horizontally
  131.             for (int b = 0; b < n; b++)
  132.             {
  133.                 fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  134.             }
  135.         }
  136.         // adds padding to outfile
  137.         for (int c = 0; c < padding; c++)
  138.         {
  139.             fputc(0x00, outptr);
  140.         }
  141.         // skip over padding, if any
  142.         fseek(inptr, padding0, SEEK_CUR);
  143.     }
  144.  
  145.     // close infile
  146.     fclose(inptr);
  147.  
  148.     // close outfile
  149.     fclose(outptr);
  150.  
  151.     // success
  152.     return 0;
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement