Набралось еще немного соображений о том, как не надо программировать. Речь пойдет о работе с изображениями.Работу с изобарежниями будем рассматривать а) на примере Windows-изображений, б) на примере собственного класса для работы с изображениями. Почему я использую собственный класс, а не Windows, VCL, MFC? Просто рассмотренные ошибки настолько примитивны, что могут воникнуть и там, и там, и там, и там, а я не хочу жертвовать общностью изложения. Класс, который мы будем рассматривать, вот такой:
class ImageClass
{
public:
// Ширина в пикселях
int GetWidth();
// Высота в пикселях
int GetHeight();
// Количество пикселей в строке, учитывая выравнивание
int GetBytesPerLine();
// Массив цветов пикселей. Подряд идущие тройки {красный, желтый, зеленый}. Итого m_Width*m_Height*3 элементов массива
BYTE* GetRowData();
// Ссылка на массив, каждый элемент которого является ссылкой на строку изображения. Итого m_Height элементов массива
BYTE** GetLineArray();
};
1. При работе с изображениями не стоит инициализировать цвет пикселя вот таким циклом:
ImageClass image;
for (BYTE* pLines = image.GetLineArray()[0]; pLines != image.GetLineArray()[image.GetHeight()]; ++pLines)
memset(pLines, 0, image.GetBytesPerLine());
Почему? Ответ кроется в значении величины image->m_LineArray[image->m_Height]. Эта величина не определена, ибо у нас в изображении всего m_Height строк, значит массив m_LineArray содержит m_Height элементов и последний его элемент - image->m_LineArray[image->m_Height - 1].
Код, который будет работать правильно, очень похож, да не совсем:
ImageClass image;
for (BYTE* pLines = image.GetLineArray()[0]; pLines != image.GetLineArray()[image.GetHeight() - 1] + 1; ++pLines)
memset(pLines, 0, image.GetBytesPerLine());