Advertisement
hjerting

resize.c new version

Apr 6th, 2016
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.23 KB | None | 0 0
  1. /**
  2. * resize.c
  3. *
  4. * Computer Science 50
  5. * Problem Set 4
  6. *
  7. * Resizes a bmp by a factor ranging from 0 to 100 inclusive.
  8. * I am starting with the code supplied by CS50 course called
  9. * copy.c
  10. *
  11. * Changes to the code of copy.c written by
  12. * Jon Hjerting
  13. * March 2016
  14. *
  15. *
  16. */
  17.  
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20.  
  21. #include "bmp.h"
  22.  
  23. int main(int argc, char* argv[])
  24. {
  25. // ensure proper usage
  26. if (argc != 4)
  27. {
  28. printf("Usage: ./test.c n infile outfile\n");
  29. return 1;
  30. }
  31.  
  32. // check n value
  33. int n = atoi(argv[1]);
  34. if (n < 1 || n > 100)
  35. {
  36. printf("n must be an integer in the range [1, 100]");
  37. return 5;
  38. }
  39.  
  40. // remember filenames
  41. char* infile = argv[2];
  42. char* outfile = argv[3];
  43.  
  44. // open input file
  45. FILE* inptr = fopen(infile, "r");
  46. if (inptr == NULL)
  47. {
  48. // abort if file failed to open
  49. printf("Could not open %s.\n", infile);
  50. return 2;
  51. }
  52.  
  53. // open output file
  54. FILE* outptr = fopen(outfile, "w");
  55. if (outptr == NULL)
  56. {
  57. // abort if opening new file failed
  58. fclose(inptr);
  59. fprintf(stderr, "Could not create %s.\n", outfile);
  60. return 3;
  61. }
  62.  
  63. // read infile's BITMAPFILEHEADER
  64. BITMAPFILEHEADER bf;
  65. fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
  66.  
  67. // read infile's BITMAPINFOHEADER
  68. BITMAPINFOHEADER bi;
  69. fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
  70.  
  71. // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
  72. if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
  73. bi.biBitCount != 24 || bi.biCompression != 0)
  74. {
  75. fclose(outptr);
  76. fclose(inptr);
  77. fprintf(stderr, "Unsupported file format.\n");
  78. return 4;
  79. }
  80.  
  81. // determine padding for original
  82. int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  83.  
  84. // original width and height
  85. int oldWidth = bi.biWidth;
  86. int oldHeight = abs(bi.biHeight);
  87.  
  88. // update width
  89. bi.biWidth *= n;
  90.  
  91. // update height
  92. bi.biHeight *= n;
  93.  
  94. // determine new padding for enlarged file
  95. int newPadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
  96.  
  97. // update biSizeImage
  98. bi.biSizeImage = (bi.biWidth * sizeof(RGBTRIPLE) + newPadding) * abs(bi.biHeight);
  99.  
  100. // update bfSize
  101. bf.bfSize = bi.biSizeImage + bf.bfOffBits;
  102.  
  103. // write outfile's BITMAPFILEHEADER
  104. fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
  105.  
  106. // write outfile's BITMAPINFOHEADER
  107. fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
  108.  
  109. // pixel counter for position in array
  110. int pixelNo;
  111.  
  112. // array for storing one line of pixels
  113. RGBTRIPLE lineArray[bi.biWidth];
  114. int arraySize = sizeof(RGBTRIPLE) * bi.biWidth;
  115.  
  116. // iterate over infile's scanlines
  117. for (int line = 0; line < oldHeight; line++)
  118. {
  119. // counter for inserting pixel in lineArray
  120. pixelNo = 0;
  121.  
  122. // iterate over pixels in scanline
  123. for (int pixel = 0; pixel < oldWidth; pixel++)
  124. {
  125. // temporary storage
  126. RGBTRIPLE triple;
  127.  
  128. // read RGB triple from infile
  129. fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
  130.  
  131. // repeat n times to enlarge width by n
  132. for (int repeatpixel = 0; repeatpixel < n; repeatpixel++)
  133. {
  134. // write RGB triple to lineArray
  135. lineArray[pixelNo] = triple;
  136. pixelNo++;
  137. }
  138. }
  139.  
  140. // repeat n times writing line to file
  141. for (int repeatLine = 0; repeatLine < n; repeatLine++)
  142. {
  143. // write lineArray to file
  144. fwrite(lineArray, arraySize, 1, outptr);
  145.  
  146. // add padding to outfile
  147. for (int k = 0; k < newPadding; k++)
  148. {
  149. fputc(0x00, outptr);
  150. }
  151.  
  152. }
  153.  
  154. // skip over padding, if any
  155. fseek(inptr, padding, SEEK_CUR);
  156.  
  157. }
  158.  
  159. // close infile
  160. fclose(inptr);
  161.  
  162. // close outfile
  163. fclose(outptr);
  164.  
  165. // that's all folks
  166. return 0;
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement