1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
| Program PCX_Viewer;
uses
Dos, graph, Crt;
const
MaxBufLen = 65520; {Размер буфера (в кортежах) для хеш-таблицы, которая будет использоваться во время выполнения операции соединения}
type
RGB = record {запись описания способа синтеза цвета для цветовоспроизведения}
Red,
Green,
Blue : Byte;
end;
PCXHeader = record { Заголовок библиотеки изображений }
Maker : Byte;
Version : Byte; { Версия pcxLib }
Code : Byte; {групповое кодирование}
BitsPerPixel : Byte; {количество бит на точку пиксела}
XLow : Word; {минимальное значение ширины экрана}
YLow : Word; {минимальное значение длины экрана}
XHigh : Word; {максимальное значение ширины экрана}
YHigh : Word; {максимальное значение длины экрана}
Hres : Word; {Гориз.разрешение дисплея}
Vres : Word; {Вертик.разрешение дисплея}
Palette : array [0..15] of RGB; {поскольку данная палитра содержит 256 цветов, то формат PCX может поддерживать только 16 цветов как максимум, поэтому палитра не может храниться в заголовке изображения по своему обычному адресу}
VMode : Byte; {игнорируется}
PlaneCount : Byte; {оператор поддержки точечных рисунков}
BytesPerLine : Word; {элемент определения количества байтов в строке развертки в результирующем файле изображения}
Reserved : array [0..59] of byte;
end;
BufType = array [1..MaxBufLen] of Byte; {обработка идентификатора типа проектного решения изображения при выводе на экран}
PtrToByte = ^Byte; {чтение байт из адреса памяти для хранения всей палитры VGA}
Pallette = array [0..255] of RGB; {палитра содержит 256 цветов}
var
PCXFile : File; {файл типа PCX}
FileName : PathStr; {Имя файла изображения}
Header : PCXHeader; { Заголовок библиотеки изображений }
VGAPtr : PtrToByte; { диапазон значений которой состоит из адресов ячеек памяти и специального значения — нулевого адреса, указатель, хранящий специальное значение, используемое для того, чтобы показать, что данная переменная-указатель не ссылается (не указывает) ни на какой объект}
Count : Byte; {Возвращаемый результат счетчика}
Data : Byte; {тип байтовых данных,всегда определяется, как, составляющая из 8 битов будучи подписанной типом данных, держа значения −128 до 127 байт}
i : Byte;
Regs : Registers; {число регистров}
PlaneNum : Byte;{точечный рисунок, в котором мы будем работать}
Bytes : Word; {число байт на точку изображения}
Lines : Word; {строки разрешения экрана}
Buf : ^BufType; {тип буфера}
BufPtr : Word; {діапазон значений буфера}
BufLen : Word; {длина буфера}
Pal : Pallette; {значение палитры}
VGAFile : Boolean; {логический тип файла VGA}
Function RGBColor(ColorNum : Byte) : Byte; {функция комбинирования красных, зеленых, и голубых значений к единственному RGB значению цвета}
begin
RGBColor := (((Header.Palette[ColorNum].Red div 85) and 1) shl 5) +
(((Header.Palette[ColorNum].Red div 85) and 2) shl 1) +
(((Header.Palette[ColorNum].Green div 85) and 1) shl 4) +
(((Header.Palette[ColorNum].Green div 85) and 2) shl 0)+
(((Header.Palette[ColorNum].Blue div 85) and 1) shl 3)+
(((Header.Palette[ColorNum].Blue div 85) and 2) shr 1);
end;
BEGIN
FileName := ParamStr(1); {присвоение имени файла первого параметра командной строки}
Write('File name : '); {ввод имени файла}
if FileName = '' then
ReadLn(FileName) {Считывание имени файла}
else
WriteLn(FileName); {если данные операции выполнены некорректно, то ввести повторно имя файла}
Assign(PCXFile, ParamStr(1)); {данный оператор позволяет связать имя файла с первым параметром командной строки, т.е. для указания адреса расположения файла}
Reset(PCXFile, 1); {считывание данных из файла и его адреса}
BlockRead(PCXFile, Header, SizeOf(PCXHeader)); {данный оператор используется для чтения записей заголовка и размера заголовка PCX файла в Buffer из не типизированного двоичного файла, данного PCXFile}
VGAFile := Header.BitsPerPixel = 8; { Если 8 бит, то 256 цветов}
if VGAFile then
begin
Seek(PCXFile, FileSize(PCXFile)-SizeOf(Pal)); {поиск данных PCXFile, размера файла, в 256-цветовом файле}
BlockRead(PCXFile, Pal, SizeOf(pal)); { чтение записей заголовка и размера палитры файла в Buffer из не типизированного двоичного файла, данного PCXFile}
Seek(PCXFile, SizeOf(header)); {поиск данных PCXFile, размера заголовка файла}
end;
New(Buf); {cоздание нового буфера т.е. увеличивает объектный контрольный счет, чтобы позволить управлению памяти удалить ресурс}
BufLen := 0; {длина буфера}
BufPtr := 1; {число значений диапазона буфера}
Lines := 0; {число строк экрана}
if VGAFile then
asm {использование элементов встроенного ассемблера для пpоцедуpы загpузки VGA палитpы}
lea si, pal {адрес поиска 256 цветовой палитры}
mov cx, 768 {поскольку палитра VGA 256 цветовая, то для её хранения требуется 768 байт}
@1: {операция метки или взятия адреса у значений дипазона буфера}
shr byte ptr [si], 1 {Сдвиг значений выражения вправо на число бит заданных значением счетчика и приведение адресного выражения к размеру в байт 16 разрядного регистра, поскольку заголовок PCX файлов может максимум поддерживать 16 цветов}
shr byte ptr [si], 1
inc si {подключение 16 разрядного индексного регистра}
loop @1 {организация цикла для метки значения диапазона буфера}
mov ax, 0013h {допустимое разрешение файла 320x200x256 colors }
int 10h {установка видео режима для изображения}
mov ax, 1012h {установка набора регистров палитры VGA}
xor bx, bx {очищение 16 разрядного регистра общего назначения}
mov cx, 256 {количество цветов палитры VGA}
mov dx, seg pal {непосредственное значение палитры}
mov es, dx {использование 16 разрядного сегментного регистра с регистром общего назначения}
mov dx, offset pal {Возвращение смещения следующего за операцией выражения (младшее слово) результатом будет непосредственное значение палитры}
int 10h {установка видео режима для изображения c использованием палитры VGA}
end
else
begin
[B]Regs.AX:=$0010;
Intr($10, Regs);
for i := 0 to 15 do
begin
Regs.AH := $10;
Regs.AL := 0;
Regs.BL := i;
Regs.BH := RGBColor(i);
Intr($10, Regs);
end;
{ Write mode }
Port[$3CE] := 5; { Инит поpтов для записи. }
Port[$3CF] := 0;
Bytes := 1;
PlaneNum := 1;
Port[$3C4] := 2; { План #1. }
Port[$3C5] := 0;
end;
VGAPtr := Ptr($A000, $0000);
repeat
if BufPtr > BufLen then
begin
BlockRead(PCXFile, Buf^, MaxBufLen, BufLen);
BufPtr := 1;
end;
Data := Buf^[BufPtr];
Inc(BufPtr);
if Data and $C0 = $C0 then { Распаковка RLE-компpессии. }
begin
Count := Data and $3F;
if BufPtr > BufLen then
BlockRead(PCXFile, Data, 1)
else
begin
Data := Buf^[BufPtr];
Inc(BufPtr);
end;
end
else
Count := 1;
for i := 1 to Count do
begin
PtrToByte(Longint(VGAPtr) + Bytes - 1)^ := Data;
Inc(Bytes);
if Bytes > Header.BytesPerLine then
begin
Bytes := 1;
if VGAFile then
begin
Inc(Longint(VGAPtr), Header.BytesPerLine); { VGA => пpосто увели- }
Inc(Lines); { чить счетчик. }
end
else
begin { EGA => пеpеключать }
if PlaneNum > 3 then { планы от 0 до 3, а }
begin { потом - счетчик. }
PlaneNum := 0;
Inc(Longint(VGAPtr), Header.BytesPerLine);
Inc(Lines);
end;
Inc(PlaneNum);
Port[$3C4] := 2; { Собственно выбоp }
Port[$3C5] := 1 shl (PlaneNum-1); { плана. }
end;
end;
end;
until Lines > Header.YHigh;
ReadKey;
Dispose(Buf);
Close(PCXFile);
TextMode(3);
END.[/B] |