Смекни!
smekni.com

Просмотрщик графических файлов. Форматы PCX и BMP (стр. 3 из 3)

Следующим шагом происходит считывание растровые данные из файла. Как только строка со значениями пикселов прочитана из файла, она в функции put_pixel передается в видео-буфеp для получения изображения на экране.

2.3. Используемые переменные и функции.

2.3.1. Глобальные переменные.

typedefunsignedcharbyte

Объявление типа.

char far *video = (char far *) 0xA0000000L

Указатель на видеопамять.

intMaxX, MaxY

Максимальное разрешение экрана.

VidMode=0x13

Гафический режим 13h.

1.3.2. Основные функции и процедуры

structpcxHeaderType

Структура заголовка файла PCX.

struct bmpHeaderType

Структура заголовка файла BMP.

voidset_mode (void)

Установка графического режима 13h.

voidset_text (void)

Установкатекстовогорежимa.

void set_palette (int color, byte r, byte g, byte b)

Установление цвета в палитре.

voidput_pixel (intx, inty, bytecolor)

Вывод пиксела установленного цвета в позицию x y.

void read_pcx_header (FILE *dataFile, pcxHeaderType &pcxHeader)

Чтениезаголовка pcx файла.

int show_pcx (char *name)

Вывод pcx файла на экран.

void read_bmp_header (FILE *dataFile, bmpHeaderType &bmpHeader)

Чтениезаголовка bmp файла.

void read_bmp_header (FILE *dataFile, bmpHeaderType &bmpHeader)

Чтениезаголовка bmp файла.

int show_bmp (char *name)

Вывод bmp файла на экран.

void main(int argc, char *argv[])

Читает имя файла из командной строки, проверяет по расширению к какому типу файлов он относится и вызывает соответствующую функция просмотра.

2.4. Запуск программы

Программа является консольным приложением и функционирует под управлением операционной системы MSDOS или её эмуляции («Сеанс MSDOS» в Windows’е).

Запуск программы производится из окна файлового менеджера, либо из командной строки, и имеет следующий синтаксис:

PCX_BMP.EXE <имя графического файла>[PCX]/[BMP]

Примеры:

PCX_BMP.EXETEST.PCX

PCX_BMP.EXETEST.BMP

При запуске программы следует обратить внимание на то, что если не указывать имя файла то на экран будет выдана подсказка по формату запуска программы.

2.5. Содержание дистрибутивной дискеты

Дискета с дистрибутивом содержит следующие файлы:

В каталоге DEMO находится файл основной запускающей программы PCX_BMP.EXE.

В каталоге SOURCE находятся файл PCX_BMP.cpp - исходный текст программы, написанный на языке С++.

В каталоге DOC находится файл Viewer.doc - описание алгоритма и работы программы просмотра графических файлов.

В каталоге TEST находятся тестовые графические файлы.

TEST.BMP – графический файл формата BMP (320x200)

TEST.PCX – графический файл формата PCX (320x200)

TEST2.BMP – графический файл формата BMP (224x160)

TEST2.PCX – графический файл формата PCX (256x160)

TEST3.BMP – графический файл формата BMP (320x22)

TEST3.PCX – графический файл формата PCX (200x125)

В корневом каталоге дискеты находится файл Read.me.

СПИСОК ЛИТЕРАТУРЫ

  1. Д.С. Ватолин "Алгоритмы сжатия изображений". Методические материалы к спецкурсу ВМиК МГУ "Машинная графика-2" под руководством Ю.М. Баяковского.
  2. Справочное руководство по IBMPC. Часть 1. Москва ТПП “Сфера” 1991 стр. 55-62
  3. http://home.novgorod.ru/lab/index.php3?path=formtfil/n-q
  4. http://fileformat.virtualave.net/ind_form.htm
  5. http://www.codenet.ru/progr/formt/intro.php
  6. http://vnews.uka.ru/html/school.htm
  7. http://www.halyava.ru/document/ext_b.htm
  8. http://members.nbci.com/treestation/
  9. http://graphics.cs.msu.su/
  10. http://www.programmersheaven.com/zone10/index.htm
  11. http://www.dcs.ed.ac.uk/home/mxr/gfx/utils-hi.html
  12. http://rtfm.vn.ua/
  13. http://www2.crosswinds.net/~hellerzone/manuals.html
  14. http://www.math.rsu.ru/dictionary/fileform.htm

ПРИЛОЖЕНИЕ

Листинг программы “Просмотрщик графических файлов”.

#include <dos.h>

#include <iostream.h>

#include <conio.h>

#include <stdio.h>

#include <string.h>

#include <dir.h>

// Глобальные переменные

typedef unsigned char byte; // объявлениетипа

char far *video = (char far *) 0xA0000000L; // указатель на видеопамять

int MaxX=320, MaxY=200, VidMode=0x13; // Максимальное разрешение экрана

// Структура заголовка файла PCX

struct pcxHeaderType

{

charmanufacturer; // всегда 10 для Paintbrush

char version; // информация о версии (версия 5)

char encoding; // групповое кодирование (=1)

char bitsPerPixel; // число бит на пиксел

int x, y; // координаты левого верхнего угла

int width, height; // размеры изображения

int hResolution, vResolution; // горизонтальное и вертикальное разрешение экрана

char egaPalette[48]; // палитра 256 цветов

char reserved; // зарезервировано всегда 0

char nColorPlanes; // число цветовых слоев

int bytesPerLine; // число байт на строку в цветном слое

int paletteType; // определение палитры (1-цветная/черно-белая, 2-градация серого)

char padding[58]; // заполняется 0 до конца заголовка

};

// Структура заголовка файла BMP

structbmpHeaderType

{

char magic1, magic2; // типфайла ('BM')

long fileSize; // размер файла в байтах

long reserved; // зарезервировано всегда 0

long pixelOffset; // смещениме данных от заголовка

long bmiSize; // размер заголовка

long cols, rows; // ширина и высота картинки

int nPlanes; // число цветовых слоев (1)

int bitsPerPixel; // число битов на пиксел (1 - 2 цвета, 4 - 16 цветов, 8 - 256 цветов)

long compression, cmpSize; // сжатиекартинки?

long xScale, yScale; // горизонтальное и вертикальное разрешение

long colors, impColors; // число используемых цветов

};

// Установка графического режима 13h

void set_mode (void)

{

union REGS regs; // объявлено в dos.h - регистры

regs.h.ah = 0;

regs.h.al = VidMode;

int86 (0x10, &regs, &regs);

}

// Установка текстового режимa

void set_text (void)

{

union REGS regs; // объявленов dos.h - регистры

regs.h.ah = 0;

regs.h.al = 0x03; // номер текстового режима

int86 (0x10, &regs, &regs);

}

void set_palette (int color, byte r, byte g, byte b) // устанавлениецветавпалитре

{

outportb (0x3C8, color);

outportb (0x3C9, r);

outportb (0x3C9, g);

outportb (0x3C9, b); }

// вывод пиксела установленного цвета в позицию x y

void put_pixel (int x, int y, byte color)

{

if (y>=0 && y<MaxY) // можно вывести эту точку

if (x>=0 && x<MaxX)

video[y*MaxX+x] = color; // использование прямого доступа к памяти

}

// Чтениезаголовка pcx файла

void read_pcx_header (FILE *dataFile, pcxHeaderType &pcxHeader)

{

fread (&pcxHeader, sizeof (pcxHeaderType), 1, dataFile);

}

// Вывод pcx файланаэкран

int show_pcx (char *name)

{

pcxHeaderType pcxHeader; // структуразаголовка

FILE *dataFile; // указательна pcx файл

byte color, r, g, b, // установка палитры

counter, length; // for RLE (счетчик, длина)

unsigned int x, y; // координатыпиксела

dataFile = fopen (name, "rb"); // открытиекартинки

if (dataFile == NULL) return 4; // ошибкаоткрытия

read_pcx_header (dataFile, pcxHeader); // тестированиенаошибки

if (pcxHeader.bitsPerPixel != 8) // не поддерживается (8 бит -256 цветов)

{ fclose (dataFile); return 1; }

else

cout << "Этот формат PCX не поддерживается" << endl;

if (pcxHeader.nColorPlanes != 1)// не поддерживается (число цветовых слоев - 1)

{ fclose (dataFile); return 2; }

else

cout << "Этот формат PCX не поддерживается" << endl;

if (pcxHeader.manufacturer != 10) // ошибка pcx (10 для Paintbrush)

{ fclose (dataFile); return 3; }

else

cout << "Ошибкав PCX" << endl;

fseek (dataFile, -768, SEEK_END); // начало чтения картинки

set_mode(); // установка графического режима

for (x=0; x<256; x++) // чтение палитры

{

r = fgetc (dataFile); r = r>>2;

g = fgetc (dataFile); g = g>>2;

b = fgetc (dataFile); b = b>>2;

set_palette (x, r, g, b);

}

// начало вывода

x=0; y=0; // верхная левая координата

fseek (dataFile, 128, SEEK_SET); // перемещение указателя

while (y <= pcxHeader.height) // выводить пока не дойдет до последней строки

{

color = fgetc (dataFile); // чтение байта

if (color < 192) // не сжатый?

{

if (x > pcxHeader.width) // проверка на переполнение

{

x = 0;

y++;

}

put_pixel (x++, y, color); // вывод точки на экран

}

else // сжатый

{

length = color-192; // определение количества выводимых пикселов

color = fgetc (dataFile); // чтение следующего байта

for (counter=0; counter<length; counter++)

{

if (x > pcxHeader.width) // проверка на переполнение

{

x = 0;

y++;

}

put_pixel (x++, y, color); // вывод точки на экран

}

}

}

fclose (dataFile); // закрыть файл

getch(); // ждать нажатие любой клавиши

set_text(); // установка текстового режима

return 0; // вернуть код ошибки 0 (без ошибки)

}

// Чтениезаголовка bmp файла

void read_bmp_header (FILE *dataFile, bmpHeaderType &bmpHeader)

{

fread (&bmpHeader, sizeof (bmpHeaderType), 1, dataFile);

}

// Вывод bmp файланаэкран

int show_bmp (char *name)

{

bmpHeaderType bmpHeader; // структуразаголовка

FILE *dataFile; // указательнафайл

byte r, g, b; // красный, зеленый и синий в палитре

int x, y; // координаты пиксела

unsignedintwidth; // ширина картинки

dataFile = fopen (name, "rb"); // открытьфайл

if (dataFile == NULL) return 5; // еслинеможетоткрыть

read_bmp_header (dataFile, bmpHeader); // тестированиенаошибки

if (bmpHeader.nPlanes != 1) // не поддерживается (число цветовых слоев - 1)

{ fclose (dataFile); return 1; }

else

cout << "Этот формат BMP не поддерживается" << endl;

if (bmpHeader.bitsPerPixel != 8) // не поддерживается (8 бит -256 цветов)

{ fclose (dataFile); return 2; }

else

cout << "Этот формат BMP не поддерживается" << endl;

if (bmpHeader.compression != 0) // неподдерживается

{ fclose (dataFile); return 3; }

else

cout << "Этот формат BMP не поддерживается" << endl;

if (bmpHeader.magic1 != 'B' || bmpHeader.magic2 != 'M')

{fclose (dataFile); return 4;} // ошибка bmp

else

cout << "Это не формат BMP" << endl;

fseek (dataFile, 54, SEEK_SET); // начало чтения картинки

set_mode(); // установка графического режима

for (x=0; x<256; x++) // чтение палитры

{

b = fgetc (dataFile); b = b>>2;

g = fgetc (dataFile); g = g>>2;

r = fgetc (dataFile); r = r>>2;

set_palette (x, r, g, b); // установка палитры

fgetc (dataFile); // следующий байт

}

width = bmpHeader.cols; // чтение ширины из заголовка

while (width % 4 != 0) width++; // пока не кратно 4

for (y=bmpHeader.rows; y>0; y--) // до высоты картинки

for (x=0; x<width; x++) // до ширины картинки

put_pixel (x, y, fgetc(dataFile)); // чтение и вывод

fclose (dataFile); // закрытие файла

getch(); // ждать нажатия клавиши

set_text(); // возврат в текстовый режим

return 0; // вернуть код ошибки 0 (без ошибки)

}

//Читает имя файла из командной строки, проверяет по расширению к какому типу

//относится и вызывает соответствующую функция просмотра

void main(int argc, char *argv[]) //количество параметров и массив параметров

{

char fodrive[MAXDRIVE], fodir[MAXDIR], foname[MAXFILE], foext[MAXEXT];

if (argc > 1) //если количество параметров больше 1

{

fnsplit(argv[1],fodrive,fodir,foname,foext);

if (strcmp(strupr(foext),strupr(".pcx")) == 0) //сравнениепорасширению

show_pcx(argv[1]); //берем 2 параметр и выводим

if (strcmp(strupr(foext),strupr(".bmp")) == 0)

show_bmp(argv[1]); //берем 2 параметр и выводим

}

else

cout << "Запуск: PCX_BMP.EXE <Имя файла>" << endl; // вывод на экран подсказки

}