Advertisement
CitraDeus

Untitled

Jul 13th, 2014
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.01 KB | None | 0 0
  1. /**
  2.  * resize.c
  3.  *
  4.  * Computer Science 50
  5.  * Problem Set 5
  6.  *
  7.  * Resizes a BMP.
  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 scale infile outfile\n");
  21.         return 1;
  22.     }
  23.  
  24.     // remember filenames and scale factor
  25.     char* infile = argv[2];
  26.     char* outfile = argv[3];
  27.    
  28.     // turn the scale into an int
  29.     int scale = atoi(argv[1]);
  30.  
  31.     // open input file
  32.     FILE* inptr = fopen(infile, "r");
  33.     if (inptr == NULL)
  34.     {
  35.         printf("Could not open %s.\n", infile);
  36.         return 2;
  37.     }
  38.  
  39.     // open output file
  40.     FILE* outptr = fopen(outfile, "w");
  41.     if (outptr == NULL)
  42.     {
  43.         fclose(inptr);
  44.         fprintf(stderr, "Could not create %s.\n", outfile);
  45.         return 3;
  46.     }
  47.  
  48.     // read infile's BITMAPFILEHEADER
  49.     BITMAPFILEHEADER bf;
  50.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  51.  
  52.     // read infile's BITMAPINFOHEADER
  53.     BITMAPINFOHEADER bi;
  54.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  55.     BITMAPINFOHEADER old_bi = bi;
  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.     // update outfile's header
  68.    
  69.     printf("Old file size: %i\n", bf.bfSize);
  70.     bf.bfSize *= scale;
  71.     printf("New file size: %i\n\n", bf.bfSize);
  72.    
  73.     printf("Old image size: %i\n", bi.biSizeImage);
  74.     bi.biSizeImage *= scale;
  75.     printf("New image size: %i\n\n", bi.biSizeImage);
  76.    
  77.     printf("Old image width: %i\n", bi.biWidth);
  78.     bi.biWidth *= scale;
  79.     printf("New image width: %i\n\n", bi.biWidth);
  80.    
  81.     printf("Old image height: %i\n", bi.biHeight);
  82.     bi.biHeight *= scale;
  83.     printf("New image height: %i\n\n", bi.biHeight);
  84.    
  85.  
  86.     // write outfile's BITMAPFILEHEADER
  87.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  88.  
  89.     // write outfile's BITMAPINFOHEADER
  90.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  91.  
  92.     // determine padding for scanlines
  93.     int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  94.     int old_padding =  (4 - (old_bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  95.  
  96.     // iterate over infile's scanlines
  97.     for (int i = 0, biHeight = abs(old_bi.biHeight); i < biHeight; i++)
  98.     {
  99.         // repeat the row scale number of times
  100.         for (int m = 0; m < scale; m++)
  101.         {  
  102.             // get current position
  103.             int f_pos = ftell(inptr);
  104.             printf("%i\n", f_pos);
  105.            
  106.             // iterate over pixels in scanline
  107.             for (int j = 0; j < old_bi.biWidth; j++)
  108.             {
  109.                 // temporary storage
  110.                 RGBTRIPLE triple;
  111.  
  112.                 // read RGB triple from infile
  113.                 fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  114.  
  115.                 // write RGB triple to outfile scale number of times
  116.                 for (int k = 0; k < scale; k++)
  117.                 {
  118.                     fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  119.                 }
  120.             }
  121.  
  122.             // skip over padding, if any
  123.             fseek(inptr, old_padding, SEEK_CUR);
  124.  
  125.             // then add it back (to demonstrate how)
  126.             for (int l = 0; l < padding; l++)
  127.             {
  128.                 fputc(0x00, outptr);
  129.             }
  130.            
  131.             // go back to original line in infile
  132.             long offset = -(old_bi.biWidth * sizeof(RGBTRIPLE)) - old_padding;
  133.             fseek(inptr, offset, SEEK_CUR);
  134.            
  135.             // get current position
  136.             f_pos = ftell(inptr);
  137.             printf("%i\n", f_pos);
  138.         }  
  139.     }
  140.  
  141.     // close infile
  142.     fclose(inptr);
  143.  
  144.     // close outfile
  145.     fclose(outptr);
  146.  
  147.     // that's all folks
  148.     return 0;
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement