Guest User

Untitled

a guest
Aug 19th, 2019
80
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Resizes a BMP file
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. #include "bmp.h"
  7.  
  8. int main(int argc, char *argv[])
  9. {
  10.  
  11. char *p;
  12. if (!argv[1])
  13. {
  14. fprintf(stderr, "Usage: resize n infile outfile\n");
  15. return 1;
  16. }
  17. int n = strtol(argv[1], &p, 10);
  18. if (*p != '\0')
  19. {
  20. fprintf(stderr, "Usage: resize n infile outfile\n");
  21. return 1;
  22. }
  23. // ensure proper usage
  24. if (argc != 4 || n > 100)
  25. {
  26. fprintf(stderr, "Usage: resize n infile outfile\n");
  27. return 1;
  28. }
  29.  
  30. // remember filenames
  31. char *infile = argv[2];
  32. char *outfile = argv[3];
  33.  
  34. // open input file
  35. FILE *inptr = fopen(infile, "r");
  36. if (inptr == NULL)
  37. {
  38. fprintf(stderr, "Could not open %s.\n", infile);
  39. return 2;
  40. }
  41.  
  42. // open output file
  43. FILE *outptr = fopen(outfile, "w");
  44. if (outptr == NULL)
  45. {
  46. fclose(inptr);
  47. fprintf(stderr, "Could not create %s.\n", outfile);
  48. return 3;
  49. }
  50.  
  51. // read infile's BITMAPFILEHEADER
  52. BITMAPFILEHEADER bfSmall;
  53. fread(&bfSmall, sizeof(BITMAPFILEHEADER), 1, inptr);
  54.  
  55. // read infile's BITMAPINFOHEADER
  56. BITMAPINFOHEADER biSmall;
  57. fread(&biSmall, sizeof(BITMAPINFOHEADER), 1, inptr);
  58.  
  59. // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  60. if (bfSmall.bfType != 0x4d42 || bfSmall.bfOffBits != 54 || biSmall.biSize != 40 ||
  61. biSmall.biBitCount != 24 || biSmall.biCompression != 0)
  62. {
  63. fclose(outptr);
  64. fclose(inptr);
  65. fprintf(stderr, "Unsupported file format.\n");
  66. return 4;
  67. }
  68.  
  69. BITMAPFILEHEADER bfLarge = bfSmall;
  70. BITMAPINFOHEADER biLarge = biSmall;
  71.  
  72. // determine padding for scanlines
  73. int paddingSmall = (4 - (biSmall.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  74. int paddingLarge = (4 - (biLarge.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  75.  
  76. //update the header files
  77. if(n != 1)
  78. {
  79. biLarge.biWidth *= n;
  80. paddingLarge = (4 - (biLarge.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  81. biLarge.biHeight *= n;
  82. biLarge.biSizeImage = ((sizeof(RGBTRIPLE) * biLarge.biWidth) + paddingLarge) * abs(biLarge.biHeight);
  83. bfLarge.bfSize = biLarge.biSizeImage + sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
  84. }
  85. // write outfile's BITMAPFILEHEADER
  86. fwrite(&bfLarge, sizeof(BITMAPFILEHEADER), 1, outptr);
  87.  
  88. // write outfile's BITMAPINFOHEADER
  89. fwrite(&biLarge, sizeof(BITMAPINFOHEADER), 1, outptr);
  90. RGBTRIPLE secLine[biSmall.biWidth];
  91.  
  92. // iterate over infile's scanlines
  93. for (int i = 0, biHeight = abs(biLarge.biHeight); i < biHeight; i++)
  94. {
  95. // iterate over pixels in scanline
  96. for (int j = 0; j < biSmall.biWidth; j++)
  97. {
  98. if (i % n == 0)
  99. {
  100. // temporary storage
  101. RGBTRIPLE triple;
  102.  
  103. // read RGB triple from infile
  104. fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  105. secLine[j] = triple;
  106.  
  107. // write RGB triple to outfile n times
  108. for(int k = 0; k < n; k++)
  109. {
  110. fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  111. }
  112. }
  113. else
  114. {
  115. for (int k = 0; k < n; k++)
  116. {
  117. fwrite(&secLine[j], sizeof(RGBTRIPLE), 1, outptr);
  118. }
  119. }
  120. }
  121.  
  122. // skip over padding, if any
  123. fseek(inptr, paddingSmall, SEEK_CUR);
  124.  
  125.  
  126. // then add it back (to demonstrate how)
  127. for (int z = 0; z < paddingLarge; z++)
  128. {
  129. fputc(0x00, outptr);
  130. }
  131. }
  132. // close infile
  133. fclose(inptr);
  134.  
  135. // close outfile
  136. fclose(outptr);
  137.  
  138. // success
  139. return 0;
  140. }
RAW Paste Data