Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "../include/image.h"
- #include "../include/exceptions.h"
- namespace lab_bmp {
- void image::read(const std::string &name_input_file) {
- std::ifstream input_file(name_input_file, std::ios_base::binary);
- if (!input_file.is_open()) {
- throw unable_open_file(name_input_file);
- }
- input_file.read(reinterpret_cast<char *>(&file_header),
- sizeof(file_header));
- if (file_header.file_type != 0x4D42) {
- throw invalid_version_file_type(std::to_string(bmp_info_header.size));
- }
- input_file.read(reinterpret_cast<char *>(&bmp_info_header),
- sizeof(bmp_info_header));
- if (bmp_info_header.height <= 0) {
- throw bad_height(std::to_string(bmp_info_header.height));
- }
- if (bmp_info_header.bit_count != 24) {
- throw bad_bit_count(std::to_string(bmp_info_header.bit_count));
- }
- input_file.seekg(file_header.offset_data, std::ifstream::beg);
- auto byte_count_per_row =
- bmp_info_header.width * bmp_info_header.bit_count / 8;
- unsigned long padding_byte_count_per_row =
- calculate_padding(byte_count_per_row);
- data.resize((byte_count_per_row + padding_byte_count_per_row) *
- bmp_info_header.height);
- input_file.read(reinterpret_cast<char *>(data.data()),
- static_cast<std::streamsize>(data.size()));
- input_file.close();
- }
- void image::write(const std::string &name_output_file) {
- std::ofstream output_file(name_output_file, std::ios_base::binary);
- output_file.write(reinterpret_cast<char *>(&file_header),
- sizeof(file_header));
- output_file.write(reinterpret_cast<char *>(&bmp_info_header),
- sizeof(bmp_info_header));
- output_file.write(reinterpret_cast<char *>(data.data()),
- static_cast<std::streamsize>(data.size()));
- output_file.close();
- }
- void image::cropp(int32_t x, int32_t y, int32_t new_width, int32_t new_height) {
- if (!(0 <= x && x < x + new_width &&
- x + new_width <= bmp_info_header.width && 0 <= y &&
- y < y + new_height && y + new_height <= bmp_info_header.height)) {
- throw bad_arguments();
- }
- auto bytes_in_px = bmp_info_header.bit_count / 8;
- auto bytes_in_row = bmp_info_header.width * bytes_in_px;
- auto old_padding = calculate_padding(bytes_in_row);
- auto new_padding_bytes = calculate_padding(new_width * bytes_in_px);
- auto size_bytes =
- (bytes_in_px * new_width + new_padding_bytes) * new_height;
- std::vector<std::uint8_t> new_data;
- new_data.resize(size_bytes);
- auto new_width_bytes = new_width * bytes_in_px;
- auto cur_byte = 0;
- for (auto line_px = new_height; line_px > 0; line_px--) {
- auto cur_x_position = (bmp_info_header.height - y - line_px) *
- (bytes_in_row + old_padding) +
- x * bytes_in_px;
- for (auto i = cur_x_position; i < cur_x_position + new_width_bytes;
- i++) {
- new_data[cur_byte++] = data[i];
- }
- for (auto i = 0; i < static_cast<int>(new_padding_bytes); i++) {
- new_data[cur_byte++] = 0;
- }
- }
- data = std::move(new_data);
- bmp_info_header.height = new_height;
- bmp_info_header.width = new_width;
- bmp_info_header.size_image = static_cast<uint32_t>(data.size());
- file_header.file_size = sizeof(bmp_info_header) + sizeof(file_header) +
- static_cast<uint32_t>(data.size());
- }
- void image::rotate() {
- auto bytes_in_pixel = bmp_info_header.bit_count / 8;
- auto padding = calculate_padding(bmp_info_header.width * bytes_in_pixel);
- std::vector<uint8_t> data_new;
- auto new_padding_bytes =
- calculate_padding(bmp_info_header.height * bytes_in_pixel);
- auto new_size_data =
- (bytes_in_pixel * bmp_info_header.height + new_padding_bytes) *
- bmp_info_header.width;
- data_new.resize(new_size_data);
- int cur_bytes = 0;
- for (int l = bmp_info_header.width * bytes_in_pixel - bytes_in_pixel;
- l >= 0; l -= bytes_in_pixel) {
- for (int k = 0; k < bmp_info_header.height; k++) {
- for (int i = 0; i < bytes_in_pixel; i++, cur_bytes++) {
- data_new[cur_bytes] =
- data[l +
- k * (bmp_info_header.width * bytes_in_pixel +
- padding) +
- i];
- }
- }
- for (auto i = 0; i < new_padding_bytes; i++) {
- data_new[cur_bytes++] = 0;
- }
- }
- data = std::move(data_new);
- auto tmp = bmp_info_header.width;
- bmp_info_header.width = bmp_info_header.height;
- bmp_info_header.height = tmp;
- bmp_info_header.size_image = static_cast<uint32_t>(data.size());
- file_header.file_size = sizeof(bmp_info_header) + sizeof(file_header) +
- static_cast<uint32_t>(data.size());
- }
- } // namespace lab_bmp
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement