mirror of
https://github.com/simtactics/niotso.git
synced 2025-07-04 13:47:05 -04:00
* Updated libpng and zlib
* Added SPR# parsing to the iff library * iff2html now displays BMP_/FBMP, PALT, and SPR# chunks
This commit is contained in:
parent
78f1ca1d6f
commit
1f7061d98a
10 changed files with 219 additions and 41 deletions
|
@ -16,6 +16,7 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "read_bmp.h"
|
||||
|
@ -33,6 +34,7 @@
|
|||
#endif
|
||||
|
||||
int bmp_read_header(bmpheader_t * BMPHeader, const uint8_t * Buffer, size_t FileSize){
|
||||
unsigned padding;
|
||||
if(FileSize < 54) return 0;
|
||||
BMPHeader->bfType = read_uint16(Buffer);
|
||||
BMPHeader->bfSize = read_uint32(Buffer+2);
|
||||
|
@ -52,25 +54,27 @@ int bmp_read_header(bmpheader_t * BMPHeader, const uint8_t * Buffer, size_t File
|
|||
BMPHeader->biClrUsed = read_uint32(Buffer+46);
|
||||
BMPHeader->biClrImportant = read_uint32(Buffer+50);
|
||||
|
||||
BMPHeader->CompressedSize = FileSize - BMPHeader->bfOffBits;
|
||||
if(BMPHeader->bfSize == 0) BMPHeader->bfSize = FileSize;
|
||||
BMPHeader->CompressedSize = BMPHeader->bfSize - BMPHeader->bfOffBits;
|
||||
BMPHeader->DecompressedSize = BMPHeader->biWidth * BMPHeader->biHeight * 3;
|
||||
padding = BMPHeader->biWidth%4;
|
||||
if(padding != 0) padding = (BMPHeader->biHeight-1)*(4-padding);
|
||||
|
||||
if(BMPHeader->bfType != 0x4D42 ||
|
||||
BMPHeader->bfSize != FileSize ||
|
||||
BMPHeader->bfSize > FileSize ||
|
||||
BMPHeader->bfReserved1 != 0 || BMPHeader->bfReserved2 != 0 ||
|
||||
BMPHeader->biSize != 40 ||
|
||||
BMPHeader->biWidth == 0 || BMPHeader->biWidth > 4096 || /*< Includes negative check */
|
||||
BMPHeader->biHeight == 0 || BMPHeader->biHeight > 4096 || /*< by treating as unsigned */
|
||||
BMPHeader->biPlanes != 1 ||
|
||||
(BMPHeader->biBitCount != 24 &&
|
||||
(BMPHeader->biBitCount != 8 || FileSize < 1078 /* We need room for the color palette */)) ||
|
||||
(BMPHeader->biBitCount != 8 || BMPHeader->bfSize < 1078 /* We need room for the color palette */)) ||
|
||||
(BMPHeader->biCompression != BI_RGB &&
|
||||
(BMPHeader->biCompression != BI_RLE8 || BMPHeader->biBitCount > 8)) ||
|
||||
BMPHeader->bfOffBits >= FileSize ||
|
||||
BMPHeader->bfOffBits >= BMPHeader->bfSize ||
|
||||
(BMPHeader->biCompression == BI_RGB &&
|
||||
((BMPHeader->biBitCount == 24 && BMPHeader->CompressedSize < BMPHeader->DecompressedSize) ||
|
||||
(BMPHeader->biBitCount == 8 && BMPHeader->CompressedSize < BMPHeader->DecompressedSize/3 +
|
||||
BMPHeader->biHeight*(BMPHeader->biWidth%4) /* Account for padding in 8-bit BMPs */)))
|
||||
((BMPHeader->biBitCount == 24 && BMPHeader->CompressedSize < BMPHeader->DecompressedSize + padding) ||
|
||||
(BMPHeader->biBitCount == 8 && BMPHeader->CompressedSize < BMPHeader->DecompressedSize/3 + padding)))
|
||||
) return 0;
|
||||
|
||||
return 1;
|
||||
|
@ -78,7 +82,24 @@ int bmp_read_header(bmpheader_t * BMPHeader, const uint8_t * Buffer, size_t File
|
|||
|
||||
int bmp_read_data(bmpheader_t * BMPHeader, const uint8_t *__restrict InBuffer, uint8_t *__restrict OutBuffer){
|
||||
if(BMPHeader->biBitCount == 24 && BMPHeader->biCompression == BI_RGB){
|
||||
memcpy(OutBuffer, InBuffer+BMPHeader->bfOffBits, BMPHeader->DecompressedSize);
|
||||
unsigned pitch = BMPHeader->biWidth*3;
|
||||
unsigned i;
|
||||
unsigned padding = pitch%4;
|
||||
if(padding != 0) padding = 4-padding;
|
||||
|
||||
for(i=0; i<BMPHeader->biHeight; i++)
|
||||
memcpy(OutBuffer + i*pitch, InBuffer+BMPHeader->bfOffBits + i*(pitch + padding), pitch);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(BMPHeader->biBitCount == 32 && BMPHeader->biCompression == BI_RGB){
|
||||
unsigned i;
|
||||
for(i=0; i<BMPHeader->biHeight*BMPHeader->biWidth; i++){
|
||||
*(OutBuffer++) = *(InBuffer++);
|
||||
*(OutBuffer++) = *(InBuffer++);
|
||||
*(OutBuffer++) = *(InBuffer++);
|
||||
InBuffer++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -89,6 +110,8 @@ int bmp_read_data(bmpheader_t * BMPHeader, const uint8_t *__restrict InBuffer, u
|
|||
if(BMPHeader->biCompression == BI_RGB){
|
||||
unsigned y, x;
|
||||
unsigned padding = BMPHeader->biWidth % 4;
|
||||
if(padding != 0) padding = 4-padding;
|
||||
|
||||
for(y=0; y<BMPHeader->biHeight; y++){
|
||||
for(x=0; x<BMPHeader->biWidth; x++){
|
||||
unsigned index = 4*(*InBuffer++);
|
||||
|
|
|
@ -9,6 +9,7 @@ set(IFF_SOURCES
|
|||
glob.c
|
||||
palt.c
|
||||
rsmp.c
|
||||
spr.c
|
||||
str.c
|
||||
string.c
|
||||
tmpl.c
|
||||
|
|
|
@ -34,6 +34,7 @@ iff_register(c_string);
|
|||
iff_register(glob);
|
||||
iff_register(fcns);
|
||||
iff_register(palt);
|
||||
iff_register(spr);
|
||||
iff_register(tmpl);
|
||||
iff_register(trcn);
|
||||
iff_register(rsmp);
|
||||
|
@ -47,6 +48,7 @@ const char chunktypes[] =
|
|||
"BCON"
|
||||
"FCNS"
|
||||
"PALT"
|
||||
"SPR#"
|
||||
"TMPL"
|
||||
"TRCN"
|
||||
"rsmp"
|
||||
|
@ -59,6 +61,7 @@ int (* const iff_parse_function[])(IFFChunk*, const uint8_t*) = {
|
|||
iff_parse_bcon,
|
||||
iff_parse_fcns,
|
||||
iff_parse_palt,
|
||||
iff_parse_spr,
|
||||
iff_parse_tmpl,
|
||||
iff_parse_trcn,
|
||||
iff_parse_rsmp
|
||||
|
@ -71,6 +74,7 @@ void (* const iff_free_function[])(void*) = {
|
|||
iff_free_bcon,
|
||||
iff_free_fcns,
|
||||
NULL,
|
||||
iff_free_spr,
|
||||
iff_free_tmpl,
|
||||
iff_free_trcn,
|
||||
iff_free_rsmp
|
||||
|
@ -185,6 +189,17 @@ int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
|||
return 0;
|
||||
}
|
||||
|
||||
IFFChunk * iff_find_chunk(IFFFile * IFFFileInfo, const char * Type, int ChunkID){
|
||||
unsigned i;
|
||||
for(i=0; i<IFFFileInfo->ChunkCount; i++){
|
||||
IFFChunk * Chunk = &IFFFileInfo->Chunks[i];
|
||||
if((Type == NULL || !strcmp(Chunk->Type, Type)) &&
|
||||
(ChunkID == -1 || Chunk->ChunkID == ChunkID))
|
||||
return Chunk;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void iff_free_chunk(IFFChunk * ChunkInfo){
|
||||
unsigned i;
|
||||
if(ChunkInfo == NULL || ChunkInfo->FormattedData == NULL) return;
|
||||
|
|
|
@ -109,6 +109,27 @@ typedef struct IFFPalette_s
|
|||
uint8_t Data[256*3];
|
||||
} IFFPalette;
|
||||
|
||||
/* SPR# chunk */
|
||||
|
||||
typedef struct IFFSprite_s
|
||||
{
|
||||
uint32_t Reserved;
|
||||
uint16_t Height;
|
||||
uint16_t Width;
|
||||
uint8_t * IndexData;
|
||||
uint8_t * BGRA32Data;
|
||||
} IFFSprite;
|
||||
|
||||
typedef struct IFFSpriteList_s
|
||||
{
|
||||
uint32_t Version;
|
||||
uint32_t SpriteCount;
|
||||
uint32_t PaletteID;
|
||||
IFFSprite * Sprites;
|
||||
} IFFSpriteList;
|
||||
|
||||
int iff_depalette(IFFSprite * Sprite, const IFFPalette * Palette);
|
||||
|
||||
/* STR# chunk */
|
||||
|
||||
enum IFFLanguage {
|
||||
|
@ -232,6 +253,7 @@ IFFChunk * iff_add_chunk(IFFFile * IFFFileInfo);
|
|||
int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChunkSize);
|
||||
int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer);
|
||||
int iff_enumerate_chunks(IFFFile * IFFFileInfo, const uint8_t * Buffer, unsigned BufferSize);
|
||||
IFFChunk * iff_find_chunk(IFFFile * IFFFileInfo, const char * Type, int ChunkID);
|
||||
|
||||
void iff_free_chunk(IFFChunk * ChunkInfo);
|
||||
void iff_delete_chunk(IFFFile * IFFFileInfo, int Position);
|
||||
|
|
|
@ -266,8 +266,8 @@ void iff_free_str(void * FormattedData){
|
|||
|
||||
for(ls=0; ls<20; ls++){
|
||||
IFFLanguageSet * LanguageSet = &StringData->LanguageSets[ls];
|
||||
unsigned p;
|
||||
if(LanguageSet->Pairs){
|
||||
unsigned p;
|
||||
for(p=0; p<LanguageSet->PairCount; p++){
|
||||
free(LanguageSet->Pairs[p].Key);
|
||||
free(LanguageSet->Pairs[p].Value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue