Информация о 256-цветной палитре vga
В настоящее время ZSoft добавил возможность хранения в файле изображения PCX палитры, превышающей 16 цветов. 256-цветная палитра форматируется и интерпретируется точно также, как 16-цветная, естественно, за исключением того, что она длиннее. Палитра (число цветов x 3 байта длины) добавляется в конец PCX файла и ей предшествует байт с десятичным значением 12. Для определения палитры VGA BIOS вам достаточно разделить прочитанные значения цветов на 4.
Для доступа к 256-цветной палитре следует:
1. Прочитать в заголовке поле Version. Если оно равно 5, палитра должна быть.
2. Прочитать конец файла и отсчитать назад 769 байт. Найденное значение должно равняться 12, что указывает на присутствие 256-цветной палитры.
Информация о цветовой палитре cga
Для стандартной платы IBM CGA битовый набор для определения палитры более сложен. Используется только первый байт тройки. Первая тройка содержит только первый байт с осмысленным значением, который определяет цвет фона. Чтобы определить цвет фона, нужно значение этого байта (беззнаковое) разделить на 16. В результате будет получено значение в диапазоне 0-15, которое и определяет цвет фона. Вторая тройка содержит осмысленное значение первого байта, которое определяет значение палитры для трех оставшихся цветов. PC Paintbrush поддерживает для этих цветов 8 возможных палитр CGA, и, поскольку значение байта может быть от 0 до 255, его следует разделить на 32 (см. схему, приведенную ниже).
Taблица цветов для CGA
Байт #16 в заголовке
Цвет фона определяется 4 старшими битами.
Байт #19 в заголовке
Используются только 3 старших бита, остальные 5
игнорируются. Первые три бита обозначаются как C, P, I.
Их интерпретация:
C: разрешение color burst - 0 = color; 1 = monochrome
P: палитра - 0 = желтая; 1 = белая
I: яркость - 0 = малая; 1 = повышенная.
Примеры программ на c
Приведенный ниже набор программ на C предназначен для
чтения из PCX файла.
/* Данная процедура читает из файла один блок закодированных
данных из файла и запоминает повторитель count и байт
данных data. Результат:
0 = данные прочитаны
EOF = данных нет (вышли за пределы файла) */
encget(pbyt, pcnt, fid)
int *pbyt; /* сюда писать байт данных */
int *pcnt; /* сюда писать повторитель */
FILE *fid; /* ссылка на файл изображения */
{
int i;
*pcnt = 1;
if(EOF == (i = getc(fid))) return(EOF);
if(0xc0 == (0xc0 & i)) {
*pcnt = 0x3f&i;
if(EOF == (i=getc(fid))) return(EOF);
}
*pbyt = i;
return(0);
}
/* Это фрагмент программы, использующей encget. Она читает
файл целиком и запоминает результат декодирования в
(большом) буфере, на который ссылается переменная "bufr".
"fp" - это ссылка на файл с изображением */
while (EOF != encget(&chr, &cnt, fp))
for (i = 0; i < cnt; i++, *bufr++ = chr)
Приведенный ниже набор программ предназначен для записи
в .PCX файл.
/* Эта программа кодирует содержимое одной строки
изображения и записывает его в файл */
encLine(inBuff, inLen, fp)
unsigned char *inBuff; /* указатель на строку данных */
int inLen; /* длина строки в байтах */
FILE *fp; /* указатель на запис. файл */
{ /* возвращает число байтов, запис. в файл, или 0, если
имела место ошибка */
unsigned char this, last;
int srcIndex, i;
register int total;
register unsigned char runCount; /* макс. значение равно
63 */
total = 0;
last = *(inBuff); runCount = 1;
for (srcIndex = 1; srcIndex < inLen; srcIndex++) {
this = *(++inBuff);
if (this == last) {
runCount++; /* он кодируется */
if (runCount == 63) {
if (!(i=encput(last, runCount, fp))) return(0);
total += i;
runCount = 0;
}
}
else { /* this != last */
if (runCount) {
if (!(i=encput(last, runCount, fp))) return(0);
total += i;
}
last = this;
runCount = 1;
}
} /* конец цикла */
if (runCount) { /* завершение */
if (!(i=encput(last, runCount, fp))) return(0);
return(total + i);
}
return(total);
}
/* программа для записи закодированной пары байтов (или
одиночного байта, если он не кодируется) в файл */
encput(byt, cnt, fid) /* возвращает число записанных байтов
или 0, если имела место ошибка */
unsigned char byt, cnt;
FILE *fid;
{
if(cnt) {
if( (cnt==1) && (0xc0 != (0xc0&byt)) ) {
if(EOF == putc((int)byt, fid))
return(0); /* ошибка при записи на диск */
return(1);
}
else {
if(EOF == putc((int)0xC0 | cnt, fid))
return(0); /* ошибка при записи на диск */
if(EOF == putc((int)byt, fid))
return(0); /* ошибка при записи на диск */
return(2);
}
}
return(0);
}
Конец примера
