Форум: "Начинающим";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];
ВнизПомогите с реализацией алгоритма Найти похожие ветки
← →
Gens © (2006-09-03 15:20) [0]Здравствуйте уважаемые,надеюсь вы мне поможите с моими затруднениями возникшими в процессе разработки.Я использую Kol+MCK, но это не суть важно.И так:
Файл грубо говоря выглядит следующим образом
В начале заголовок:
GRPHeader: record
Sprites: LongInt; //Количество спрайтов
FullWidth: LongInt; //Полная ширина изображения
FullHeight: LongInt; //Полная высота изображения
End;
По адресу $06 располагается SAT (Sprite Allocation Table) - таблица расположе-
ния спрайтов. Каждая запись имеет следующую структуру:
SATRecord: record
OffsetLeft: Byte; //Смещение спрайта от левого края изображения
OffsetTop: Byte; //Смещение спрайта от верхнего края изображения
SpriteWidth: Byte; //Ширина спрайта
SpriteHeight: Byte; //Высота спрайта
Offset: LongInt; //Смещение до данных спрайта
End;
Считываю данные следующим образом:
var
GprStream,NewStream: PStream;//Потоки для открытия и конвертирования спрайтов
Sprites: LongInt; //Количество спрайтов
FullWidth: LongInt; //Полная ширина изображения
FullHeight: LongInt; //Полная высота изображения
OffsetLeft: Byte; //Смещение спрайта от левого края изображения
OffsetTop: Byte; //Смещение спрайта от верхнего края изображения
SpriteWidth: Byte; //Ширина спрайта
SpriteHeight: Byte; //Высота спрайта
Offset: LongInt; //Смещение до данных спрайта
BMPHeader: RECORD //Заголовок *.bmp формата(необходим для конвертирования)
FullSize: LongInt;
_H1: LongInt;
_C1: LongInt;
_C2: LongInt;
X: LongInt;
Y: LongInt;
_C3: Word;
_C4: Word;
_H2: LongInt;
_H3: LongInt;
DataSize1: LongInt; //DataSize=X*Y+2*Y
DataSize2: LongInt; //DataSize=X*Y+2*Y
_C5: ARRAY[1..8]OF Byte;
END;
inplemenation
Procedure OpenGpr(FileName: string;ProgressBar:PControl);
var
Binfo: longInt;
begin
GprStream:=NewReadFileStream(FileName);
ProgressBar.Position:=0;
ProgressBar.MaxProgress:=GprStream.Size;
ProgressBar.Position:=GprStream.Position;
GprStream.Seek(Binfo,spBegin);
While GprStream.Position < $06 do //Пока позиция не равна позиции SAT читаем Header
begin
GprStream.Read(Sprites,4);
GprStream.Read(FullWidth,4);
GprStream.Read(FullHeight,4);
end;
if GprStream.Position = $06 then
repeat
begin
GprStream.Read(OffsetLeft,1);
GprStream.Read(OffsetTop,1);
GprStream.Read(SpriteWidth,1);
GprStream.Read(SpriteHeight,1);
GprStream.Read(Offset,4);
{***расшифровка спрайта***}
until
end;
Собственно трудности с реализацией расшифровки спрайта - алгоритм выглядит следующим образом:
В заголовке спрайта последовательно
размещены смещения на каждую из строк спрайта. Наша задача состоит в том, чтобы
последовательно перейти на начало каждой строки и по определенной схеме эту
строку расшифровать . Да, да , именно расшифровать, потому что этот формат ока-
зался не таким уж простым. Во всяком случае - на первый взгляд . Итак, будем
считать, что мы перешли к некой строке. Строка состоит из нескольких сегментов.
Каждый сегмент состоит из байта-описателя и, собственно, байтов данных. Левые 2
бита байта-описателя определяют тип сегмента (в дальнейшем - Type), остальные 6
бит - длина сегмента (в дальнейшем - Length). Вот возможные типы сегментов и их
значения:
*** Таблица типов сегментов ***************************************************
b00 - Сегмент представляет собой последовательность пикселей. Группа пикселей
длиной в Length считывается сразу за байтом - описателем.
b01 - Сегмент представляет собой последовательность одинаковых пикселей длиной
в Length. Образец пикселя считывается сразу за байтом-описателем.
b10 - Сегмент представляет собой последовательность прозрачных пикселей длиной
в Length.
b11 - Сегмент представляет собой последовательность прозрачных пикселей длиной
в Length+64.
*******************************************************************************
Рассмотрим конкретный пример строки.
*** Образец строки ****************************
86 09 47 8F 8F 44 46 8D 42 8E 49 44 94 01 49 9E
***********************************************
1. Позиция в строке - $00: байт-описатель первого сегмента - $86. Разбиваем
его на левую (2 бита) часть и правую (6 бит). Левая равняется b10 - это тип
сегмента. Правая - b000110, или d6 - это длина сегмента. Значит, тип равен
b10. Следовательно сегмент этот определяет прозрачную строку длиной в 6 пик-
селей. Раз пиксель прозрачный, значит его значение нам считывать не нужно -
оно всегда равняется $00. Получаем первые 6 пикселей строки.
2. Позиция в строке - $01: байт-описатель второго сегмента - $09. Type=b00,
Length=d9. Тип b00 подразумевает чтение группы байтов длиной в 9 и формиро-
вания из них строки.
3. Позиция в строке - $0B: байт-описатель третьего сегмента - $44. Type=b01,
Length=d4. Раз тип равен b01 , значит строка длиной в 4 пикселя состоит из
одинавовых пикселей, образец которого помещается в следующем байте.
4. Позиция в строке - $0D: байт-описатель четвертого сегмента - $01.Type=b00
, Length=d1. Читаем следующий байт. Это и будет короткий сегмент.
4. Позиция в строке - $0F: байт-описатель пятого сегмента - $9E.Type=b10,
Length=d30. Это - прозрачный сегмент длиной в 30 пикселов.
Таким образом, в сумме все эти сегменты образуют полную строку длиной в 50 пик-
селов (6+9+4+1+30). Таким же образом разбираются и остальные строки.
Так вот.......Как это реализовать???Заранее благодарен.
← →
SerJaNT © (2006-09-03 15:23) [1]Нихрена себе, и это в разделе для начинающих... Если не секрет, для чего это?
← →
Zeqfreed © (2006-09-03 15:40) [2]В чем конкретно трудности? А то такое ощущение, что опять требуют готового кода.
← →
Gens © (2006-09-03 15:42) [3]Для открытия и конвертирования графики из старкрафта=)И для собственного обучения=)
← →
Gens © (2006-09-03 15:48) [4]А трудности вот в чём...Как байт разбить на биты и произвести необходимые вычисления?
← →
Zeqfreed © (2006-09-03 15:50) [5]> [4] Gens © (03.09.06 15:48)
Посредством логических операторов and, or и др.
← →
Desdechado © (2006-09-03 15:53) [6]> GRPHeader: record
> Sprites: LongInt; //Количество спрайтов
> FullWidth: LongInt; //Полная ширина изображения
> FullHeight: LongInt; //Полная высота изображения
> End;
> По адресу $06 располагается SAT
Вообще-то longint - 4 байта. Поэтому record имеет длину 12, а не 6.
Да и то,только в случае packed record. Для спрайтов это тоже актуально.
← →
Gens © (2006-09-03 16:20) [7]Можно пример разбиения байта на биты?
← →
Zeqfreed © (2006-09-03 16:24) [8]> [7] Gens © (03.09.06 16:20)
http://delphimaster.net/view/2-1157121160/
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.09.24;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.043 c