Advertisement
Guest User

resize.c

a guest
Jun 22nd, 2018
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.64 KB | None | 0 0
  1. // resizes bmp file
  2.  
  3. #include <math.h>
  4. #include <stdio.h>
  5. #include <stdlib.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.  
  18.     int n = atoi(argv[1]);
  19.  
  20.     // ensure n is positive and no more than 100
  21.     if (n > 100 || n < 1)
  22.     {
  23.         fprintf(stderr, "n must be a positive integer less than or equal to 100\n");
  24.         return 1;
  25.     }
  26.  
  27.     // remember filenames
  28.     char *infile = argv[2];
  29.     char *outfile = argv[3];
  30.  
  31.     // open input file
  32.     FILE *inptr = fopen(infile, "r");
  33.     if (inptr == NULL)
  34.     {
  35.         fprintf(stderr, "Could not open %s.\n", infile);
  36.         return 1;
  37.     }
  38.  
  39.     // open output file
  40.     FILE *outptr = fopen(outfile, "w");
  41.     if (outptr == NULL)
  42.     {
  43.         fclose(inptr);
  44.         fprintf(stderr, "Could not create %s.\n", outfile);
  45.         return 1;
  46.     }
  47.  
  48.     // read infile's BITMAPFILEHEADER
  49.     BITMAPFILEHEADER bf;
  50.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  51.  
  52.     // read infile's BITMAPINFOHEADER
  53.     BITMAPINFOHEADER bi;
  54.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  55.  
  56.     // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  57.     if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  58.         bi.biBitCount != 24 || bi.biCompression != 0)
  59.     {
  60.         fclose(outptr);
  61.         fclose(inptr);
  62.         fprintf(stderr, "Unsupported file format.\n");
  63.         return 4;
  64.     }
  65.  
  66.      // stores infiles' dimensions
  67.     int inHeight = bi.biHeight;
  68.     int inWidth = bi.biWidth;
  69.  
  70.     // update the dimensions of the image
  71.     bi.biHeight = bi.biHeight * n;
  72.     bi.biWidth = bi.biWidth * n;
  73.  
  74.     // determine padding for scanlines
  75.     int out_padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  76.     int in_padding = (4 - (inWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  77.  
  78.     // update the size of the image
  79.     bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + ((bi.biWidth * abs(bi.biHeight)) * sizeof(RGBTRIPLE)) + out_padding;
  80.  
  81.     // write outfile's BITMAPFILEHEADER
  82.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  83.  
  84.     // write outfile's BITMAPINFOHEADER
  85.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  86.  
  87.     // iterate over infile's scanlines
  88.     for (int i = 0, Height = abs(inHeight); i < Height; i++)
  89.     {
  90.         // write n scanlines to outfile per scanline on infile
  91.         for (int m = 0; m < n; m++)
  92.         {
  93.             // iterate over pixels in infile's scanline
  94.             for (int j = 0; j < inWidth; j++)
  95.             {
  96.                 // temporary storage
  97.                 RGBTRIPLE triple;
  98.  
  99.                 // read RGB triple from infile
  100.                 fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  101.  
  102.                 // write RGB triple to outfile n times
  103.                 for (int l = 0; l < n; l++)
  104.                 {
  105.                     fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  106.                 }
  107.             }
  108.  
  109.             // change offset to the beginning of scanline if this isn't the last iteration of the loop
  110.             if (m != n - 1)
  111.             {
  112.                 fseek(inptr, (inWidth * sizeof(RGBTRIPLE)) * -1, SEEK_CUR);
  113.             }
  114.  
  115.             // add the padding on outfile
  116.             for (int k = 0; k < out_padding; k++)
  117.             {
  118.                 fputc(0x00, outptr);
  119.             }
  120.         }
  121.  
  122.         // skip over padding on infile
  123.         fseek(inptr, in_padding, SEEK_CUR);
  124.     }
  125.  
  126.     // close infile
  127.     fclose(inptr);
  128.  
  129.     // close outfile
  130.     fclose(outptr);
  131.  
  132.     // success
  133.     return 0;
  134. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement