Пишу программу для поворота изображения на 90 градусов. В результате создается выходной файл того же размера, что и исходный, но не открывается - файл поврежден. Очевидно, что-то напутала с выводом самого изображения или заголовка. Буду признательна, если укажете ошибку.
Код:
#include <stdio.h>
#include <iostream>
using namespace std;
#pragma push pack
#pragma pack(1)
struct BmpHeader
{
//---- from BITMAPFILEHEADER structure
unsigned short bfType; // Сигнатура
unsigned long bfSize; // Размер файла в байтах
unsigned long bfUnused;
unsigned long bfOffBits; // Смещение растра от начала файла
//---- from BITMAPINFOHEADER structure
unsigned long biSize; // Размер дополнительного заголовка (обычно 40 = 0x28)
unsigned long biWidth; // Ширина растра
unsigned long biHeight; // Высота растра
unsigned short biPlanes; // Количество слоев
unsigned short biBitCount; // Разрядность растра
unsigned long biCompression; // Тип компрессии
} header;
#pragma pop pack
int main (int argc, char** argv)
{
setlocale(LC_ALL,"Russian");
char *inputFileName=new char[255];
char *outputFileName=new char[255];
if (argc < 2)
{
cout<<"Введите имя входного файла:\n";
cin>>inputFileName;
}
else inputFileName=argv[1];
if (argc < 3)
{
cout<<"Введите имя выходного файла:\n";
cin>>outputFileName;
}
else outputFileName=argv[2];
// Попытаемся открыть входной файл
FILE *in = fopen (inputFileName, "rb");
if (in == NULL)
{
cout<<"Ошибка открытия входного файла.\n";
return -1;
}
// Попытаемся прочесть заголовок BMP из входного файла
if (fread (&header, sizeof(header), 1, in) != 1)
{
cout<<"Ошибка чтения входного файла.\n";
fclose (in);
return -1;
}
// Сигнатура BMP должна быть "BM" = 0x4D42
if (header.bfType != 0x4D42)
{
cout<<"Ошибка. Ошибка сигнатуры входного файла.\n";
fclose (in);
return -1;
}
// Проверяем длину дополнительного заголовка
if (header.biSize != 40)
{
cout<<"Ошибка. Нестандартный BITMAPINFOHEADER.\n";
fclose (in);
return -1;
}
// Обрабатываем только неупакованные BMP
if (header.biCompression != 0)
{
cout<<"Ошибка. Упакованный BMP.\n";
fclose (in);
return -1;
}
// Обрабатываем только однослойные BMP
if (header.biPlanes != 1)
{
cout<<"Ошибка. Многослойный BMP.\n";
fclose (in);
return -1;
}
// Обрабатываем только 24 или 32 разряда
if ((header.biBitCount != 24) && (header.biBitCount != 32))
{
cout<<"Ошибка. Не 24b или 32b BMP.\n";
fclose (in);
return -1;
}
// работа программы
// Попытаемся открыть выходной файл
FILE *out = fopen (outputFileName, "wb");
if (out == NULL)
{
cout<<"Ошибка создания выходного файла.\n";
fclose (in);
return -1;
}
fwrite(&header.bfType,sizeof(unsigned long),1,out);
fwrite(&header.bfSize,sizeof(unsigned long),1,out);
fwrite(&header.bfUnused,sizeof(unsigned long),1,out);
fwrite(&header.bfOffBits,sizeof(unsigned long),1,out);
fwrite(&header.biSize,sizeof(unsigned long),1,out);
fwrite(&header.biHeight,sizeof(unsigned long),1,out);
fwrite(&header.biWidth,sizeof(unsigned long),1,out);
fwrite(&header.biPlanes,sizeof(unsigned long),1,out);
fwrite(&header.biBitCount,sizeof(unsigned long),1,out);
fwrite(&header.biCompression,sizeof(unsigned long),1,out);
// Обработка растра
int sizeOfPixel = header.biBitCount >> 3; // Длина пикселя в байтах
unsigned char *pic=new unsigned char[4*header.biWidth*header.biHeight];
int k=0;
for (int i=0;i<header.biHeight;i++)
{
for (int j=0;j<header.biWidth;j++)
{
fread(&pic[k],sizeOfPixel,1,in);
k++;
}
if ((header.biWidth * sizeOfPixel) & 1)
fread (&pic[k], 1, 1, in);
k++;
}
for (int j = header.biWidth-1; j >=0; j--)
{
int i;
for (i = 0; i < header.biHeight; i++)
fwrite (&pic[j+i], sizeOfPixel, 1, out);
}
// Всё !
cout<<"Программа выполнена успешно.\n";
fclose (out);
fclose (in);
system("pause");
return 0;
}