Реализация алгоритма просмотра файла PCX.
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Вывод на экран картинки, хранящейся в PCX-файле, начинается с чтения заголовка файла. С помощью этого определяется является ли этой файл форматом PCX (manufacturer должен быть равен 10), размеры изображения, информации о палитре, число цветовых слоев. После чего происходит переход на 768 байт с конца файла для чтения набора цветовой палитры и с помощью функции Set_palette заполнение цветовой палитры значениями.

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

 

Реализация алгоритма просмотра файла BMP.

Вывод на экран картинки, хранящейся в BMP-файле, начинается с чтения заголовка файла и информационного заголовка. Программа таким образом проверяет является ли этот файл графически форматом BMP (сигнатура должна быть ‘BM’) а так же узнает размеры изображения и количество цветов.

Затем программа читает цветовую таблицу. После чего программа с помощью функции Set_palette заполняет цветовую палитру значениями из цветовой таблицы. Таким образом, обеспечивается правильная передача цветов картинки. Если компьютер способен отобразить тысячи или миллионы цветов одновременно, то цветовую палитру заполнять не нужно.

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

 

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

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

typedef unsigned char byte

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

 

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

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

 

int MaxX, MaxY

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

 

VidMode=0x13

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

 

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

struct pcxHeaderType

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

 

struct bmpHeaderType

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

 

void set_mode (void)

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

 

void set_text (void)

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

 

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

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

 

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

Вывод пиксела установленного цвета в позицию 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[])

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

 

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

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

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

 

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

 

Примеры:

          PCX_BMP.EXE TEST.PCX

          PCX_BMP.EXE TEST.BMP

 

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

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

 

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

 

В каталоге 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. Справочное руководство по IBM PC. Часть 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

{

char manufacturer; // всегда 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

struct bmpHeaderType

{

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;                                       // координаты пиксела

unsigned int width;                    // ширина картинки

 

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; // вывод на экран подсказки

}

Дата: 2019-12-10, просмотров: 249.