Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка простого графического редактора.doc
Скачиваний:
28
Добавлен:
28.06.2014
Размер:
137.73 Кб
Скачать

3.2 Программный код кодирования и декодирования формата .Pcx

void PCXImage::create()

{

if (!Image)

{

head.Manufacturer = 10;

head.Version = 5;

head.Encoding = 1;

head.BitsPerLayer = 8;

head.Xmin = MINX;

head.Ymin = MINY;

head.Xmax = MAXX;

head.Ymax = MAXY;

head.NPlanes = 3;

head.BytesPerLine = MAXX;

head.Palette = 1;

for (int i = 0; i < 58; i++)

head.Filler[i] = 0;

Image = new int[MAXX * MAXY];

}

}

void PCXImage::synhr(TImage * IM)

{

if (Image)

{

short int XSIZE, YSIZE;

XSIZE = head.Xmax - head.Xmin + 1;

YSIZE = head.Ymax - head.Ymin + 1;

for (int i = 0; i < MIN(MAXY, YSIZE); i++)

for (int j = 0; j < MIN(MAXX, XSIZE); j++)

Image[i * XSIZE + j] = IM->Canvas->Pixels[1 + j][1 + i];

}

}

void PCXImage::recover(TImage * IM)

{

if (Image)

{

short int XSIZE, YSIZE;

XSIZE = head.Xmax - head.Xmin + 1;

YSIZE = head.Ymax - head.Ymin + 1;

for (int i = 0; i < MIN(IM->Height, YSIZE); i++)

for (int j = 0; j < MIN(IM->Width, XSIZE); j++)

IM->Canvas->Pixels[1 + j][1 + i] = (TColor)Image[i * XSIZE + j];

}

}

char PCXImage::load(char *fName)

{

FILE *fToRead;

short int XSIZE, YSIZE;

short int TotalBytes;

register char c, count;

register short int j, k;

char *bufStr;

if (fToRead = fopen(fName, "rb"))

{

if (Image) delete []Image;

fread(&head, 128, 1, fToRead);

XSIZE = head.Xmax - head.Xmin + 1;

YSIZE = head.Ymax - head.Ymin + 1;

Image = new int [XSIZE * YSIZE];

TotalBytes = head.NPlanes * head.BytesPerLine;

bufStr = new char[TotalBytes];

k = 0;

for (int i = 0; i < YSIZE; i++)

{

j = 0;

if (k)

{

for (; k < count && j < TotalBytes; k++)

bufStr[j++] = c;

if (k == count)

k = 0;

}

while (j < TotalBytes)

{

fread(&c, 1, 1, fToRead);

if (0xC0 == (c & 0xC0))

{

count = 0x3F & c;

fread(&c, 1, 1, fToRead);

for (; k < count && j < TotalBytes; k++)

bufStr[j++] = c;

if (k == count)

k = 0;

}

else

bufStr[j++] = c;

}

for (j = 0; j < XSIZE; j++)

{

Image[i * XSIZE + j] = 0;

for (char u = 0; u < head.NPlanes; u++)

Image[i * XSIZE + j] |= ((int)bufStr[u * head.BytesPerLine + j] & 0xFF) << u * 8;

}

}

fclose(fToRead);

delete []bufStr;

return 1;

}

else return 0;

}

char PCXImage::save(char *fName)

{

if (Image)

{

FILE *fToWrite;

short int XSIZE, YSIZE;

short int TotalBytes;

register char cur, last, count;

register short int j, k;

char *bufStr;

const int cRGB[3] = {0xFF, 0xFF00, 0xFF0000};

if (fToWrite = fopen(fName, "wb"))

{

fwrite(&head, 128, 1, fToWrite);

XSIZE = head.Xmax - head.Xmin + 1;

YSIZE = head.Ymax - head.Ymin + 1;

TotalBytes = head.NPlanes * head.BytesPerLine;

bufStr = new char[TotalBytes];

for (int i = 0; i < YSIZE; i++)

{

for (j = 0; j < head.BytesPerLine; j++)

for (k = 0; k < head.NPlanes; k++)

if (j < XSIZE)

bufStr[k * head.BytesPerLine + j] = ((Image[i * XSIZE + j] & cRGB[k]) >> k * 8) & 0xFF;

else bufStr[k * head.BytesPerLine + j] = 0;

last = bufStr[0];

count = 1;

for (j = 1; j < TotalBytes; j++)

{

cur = bufStr[j];

if (cur == last)

{

count++;

if (count == 63)

{

count = 0xFF;

fwrite(&count, 1, 1, fToWrite);

fwrite(&last, 1, 1, fToWrite);

count = 0;

}

}

else

{

if (count)

if((count == 1) && (0xC0 != (0xC0 & last)))

fwrite(&last, 1, 1, fToWrite);

else

{

count = 0xC0 | count;

fwrite(&count, 1, 1, fToWrite);

fwrite(&last, 1, 1, fToWrite);

}

last = cur;

count = 1;

}

}

if (count)

if((count == 1) && (0xC0 != (0xC0 & last)))

fwrite(&last, 1, 1, fToWrite);

else

{

count = 0xC0 | count;

fwrite(&count, 1, 1, fToWrite);

fwrite(&last, 1, 1, fToWrite);

}

}

fclose(fToWrite);

delete []bufStr;

return 1;

}

else return 0;

}

else return 0;

}