Advertisement
Guest User

Untitled

a guest
Feb 28th, 2015
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.73 KB | None | 0 0
  1. /**
  2.  * copy.c
  3.  *
  4.  * Computer Science 50
  5.  * Problem Set 4
  6.  *
  7.  * Copies a BMP piece by piece, just because.
  8.  */
  9.        
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #include "bmp.h"
  15.  
  16. int main(int argc, char* argv[])
  17. {
  18.     // ensure proper usage
  19.     if (argc != 4)
  20.     {
  21.         printf("Usage: ./copy infile outfile\n");
  22.         return 1;
  23.     }
  24.  
  25.     // remember filenames
  26.     int factor = atoi(argv[1]);
  27.     char* infile = argv[2];
  28.     char* outfile = argv[3];
  29.    
  30.     if (factor <= 1 || factor >= 100)
  31.     {
  32.         printf("Please enter a factor between 1 and 100.\n");
  33.     }
  34.  
  35.     // open input file
  36.     FILE* inptr = fopen(infile, "r");
  37.     if (inptr == NULL)
  38.     {
  39.         printf("Could not open %s.\n", infile);
  40.         return 2;
  41.     }
  42.  
  43.     // open output file
  44.     FILE* outptr = fopen(outfile, "w+");
  45.     if (outptr == NULL)
  46.     {
  47.         fclose(inptr);
  48.         fprintf(stderr, "Could not create %s.\n", outfile);
  49.         return 3;
  50.     }
  51.  
  52.     // read infile's BITMAPFILEHEADER
  53.     BITMAPFILEHEADER bf;
  54.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  55.    
  56.  
  57.     // read infile's BITMxAPINFOHEADER
  58.     BITMAPINFOHEADER bi;
  59.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  60.    
  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.    
  73.     // write outfile's BITMAPFILEHEADER
  74.     //fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  75.  
  76.     // write outfile's BITMAPINFOHEADER
  77.     //fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  78.    
  79.     // determine new height    
  80.     int oldWidth = bi.biWidth;
  81.     int newWidth = oldWidth * factor;
  82.    
  83.     // determine new width
  84.     int oldHeight = bi.biHeight;
  85.     int newHeight = oldHeight * factor;
  86.  
  87.     // determine new padding
  88.     //int oldPadding =  (4 - (oldWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  89.     int newPadding =  (4 - (newWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  90.    
  91.     // image size
  92.     bi.biSizeImage = (newWidth * sizeof(RGBTRIPLE) + abs(newPadding)) * abs(newHeight);
  93.     bf.bfSize = (bi.biSizeImage) + 54;
  94.    
  95.     // write outfile's BITMAPFILEHEADER
  96.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  97.    
  98.     // write outfile's BITMAPINFOHEADER
  99.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);  
  100.  
  101.     // iterate over infile's scanlines
  102.     for (int i = 0, oldHeight = abs(newHeight); i < oldHeight; i++)
  103.    
  104.     {
  105.         // iterate over scanline factor times
  106.         for (int j = 0; j < factor; j++)
  107.         {
  108.             // iterate over pixels of scanline
  109.             for (int k = 0; k < newWidth; k++)
  110.             {
  111.                 // temporary storage
  112.                 RGBTRIPLE triple;
  113.  
  114.                 // read RGB triple from infile
  115.                 fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  116.  
  117.                 // write RGB triple to outfile
  118.                 for (int l = 0; l < factor; l++)
  119.                 fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  120.             }
  121.            
  122.             // update padding
  123.             for (int l = 0; l < newPadding; l++)
  124.                 fputc(0x00, outptr);
  125.                
  126.             // go back to the beginning of the line
  127.             if (j < factor - 1)
  128.                 fseek(inptr, (-oldWidth * sizeof(RGBTRIPLE)), SEEK_CUR);
  129.         }
  130.        
  131.         // skip over padding, if any
  132.         fseek(inptr, newPadding, SEEK_CUR);
  133.     }
  134.        
  135.  
  136.     // close infile
  137.     fclose(inptr);
  138.  
  139.     // close outfile
  140.     fclose(outptr);
  141.  
  142.     // that's all folks
  143.     return 0;
  144. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement