mirror of
https://github.com/Garhoogin/NitroPaint.git
synced 2025-06-18 14:25:31 -04:00
Simplify IS-CAD footer scanning code
This commit is contained in:
parent
43554ae349
commit
befbe9eb06
@ -87,49 +87,21 @@ int ChrIsValidNcg(const unsigned char *buffer, unsigned int size) {
|
||||
}
|
||||
|
||||
static int ChriIsCommonScanFooter(const unsigned char *buffer, unsigned int size, int type) {
|
||||
if (size < 8) return -1;
|
||||
//scan for footer with these required blocks
|
||||
const char *const requiredBlocks[] = { "LINK", "CMNT", "MODE", "SIZE", "VER ", "END " };
|
||||
int offs = IscadScanFooter(buffer, size, requiredBlocks, sizeof(requiredBlocks) / sizeof(requiredBlocks[0]));
|
||||
if (offs == -1) return -1;
|
||||
|
||||
//scan for possible locations of the footer
|
||||
for (unsigned int i = 0; i < size - 8; i++) {
|
||||
if (buffer[i] != 'L') continue;
|
||||
if (memcmp(buffer + i, "LINK", 4) != 0) continue;
|
||||
|
||||
//candidate location
|
||||
int hasLink = 0, hasCmnt = 0, hasMode = 0, hasSize = 0, hasVer = 0, hasEnd = 0;
|
||||
unsigned int footerSize = size - (unsigned int) offs;
|
||||
const unsigned char *footer = buffer + offs;
|
||||
|
||||
//scan sections
|
||||
unsigned int offset = i;
|
||||
while (1) {
|
||||
const unsigned char *section = buffer + offset;
|
||||
unsigned int length = *(uint32_t *) (buffer + offset + 4);
|
||||
offset += 8;
|
||||
//check blocks
|
||||
unsigned int verSize;
|
||||
const unsigned char *verBlock = IscadFindBlockBySignature(footer, footerSize, "VER ", &verSize);
|
||||
|
||||
if (memcmp(section, "LINK", 4) == 0) hasLink = 1;
|
||||
else if (memcmp(section, "CMNT", 4) == 0) hasCmnt = 1;
|
||||
else if (memcmp(section, "MODE", 4) == 0) hasMode = 1;
|
||||
else if (memcmp(section, "SIZE", 4) == 0) hasSize = 1;
|
||||
else if (memcmp(section, "VER ", 4) == 0) hasVer = 1;
|
||||
else if (memcmp(section, "END ", 4) == 0) hasEnd = 1;
|
||||
|
||||
if (memcmp(section, "VER ", 4) == 0) {
|
||||
//ACG: ver = "IS-ACG0x" (1-3)
|
||||
//ICG: ver = "IS-ICG01"
|
||||
const char *ver = section + 8;
|
||||
if (type == NCGR_TYPE_AC && (length < 8 || memcmp(ver, "IS-ACG", 6))) return -1;
|
||||
if (type == NCGR_TYPE_IC && (length < 8 || memcmp(ver, "IS-ICG", 6))) return -1;
|
||||
}
|
||||
|
||||
offset += length;
|
||||
if (offset >= size) break;
|
||||
if (hasEnd) break;
|
||||
}
|
||||
|
||||
if (hasLink && hasCmnt && hasMode && hasSize && hasVer && hasEnd && offset <= size) {
|
||||
//candidate found
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
if (type == NCGR_TYPE_AC && (verSize < 8 || memcmp(verBlock, "IS-ACG", 6))) return -1; // ASC must have version IS-ACGxx
|
||||
if (type == NCGR_TYPE_IC && (verSize < 8 || memcmp(verBlock, "IS-ICG", 6))) return -1; // ISC must have version IS-ICGxx
|
||||
return offs;
|
||||
}
|
||||
|
||||
int ChrIsValidAcg(const unsigned char *buffer, unsigned int size) {
|
||||
|
@ -709,6 +709,9 @@ int IscadIsValidFooter(const unsigned char *footer, unsigned int size) {
|
||||
if ((size - pos) < blockSize) return 0;
|
||||
|
||||
pos += blockSize;
|
||||
|
||||
//check for 'END ' signature
|
||||
if (memcmp(hdr, "END ", 4) == 0) break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -728,10 +731,40 @@ unsigned char *IscadFindBlockBySignature(const unsigned char *buffer, unsigned i
|
||||
pos += 8;
|
||||
unsigned int blockSize = *(const uint32_t *) (hdr + 4);
|
||||
pos += blockSize;
|
||||
|
||||
//check for 'END ' signature
|
||||
if (memcmp(hdr, "END ", 4) == 0) break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int IscadScanFooter(const unsigned char *buffer, unsigned int size, const char *const *requiredBlocks, unsigned int nRequiredBlocks) {
|
||||
//scan for locations, check for required blocks.
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
//check valid footer data
|
||||
if (!IscadIsValidFooter(buffer + i, size - i)) continue;
|
||||
|
||||
//check required blocks
|
||||
int foundAll = 1;
|
||||
for (unsigned int j = 0; j < nRequiredBlocks; j++) {
|
||||
unsigned int blockSize;
|
||||
const unsigned char *block = IscadFindBlockBySignature(buffer + i, size - i, requiredBlocks[j], &blockSize);
|
||||
if (block == NULL) {
|
||||
foundAll = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//buffer here
|
||||
if (foundAll) {
|
||||
return (int) i;
|
||||
}
|
||||
}
|
||||
|
||||
//not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void IscadStreamCreate(IscadStream *stream) {
|
||||
stream->inFooter = 0;
|
||||
@ -747,7 +780,7 @@ void IscadStreamStartBlock(IscadStream *stream, const char *signature) {
|
||||
stream->blockStart = stream->stream.pos;
|
||||
|
||||
uint32_t tmpSize = 0;
|
||||
bstreamWrite(&stream->stream, signature, 4);
|
||||
bstreamWrite(&stream->stream, (void *) signature, 4);
|
||||
bstreamWrite(&stream->stream, &tmpSize, sizeof(tmpSize));
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,7 @@ void NnsStreamFree(NnsStream *stream);
|
||||
|
||||
// ----- ISCAD stream functions
|
||||
|
||||
int IscadScanFooter(const unsigned char *buffer, unsigned int size, const char *const *requiredBlocks, unsigned int nRequiredBlocks);
|
||||
int IscadIsValidFooter(const unsigned char *footer, unsigned int size);
|
||||
unsigned char *IscadFindBlockBySignature(const unsigned char *buffer, unsigned int size, const char *signature, unsigned int *pSize);
|
||||
|
||||
|
@ -210,53 +210,23 @@ int ScrIsValidNsc(const unsigned char *buffer, unsigned int size) {
|
||||
}
|
||||
|
||||
int ScriIsCommonScanFooter(const unsigned char *buffer, unsigned int size, int type) {
|
||||
if (size < 8) return -1;
|
||||
//scan for a footer with the required blocks
|
||||
const char *requiredBlocks[] = { "CLRF", "LINK", "CMNT", "CLRC", "MODE", "VER ", "END " };
|
||||
int offs = IscadScanFooter(buffer, size, requiredBlocks, sizeof(requiredBlocks) / sizeof(requiredBlocks[0]));
|
||||
if (offs == -1) return -1;
|
||||
|
||||
//scan for possible locations of the footer
|
||||
for (unsigned int i = 0; i < size - 8; i++) {
|
||||
if (buffer[i] != 'C') continue;
|
||||
if (memcmp(buffer + i, "CLRF", 4) != 0) continue;
|
||||
unsigned int footerSize = size - (unsigned int) offs;
|
||||
const unsigned char *footer = buffer + offs;
|
||||
|
||||
//candidate location
|
||||
int hasClrf = 0, hasLink = 0, hasCmnt = 0, hasClrc = 0, hasMode = 0, hasVer = 0, hasEnd = 0, hasSize = 0;
|
||||
//check blocks
|
||||
unsigned int verSize, sizeSize;
|
||||
const unsigned char *verBlock = IscadFindBlockBySignature(footer, footerSize, "VER ", &verSize);
|
||||
const unsigned char *sizeBlock = IscadFindBlockBySignature(footer, footerSize, "SIZE", &sizeSize);
|
||||
|
||||
//scan sections
|
||||
unsigned int offset = i;
|
||||
while (1) {
|
||||
const char *section = buffer + offset;
|
||||
unsigned int length = *(unsigned int *) (buffer + offset + 4);
|
||||
offset += 8;
|
||||
|
||||
if (memcmp(section, "CLRF", 4) == 0) hasClrf = 1;
|
||||
else if (memcmp(section, "LINK", 4) == 0) hasLink = 1;
|
||||
else if (memcmp(section, "CMNT", 4) == 0) hasCmnt = 1;
|
||||
else if (memcmp(section, "CLRC", 4) == 0) hasClrc = 1;
|
||||
else if (memcmp(section, "MODE", 4) == 0) hasMode = 1;
|
||||
else if (memcmp(section, "SIZE", 4) == 0) hasSize = 1;
|
||||
else if (memcmp(section, "VER ", 4) == 0) hasVer = 1;
|
||||
else if (memcmp(section, "END ", 4) == 0) hasEnd = 1;
|
||||
|
||||
if (memcmp(section, "VER ", 4) == 0) {
|
||||
//ACG: ver = "IS-ACG0x" (1-3)
|
||||
//ICG: ver = "IS-ICG01"
|
||||
const char *ver = section + 8;
|
||||
if (type == NSCR_TYPE_AC && (length < 8 || memcmp(ver, "IS-ASC", 6))) return -1;
|
||||
if (type == NSCR_TYPE_IC && (length < 8 || memcmp(ver, "IS-ISC", 6))) return -1;
|
||||
}
|
||||
|
||||
offset += length;
|
||||
if (offset >= size) break;
|
||||
if (hasEnd) break;
|
||||
}
|
||||
|
||||
//ISC files have a SIZE section, but ASC files do not
|
||||
int sizeSatisfied = (type == NSCR_TYPE_IC && hasSize) || (type != NSCR_TYPE_IC);
|
||||
if (hasClrf && hasLink && hasCmnt && hasClrc && hasMode && sizeSatisfied && hasVer && hasEnd && offset <= size) {
|
||||
//candidate found
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
if (type == NSCR_TYPE_AC && (verSize < 8 || memcmp(verBlock, "IS-ASC", 6))) return -1; // ASC must have version IS-ASCxx
|
||||
if (type == NSCR_TYPE_IC && (verSize < 8 || memcmp(verBlock, "IS-ISC", 6))) return -1; // ISC must have version IS-ISCxx
|
||||
if (type == NSCR_TYPE_IC && sizeBlock == NULL) return -1; // ISC must have a SIZE block
|
||||
return offs;
|
||||
}
|
||||
|
||||
int ScrIsValidAsc(const unsigned char *file, unsigned int size) {
|
||||
|
Loading…
Reference in New Issue
Block a user