Advertisement
cs-lazaro

Untitled

Sep 7th, 2017
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.95 KB | None | 0 0
  1. /**
  2.  * Copies a BMP piece by piece, just because.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7.  
  8. #include "bmp.h"
  9.  
  10. int main(int argc, char *argv[])
  11. {
  12.     // ensure proper usage
  13.     if (argc != 4)
  14.     {
  15.         fprintf(stderr, "Usage: ./resize k infile outfile\n");
  16.         return 1;
  17.     }
  18.  
  19.     // remember filenames
  20.     int factor = atoi(argv[1]);
  21.     char *infile = argv[2];
  22.     char *outfile = argv[3];
  23.  
  24.     // open input file
  25.     FILE *inptr = fopen(infile, "r");
  26.     if (inptr == NULL)
  27.     {
  28.         fprintf(stderr, "Could not open %s.\n", infile);
  29.         return 2;
  30.     }
  31.  
  32.     // open output file
  33.     FILE *outptr = fopen(outfile, "w");
  34.     if (outptr == NULL)
  35.     {
  36.         fclose(inptr);
  37.         fprintf(stderr, "Could not create %s.\n", outfile);
  38.         return 3;
  39.     }
  40.  
  41.     // read infile's BITMAPFILEHEADER
  42.     BITMAPFILEHEADER bf;
  43.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  44.  
  45.     // read infile's BITMAPINFOHEADER
  46.     BITMAPINFOHEADER bi;
  47.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  48.  
  49.  
  50.     // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  51.     if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  52.         bi.biBitCount != 24 || bi.biCompression != 0)
  53.     {
  54.         fclose(outptr);
  55.         fclose(inptr);
  56.         fprintf(stderr, "Unsupported file format.\n");
  57.         return 4;
  58.     }
  59.  
  60.  
  61.     int padding_old = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  62.  
  63.     //debugging (although not necessary 'cause there's )
  64.     printf("biWidth = %d \nbiHeight = %d \nbiSizeImage = %d \nbfSize = %d \n", bi.biWidth, bi.biHeight, bi.biSizeImage, bf.bfSize);
  65.  
  66.     //increasing height and width by factor
  67.     bi.biWidth *= factor;
  68.     bi.biHeight *= factor;
  69.  
  70.     //calculating padding from new width
  71.     int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  72.  
  73.     //calculating new sizes for headings
  74.     bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + padding) * abs(bi.biHeight);
  75.     bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  76.  
  77.     //just for debugging:
  78.     printf("biWidth = %d \nbiHeight = %d \nbiSizeImage = %d \nbfSize = %d \npadding_old = %d \npadding_new = %d \n", bi.biWidth, bi.biHeight, bi.biSizeImage, bf.bfSize, padding_old, padding);
  79.  
  80.  
  81.     // write outfile's BITMAPFILEHEADER
  82.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  83.  
  84.     // write outfile's BITMAPINFOHEADER
  85.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  86.  
  87.  
  88.     // determine padding for scanlines (OBSOLETE)
  89.     // int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  90.  
  91.     // iterate over infile's scanlines
  92.     for (int i = 0, biHeight = abs(bi.biHeight); i < (biHeight / factor); i++)
  93.     {
  94.         // iterate over pixels in scanline
  95.         for (int l = 0; l < factor; l++)
  96.         {
  97.             //resize vertically
  98.             for (int j = 0; j < (bi.biWidth / factor); j++)
  99.             {
  100.                 // temporary storage
  101.                 RGBTRIPLE triple;
  102.  
  103.                 // read RGB triple from infile
  104.                 fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  105.  
  106.  
  107.                 // write RGB triple to outfile
  108.                 fwrite(&triple, sizeof(RGBTRIPLE), factor, outptr);
  109.             }
  110.  
  111.             // write new padding
  112.             for (int k = 0; k < padding; k++)
  113.             {
  114.                 fputc(0x00, outptr);
  115.             }
  116.  
  117.             //measure of control, to ensure the file pointer is still at the same point.
  118.             fseek(inptr, 0, SEEK_CUR);
  119.  
  120.             //go back to the begining of the input file's line to rewrite it as many times as we are resizing it
  121.             if (l < factor - 1)
  122.             {
  123.                 fseek(inptr, -(bi.biWidth / factor), SEEK_CUR);
  124.             }
  125.         }
  126.  
  127.         // skip over padding, if any
  128.         fseek(inptr, padding_old, SEEK_CUR);
  129.     }
  130.  
  131.  
  132.     // close infile
  133.     fclose(inptr);
  134.  
  135.     // close outfile
  136.     fclose(outptr);
  137.  
  138.     // success
  139.     return 0;
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement