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;
}