Ранее я уже публиковал информацию по хранению несжатой графики на различных игровых системах (http://pscd.ru/forum/index.php?/topic/316-khranenie-neszhatoi-grafiki-na-razlichnykh-igrovy/). Теперь подошла очередь и до Sony PlayStation.
Сам я начал недавно разбираться, как же всё же устроены TIM файлы для PlayStation. Поэтому надеюсь на помощь экспертов, если я где-то что-то упущу или перепутаю. Так же буду приводить свои догадки, какие могут оказаться не верными.
Для начала немного общей информации
В файлах формата *.TIM чаше всего в играх и программах для PSX хранится графическое изображение, проще говоря, картинка / рисунок / фотография. Судя по всему, имеется четыре распространенных формата хранения данных:
4-bit (color indices)
8-bit (color indices)
16-bit (actual colors)
24-bit (actual colors)
Возможно, есть и другие, так сказать авторские.
Заголовок занимает 20 байт, дальше идут данные изображения. Байты хранятся в перевёрнутом виде.
TIM 4-bit (color indices) (http://pscd.ru/forum/index.php?/topic/360-tim-faily--format-khraneniia-grafiki-psx/?p=3683)
TIM 8-bit (color indices) (http://pscd.ru/forum/index.php?/topic/360-tim-faily--format-khraneniia-grafiki-psx/?p=3685)
TIM 16-bit (actual colors) [TBGR / A1B5G5R5] (http://pscd.ru/forum/index.php?/topic/360-tim-faily--format-khraneniia-grafiki-psx/?p=3647)
TIM 24-bit (actual colors) [RGB / R8G8B8] (http://pscd.ru/forum/index.php?/topic/360-tim-faily--format-khraneniia-grafiki-psx/?p=3721)
TIM файл с несколькими палитрами (4-bit и 8-bit) (http://pscd.ru/forum/index.php?/topic/360-tim-faily--format-khraneniia-grafiki-psx/?p=3695)
Дополнительная информация:
Quake II Текстуры (Графика) [PSX] (http://pscd.ru/forum/index.php?/topic/492-quake-ii-tekstury-grafika-psx/)
TIM 16-bit (actual colors) [TBGR / A1B5G5R5]
В самом устройстве
TIM нет ничего сложного, кроме формата хранения (присвоения) палитры пикселю.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-96266300-1431242323.png)
В качестве примера будем рассматривать прикрепленный файл
SPIN.TIM. Это изображение размером
188x24.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-52397200-1431242324.png)
Вид в
Hex-редакторе.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-74151100-1431242324.png)
Константа (постоянное значение), видимо для обозначения, что это формат
TIM.
Первые
4 байта можно назвать
константой = 0x
10000000. (
Дополнение от TTEMMA)
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-96945600-1431242324.png)
Следующие
4 байта, обозначают какого
типа (формата) будут
данные (будет
TIM файл). В нашем случае это
16-bit (A1B5G5R5).
Следующие
4 байта =
тип изображения: (
Дополнение от TTEMMA)
- 0x08 = 4-bit
- 0x09 = 8-bit
- 0x02 = 16-bit
- 0x03 = 24-bit
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-15252900-1431242325.png)
Размер файла. Отсчёт начинает с
8h. То есть с того место, где начинается информация об изображении. Данные хранятся в перевёрнутом виде. Размер данных составляет
0x234C (отсчёт с
$8 до
$2353 включительно). В файле данные имеют вид
4C 23. Для нормального восприятия нужно переставить байты местами. Сделав это,
мы получим 23 4C, собственно говоря, это и есть
размер данных.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-36720000-1431242325.png)
Ширина (длинна) изображения в пикселях по X. У нас оно составляет
188 пикселей. Что соответствует в байтах
00 BC. В файле данное значение записано как
BC 00. То есть в перевёрнутом виде.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-58220700-1431242325.png)
Высота изображения в пикселях по Y. У нас оно составляет
24 пикселя. Что соответствует в байтах
00 18. В файле данное значение записано как
18 00. То есть в перевёрнутом виде.
Всё остальное данные (с
14h) это пиксели идущие друг за другом.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-16272100-1431242324.png)
Один пиксель состоит из двух байт.
Дальше начинается самое сложное. Данные хранятся в виде (порядке)
TBGR (Transparency, Blue, Green, Red (Прозрачность, Синий, Зелёный, Красный)) /
A1B5G5R5.
Сначала идёт бит устанавливающий прозрачность. Затем
на каждый из цветов приходится по 5 бит. Таким образом, мы имеем
15-bit RGB (
R5 G5 B5).
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-85044600-1431242301.png)
Поскольку данные в файле хранятся в перевёрнутом виде, чтобы с ними работать их нужно перевести в нормальный вид. В файле один пиксель записан как
18 63. Меняем байты местами и получаем
63 18. С этими данными нам и предстоит работать.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-52160300-1431242302.png)
Дальше нам предстоит работать с битами.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-32078300-1431242302.png)
В битах данные имеют следующий вид:
0 11000 11000 11000 Теперь нужно преобразовать эту информацию в
RGB.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-07691800-1431242302.png)
Для лучшего восприятия
5 битам приписываем
3 нулевых
бита в начало.
Было:
11000 Стало:
00011000 Теперь
8 бит, преобразовываем в цифры. 00011000 =
24 И это число нужно умножить на
8.
24 *
8 =
192 (http://pscd.ru/forum/uploads/monthly_05_2015/post-1-0-60919300-1431244867.jpg)
Теперь остаётся вписать данные на своё место и мы получим цвет пикселя. В данном случае это один из оттенков серого.
SPOT, большое спасибо за предоставленную информацию, даже я понял, о чём идёт речь. Информация подана очень хорошо и понятно. Продолжайте в том же духе.
В начале слегка неверно, первые 4 байта можно назвать константой = 0x10000000
Следующие 4 байта = тип изображения:
- 0x08 = 4-bit
- 0x09 = 8-bit
- 0x02 = 16-bit
- 0x03 = 24-bit
Дальше идёт информация либо о палитре(если 4 или 8 битное изображение), либо о самом изображение(16 или 24 битное изображение).
Структура палитры такова:
- 4 байта = размер палитры + 0x0C
- 2 байта = VramX
- 2 байта = VramY
- 2 байта = Ширина
- 2 байта = Высота
- Сама палитра
Следом после палитры идёт информация о изображении:
- 4 байта = размер изображения + 0x0C
- 2 байта = VramX
- 2 байта = VramY
- 2 байта = Ширина
- 2 байта = Высота
- Само изображение
Так же, кол-во палитр в файле означает высота.(Если 4 или 8 битное изображение).
Есть ещё нюансы по ширине и изображения:
4 битное изображение
8 битное изображение
Вроде, пока что, всё :)
TTEMMA, спасибо за информацию. Внёс правки.
Что такое VramX и VramY? Это типа куда в видеопамять записать данный элемент, так почему по осям? Или потому что в PSX данные во Vram хранятся в пикселях, а не в тайлах как например в SMD.
TIM 4-bit (color indices)
Этот принцип хранения данных и построения изображения схож с принципом хранения графических данных в 16-битных игровых системах.(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-07714300-1431426279.png)
В качестве примера мы будем рассматривать
TIM файл
CALLSIGN.TIM из игры Twisted Metal 2 (http://pscd.ru/games/psx/t/1146-twisted-metal-2.html). Данный файл я прикреплю к сообщению. Это изображение размером
128x64.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-61559600-1431426278.png)
Вид в
Hex-редакторе.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-23307900-1431426279.png)
Константа дающая понять, что это
TIM файл.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-41239800-1431426279.png)
Следующие
4 байта, обозначают
какого типа (формата)
будет TIM файл. В нашем случае это
4-bit (color indices).
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-52318700-1431426279.png)
Далее идёт
информация о палитре. (
Напомню, что данные хранятся в перевёрнутом виде)
Структура палитры такова:
- 4 байта = размер палитры + 0x0C
- 2 байта = VramX
- 2 байта = VramY
- 2 байта = Ширина
- 2 байта = Высота
- Сама палитра
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-18064400-1431426772.png)
Размер данных относящихся к палитре. 0x
2C то есть
44 байта,
32 байта из которых занимает сама палитра.
По 2 байта на 1 цвет.
Всего 16 цветов.
Скорее всего, 0x2C000000 можно считать константой. Не думаю, что тут может быть какое-то другое значение. (http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-33160400-1431426278.png)
2 байта =
VramX (http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-99278100-1431426287.png)
2 байта =
VramY (http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-23285000-1431426288.png)
2 байта =
Ширина (http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-10735800-1431426288.png)
Количество палитр. В данном случае
одна палитра.
(2 байта =
Высота)
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-35448800-1431426288.png)
Палитра. Данные
занимают 32 байта. По
2 байта на один цвет. Палитра хранится в формате
TBGR / A1B5G5R5. Данные хранятся в перевёрнутом виде.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-49394400-1431426288.png)
Первый цвет.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-50264600-1431426278.png)
Поскольку данные хранятся в перевёрнутом виде, для визуального восприятия их нужно перевернуть. То есть было
FF 7F, а мы его перевернули и получили
7F FF.
Дальше мне лень повторяться и писать, как узнать какому цвету соответствует данное значение. Нужно просто действовать точно так же как и в случае с TIM 16-bit (actual colors) [TBGR / A1B5G5R5] (http://pscd.ru/forum/index.php?/topic/360-tim-faily--format-khraneniia-grafiki-psx/?p=3647). (http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-67968500-1431426288.png)
Размер, занимаемый данными изображения плюс 0x0C.
4 байта = размер изображения + 0x
0CДанные хранятся в перевёрнутом виде
0C 10 00 00. Для нормального восприятия их нужно перевернуть. Перевернув их, мы получим
00 00 10 0C.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-81216700-1431426288.png)
2 байта =
VramX (http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-92843200-1431426288.png)
2 байта =
VramY (http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-18618100-1431426289.png)
Ширина (длинна) изображения в пикселях по X. У нас оно составляет
128 пикселей. В файле данное значение записано как
20 00. То есть в перевёрнутом виде. Мы должны перевернуть это значение
00 20. Преобразовав
00 20 в десятичную систему счисления, мы получим значение 32. Теперь данное значение нужно умножить на
4.
32 *
4 =
128 Вот мы и получили ширину в пикселях.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-05802800-1431426289.png)
Высота изображения в пикселях по Y. У нас оно составляет
64 пикселя. Что соответствует в байтах
00 40. В файле данное значение записано как
40 00. То есть в перевёрнутом виде.
Начиная с
40h идут данные самого изображения. Метод хранения схож с методом хранения несжатой графики в GBA (http://pscd.ru/forum/index.php?/topic/316-khranenie-neszhatoi-grafiki-na-razlichnykh-igrovy/?p=3276).
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-94228300-1431426278.png)
Один
пиксель занимает пол байта, то есть
4 бита. Значение от
0 до
F, что соответствует от
1 до
16.
Палитра состоит из 16 цветов. Каждому цвету
соответствует значение из 4 бит.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-77537400-1431426278.png)
Данные хранятся в перевёрнутом виде. Сначала идёт второй пиксель, а потом первый.
Честно, точно не знаю для чего VramX, VramY. Вроде, расположение TIM в видеопамяти, но я не уверен.
Потом, в статье о 16-bit 2 раза повторяется "Следующие 4 байта".
Потом в статье по 4 байта, где вы говорите, мол размер палитры можно считать константой - надо исправить, ибо размер палитры может быть и меньше, это зависит от изображения. Так же, не забывайте, что в файле может быть несколько палитр. На кол-во палитр указывают последние 2 байта(Высота).
К примеру, возьмём шрифт из RE2.
0xAC - Размер палитры в целом, то бишь 0х14+A0 = начала блока с информацией об изображении.(размер, высота, ширина и т.д.)
0x05 - Кол-во палитр в файле.
Следовательно, 0x20 на каждую палитру.
К примеру, если выбрать 2 палитру, то цвет текста с белого меняется на зелёный.
TIM 8-bit (color indices)
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-93114900-1431445901.png)
В качестве примера мы будем рассматривать
TIM файл
CAB_CARD.TIM из игры Twisted Metal 2 (http://pscd.ru/games/psx/t/1146-twisted-metal-2.html). Данный файл я прикреплю к сообщению. Это изображение размером
128x64.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-77904600-1431445901.png)
Вид в
Hex-редакторе.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-95184500-1431445891.png)
Константа дающая понять, что это
TIM файл.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-10573700-1431445892.png)
Следующие
4 байта, обозначают какого типа (формата) будет
TIM файл. В данном случае это
8-bit (color indices).
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-26418100-1431445892.png)
Размер данных относящихся к палитре. 0x
2C то есть
524 байта, 512 байта из которых занимает сама палитра.
По 2 байта на 1 цвет.
Всего 256 цветов.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-47088100-1431445892.png)
2 байта =
VramX (
для палитры)
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-72956200-1431445892.png)
2 байта =
VramY (
для палитры)
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-21535000-1431445893.png)
2 байта =
Ширина (
для палитры)
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-06383700-1431445893.png)
Количество палитр. В данном случае
одна палитра.
(2 байта =
Высота (
для палитры))
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-59605700-1431445901.png)
Палитра. Данные
занимают 200 байта. По
2 байта на один цвет.
Всего 256 цветов. Палитра хранится в формате
TBGR / A1B5G5R5. Данные хранятся в перевёрнутом виде.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-90075100-1431445892.png)
Первый цвет.
Как определить какому цвету соответствуют данные читайте в TIM 16-bit (actual colors) [TBGR / A1B5G5R5] (http://pscd.ru/forum/index.php?/topic/360-tim-faily--format-khraneniia-grafiki-psx/?p=3647). (http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-67577100-1431445891.png)
Размер, занимаемый данными изображения плюс 0x0C.4 байта = размер изображения + 0x
0CДанные хранятся в перевёрнутом виде
0C 20 00 00. Для нормального восприятия их нужно перевернуть. Перевернув их, мы получим
00 00 20 0C.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-99521500-1431445900.png)
2 байта =
VramX (
для изображения)
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-13384700-1431445901.png)
2 байта =
VramY (
для изображения)
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-82543500-1431445900.png)
Ширина (длинна) изображения в пикселях по X. У нас оно составляет
128 пикселей. В файле данное значение записано как
40 00. То есть в перевёрнутом виде. Мы должны перевернуть это значение
00 40. Преобразовав
00 40 в десятичную систему счисления, мы получим значение 64. Теперь данное значение нужно умножить на
2.
32 *
2 =
128 Вот мы и получили ширину в пикселях.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-69289100-1431445900.png)
Высота изображения в пикселях по Y. У нас оно составляет
64 пикселя. Что соответствует в байтах
00 40. В файле данное значение записано как
40 00. То есть в перевёрнутом виде.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-24394900-1431445901.png)
Один пиксель занимает
8 бит или, проще говоря, равен
одному байту. Счёт идёт от
00 до
FF, то есть всего
256 значений.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-41900200-1431445901.png)
Цитата: TTEMMA от 12 мая 2015, 17:44мол размер палитры можно считать константой - надо исправить, ибо размер палитры может быть и меньше,
Мне кажется, что размер всё же фиксированный. Для
4-bit (color indices) это палитра из
16 цветов. Для
8-bit (color indices) это
256 цветов.
Цитата: TTEMMA от 12 мая 2015, 17:44Так же, не забывайте, что в файле может быть несколько палитр.
Вот это нужно изучить :)
Кто знает в какой игре есть
TIM в формате 24-bit (actual colors)?
ЦитироватьМне кажется, что размер всё же фиксированный.
Только кажется, размер зависит от кол-во палитр и типа изображения.
TTEMMA, Скинь (залей) файл из RE2, где несколько палитр используется. Если не сложно.
Да, конечно.
1 файл - 4 битное
2 файл - 8 битное
TIM файл с несколькими палитрами (4-bit и 8-bit)
Кратко рассмотрим вариант с
несколькими палитрами в TIM файлах. В начале идёт значение указывающие на
количество палитры в файле, затем разными цветами выделена
палитра.
4-bit (color indices)
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-70152100-1431497848.png)
8-bit (color indices)
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-36427300-1431497848.png)
Ещё раз повторю вопрос:
Кто знает в какой игре есть TIM в формате 24-bit (actual colors)?
Вот пример.
Цитата: TTEMMA от 15 мая 2015, 10:12Вот пример.
Благодарю.
А данный формат (24-bit (actual colors)) в играх для
PSX встречается? Или он для
PS2?
Встречается, редко, но встречается.
В PS2 идёт уже tm2(TIM2)
24-bit (actual colors) [RGB / R8G8B8]
Заголовок (
первые 20 байт) имеют точно такое же значение, как и в случае с
TIM 16-bit (actual colors) (http://pscd.ru/forum/index.php?/topic/360-tim-faily--format-khraneniia-grafiki-psx/?p=3647). Поэтому рассматривать данные значения не будем.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-22765600-1431758506.png)
За исключением обозначения ($4) 0x
03000000. Данные байты указывает на то, что это
24-bit (actual colors).
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-84729800-1431758506.png)
С
14h ($
14) хранится набор пикселей.
Один пиксель занимает 3 байта. В отличие от предыдущих вариантов. Данные здесь хранятся
не в перевёрнутом виде.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-07808700-1431758507.png)
По сравнению с
16-bit (actual colors) тут всё просто.
Данные идут подряд в RGB и на каждый из цветов приходится по
8 бит (
R8 G8 B8), то есть
по одному байту.
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-30275400-1431758507.png)
Переводим байты в десятичную систему счисления.
E9 = 233
D4 = 212
B5 = 181
(http://pscd.ru/forum/uploads/monthly_05_2015/post-95-0-55149800-1431758506.jpg)
Теперь вписываем данные на свои места и
получаем исходный цвет.
Опишите пожалуйста метод хранения графики в TIM2 если нужны примеры файлов здесь они есть rutracker.org/forum/viewtopic.php?t=4514120
SPOT твои объяснения о хранению несжатой графики о очень просто и понятны,СПАСИБО ТЕБЕ БОЛЬШОЕ за них.
Цитата: zetper от 29 августа 2015, 15:39Опишите пожалуйста метод хранения графики в TIM2 если нужны примеры файлов здесь они есть rutracker.org/forum/viewtopic.php?t=4514120
SPOT твои объяснения о хранению несжатой графики о очень просто и понятны,СПАСИБО ТЕБЕ БОЛЬШОЕ за них.
gtamodding.ru/wiki/TIM2
Цитата: TTEMMA от 01 сентября 2015, 08:31
Цитата: zetper от 29 августа 2015, 15:39Опишите пожалуйста метод хранения графики в TIM2 если нужны примеры файлов здесь они есть rutracker.org/forum/viewtopic.php?t=4514120
SPOT твои объяснения о хранению несжатой графики о очень просто и понятны,СПАСИБО ТЕБЕ БОЛЬШОЕ за них.
gtamodding.ru/wiki/TIM2
В статье с gtamodding описано всё языком профессионала,а хотелось бы видеть в простом виде как в этой статье, где всё разложено по полочка и наглядно.
Цитата: zetper от 29 августа 2015, 15:39Опишите пожалуйста метод хранения графики в TIM2 если нужны примеры файлов здесь они есть
SPOT твои объяснения о хранению несжатой графики о очень просто и понятны,СПАСИБО ТЕБЕ БОЛЬШОЕ за них.
Сейчас напряг со свободным временем, как оно появится обязательно займусь разборкой и описанием
TIM2.
По быстрому накидал код для извлечения изображений из TIM в PNG:
Type
TBpp = (Bpp_4 = 8, Bpp_8 = 9, Bpp_16 = 2, Bpp_24 = 3);
TTim_Palette = packed record
Size : LongWord;
VramX : Word;
VramY : Word;
Width : Word;
Height : Word;
end;
TTim_Image = Packed Record
Size : LongWord;
VramX : Word;
VramY : Word;
Width : Word;
Height : Word;
end;
TTim = Packed Record
Bpp : TBpp;
Tim_Palette : TTim_Palette;
Tim_Image : TTim_Image;
const
ID : LongWord = $10;
end;
Procedure GetRGB555(Color : Word;var R,G,B:Byte);
begin
R := (Color and $1F) * 8;
G := ((Color shr 5) and $1F) * 8;
B := ((Color shr 10) and $1F) * 8;
end;
Function Create_HPalette(Stream:TStream;Count:Word):HPalette;
var
I:Integer;
_Pal:PLogPalette;
w:word;
begin
_Pal := 0;
GetMem(_pal, sizeof(TLogPalette) + sizeof(TPaletteEntry) * Count);
_Pal.palVersion := $300;
_Pal.palNumEntries := Count;
for I := 0 to Count-1 do
begin
Stream.Read(w,2);
GetRGB555(w,_Pal.palPalEntry[i].peRed,_Pal.palPalEntry[i].peGreen,_Pal.palPalEntry[i].peBlue);
_Pal.palPalEntry[i].peFlags := 0;
end;
Result := CreatePalette(_PAL^);
end;
Function Convert_Tim_To_PNG(TIM_Stream:TStream; Palette_Number: Byte):TPNGImage;
var
TIM : TTIM;
L : LongWord;
scanline : pByteArray;
RGBScanline : pRgbLine;
_Palette : HPalette;
B : Byte;
w : Word;
I,x,y :Integer;
begin
TIM_Stream.Position := 0;
TIM_Stream.Read(l,4);
if l = TTim.ID then
begin
TIM_Stream.Read(TIM.Bpp,4);
case TIM.Bpp of
Bpp_4: begin
TIM_Stream.Read(TIM.Tim_Palette,SizeOF(TIM.Tim_Palette));
_Palette := 0;
for I := 1 to TIM.Tim_Palette.Height do
begin
if i = Palette_Number then
_Palette := Create_HPalette(TIM_Stream,16) else
TIM_Stream.Position := TIM_Stream.Position + $20;
end;
TIM_Stream.Read(TIM.Tim_Image,SizeOf(Tim.Tim_Image));
Tim.Tim_Image.Width := TIM.Tim_Image.Width * 4;
Result := TPngImage.Create;
Result.CreateBlank(COLOR_PALETTE,8,Tim.Tim_Image.Width,Tim.Tim_Image.Height);
Result.Palette := _Palette;
for y := 0 to TIM.Tim_Image.Height - 1 do
begin
scanline := Result.Scanline[y];
x:=0;
while x<Tim.Tim_Image.Width do
begin
TIM_Stream.Read(b,1);
scanline[x] := b and $F;
scanline[x+1] := b shr 4;
inc(x,2);
end;
end;
end;
Bpp_8: begin
TIM_Stream.Read(TIM.Tim_Palette,SizeOF(TIM.Tim_Palette));
_Palette := 0;
for I := 1 to TIM.Tim_Palette.Height do
begin
if i = Palette_Number then
_Palette := Create_HPalette(TIM_Stream,256) else
TIM_Stream.Position := TIM_Stream.Position + $200;
end;
TIM_Stream.Read(TIM.Tim_Image,SizeOf(Tim.Tim_Image));
Tim.Tim_Image.Width := TIM.Tim_Image.Width * 2;
Result := TPngImage.Create;
Result.CreateBlank(COLOR_PALETTE,8,Tim.Tim_Image.Width,Tim.Tim_Image.Height);
Result.Palette := _Palette;
for y := 0 to TIM.Tim_Image.Height - 1 do
begin
scanline := Result.Scanline[y];
for x := 0 to TIM.Tim_Image.Width - 1 do
TIM_Stream.Read(scanline[x],1);
end;
end;
Bpp_16: begin
TIM_Stream.Read(TIM.Tim_Image,SizeOf(Tim.Tim_Image));
Tim.Tim_Image.Width := TIM.Tim_Image.Width;
Result := TPngImage.Create;
Result.CreateBlank(COLOR_RGB,8,Tim.Tim_Image.Width,Tim.Tim_Image.Height);
for y := 0 to TIM.Tim_Image.Height - 1 do
begin
RGBScanline := Result.Scanline[y];
for x := 0 to TIM.Tim_Image.Width - 1 do
begin
TIM_Stream.Read(w,2);
GetRGB555(w,RGBScanline[x].rgbtRed,RGBScanline[x].rgbtGreen,RGBScanline[x].rgbtBlue);
end;
end;
end;
Bpp_24: begin
TIM_Stream.Read(TIM.Tim_Image,SizeOf(Tim.Tim_Image));
Tim.Tim_Image.Width := TIM.Tim_Image.Width * 2 div 3;
Result := TPngImage.Create;
Result.CreateBlank(COLOR_RGB,8,Tim.Tim_Image.Width,Tim.Tim_Image.Height);
for y := 0 to TIM.Tim_Image.Height - 1 do
begin
RGBScanline := Result.Scanline[y];
for x := 0 to TIM.Tim_Image.Width - 1 do
begin
TIM_Stream.Read(RGBScanline[x].rgbtRed,1);
TIM_Stream.Read(RGBScanline[x].rgbtGreen,1);
TIM_Stream.Read(RGBScanline[x].rgbtBlue,1);
end;
end;
end;
end;
end;
end;Может кому пригодится ;)
А обратная конверсия?)
Цитата: Mefistotel от 13 июня 2016, 23:17А обратная конверсия?)
Обратную я тоже написал, но она слегка "костыльная".
Её костыль в том, что если надо сохранить в 4bpp или 8bpp, то изображение(png) должно быть с палитрой, иначе не запакуется. Так же и с 16bpp и 24bpp, они должны быть строго в RGB, без палитры.
Я пока что не разбирался с квантованием цветов, но в будущем планирую
Вот же блин, как народ в этом разбирается?)))) Ттемма как твои проекты?
Пилятся потихонечку)