Guest User

resize.c

a guest
Aug 16th, 2016
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.27 KB | None | 0 0
  1. /**********************************************************
  2.  * resize.c                                               *
  3.  *                                                        *
  4.  * Made by Husam Malakwi                                  *                    
  5.  *                                                        *
  6.  * This program risizes bmp files.                        *
  7.  *                                                        *
  8.  **********************************************************/
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12.  
  13. #include "bmp.h"
  14. #include "helper.h"
  15.  
  16. // prototypes
  17. void create_new_file(char* infile, char* outfile);
  18. void edit_file_header(int scale);
  19. void draw_image(int scale);
  20.  
  21. // struct that contains FILE* for input/output files
  22. ioptrs ioptr;
  23. // struct that contains both padding values
  24. pad padding;
  25.  
  26. // sruct that contain file header info
  27. BITMAPFILEHEADER bf;
  28. BITMAPINFOHEADER bi;
  29.  
  30. int main(int argc, char* argv[])
  31. {
  32.     // ensure proper use
  33.     if(argc != 4)
  34.     {
  35.         printf("Usage ./resize n infile outfile\n");
  36.         return 1;
  37.     }
  38.      
  39.     // store the scale factor "scale"
  40.     int scale = atoi(argv[1]);
  41.    
  42.     // checks if the value is in range
  43.     if (scale <= 0 || scale > 100)
  44.     {
  45.         printf("invalid number");
  46.         return 2;
  47.     }
  48.      
  49.     // remember filenames
  50.     char* infile = argv[2];
  51.     char* outfile = argv[3];
  52.      
  53.     create_new_file(infile, outfile);
  54.     edit_file_header(scale);
  55.     draw_image(scale);
  56.    
  57.     // close infile
  58.     fclose(ioptr.inptr);
  59.    
  60.     //close outfile
  61.     fclose(ioptr.outptr);
  62.    
  63.     return 0;
  64. }
  65.  
  66. /*********************************************************************************
  67.  * create_new_file: This function opens the infile for readin and creates an     *
  68.  *                  outfile for writing the new data according to the names      *
  69.  *                  specified by the user.                                       *
  70.  *                                                                               *
  71.  *********************************************************************************/
  72. void create_new_file(char* infile, char* outfile)
  73. {
  74.     // open input file
  75.     ioptr.inptr = fopen(infile, "r");
  76.     if (ioptr.inptr == NULL)
  77.     {
  78.         printf("could not open %s.\n", infile);
  79.         exit(3);
  80.     }
  81.      
  82.     // open output file
  83.     ioptr.outptr = fopen(outfile, "w");
  84.     if (ioptr.outptr == NULL)
  85.     {
  86.         fclose(ioptr.inptr);
  87.         fprintf(stderr, "could not create %s.\n", outfile);
  88.         exit(4);
  89.     }
  90. }
  91.  
  92. /*********************************************************************************
  93.  * edit_file_header: This function reads the old value if the BITMAPFILEHEADER   *
  94.  *                   and edits it according to the scale factor specified by the *
  95.  *                   user.                                                       *
  96.  *                                                                               *
  97.  *********************************************************************************/
  98.  
  99. void edit_file_header(int scale)
  100. {
  101.     // read the infile's BITMAPFILEHEADER
  102.     fread (&bf, sizeof(BITMAPFILEHEADER), 1, ioptr.inptr);
  103.  
  104.     // read the infile's BITMAPINFOHEADER
  105.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, ioptr.inptr);
  106.  
  107.     // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  108.     if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  109.         bi.biBitCount != 24 || bi.biCompression != 0)
  110.     {
  111.         fclose(ioptr.outptr);
  112.         fclose(ioptr.inptr);
  113.         printf("invalid file type\n");
  114.         exit(5);
  115.     }
  116.  
  117.     // determing the original padding value
  118.     padding.oldPadding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  119.     // determine the new padding value
  120.     padding.newPadding =  (4 - ((bi.biWidth * scale) * sizeof(RGBTRIPLE)) % 4) % 4;
  121.  
  122.     // Edits the header file according to the scale
  123.     bi.biWidth *= scale;
  124.     bi.biHeight *= scale;
  125.     bi.biSizeImage = (bi.biWidth * sizeof(RGBTRIPLE) + padding.newPadding) *
  126.                       abs(bi.biHeight);
  127.     bf.bfSize = bi.biSizeImage + 54;
  128.  
  129.     // write outfile's BITMAPFILEHEADER
  130.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, ioptr.outptr);
  131.  
  132.     // write oufile's BITMAPINFOHEADER
  133.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, ioptr.outptr);
  134. }
  135.  
  136. /*********************************************************************************
  137.  * draw_image: This function scan pixels from the infile and then it writes an   *
  138.  *             edited version of the pixels and padding according to the scale   *
  139.  *             factor specified by the user.                                     *
  140.  *                                                                               *
  141.  *********************************************************************************/
  142.  
  143. void draw_image(int scale)
  144. {
  145.     //iterate over infile's scan lines "/ scale" is used to get teh original value of biHeight.
  146.     for(int i = 0, biHeight = abs(bi.biHeight / scale); i < biHeight; i++)
  147.     {
  148.         //writes the line * scale factor
  149.         for (int m = 0; m < scale; m++)
  150.         {
  151.             // iterate over pixels in scanline
  152.             for(int j = 0; j < (bi.biWidth / scale); j++)
  153.             {
  154.                 //temporary storage
  155.                 RGBTRIPLE triple;
  156.  
  157.                 //read RGB triple from infile
  158.                 fread(&triple, sizeof(RGBTRIPLE), 1, ioptr.inptr);
  159.  
  160.                 // write RGB triple to outfile * the scale factor
  161.                 fwrite(&triple, sizeof(RGBTRIPLE), scale, ioptr.outptr);
  162.             }
  163.  
  164.             // skip over padding if any
  165.             fseek(ioptr.inptr, padding.oldPadding, SEEK_CUR);
  166.  
  167.             // write the new padding
  168.             for(int k = 0; k < padding.newPadding; k++)
  169.             {
  170.                 fputc(0x00, ioptr.outptr);
  171.             }
  172.         }
  173.     }
  174. }
  175. /*************************************************************************************************************************************/
  176. /**
  177.  * bmp.h
  178.  *
  179.  * Computer Science 50
  180.  * Problem Set 4
  181.  *
  182.  * BMP-related data types based on Microsoft's own.
  183.  */
  184.  
  185. #include <stdint.h>
  186.  
  187. /**
  188.  * Common Data Types
  189.  *
  190.  * The data types in this section are essentially aliases for C/C++
  191.  * primitive data types.
  192.  *
  193.  * Adapted from http://msdn.microsoft.com/en-us/library/cc230309.aspx.
  194.  * See http://en.wikipedia.org/wiki/Stdint.h for more on stdint.h.
  195.  */
  196. typedef uint8_t  BYTE;
  197. typedef uint32_t DWORD;
  198. typedef int32_t  LONG;
  199. typedef uint16_t WORD;
  200.  
  201. /**
  202.  * BITMAPFILEHEADER
  203.  *
  204.  * The BITMAPFILEHEADER structure contains information about the type, size,
  205.  * and layout of a file that contains a DIB [device-independent bitmap].
  206.  *
  207.  * Adapted from http://msdn.microsoft.com/en-us/library/dd183374(VS.85).aspx.
  208.  */
  209. typedef struct
  210. {
  211.     WORD   bfType;
  212.     DWORD  bfSize;
  213.     WORD   bfReserved1;
  214.     WORD   bfReserved2;
  215.     DWORD  bfOffBits;
  216. } __attribute__((__packed__))
  217. BITMAPFILEHEADER;
  218.  
  219. /**
  220.  * BITMAPINFOHEADER
  221.  *
  222.  * The BITMAPINFOHEADER structure contains information about the
  223.  * dimensions and color format of a DIB [device-independent bitmap].
  224.  *
  225.  * Adapted from http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx.
  226.  */
  227. typedef struct
  228. {
  229.     DWORD  biSize;
  230.     LONG   biWidth;
  231.     LONG   biHeight;
  232.     WORD   biPlanes;
  233.     WORD   biBitCount;
  234.     DWORD  biCompression;
  235.     DWORD  biSizeImage;
  236.     LONG   biXPelsPerMeter;
  237.     LONG   biYPelsPerMeter;
  238.     DWORD  biClrUsed;
  239.     DWORD  biClrImportant;
  240. } __attribute__((__packed__))
  241. BITMAPINFOHEADER;
  242.  
  243. /**
  244.  * RGBTRIPLE
  245.  *
  246.  * This structure describes a color consisting of relative intensities of
  247.  * red, green, and blue.
  248.  *
  249.  * Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx.
  250.  */
  251. typedef struct
  252. {
  253.     BYTE  rgbtBlue;
  254.     BYTE  rgbtGreen;
  255.     BYTE  rgbtRed;
  256. } __attribute__((__packed__))
  257. RGBTRIPLE;
  258. /*************************************************************************************************************************************/
  259. /**
  260.  * helper.h
  261.  *
  262.  * Husam Malkawi
  263.  *
  264.  * This contains structures that help resize.c
  265.  */
  266.  
  267. typedef struct
  268.  {
  269.     FILE* inptr;
  270.     FILE* outptr;
  271.  }
  272.  ioptrs;
  273.  
  274.  typedef struct
  275.  {
  276.     int oldPadding;
  277.     int newPadding;
  278.  }
  279.  pad;
Advertisement
Add Comment
Please, Sign In to add comment