XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Моделлинг
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
RazArt

offline
Опыт: 11,197
Активность:
Открытие BLP формата
Пишу программу (Visual Basic), необходимо открытие BLP текстуры, могут отписаться те ктознаком с этим, ну или выложить ссылки на примеры. Юзав гугл я нашёл всего лишь 1 пример(http://forum.valhallalegends.com/index.php?topic=14286.0) открытия, но программа просто зависала при выполнении кода
Старый 23.02.2009, 00:13
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
Для начала советую ознакомиться с Magos BLP file specification

Варовские BLP делятся на два типа - палитровые и сжатые (с помощью jpeg).

Палитровые можно открывать без дополнительных модулей.
1. Прочитать палитру (обычно она начинается с адреса $009C), в массив.
2. Прочитать блок данных индексов (руководствуясь начальной позицией aka оффсетом, записанным в $001C, и размером блока, записанным в $005C).
3. Сопоставить каждый индекс в блоке данных цвету из палитры. То есть организовать цикл чтения побайтово (на входе 8-битное index), и возвращать соответствующее значение из палитры (на выходе 32-битное palette[index]).

Сжатые открываются ненамного сложнее.
1. Прочитать заголовок по адресу $00A0 (если значение в $009C больше нуля).
2. Прочитать блок данных jpeg (руководствуясь начальной позицией aka оффсетом, записанным в $001C, и размером блока, записанным в $005C).
3. Загнать все это в jpeg декодер с параметрами:
Код:
{ параметры }
      { цветовое пространство исходных данных, RGBA нету, так что пишем UNKNOWN }
      jc.d.jpeg_color_space := JCS_UNKNOWN;

      { кол-во компонентов в цветовом пространстве - для RGBA значение 4 }
      jc.d.num_components := 4;

      { см. выше }
      jc.d.out_color_space := JCS_UNKNOWN;

      { по 1 байту на каждый компонент цвета }
      FBitmap.PixelFormat := pf32bit;


Собственно, я написал библиотеку (с помощью которой можно читать и записывать BLP), API скину, если решишь использовать ее.
Старый 23.02.2009, 10:38
RazArt

offline
Опыт: 11,197
Активность:
Вообще я пишу на VB. Вот листинг загрузки самого изображения:
» Загрузка

Код:
'Header for blizzards .blp(1) files (this code is anti jpeg, for now)
Private Type BLP1_HEADER
    bBLPid          As Long
    bIsPal          As Long
    bMipMaps        As Long
    bWidth          As Long
    bHeight         As Long
    bUnknown1       As Long
    bUnknown2       As Long
    bPicPtr(15)     As Long
    bPicLen(15)     As Long
End Type

'for the pallet
Private Type RGBQUAD
    rgbBlue         As Byte
    rgbGreen        As Byte
    rgbRed          As Byte
    rgbReserved     As Byte
End Type

'Bit Map
Private Type BITMAPINFOHEADER
    biSize          As Long
    biWidth         As Long
    biHeight        As Long
    biPlanes        As Integer
    biBitCount      As Integer
    biCompression   As Long
    biSizeImage     As Long
    biXPelsPerMeter As Long
    biYPelsPerMeter As Long
    biClrUsed       As Long
    biClrImportant  As Long
End Type

Public Type BITMAPSTRUT
    Width  As Long
    Height As Long
    handle As Long
End Type

'for the API containing both pallet and bitmap header
Private Type BITMAPINFO_8
    bmiHeader       As BITMAPINFOHEADER
    bmiColors(255)  As RGBQUAD
End Type

Public W3IconTest() As BITMAPSTRUT

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal numbytes As Long)
Private Declare Function CreateDIBitmap_8 Lib "gdi32" Alias "CreateDIBitmap" (ByVal hdc As Long, lpInfoHeader As BITMAPINFOHEADER, ByVal dwUsage As Long, lpInitBits As Any, lpInitInfo As BITMAPINFO_8, ByVal wUsage As Long) As Long
Public Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Public Function LoadBLP(ByVal FilePath As String, ByRef BMPArray() As BITMAPSTRUT) As Boolean
    Dim FF As Integer: FF = FreeFile
    Dim FileData()     As Byte
    Dim tmpBMP()       As Byte
    Dim blpHeader      As BLP1_HEADER
    Dim BMP8           As BITMAPINFO_8
    Dim i              As Integer
    Dim hdc            As Long
    
    LoadBLP = False
    
    'open file and extract data
    Open FilePath For Binary As #FF
        ReDim FileData(LOF(FF) - 1)
        Get FF, , FileData
    Close #FF
    'copy header data into header type
    Call CopyMemory(blpHeader, FileData(0), 156)
    'Check its a blp file
    If Not blpHeader.bBLPid = &H31504C42 Then Exit Function 'BLP1
    'Check its a raw blp format (not jpeg)
    If Not blpHeader.bIsPal = 1 Then Exit Function 'its jpeg
    'copy the pallet into are bitmap RGBQUAD
    Call CopyMemory(BMP8.bmiColors(0), FileData(156), 1024)
    'add needed info to the bitmap header for when the API creates it
    With BMP8.bmiHeader
        .biSize = Len(BMP8.bmiHeader)
        .biWidth = blpHeader.bWidth
        .biHeight = blpHeader.bHeight
        .biPlanes = 1
        .biBitCount = 8
    End With
    'Create a bitmap in memory from the set data, and get the handle to it
    For i = 0 To 15
        'Check theres a pointer to the picture data, other wise last image was loaded last for
        If blpHeader.bPicPtr(i) = 0 And i > 0 Then Exit For
        'Copy the first bitmap into tmpBMP()
        ReDim tmpBMP(blpHeader.bPicLen(i) - 1)
        Call CopyMemory(tmpBMP(0), FileData(blpHeader.bPicPtr(i)), blpHeader.bPicLen(i))
        'flip/mirror/lower bits of the bitmap data
        Call MakeBitmap_8(tmpBMP(), 64, 64)
        'Create a bitmap and put it into the correct index of BMPArray
        hdc = GetDC(0)
        ReDim Preserve BMPArray(i)
        BMPArray(i).Width = BMP8.bmiHeader.biWidth
        BMPArray(i).Height = BMP8.bmiHeader.biHeight
        BMPArray(i).handle = CreateDIBitmap_8(hdc, BMP8.bmiHeader, &H4, tmpBMP(0), BMP8, &H0)
        BitBlt Form1.Picture1.hdc, 0, 0, BMPArray(0).Width, BMPArray(0).Height, hdc, 0, 0, vbSrcCopy
        Call DeleteDC(hdc)
        'lower image size to the next image block's size
        BMP8.bmiHeader.biWidth = BMP8.bmiHeader.biWidth / 2
        BMP8.bmiHeader.biHeight = BMP8.bmiHeader.biHeight / 2
        'Alwas return true if a bitmap was created
        LoadBLP = True
    Next i
    'erase the file/bitmap datas
    Erase FileData()
    Erase tmpBMP()
End Function


Private Sub MakeBitmap_8(imgArray() As Byte, Lines As Long, BytesLine As Long)
    Dim tmpBM() As Byte, G As Long, GBMP As Long, i As Long, i2 As Long, tmpBMX As Long
    If (BytesLine Mod 4) = 0 Then
        tmpBMX = BytesLine - 1
    Else
        tmpBMX = (BytesLine \ 4) * 4 + 3
    End If
    G = Lines * BytesLine
    GBMP = Lines * (tmpBMX + 1) - 1
    ReDim tmpBM(UBound(imgArray))
    CopyMemory tmpBM(0), imgArray(0), UBound(imgArray) + 1
    ReDim imgArray(GBMP)
    For i = 0 To BytesLine * Lines - BytesLine Step BytesLine
        CopyMemory imgArray(i2), tmpBM(G - i - BytesLine), BytesLine
        i2 = i2 + tmpBMX + 1
    Next i
    Erase tmpBM()
End Sub


» Мои действия

Код:
Dim hRet As Long
LoadBLP "C:\234.blp", W3IconTest
hRet = GetDC(W3IconTest(0).handle)
BitBlt Picture1.hdc, 0, 0, W3IconTest(0).Width, W3IconTest(0).Height, hRet, 0, 0, vbSrcCopy


Я получаю хендл изобрбажения BLP, а когда хочу его отрисовать, то ничего не происходит. А за библиотеку и API буду очень благодарен, но всёже хочется ещё и самому написать, чтобы не таскать с собой диллки
Старый 23.02.2009, 10:45
Van Damm
wait... what?
offline
Опыт: 22,268
Активность:
2 swdn: я бы не отказался от API =) Давно хочется конверсии больших картинок, а ни одна прога не делает. Так хоть сам напишу по-быстренькому.
Старый 23.02.2009, 12:00
RazArt

offline
Опыт: 11,197
Активность:
А я хочу написать удобную смотрелку blp'ешок, а то их просматривать не удобно =) Ну конечно всяких рюшечек прикручу туда)
Старый 23.02.2009, 12:24
NETRAT

offline
Опыт: 83,712
Активность:
Van Damm я собсна swdn'у то же самое говорил - делай библиотеку что бы ее юзать другие девелоперы могли =) она есть!
ijl15.dll сосет по известным всем причинам
Старый 23.02.2009, 12:27
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
RazArt, хмм, боюсь тебя огорчить, но я тоже собирался писать удобный вьювер для BLP =) (исходя из содержания некоторых тем академии, как раз его-то многим модмейкерам и не хватает, ну и просто "для себя").

Может быть, стоит создать отдельную тему для библиотеки?
Старый 23.02.2009, 14:39
RazArt

offline
Опыт: 11,197
Активность:
А эта чем не тема для библиотеки? Да и кста, у нас монополия на вьюверы?)

RazArt добавил:
Так ты выложишь библиотеку?
Старый 23.02.2009, 14:49
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
вот она, вот она, на ногу намотана =)
API для библиотеки:

BLP_LoadFromMemory


Код:
procedure BLP_LoadFromMemory(Image: Pointer; Mipmap: DWord; Data: Pointer; var Datasize: DWord); stdcall;

Загружает из BLP выбранное изображение.
  • Image - указатель на блок данных исходного файла BLP;
  • Mipmap - номер изображения, которое необходимо загрузить (нумерация с 0);
  • Data - указатель на блок данных вида [BGRA][BGRA]...[BGRA] - выходной параметр;
  • Datasize - размер блока данных Data - выходной параметр.

BLP_SaveToMemory


Код:
procedure BLP_SaveToMemory(Image: Pointer; Header: pBLP1_Header; Mipmaps, Val: DWord; Flag: Boolean; Data: Pointer; var Datasize: DWord); stdcall;

Сохраняет изображение в BLP файл.
  • Image - указатель на блок данных исходного изображения (вида [BGRA][BGRA]...[BGRA]);
  • Header - заголовок будущего BLP файла, заполняются только некоторые поля;
  • Mipmaps - количество изображений, которое будет сгенерировано;
  • Val - значение качества сжатия или количество цветов (зависит от поля Compression в заголовке Header);
  • Flag - если True, то будут использованы специальные методы для уменьшения размера BLP файла;
  • Data - указатель на блок данных готового BLP файла - выходной параметр;
  • Datasize - размер блока данных Data - выходной параметр.

BLP_GetHeader


Код:
procedure BLP_GetHeader(Image: Pointer; Header: pBLP1_Header); stdcall;

Если лень вытащить заголовок BLP файла самому...
  • Image - указатель на блок данных исходного файла BLP;
  • Header - заголовок BLP файла - выходной параметр

BLP_SetHeader


Код:
procedure BLP_SetHeader(Compression, Flags, Width, Height, PicType: DWord; Header: pBLP1_Header); stdcall;

Заполняет существенные параметры заголовка BLP
  • Compression - тип сжатия данных (0 - jpeg сжатие, 1 - палитровый формат);
  • Flags - содержит ли изображение альфа канал (8 - есть, 0 - нет);
  • Width - ширина изображения;
  • Height - высота изображения;
  • PicType - если имеет значение 5, то в палитровом формате не будет сохраняться альфа канал, если 3 или 4 - будет;
  • Header - заголовок BLP файла - выходной параметр

Ах да, чуть не забыл:
Код:
TBLP1_Header = Record
  Signature:   DWord;
  Compression: DWord;
  Flags:  DWord;
  Width:  DWord;
  Height: DWord;
  PictureType:    DWord;
  PictureSubType: DWord;
  MipMapOffset: Array [0..15] of DWord;
  MipMapSize:   Array [0..15] of DWord;
end;
pBLP1_Header = ^TBLP1_Header;

Структура заголовка файла BLP версии 1.

Чтобы сэкономить место, я запихал в библиотеку еще процедуры открытия и сохранения jpeg (нуачо, иметь одинаковые *.obj в УЧУ-шнике и библиотеке - это моветон как минимум ^_^)
Код:
procedure JPG_LoadFromMemory(Image: Pointer; ImageSize: DWord; Data: Pointer; var Width, Height: DWord); stdcall;
procedure JPG_SaveToMemory(Image: Pointer; Width, Height: DWord; Data: Pointer; var Datasize: DWord); stdcall;
Прикрепленные файлы
Тип файла: rar swdn_blp.rar (86.9 Кбайт, 128 просмотров )

Отредактировано ShadoW DaemoN, 23.02.2009 в 15:51.
Старый 23.02.2009, 15:44
NETRAT

offline
Опыт: 83,712
Активность:
а я собирался писать правильный MPQ архиватор с плагинами оптимизатора, взломщика и просмотрщика mdx и blp (примерно так как это было в biturn или w3viewer)

NETRAT добавил:
не не, надо отдельную тему в барахолку
Старый 23.02.2009, 15:52
adic3x

offline
Опыт: 108,439
Активность:
а где опенСорц что бы светлые умы человечества могли ее улучшить ? ;)
Старый 23.02.2009, 17:39
tysch_tysch
Работаем
offline
Опыт: отключен
напишите лучше плагин для ирфана http://www.irfanview.com/
Старый 23.02.2009, 20:40
FaB0SS

offline
Опыт: 2,504
Активность:
ShadoW DaemoN
Что я не так делаю?
1.Читаю файл blp в поток(пробовал и массив char'ов)
2.Вызываю твою функцию BLP_LoadFromMemory c параметрами:
1-й - адрес массива char'ов файла blp;
2-й - 0;
3-й - адрес массива структур RGBQUAD
» RGBQUAD
Код:
typedef struct tagRGBQUAD { // rgbq  
    BYTE    rgbBlue; 
    BYTE    rgbGreen; 
    BYTE    rgbRed; 
    BYTE    rgbReserved; 
} RGBQUAD;
4-й - int size;

И ничего не получается...
Старый 06.03.2009, 21:31
Кет

offline
Опыт: 111,109
Активность:
Цитата:
напишите лучше плагин для ирфана http://www.irfanview.com/

А еще лучше расширение ядра windows =)
Старый 06.03.2009, 21:53
FaB0SS

offline
Опыт: 2,504
Активность:
Все, большое спасибо, сам разобрался, в 4-тый параметр надо передавать не саму переменную, а адрес переменной ;) Теперь работает =)

P.S.
Урааа-ааа!!!

FaB0SS добавил:
А вот с "BLP_GetHeader" что-то не получается... =/
Старый 07.03.2009, 01:22
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
FaB0SS,
1. Параметр входящий, указатель на массив байтов BLP-файла.
2. Параметр исходящий, указатель на структуру TBLP1_Header (которая занимает 156 байт, кстати). Выделять память под структуру, конечно, нужно. Или, как вариант, можно объявить указатель my_pointer, выделить под него место в памяти GetMem(my_pointer, sizeof(TBLP1_Header)) байтов, а затем привести к указателю на заголовок pBLP1_Header(my_pointer) и работать с ним.

ZlaYa1000, ненене, в топку, во-первых, автор не выложил SDK для плагинов, во-вторых, не хочу его софтину поддерживать.
Старый 07.03.2009, 14:10
FaB0SS

offline
Опыт: 2,504
Активность:
ShadoW DaemoN
Да я уже сам его вытащил...
Старый 07.03.2009, 14:53
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 01:44.