Advertisement
DragonOsman

CS50 Pset4 Resize

Oct 30th, 2016
332
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.35 KB | None | 0 0
  1. /**
  2.  * resize.c
  3.  *
  4.  * Computer Science 50
  5.  * Problem Set 4
  6.  *
  7.  * Resizes the file whose name is passed to it as a commandline argument.
  8.  */
  9.        
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12.  
  13. #include "bmp.h"
  14.  
  15. int main(int argc, char* argv[])
  16. {
  17.     // ensure proper usage
  18.     if (argc != 4)
  19.     {
  20.         printf("Usage: ./resize n infile outfile\n");
  21.         return 1;
  22.     }
  23.  
  24.     // remember filenames
  25.     char* infile = argv[2];
  26.     char* outfile = argv[3];
  27.    
  28.     // change n into a number so we can use it as such
  29.     int n = atoi(argv[1]);
  30.    
  31.     if (n <= 0 || n > 100)
  32.     {
  33.         printf("The value provided as the size must be that of a positive integer less than or equal to 100!\n");
  34.         return 2;
  35.     }
  36.  
  37.     // open input file
  38.     FILE* inptr = fopen(infile, "r");
  39.     if (inptr == NULL)
  40.     {
  41.         printf("Could not open %s.\n", infile);
  42.         return 3;
  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 4;
  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.     // remember the old padding
  73.     int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  74.    
  75.     // remember dimensions of original image
  76.     int img_height = bi.biHeight;
  77.     int img_width = bi.biWidth;
  78.    
  79.     // calculate dimensions of resized image
  80.     bi.biHeight *= n;
  81.     bi.biWidth *= n;
  82.     int resized_height = bi.biHeight;
  83.     int resized_width = bi.biWidth;
  84.    
  85.     // determine scanline padding
  86.     int new_padding = (4 - (resized_width * sizeof(RGBTRIPLE)) % 4) % 4;
  87.    
  88.     // update header info
  89.     bi.biSizeImage = ((resized_width * sizeof(RGBTRIPLE) + new_padding) * abs(resized_height));
  90.     bf.bfSize = bi.biSizeImage + (sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER));
  91.  
  92.     // write outfile's BITMAPFILEHEADER
  93.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  94.  
  95.     // write outfile's BITMAPINFOHEADER
  96.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  97.  
  98.     // iterate over infile's scanlines
  99.     for (int i = 0, biHeight = abs(img_height); i < biHeight; i++)
  100.     {
  101.         // iterate over pixels in scanline
  102.         for (int j = 0; j < img_width; j++)
  103.         {
  104.             // temporary storage
  105.             RGBTRIPLE triple;
  106.            
  107.             // read RGB triple from infile
  108.             fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  109.            
  110.             for (int index = 0; index <= n - 1; index++)
  111.             {
  112.                 fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  113.             }
  114.         }
  115.         for (int k = 0; k < new_padding; k++)
  116.         {
  117.             fputc(0x00, outptr);
  118.         }
  119.         fseek(inptr, padding, SEEK_CUR);
  120.        
  121.         // send infile cursor back
  122.         // before reading the next RGBTRIPLE data
  123.         long offset = img_width * sizeof(RGBTRIPLE);
  124.         fseek(inptr, - 1 * offset, SEEK_CUR);
  125.        
  126.         // vertical resize
  127.         // for each row
  128.         for (int l = 0; l < biHeight; l++)
  129.         {
  130.             // temporary storage for triples data
  131.             RGBTRIPLE triple;
  132.            
  133.             int m;
  134.            
  135.             for (int iii = 0; iii < n - 1; iii++)
  136.             {
  137.                 for (m = 0; m < img_width; m++)
  138.                 {
  139.                     // read triples data from infile
  140.                     fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  141.                    
  142.                     // for n - 1 times:
  143.                         // write pixels and padding to outfile:
  144.                     for (int index = 0; index < n; index++)
  145.                     {
  146.                         // write pixels to outfile
  147.                         fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  148.                     }
  149.                 }
  150.                 // write padding to outfile
  151.                 for (int k = 0; k < new_padding; k++)
  152.                 {
  153.                     fputc(0x00, outptr);
  154.                 }
  155.                
  156.                 // send infile cursor back
  157.                 fseek(inptr, -1 * (offset * m), SEEK_CUR);
  158.             }
  159.             // write pixels and padding to outfile
  160.             // skip over infile padding:
  161.             for (m = 0; m < img_width; m++)
  162.             {
  163.                 fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  164.                    
  165.                 for (int index = 0; index < n; index++)
  166.                 {
  167.                     fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  168.                 }
  169.             }
  170.             for (int k = 0; k < new_padding; k++)
  171.             {
  172.                 fputc(0x00, outptr);
  173.             }
  174.             fseek(inptr, padding, SEEK_CUR);
  175.         }
  176.     }
  177.  
  178.     // close infile
  179.     fclose(inptr);
  180.  
  181.     // close outfile
  182.     fclose(outptr);
  183.  
  184.     // that's all folks
  185.     return 0;
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement