Advertisement
kolbka_

image,cpp

Apr 27th, 2022
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.98 KB | None | 0 0
  1. #include "../include/image.h"
  2. #include "../include/exceptions.h"
  3. namespace lab_bmp {
  4.  
  5. void image::read(const std::string &name_input_file) {
  6. std::ifstream input_file(name_input_file, std::ios_base::binary);
  7. if (!input_file.is_open()) {
  8. throw unable_open_file(name_input_file);
  9. }
  10. input_file.read(reinterpret_cast<char *>(&file_header),
  11. sizeof(file_header));
  12. if (file_header.file_type != 0x4D42) {
  13. throw invalid_version_file_type(std::to_string(bmp_info_header.size));
  14. }
  15. input_file.read(reinterpret_cast<char *>(&bmp_info_header),
  16. sizeof(bmp_info_header));
  17. if (bmp_info_header.height <= 0) {
  18. throw bad_height(std::to_string(bmp_info_header.height));
  19. }
  20. if (bmp_info_header.bit_count != 24) {
  21. throw bad_bit_count(std::to_string(bmp_info_header.bit_count));
  22. }
  23. input_file.seekg(file_header.offset_data, std::ifstream::beg);
  24. auto byte_count_per_row =
  25. bmp_info_header.width * bmp_info_header.bit_count / 8;
  26. unsigned long padding_byte_count_per_row =
  27. calculate_padding(byte_count_per_row);
  28. data.resize((byte_count_per_row + padding_byte_count_per_row) *
  29. bmp_info_header.height);
  30.  
  31. input_file.read(reinterpret_cast<char *>(data.data()),
  32. static_cast<std::streamsize>(data.size()));
  33. input_file.close();
  34. }
  35. void image::write(const std::string &name_output_file) {
  36. std::ofstream output_file(name_output_file, std::ios_base::binary);
  37. output_file.write(reinterpret_cast<char *>(&file_header),
  38. sizeof(file_header));
  39. output_file.write(reinterpret_cast<char *>(&bmp_info_header),
  40. sizeof(bmp_info_header));
  41. output_file.write(reinterpret_cast<char *>(data.data()),
  42. static_cast<std::streamsize>(data.size()));
  43. output_file.close();
  44. }
  45.  
  46. void image::cropp(int32_t x, int32_t y, int32_t new_width, int32_t new_height) {
  47. if (!(0 <= x && x < x + new_width &&
  48. x + new_width <= bmp_info_header.width && 0 <= y &&
  49. y < y + new_height && y + new_height <= bmp_info_header.height)) {
  50. throw bad_arguments();
  51. }
  52. auto bytes_in_px = bmp_info_header.bit_count / 8;
  53. auto bytes_in_row = bmp_info_header.width * bytes_in_px;
  54.  
  55. auto old_padding = calculate_padding(bytes_in_row);
  56.  
  57. auto new_padding_bytes = calculate_padding(new_width * bytes_in_px);
  58. auto size_bytes =
  59. (bytes_in_px * new_width + new_padding_bytes) * new_height;
  60.  
  61. std::vector<std::uint8_t> new_data;
  62. new_data.resize(size_bytes);
  63.  
  64. auto new_width_bytes = new_width * bytes_in_px;
  65. auto cur_byte = 0;
  66. for (auto line_px = new_height; line_px > 0; line_px--) {
  67. auto cur_x_position = (bmp_info_header.height - y - line_px) *
  68. (bytes_in_row + old_padding) +
  69. x * bytes_in_px;
  70. for (auto i = cur_x_position; i < cur_x_position + new_width_bytes;
  71. i++) {
  72. new_data[cur_byte++] = data[i];
  73. }
  74.  
  75. for (auto i = 0; i < static_cast<int>(new_padding_bytes); i++) {
  76. new_data[cur_byte++] = 0;
  77. }
  78. }
  79.  
  80. data = std::move(new_data);
  81.  
  82. bmp_info_header.height = new_height;
  83. bmp_info_header.width = new_width;
  84. bmp_info_header.size_image = static_cast<uint32_t>(data.size());
  85.  
  86. file_header.file_size = sizeof(bmp_info_header) + sizeof(file_header) +
  87. static_cast<uint32_t>(data.size());
  88. }
  89. void image::rotate() {
  90. auto bytes_in_pixel = bmp_info_header.bit_count / 8;
  91. auto padding = calculate_padding(bmp_info_header.width * bytes_in_pixel);
  92. std::vector<uint8_t> data_new;
  93. auto new_padding_bytes =
  94. calculate_padding(bmp_info_header.height * bytes_in_pixel);
  95. auto new_size_data =
  96. (bytes_in_pixel * bmp_info_header.height + new_padding_bytes) *
  97. bmp_info_header.width;
  98. data_new.resize(new_size_data);
  99. int cur_bytes = 0;
  100. for (int l = bmp_info_header.width * bytes_in_pixel - bytes_in_pixel;
  101. l >= 0; l -= bytes_in_pixel) {
  102. for (int k = 0; k < bmp_info_header.height; k++) {
  103. for (int i = 0; i < bytes_in_pixel; i++, cur_bytes++) {
  104. data_new[cur_bytes] =
  105. data[l +
  106. k * (bmp_info_header.width * bytes_in_pixel +
  107. padding) +
  108. i];
  109. }
  110. }
  111. for (auto i = 0; i < new_padding_bytes; i++) {
  112. data_new[cur_bytes++] = 0;
  113. }
  114. }
  115.  
  116. data = std::move(data_new);
  117. auto tmp = bmp_info_header.width;
  118. bmp_info_header.width = bmp_info_header.height;
  119. bmp_info_header.height = tmp;
  120. bmp_info_header.size_image = static_cast<uint32_t>(data.size());
  121. file_header.file_size = sizeof(bmp_info_header) + sizeof(file_header) +
  122. static_cast<uint32_t>(data.size());
  123. }
  124.  
  125. } // namespace lab_bmp
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement