int imagesize(); // возможный размер изображения void clear(); // освобождение памяти } ;
// возможный размер изображения в байтах int IMAGE::imagesize()
{
// height может быть иногда отрицательным int k=width*height; switch(bpp)
{
case 1: k/=8; break; // 2 цветное изображение
case 2: k/=4; break; // 4 цветное изображение
case 4: k/=2; break; // 16 цветное изображение
default: k*=bpp/8;
} ;
return (k<0)?-k:k;
}
// освобождение занимаемой памяти void IMAGE::clear()
{
if(inddata) {delete[]inddata;inddata=0;} if(pal) {delete[]pal;pal=0;}
}
void IMAGE::init(int w,int h,int b,
int sizepal,int bpal)
{
width=w;
height=h; bpp=b; clear();
inddata=new uchar[imagesize()]; if(sizepal) pal=new uchar[bpal/8] ;
}
/*
dst - куда сохраняются считанные из файла данные
ic - сколько байт считывать за один шаг
ia - насколько байт изменять dst
max - сколько раз считывать
order - способ чтения
f - открытый файл
*/
void IMAGE::fload_data(uchar*dst,int ic, int ia,
int max, int order, FILE*f)
{
for (int i=0;i<max;i + +)
{
fread(dst,1,ic,f); // прямой порядок (rgba)
// если обратный порядок (abgr) или bgra if(order==lI |order==2) reverse(dst, dst + ic);
// если bgra
if(order==2) rotate(dst,dst+1,dst+ic); dst+=ia;
}
}
// считать данные из файла
void IMAGE::fsave_data(uchar*src,int ic,int ia,
int max,int order,FILE*f)
{
uchar *temp=new uchar [ic]; for (int i=0;i<max;i + +)
(
copy(src, src+ic,temp);
// если обратный порядок (abgr) или bgra if(order==l||order==2) reverse(temp,temp+ic);
// если bgra
if(order==2) rotate(temp,temp+1,temp+ic); fwrite(temp,1,ic,f); // записываем данные
src+=ia;
}// конец for(int i=0;i<max;i++) delete[]temp;
}
// загрузка BMP файла
int IMAGE::loadbmp(char*fname)
{
bmpheader header; // заголовок bmp файла int k; // размер данных изображения в байтах FILE*f=fopen(fname,"rb+"); // открываем файл if(!f)return 0;
clear(); // освобождаем возможную память fread(&header,1,54,f); // загрузка заголовка // заполняем наш объект width=header.width; height=header.height ; bpp=header.bpp; sizepal=header.color;
// загружаем палитру if (sizepal)
{
bpppal=4;
pal=new uchar[sizepal*4];
fseek(f,header.imgdata-(sizepal*4),SEEK_SET); fload_data(pal,4,4,sizepal, 2, f);
}
// загружаем изображение k=imagesize(); inddata=new uchar[k]; fseek(f,header.imgdata,SEEK_SET); switch(bpp)
{
case 32: fload_data(inddata,4,4,k/4, 2, f) ; break; case 24: fload_data(inddata,3,3,k/3,1,f); break; default: fread(inddata,1,k,f);
}
fclose(f); // закрываем файл return 1;
}
// сохранение BMP файла
int IMAGE::savebmp(char*fname)
{
bmpheader header; // заголовок bmp файла header.init();
// временные переменные int k=imagesize() ;
int retvalue=l; // возвращаемое значение // заполняем заголовок header.width=width; header.height=height; header.bpp=bpp; header.color=sizepal; header.imgdatasize=k;
header.imgdata=sizeof(header)+sizepal*4; header.fsize=header.imgdata+header.imgdatasize FILE*f;