Advertisement
Guest User

resize.c

a guest
Aug 3rd, 2015
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.84 KB | None | 0 0
  1. /**
  2.  * resize.c
  3.  *
  4.  * Computer Science 50
  5.  * Problem Set 4
  6.  *
  7.  * resize 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: ./copy n(scale) infile outfile\n");
  21.         return 1;
  22.     }
  23.  
  24.     if (atoi(argv[1])<0 || atoi(argv[1])>100)
  25.     {
  26.         printf("please provide a positive integer smaller or equal to 100\n");
  27.         return 5;
  28.     }
  29.     // define scale
  30.     int scale = atoi(argv[1]);
  31.  
  32.     // remember filenames
  33.     char* infile = argv[2];
  34.     char* outfile = argv[3];
  35.  
  36.     // open input file
  37.     FILE* inptr = fopen(infile, "r");
  38.     if (inptr == NULL)
  39.     {
  40.         printf("Could not open %s.\n", infile);
  41.         return 2;
  42.     }
  43.  
  44.     // open output file
  45.     FILE* outptr = fopen(outfile, "w");
  46.     if (outptr == NULL)
  47.     {
  48.         fclose(inptr);
  49.         fprintf(stderr, "Could not create %s.\n", outfile);
  50.         return 3;
  51.     }
  52.  
  53.     // read infile's BITMAPFILEHEADER
  54.     BITMAPFILEHEADER bf_inptr, bf_outptr;
  55.     fread(&bf_inptr, sizeof(BITMAPFILEHEADER), 1, inptr);
  56.  
  57.     // read infile's BITMAPINFOHEADER
  58.     BITMAPINFOHEADER bi_inptr, bi_outptr;
  59.     fread(&bi_inptr, sizeof(BITMAPINFOHEADER), 1, inptr);
  60.  
  61.     // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  62.     if (bf_inptr.bfType != 0x4d42 || bf_inptr.bfOffBits != 54 || bi_inptr.biSize != 40 ||
  63.         bi_inptr.biBitCount != 24 || bi_inptr.biCompression != 0)
  64.     {
  65.         fclose(outptr);
  66.         fclose(inptr);
  67.         fprintf(stderr, "Unsupported file format.\n");
  68.         return 4;
  69.     }
  70.  
  71.     int *inptr_padding = malloc(sizeof(int));
  72.    
  73.     *inptr_padding = (4 - (bi_inptr.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  74.  
  75.  
  76.     // updating the outfile's BITMAPINFOHEADER
  77.     bi_outptr.biWidth = bi_inptr.biWidth * scale;
  78.     bi_outptr.biHeight = bi_inptr.biHeight * scale;
  79.     int padding =  (4 - (bi_outptr.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  80.     bi_outptr.biSizeImage = ((bi_outptr.biWidth * sizeof(RGBTRIPLE)) + padding) * bi_outptr.biHeight;
  81.    
  82.     // updating the outfile's BITMAPFILEHEADER
  83.     bf_outptr.bfSize = bi_outptr.biSizeImage + 54;
  84.  
  85.  
  86.  
  87.     // write outfile's BITMAPFILEHEADER
  88.     fwrite(&bf_outptr, sizeof(BITMAPFILEHEADER), 1, outptr);
  89.  
  90.     // write outfile's BITMAPINFOHEADER
  91.     fwrite(&bi_outptr, sizeof(BITMAPINFOHEADER), 1, outptr);
  92.  
  93.     // determine padding for scanlines
  94.     // int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  95.  
  96.     // iterate over infile's scanlines
  97.     for (int i = 0, biHeight = abs(bi_inptr.biHeight); i < biHeight; i++)
  98.     {
  99.         for (int m = 0; m<scale; m++)
  100.         {
  101.             // iterate over pixels in scanline
  102.             for (int j = 0; j < bi_inptr.biWidth; j++)
  103.             {
  104.                     // temporary storage
  105.                     RGBTRIPLE triple;
  106.  
  107.                     // read RGB triple from infile
  108.                     fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  109.                 for (int k = 0; k<scale;k++)
  110.                 {
  111.  
  112.                     // write RGB triple to outfile
  113.                     fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  114.                 }
  115.             }
  116.             // padding in outfile
  117.             for (int l = 0; l < padding; l++)
  118.             {
  119.                 fputc(0x00, outptr);
  120.             }
  121.             if (m<(scale-1))
  122.             {
  123.             fseek(inptr, -(sizeof(RGBTRIPLE)*bi_inptr.biWidth), SEEK_CUR);
  124.             }
  125.         }
  126.        
  127.         // skip over padding, if any
  128.         fseek(inptr, *inptr_padding, SEEK_CUR);
  129.  
  130.         // then add it back (to demonstrate how)
  131.     }
  132.  
  133.     // close infile
  134.     fclose(inptr);
  135.  
  136.     // close outfile
  137.     fclose(outptr);
  138.  
  139.     // free inptr_padding
  140.     free(inptr_padding);
  141.  
  142.     // that's all folks
  143.     return 0;
  144. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement