Написал куда более быстрый вариант инверсии bmp изображения на C++, чем предыдущий. В этом варианте мы читаем изображение, записывая всю информацию о нём в массив, и создаём новое изображение с такими-же данными заголовков, но с инверсированными данными цветов. Всё работает значительно быстрее и код стал более простым.
Файл main.h
#ifndef MAIN_H_INCLUDED #define MAIN_H_INCLUDED typedef struct { unsigned int bfType; unsigned long bfSize; unsigned int bfReserved1; unsigned int bfReserved2; unsigned long bfOffBits; } BITMAPFILEHEADER; typedef struct { unsigned int biSize; int biWidth; int biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned int biCompression; unsigned int biSizeImage; int biXPelsPerMeter; int biYPelsPerMeter; unsigned int biClrUsed; unsigned int biClrImportant; } BITMAPINFOHEADER; typedef struct { int rgbBlue; int rgbGreen; int rgbRed; int rgbReserved; } RGBQUAD; static unsigned short read_u16(FILE *fp); static unsigned int read_u32(FILE *fp); static int read_s32(FILE *fp); static void write_u16(unsigned short input, FILE *fp); static void write_u32(unsigned int input, FILE *fp); static void write_s32(int input, FILE *fp); #endif // MAIN_H_INCLUDEDs
Файл main.cpp
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include "main.h" int main() { printf("Starting...\n"); FILE *pFile = fopen("input.bmp", "rb"); // считываем заголовок файла BITMAPFILEHEADER header; header.bfType = read_u16(pFile); header.bfSize = read_u32(pFile); header.bfReserved1 = read_u16(pFile); header.bfReserved2 = read_u16(pFile); header.bfOffBits = read_u32(pFile); // считываем заголовок изображения BITMAPINFOHEADER bmiHeader; bmiHeader.biSize = read_u32(pFile); bmiHeader.biWidth = read_s32(pFile); bmiHeader.biHeight = read_s32(pFile); bmiHeader.biPlanes = read_u16(pFile); bmiHeader.biBitCount = read_u16(pFile); bmiHeader.biCompression = read_u32(pFile); bmiHeader.biSizeImage = read_u32(pFile); bmiHeader.biXPelsPerMeter = read_s32(pFile); bmiHeader.biYPelsPerMeter = read_s32(pFile); bmiHeader.biClrUsed = read_u32(pFile); bmiHeader.biClrImportant = read_u32(pFile); // инициализация массива пикселей RGBQUAD *pixels = new RGBQUAD[bmiHeader.biHeight * bmiHeader.biWidth]; // читаем байты цветов for (int i = 0; i < bmiHeader.biHeight * bmiHeader.biWidth; i++) { pixels[i].rgbBlue = getc(pFile); pixels[i].rgbGreen = getc(pFile); pixels[i].rgbRed = getc(pFile); } fclose(pFile); FILE *oFile = fopen("output.bmp", "wb"); // записываем заголовок файла write_u16(header.bfType, oFile); write_u32(header.bfSize, oFile); write_u16(header.bfReserved1, oFile); write_u16(header.bfReserved2, oFile); write_u32(header.bfOffBits, oFile); // записываем заголовок изображения write_u32(bmiHeader.biSize, oFile); write_s32(bmiHeader.biWidth, oFile); write_s32(bmiHeader.biHeight, oFile); write_u16(bmiHeader.biPlanes, oFile); write_u16(bmiHeader.biBitCount, oFile); write_u32(bmiHeader.biCompression, oFile); write_u32(bmiHeader.biSizeImage, oFile); write_s32(bmiHeader.biXPelsPerMeter, oFile); write_s32(bmiHeader.biYPelsPerMeter, oFile); write_u32(bmiHeader.biClrUsed, oFile); write_u32(bmiHeader.biClrImportant, oFile); // записываем байты цветов for (int i = 0; i < bmiHeader.biHeight * bmiHeader.biWidth; i++) { putc(~pixels[i].rgbBlue & 0xFF, oFile); putc(~pixels[i].rgbGreen & 0xFF, oFile); putc(~pixels[i].rgbRed & 0xFF, oFile); } fclose(oFile); printf("Complete\n"); return 0; } static unsigned short read_u16(FILE *fp) { unsigned char b0, b1; b0 = getc(fp); b1 = getc(fp); return ((b1 << 8) | b0); } static unsigned int read_u32(FILE *fp) { unsigned char b0, b1, b2, b3; b0 = getc(fp); b1 = getc(fp); b2 = getc(fp); b3 = getc(fp); return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0); } static int read_s32(FILE *fp) { unsigned char b0, b1, b2, b3; b0 = getc(fp); b1 = getc(fp); b2 = getc(fp); b3 = getc(fp); return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0); } static void write_u16(unsigned short input, FILE *fp) { putc(input, fp); putc(input >> 8, fp); } static void write_u32(unsigned int input, FILE *fp) { putc(input, fp); putc(input >> 8, fp); putc(input >> 16, fp); putc(input >> 24, fp); } static void write_s32(int input, FILE *fp) { putc(input, fp); putc(input >> 8, fp); putc(input >> 16, fp); putc(input >> 24, fp); }