Advertisement
rupek1995

resize More Comfortable [almost]

Feb 21st, 2017
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.08 KB | None | 0 0
  1. /**
  2.  * Resizes a BMP image by n-factor
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <math.h>
  8.  
  9. #include "bmp.h"
  10.  
  11. int main(int argc, char *argv[])
  12. {
  13.     // ensure proper usage
  14.     if (argc != 4)
  15.     {
  16.         fprintf(stderr, "Usage: ./resize n infile outfile\n");
  17.         return 1;
  18.     }
  19.  
  20.     // remember filenames
  21.     float n = atof(argv[1]);
  22.     char *infile = argv[2];
  23.     char *outfile = argv[3];
  24.  
  25.     // check if n value in range
  26.     if (n < 0.0 || n > 100.0)
  27.     {
  28.         fprintf(stderr, "n value out of range! [0.0-100.0]\n");
  29.         return 2;
  30.     }
  31.  
  32.     // open input file
  33.     FILE *inptr = fopen(infile, "r");
  34.     if (inptr == NULL)
  35.     {
  36.         fprintf(stderr, "Could not open %s.\n", infile);
  37.         return 3;
  38.     }
  39.  
  40.     // open output file
  41.     FILE *outptr = fopen(outfile, "w");
  42.     if (outptr == NULL)
  43.     {
  44.         fclose(inptr);
  45.         fprintf(stderr, "Could not create %s.\n", outfile);
  46.         return 4;
  47.     }
  48.  
  49.     // read infile's BITMAPFILEHEADER
  50.     BITMAPFILEHEADER bf;
  51.     fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  52.  
  53.     // read infile's BITMAPINFOHEADER
  54.     BITMAPINFOHEADER bi;
  55.     fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  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 5;
  65.     }
  66.  
  67.     // determine padding for scanlines of infile
  68.     int og_padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  69.  
  70.     // keep infile's width, height
  71.     LONG og_biWidth = bi.biWidth,
  72.         og_biHeight = bi.biHeight;
  73.  
  74.     // allocate memory for scanline pixels(array of RGBTRIPLE)
  75.     RGBTRIPLE *rgb_array = malloc(og_biWidth * sizeof(RGBTRIPLE));
  76.  
  77.     // calculate outfile's header parameters
  78.     bi.biWidth *= n;
  79.     bi.biHeight *= n;
  80.  
  81.     // determine padding for scanlines of outfile
  82.     int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  83.  
  84.     // calculate rest of outfile's header parameters
  85.     bi.biSizeImage = abs(bi.biHeight) * (bi.biWidth * sizeof(RGBTRIPLE) + padding);
  86.     bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi.biSizeImage;
  87.  
  88.  
  89.     // write outfile's BITMAPFILEHEADER
  90.     fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  91.  
  92.     // write outfile's BITMAPINFOHEADER
  93.     fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  94.  
  95.     // iterate over infile's scanlines
  96.     for (int i = 0, biHeight = abs(og_biHeight); i < biHeight; i++)
  97.     {
  98.         printf("\n\ncurrent scanline: %d\n\n", i);
  99.         // write horizontal scanlines n-times (vertical resize)
  100.         for (int v_row = 0; v_row < n; v_row++)
  101.         {
  102.             if (v_row > 0)
  103.                 printf("\n\nCopied %i scanline\n\n", i);
  104.  
  105.                 printf("new rgb_array loaded:\n");
  106.             // read scanline's RGB triples from infile to rgb_array
  107.             for (int pixel = 0; pixel < og_biWidth; pixel++)
  108.             {
  109.                 fread(&rgb_array[pixel], sizeof(RGBTRIPLE), 1, inptr);
  110.                 printf("pixel %d: %x ", pixel, rgb_array[pixel].rgbtRed);
  111.                 printf("%x ", rgb_array[pixel].rgbtGreen);
  112.                 printf("%x\n", rgb_array[pixel].rgbtBlue);
  113.             }
  114.  
  115.             // iterate over pixels in scanline
  116.             for (int j = 0; j < og_biWidth; j++)
  117.             {
  118.                 // write horizontal scanline n-times (resize)
  119.                 for (int h_row = 0; h_row < n; h_row++)
  120.                 {
  121.                     printf("J = %d\n", j);
  122.                     // if n has a decimal point
  123.                     if (fmod(n, 1)!= 0)
  124.                     {
  125.                         // first pixel is always the first pixel from scanline
  126.                         if (j == 0)
  127.                         {
  128.                             printf("First (%d) pixel of scanline written.\n", j);
  129.                             fwrite(&rgb_array[j], sizeof(RGBTRIPLE), 1, outptr);
  130.                         }
  131.  
  132.                         // if n is bigger than 1 - bmp has more pixels, so rewrite last row for each pixel in scanline
  133.                         if (n > 1)
  134.                         {
  135.                             // only write enough pixels to fill extended scanline
  136.                             if (j < bi.biWidth)
  137.                             {
  138.                                 printf("Write %dTH  pixel of scanline (rgb_array = %d)\n", j+1, j);
  139.                                 fwrite(&rgb_array[j], sizeof(RGBTRIPLE), 1, outptr);
  140.                             }
  141.                         }
  142.                         // else if n less than 1
  143.                         else
  144.                         {
  145.                             // only write enough pixels to fill shrunk scanline
  146.                             if (j < bi.biWidth)
  147.                             {
  148.                                 printf("%d pixel: value %d of rgb_array\n", j+1, j+2);
  149.                                 fwrite(&rgb_array[j + 2], sizeof(RGBTRIPLE), 1, outptr);
  150.                             }
  151.                         }
  152.                     }
  153.                     else
  154.                     {
  155.                         printf("Wrote normally\n");
  156.                         fwrite(&rgb_array[j], sizeof(RGBTRIPLE), 1, outptr);
  157.                     }
  158.                 }
  159.             }
  160.  
  161.             // skip over og_padding, if any
  162.             fseek(inptr, og_padding, SEEK_CUR);
  163.  
  164.             // then add it back (to demonstrate how)
  165.             for (int k = 0; k < padding; k++)
  166.             {
  167.                 fputc(0x00, outptr);
  168.             }
  169.  
  170.             // go back with seeker for vertical resizing of scanlines
  171.             if (v_row < n - 1)
  172.             {
  173.               fseek(inptr, -(abs(og_biWidth) * (int)sizeof(RGBTRIPLE) + og_padding), SEEK_CUR);
  174.             }
  175.         }
  176.     }
  177.  
  178.     // free memory of rgb_array
  179.     free(rgb_array);
  180.  
  181.     // close infile
  182.     fclose(inptr);
  183.  
  184.     // close outfile
  185.     fclose(outptr);
  186.  
  187.     // success
  188.     return 0;
  189. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement