Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2017
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.79 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. #include <cs50.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <errno.h>
  11. #include <math.h>
  12.  
  13.  
  14. #include "bmp.h"
  15.  
  16. int main(int argc, char *argv[])
  17. {
  18.  
  19.  
  20. bool testFloat = true;
  21. float scaleFactor;
  22. // ensure proper usage
  23. if (argc != 4)
  24. {
  25. fprintf(stderr, "Usage: ./resize float infile outfile\n");
  26. return 1;
  27. }
  28.  
  29.  
  30.  
  31. while (testFloat)
  32. {
  33. // get line of text, returning FLT_MAX on failure
  34. string line = argv[1];
  35.  
  36. if (line == NULL)
  37. {
  38. fprintf(stderr, "Float is NULL %f\n", FLT_MAX);
  39. return 1;
  40. }
  41.  
  42. // return a float if only a float was provided
  43. if (strlen(line) > 0 && !isspace(line[0]))
  44. {
  45. char *tail;1b.bmp
  46. errno = 0;
  47. float f = strtof(line, &tail);
  48. if (errno == 0 && *tail == '\0' && isfinite(f) != 0 && f < FLT_MAX)
  49. {
  50. // disallow hexadecimal and exponents
  51. if (strcspn(line, "XxEePp") == strlen(line))
  52. {
  53. scaleFactor = f;
  54. if (scaleFactor <= 0){
  55. fprintf(stderr, "Float less then 0 %f\n", scaleFactor);
  56. return 1;
  57. }
  58.  
  59. testFloat = false;
  60. }
  61. }
  62. }
  63.  
  64. if (testFloat){
  65. fprintf(stderr, "Float not entered %s\n", line);
  66. return 1;
  67. }
  68. }
  69.  
  70.  
  71.  
  72. // remember filenames
  73. char *infile = argv[2];
  74. char *outfile = argv[3];
  75.  
  76. // open input file
  77. FILE *inptr = fopen(infile, "r");
  78. if (inptr == NULL)
  79. {
  80. fprintf(stderr, "Could not open %s.\n", infile);
  81. return 1;
  82. }
  83.  
  84. // open output file
  85. FILE *outptr = fopen(outfile, "w");
  86. if (outptr == NULL)
  87. {
  88. fclose(inptr);
  89. fprintf(stderr, "Could not create %s.\n", outfile);
  90. return 1;
  91. }
  92.  
  93. // read infile's BITMAPFILEHEADER
  94. BITMAPFILEHEADER bf;
  95. fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  96.  
  97. // read infile's BITMAPINFOHEADER
  98. BITMAPINFOHEADER bi, oldbi;
  99. fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  100.  
  101.  
  102. // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  103. if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  104. bi.biBitCount != 24 || bi.biCompression != 0)
  105. {
  106. fclose(outptr);
  107. fclose(inptr);
  108. fprintf(stderr, "Unsupported file format.\n");
  109. return 4;
  110. }
  111.  
  112. oldbi.biWidth = bi.biWidth;
  113. oldbi.biHeight = bi.biHeight;
  114.  
  115. int oldpadding = (4 - (oldbi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  116.  
  117. bi.biWidth *= scaleFactor;
  118. bi.biHeight *= scaleFactor;
  119.  
  120. // determine padding for scanlines
  121. int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  122.  
  123. bi.biSizeImage = bi.biWidth * abs(bi.biHeight) * sizeof(RGBTRIPLE) + padding;
  124. bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  125.  
  126.  
  127. // write outfile's BITMAPFILEHEADER
  128. fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  129.  
  130. // write outfile's BITMAPINFOHEADER
  131. fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  132.  
  133. float hsum,vsum;
  134. int jsum,isum,rewindfile;
  135.  
  136. vsum = scaleFactor;
  137. isum = 0;
  138.  
  139.  
  140. // iterate over infile's scanlines
  141. for (int i = 0, biHeight = abs(oldbi.biHeight); i < biHeight; i++)
  142. {
  143.  
  144. while((int)vsum > isum){
  145.  
  146. hsum = scaleFactor;
  147. jsum = 0;
  148.  
  149. // iterate over pixels in scanline
  150. for (int j = 0; j < oldbi.biWidth; j++)
  151. {
  152. // temporary storage
  153. RGBTRIPLE triple;
  154.  
  155. // read RGB triple from infile
  156. fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  157.  
  158. while((int)hsum > jsum){
  159. // write RGB triple to outfile
  160. fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
  161. jsum++;
  162. }
  163. hsum += scaleFactor;
  164.  
  165. }
  166.  
  167. // skip over padding, if any
  168. fseek(inptr, oldpadding, SEEK_CUR);
  169.  
  170. // then add it back (to demonstrate how)
  171. for (int k = 0; k < padding; k++)
  172. {
  173. fputc(0x00, outptr);
  174. }
  175.  
  176. isum++;
  177. // printf("%lu %d %d\n",sizeof(RGBTRIPLE), oldbi.biWidth, oldpadding);
  178.  
  179. rewindfile = ((int)sizeof(RGBTRIPLE) * oldbi.biWidth + oldpadding) * (-1);
  180. fseek(inptr,rewindfile,SEEK_CUR);
  181. }
  182. vsum+= scaleFactor;
  183. fseek(inptr,-rewindfile,SEEK_CUR);
  184.  
  185. }
  186.  
  187.  
  188. // close infile
  189. fclose(inptr);
  190.  
  191. // close outfile
  192. fclose(outptr);
  193.  
  194. // success
  195. return 0;
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement