SKTLV

CS50 pset3 resize

Dec 13th, 2019
139
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "bmp.h"
  4.  
  5. int sizeOf();
  6.  
  7. int main(int argc, char *argv[])
  8. {
  9.  
  10.     if (argc != 4)  // make sure input has 3 arguments
  11.     {
  12.         printf("Usage: ./resize f infile outfile\n");
  13.         return (1);
  14.     }
  15.  
  16.     double f = atof(argv[1]);
  17.     if (f <= 0 || f > 100)
  18.     {
  19.         printf("First argument must be 0-100\n");
  20.         return (1);
  21.     }
  22.     // remember filenames
  23.     char *infile = argv[2];
  24.     char *outfile = argv[3];
  25.     //                              end of user input
  26.     //----------------------------------------------------------
  27.  
  28.     // open input file
  29.     FILE *inptr = fopen(infile, "r");
  30.  
  31.     if (inptr == NULL)
  32.     {
  33.         fclose(inptr);
  34.         fprintf(stderr, "Could not open %s.\n", infile);
  35.         return 2;
  36.     }
  37.  
  38.     // open output file
  39.     FILE *outptr = fopen(outfile, "w");
  40.     if (outptr == NULL)
  41.     {
  42.         fclose(inptr);
  43.         fprintf(stderr, "Could not create %s.\n", outfile);
  44.         return 3;
  45.     }
  46.  
  47.     // read infile's BITMAPFILEHEADER
  48.  
  49.     BITMAPFILEHEADER bf;
  50.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  51.  
  52.     // read infile's BITMAPINFOHEADER
  53.  
  54.     BITMAPINFOHEADER bi;
  55.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  56.  
  57.     // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  58.  
  59.     if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  60.         bi.biBitCount != 24 || bi.biCompression != 0)
  61.     {
  62.         fclose(outptr);
  63.         fclose(inptr);
  64.         fprintf(stderr, "Unsupported file format.\n");
  65.         return 4;
  66.     }
  67.  
  68.     // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ here we start manipulating the image  ++++++++++++++
  69.     // determine padding for scanlines - general formula
  70.     int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  71.  
  72.     //  Declare new HEADER FILE & INFO for the scaled file and initialize it with old picture value
  73.     //  so we can manipulate it
  74.  
  75.     BITMAPFILEHEADER scaled_bf = bf;
  76.     BITMAPINFOHEADER scaled_bi = bi;
  77.  
  78.     //  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ scaling the BitMapInfoHeader
  79.  
  80.     scaled_bi.biHeight *= f;
  81.     scaled_bi.biWidth *= f;
  82.  
  83.      // after resizing bi.biwidth, we update the padding formula with the new bi.biwidth
  84.  
  85.     int scaled_Padding = (4 - (scaled_bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  86.  
  87.     // now that we have new Padding, we can change the sizeimage in the BITMAPINFOHEADER
  88.  
  89.     scaled_bi.biSizeImage = ((sizeof(RGBTRIPLE) * scaled_bi.biWidth) + scaled_Padding) * abs(scaled_bi.biHeight);
  90.  
  91.     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Scaling the BITMAPFILEHEADER
  92.  
  93.     scaled_bf.bfSize = scaled_bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  94.  
  95.     //  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++  Writing the new Headers of the Scaled File
  96.  
  97.     RGBTRIPLE scan[scaled_bi.biWidth];
  98.  
  99.     // write outfile's BITMAPFILEHEADER
  100.     // determine padding for scanlines - general formula
  101.     fwrite(&scaled_bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  102.  
  103.     // write outfile's BITMAPINFOHEADER
  104.     fwrite(&scaled_bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  105.  
  106. //  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ resizing the pixels
  107.  
  108.  
  109.     // iterate over ROW (the original picture)
  110.     for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
  111.     {
  112.         // iterate over pixels in Lines of original Picture
  113.         for (int j = 0; j < bi.biWidth; j++)
  114.         {
  115.             // temporary storage
  116.             RGBTRIPLE triple;
  117.  
  118.             // read RGB triple from infile
  119.             fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  120.  
  121.             // write RGB triple to outfile
  122.             fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr); // Here it duplicate every pixel f times
  123.         }
  124.  
  125.         // skip over padding, if any
  126.         fseek(inptr, padding, SEEK_CUR);
  127.  
  128.         // then add it back (to demonstrate how)
  129.         for (int k = 0; k < scaled_Padding; k++) //  here it adds the new padding if needed
  130.         {
  131.             fputc(0x00, outptr);
  132.         }
  133.     }
  134.  
  135.     // close infile
  136.     fclose(inptr);
  137.  
  138.     // close outfile
  139.     fclose(outptr);
  140.  
  141.     // success
  142.     return 0;
  143.  
  144. }  // main
RAW Paste Data