Advertisement
cs-lazaro

resize - v2

Sep 9th, 2017
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.69 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.  * BMP-related data types based on Microsoft's own.
  9.  */
  10.  
  11. #include <stdint.h>
  12.  
  13. /**
  14.  * Common Data Types
  15.  *
  16.  * The data types in this section are essentially aliases for C/C++
  17.  * primitive data types.
  18.  *
  19.  * Adapted from https://msdn.microsoft.com/en-us/library/cc230309.aspx.
  20.  * See http://en.wikipedia.org/wiki/Stdint.h for more on stdint.h.
  21.  */
  22. typedef uint8_t  BYTE;
  23. typedef uint32_t DWORD;
  24. typedef int32_t  LONG;
  25. typedef uint16_t WORD;
  26.  
  27. /**
  28.  * BITMAPFILEHEADER
  29.  *
  30.  * The BITMAPFILEHEADER structure contains information about the type, size,
  31.  * and layout of a file that contains a DIB [device-independent bitmap].
  32.  *
  33.  * Adapted from https://msdn.microsoft.com/en-us/library/dd183374(v=vs.85).aspx.
  34.  */
  35. typedef struct
  36. {
  37.     WORD bfType;
  38.     DWORD bfSize;
  39.     WORD bfReserved1;
  40.     WORD bfReserved2;
  41.     DWORD bfOffBits;
  42. } __attribute__((__packed__))
  43. BITMAPFILEHEADER;
  44.  
  45. /**
  46.  * BITMAPINFOHEADER
  47.  *
  48.  * The BITMAPINFOHEADER structure contains information about the
  49.  * dimensions and color format of a DIB [device-independent bitmap].
  50.  *
  51.  * Adapted from https://msdn.microsoft.com/en-us/library/dd183376(v=vs.85).aspx.
  52.  */
  53. typedef struct
  54. {
  55.     DWORD biSize;
  56.     LONG biWidth;
  57.     LONG biHeight;
  58.     WORD biPlanes;
  59.     WORD biBitCount;
  60.     DWORD biCompression;
  61.     DWORD biSizeImage;
  62.     LONG biXPelsPerMeter;
  63.     LONG biYPelsPerMeter;
  64.     DWORD biClrUsed;
  65.     DWORD biClrImportant;
  66. } __attribute__((__packed__))
  67. BITMAPINFOHEADER;
  68.  
  69. /**
  70.  * RGBTRIPLE
  71.  *
  72.  * This structure describes a color consisting of relative intensities of
  73.  * red, green, and blue.
  74.  *
  75.  * Adapted from https://msdn.microsoft.com/en-us/library/dd162939(v=vs.85).aspx.
  76.  */
  77. typedef struct
  78. {
  79.     BYTE rgbtBlue;
  80.     BYTE rgbtGreen;
  81.     BYTE rgbtRed;
  82. } __attribute__((__packed__))
  83. RGBTRIPLE;
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91. int main(int argc, char *argv[])
  92. {
  93.     // ensure proper usage
  94.     if (argc != 4)
  95.     {
  96.         fprintf(stderr, "Usage: ./resize k infile outfile\n");
  97.         return 1;
  98.     }
  99.  
  100.     // remember filenames
  101.     int factor = atoi(argv[1]);
  102.     char *infile = argv[2];
  103.     char *outfile = argv[3];
  104.  
  105.     printf("Factor = %i\n", factor);
  106.  
  107.     // open input file
  108.     FILE *inptr = fopen(infile, "r");
  109.     if (inptr == NULL)
  110.     {
  111.         fprintf(stderr, "Could not open %s.\n", infile);
  112.         return 2;
  113.     }
  114.  
  115.     // open output file
  116.     FILE *outptr = fopen(outfile, "w");
  117.     if (outptr == NULL)
  118.     {
  119.         fclose(inptr);
  120.         fprintf(stderr, "Could not create %s.\n", outfile);
  121.         return 3;
  122.     }
  123.  
  124.     // read infile's BITMAPFILEHEADER
  125.     BITMAPFILEHEADER bf;
  126.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  127.  
  128.     // read infile's BITMAPINFOHEADER
  129.     BITMAPINFOHEADER bi;
  130.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  131.  
  132.  
  133.     // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  134.     if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  135.         bi.biBitCount != 24 || bi.biCompression != 0)
  136.     {
  137.         fclose(outptr);
  138.         fclose(inptr);
  139.         fprintf(stderr, "Unsupported file format.\n");
  140.         return 4;
  141.     }
  142.  
  143.  
  144.     int padding_old = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  145.  
  146.     //debugging (although not necessary 'cause there's )
  147.     printf("biWidth = %d \nbiHeight = %d \nbiSizeImage = %d \nbfSize = %d \n", bi.biWidth, bi.biHeight, bi.biSizeImage, bf.bfSize);
  148.  
  149.     //increasing height and width by factor
  150.     bi.biWidth *= factor;
  151.     bi.biHeight *= factor;
  152.  
  153.     //calculating padding from new width
  154.     int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  155.  
  156.     //calculating new sizes for headings
  157.     bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + padding) * abs(bi.biHeight);
  158.     bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  159.  
  160.     //just for debugging:
  161.     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);
  162.  
  163.  
  164.     // write outfile's BITMAPFILEHEADER
  165.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  166.  
  167.     // write outfile's BITMAPINFOHEADER
  168.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  169.  
  170.  
  171.  
  172.     // iterate over infile's scanlines
  173.     for (int i = 0, biHeight = abs(bi.biHeight); i < (biHeight / factor); i++)
  174.     {
  175.         // iterate over pixels in scanline
  176.         for (int l = 0; l < factor; l++)
  177.         {
  178.             //resize vertically
  179.             for (int j = 0; j < (bi.biWidth / factor); j++)
  180.             {
  181.                 // temporary storage
  182.                 RGBTRIPLE triple;
  183.  
  184.                 // read RGB triple from infile
  185.                 fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  186.  
  187.  
  188.                 // write RGB triple to outfile
  189.                 for (int z=0; z<factor; z++)
  190.                 {fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);}
  191.             }
  192.  
  193.             // write new padding
  194.             for (int k = 0; k < padding; k++)
  195.             {
  196.                 fputc(0x00, outptr);
  197.             }
  198.  
  199.             //measure of control, to ensure the file pointer is still at the same point.
  200.             fseek(inptr, 0, SEEK_CUR);
  201.  
  202.             //go back to the begining of the input file's line to rewrite it as many times as we are resizing it
  203.             if (l < factor - 1)
  204.             {
  205.                 fseek(inptr, -(bi.biWidth/factor), SEEK_CUR);
  206.             }
  207.         }
  208.  
  209.         // skip over padding, if any
  210.         fseek(inptr, padding_old, SEEK_CUR);
  211.     }
  212.  
  213.  
  214.     // close infile
  215.     fclose(inptr);
  216.  
  217.     // close outfile
  218.     fclose(outptr);
  219.  
  220.     // success
  221.     return 0;
  222. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement