Advertisement
Guest User

Untitled

a guest
Oct 24th, 2019
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.84 KB | None | 0 0
  1. // Copies a BMP file
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "bmp.h"
  7.  
  8. int main(int argc, char *argv[])
  9. {
  10.     // ensure proper usage
  11.     if (argc != 4)
  12.     {
  13.         fprintf(stderr, "Usage: ./resize n infile outfile\n");
  14.         return 1;
  15.     }
  16.  
  17.     // remember filenames
  18.     char *N = argv[1];
  19.     char *infile = argv[2];
  20.     char *outfile = argv[3];
  21.  
  22.     // convert string to integer
  23.     int n = atoi(N);
  24.  
  25.  
  26.     if(n < 0 || n > 100)
  27.     {
  28.         fprintf(stderr, "Usage: ./resize n infile outfile\n");
  29.         return 1;
  30.     }
  31.  
  32.     // open input file
  33.     FILE *inptr = fopen(infile, "r");
  34.     if (inptr == NULL)
  35.     {
  36.         fprintf(stderr, "Could not open %s.\n", infile);
  37.         return 2;
  38.     }
  39.  
  40.     // open output file
  41.     FILE *outptr = fopen(outfile, "w");
  42.     if (outptr == NULL)
  43.     {
  44.         fclose(inptr);
  45.         fprintf(stderr, "Could not create %s.\n", outfile);
  46.         return 3;
  47.     }
  48.  
  49.     // read infile's BITMAPFILEHEADER
  50.     BITMAPFILEHEADER bf;
  51.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  52.  
  53.     // read infile's BITMAPINFOHEADER
  54.     BITMAPINFOHEADER bi;
  55.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  56.  
  57.     // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  58.     if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  59.         bi.biBitCount != 24 || bi.biCompression != 0)
  60.     {
  61.         fclose(outptr);
  62.         fclose(inptr);
  63.         fprintf(stderr, "Unsupported file format.\n");
  64.         return 4;
  65.     }
  66.  
  67.     // determine new dimensions
  68.     int oldWidth = bi.biWidth;
  69.     int oldHeight = bi.biHeight;
  70.     int newWidth = oldWidth * n;
  71.     int newHeight = oldHeight * n;
  72.  
  73.     // determine padding for scanlines
  74.     int inPadding  = (4 - (oldWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  75.     int outPadding  = (4 - (newWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  76.  
  77.     printf("oldwidth is %i\n", oldWidth);
  78.     printf("newwidth is %i\n", newWidth);
  79.     printf("oldheight is %i\n", oldHeight);
  80.     printf("newheight is %i\n", newHeight);
  81.     printf("oldpadding value is %i\n", inPadding);
  82.     printf("newpadding value is %i\n ", outPadding);
  83.  
  84.     // reconfigure headers
  85.     bi.biHeight = newHeight;
  86.     bi.biWidth = newWidth;
  87.     bi.biSizeImage = ((sizeof(RGBTRIPLE) * newWidth) + outPadding) * abs(newHeight);
  88.     bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  89.  
  90.     // write outfile's BITMAPFILEHEADER
  91.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  92.  
  93.     // write outfile's BITMAPINFOHEADER
  94.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  95.  
  96.  
  97.     // iterate over infile's scanlines
  98.     for (int i = 0, biHeight = abs(oldHeight); i < biHeight; i++)
  99.     {
  100.         RGBTRIPLE buffer[newWidth];
  101.         RGBTRIPLE* current = &buffer[0]; //current starts pointing to buffer[0]
  102.  
  103.         // iterate over pixels in scanline (Horizontally)
  104.         for (int j = 0; j < oldWidth; j++)
  105.         {
  106.             RGBTRIPLE triple;
  107.  
  108.             // read RGB triple from infile
  109.             fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  110.  
  111.             // write RGB triple to ARRAY
  112.             for (int k = 0; k < n; k++)
  113.             {
  114.                 *current = triple; // triple will store into *current address
  115.                 current++; // the pointer will point to the next address in buffer
  116.             }
  117.         }
  118.  
  119.         // Write scanline n times to output
  120.         for (int l=0; l<n; l++){
  121.  
  122.             fwrite(&buffer, sizeof(buffer), 1, outptr);  // Write array to outfile
  123.  
  124.             for (int k = 0; k < outPadding; k++)
  125.             {
  126.                 fputc(0x00, outptr);
  127.             }
  128.  
  129.         }
  130.         // skip over padding, if any
  131.         fseek(inptr, inPadding, SEEK_CUR);
  132.  
  133.     }
  134.  
  135.     // close infile
  136.     fclose(inptr);
  137.  
  138.     // close outfile
  139.     fclose(outptr);
  140.  
  141.     // success
  142.     return 0;
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement