Advertisement
SKTLV

Untitled

Dec 17th, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.06 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "bmp.h"
  4.  
  5.  
  6. int main(int argc, char *argv[])
  7. {
  8.     if (argc != 4)  // make sure input has 3 arguments
  9.     {
  10.         printf("Usage: ./resize f infile outfile\n");
  11.         return (1);
  12.     }
  13.  
  14.     float f = atof(argv[1]);  //   The factor by which new BMP will be resized
  15.     if (f <= 0 || f > 100)
  16.     {
  17.         printf("Scaling must be > 0 and <= 100\n");
  18.         return (1);
  19.     }
  20.  
  21.     // remember filenames
  22.     char *infile = argv[2];
  23.     char *outfile = argv[3];
  24.  
  25.     // open input file
  26.     FILE *inptr = fopen(infile, "r");
  27.     if (inptr == NULL)
  28.     {
  29.         fprintf(stderr, "Could not open %s.\n", infile);
  30.         return 2;
  31.     }
  32.  
  33.     // open output file
  34.     FILE *outptr = fopen(outfile, "w");
  35.     if (outptr == NULL)
  36.     {
  37.         fclose(inptr);
  38.         fprintf(stderr, "Could not create %s.\n", outfile);
  39.         return 3;
  40.     }
  41.  
  42.     // read infile's BITMAPFILEHEADER
  43.     BITMAPFILEHEADER bf;
  44.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  45.  
  46.     // read infile's BITMAPINFOHEADER
  47.     BITMAPINFOHEADER bi;
  48.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  49.  
  50.     // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  51.     if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  52.         bi.biBitCount != 24 || bi.biCompression != 0)
  53.     {
  54.         fclose(outptr);
  55.         fclose(inptr);
  56.         fprintf(stderr, "Unsupported file format.\n");
  57.         return 4;
  58.     }
  59.  
  60.     //  Declare new BITMAPFILEHEADER and BITMAPINFOHEADER
  61.  
  62.     BITMAPFILEHEADER scaled_bf = bf;
  63.     BITMAPINFOHEADER scaled_bi = bi;
  64.  
  65.     // Scale the outptr file with the new Headers
  66.  
  67.     scaled_bi.biHeight = bi.biHeight * f;
  68.     scaled_bi.biWidth = bi.biWidth * f;
  69.  
  70.     // determine padding for infile and outfile
  71.     int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  72.     int scaled_padding = (4 - (scaled_bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  73.  
  74.     // Scale the biSizeImage of outfile
  75.     scaled_bi.biSizeImage = ((sizeof(RGBTRIPLE) * scaled_bi.biWidth) + scaled_padding) * (bi.biHeight);
  76.  
  77.     // Scale the bfSize of outfile
  78.     scaled_bf.bfSize = scaled_bi.biSizeImage + 54;
  79.  
  80.     // -------- FINISHED SCALING THE HEADRS --------------
  81.  
  82.     // Write the outfile new HEADERS/ FILE & INFO
  83.  
  84.     // write outfile's BITMAPFILEHEADER
  85.     fwrite(&scaled_bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  86.  
  87.     // write outfile's BITMAPINFOHEADER
  88.     fwrite(&scaled_bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  89.  
  90.    //  ----------   Start iterating the infile and write to outfile   ------------------
  91.  
  92.     // iterate over infile's lines
  93.     for (int i = 0; i < bi.biHeight; i++)
  94.     {
  95.         // execute every line f times
  96.  
  97.         for (int newLines = 0; newLines < f; newLines++)
  98.  
  99.         {
  100.             // temporary storage
  101.             RGBTRIPLE triple;
  102.  
  103.              // iterate over  all the pixels in the line in the infile
  104.             for (int j = 0; j < bi.biWidth; j++)
  105.             {
  106.  
  107.             // read a pixel at the position
  108.             fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  109.  
  110.                 for (int t = 0; t < f; t++)  // write every pixel of infile f times to outfile
  111.                 {
  112.                 // write RGB triple to outfile
  113.                 fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  114.                 }
  115.  
  116.             } // end of reading and writing single line from infile to outfile
  117.  
  118.  
  119.  
  120.             //reset the pointer of the infile to the beginning of the line
  121.             fseek(inptr, (-bi.biWidth*3), SEEK_CUR);  // movinv back from end is in bytes hence (minus) -bi.width*3
  122.  
  123.             // then add it back (to demonstrate how)
  124.             for (int k = 0; k < scaled_padding; k++)
  125.             {
  126.                 fputc(0x00, outptr);
  127.             }
  128.  
  129.         } // end of writing new line f times to outfile
  130.  
  131.         // skip over padding, if any
  132.             fseek(inptr, padding, SEEK_CUR);
  133.  
  134.  
  135.     }  //  end of iterating infile line
  136.  
  137.     // close infile
  138.     fclose(inptr);
  139.  
  140.     // close outfile
  141.     fclose(outptr);
  142.  
  143.     // success
  144.     return 0;
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement