
All the old detection functions (incase i need them later)



bool EntryDataFormat::detectPng(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 8) {
        // Check for PNG header
        if (mc[0] == 137 && mc[1] == 80 &&
                mc[2] == 78 && mc[3] == 71 &&
                mc[4] == 13 && mc[5] == 10 &&
                mc[6] == 26 && mc[7] == 10)
            return true;
    }

    return false;
}

bool EntryDataFormat::detectAnsi(MemChunk& mc) {
    // Check size: 25 lines of 80 characters coded on 2 bytes
    if (mc.getSize() == 4000) {
            return true;
    }

    return false;
}

bool EntryDataFormat::detectBmp(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 14) {
        // Check for BMP header
        if (mc[0] == 'B' && mc[1] == 'M' && mc[6] == 0 && mc[7] == 0 && mc[8] == 0 && mc[9] == 0)
            return true;
    }

    return false;
}

bool EntryDataFormat::detectGif(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 6) {
        // Check for GIF header
        if (mc[0] == 'G' && mc[1] == 'I' && mc[2] == 'F' && mc[3] == '8' &&
            (mc[4] == '7' || mc[4] =='9') && mc[5] == 'a')
            return true;
    }

    return false;
}

bool EntryDataFormat::detectPcx(MemChunk& mc) {
    // Check size
    if (mc.getSize() < 129)
        return false;
    // Manufacturer and encoding fields: must always be 10 and 1 respectively
    if (mc[0] != 0x0A || mc[2] != 0x01)
        return false;
    // Version field: only 0, 2, 3, 4 and 5 exist
    if (mc[1] > 5 || mc[1] == 1)
        return false;
    // Bit depth and color plane fields are used in combination
    switch (mc[3]) {
        case 1: // Monochrome, EGA or VGA
            if (mc[65] != 1 && mc[65] != 3 && mc[65] != 4)  return false;   break;
        case 2: // CGA
            if (mc[65] != 1)                                return false;   break;
        case 4: // EGA or VGA
            if (mc[65] != 1 && mc[65] != 2)                 return false;   break;
        case 8: // VGA, SVGA or SVGA with alpha
            if (mc[65] != 1 && mc[65] != 3 && mc[65] != 4)  return false;   break;
        default: // Not a valid bit depth
            return false;
    }
    // In 256-color mode, the palette, if any, is contained at the end
    // of the file and preceded by a 0x0C. Only version 5 is concerned.
    if (mc[1] == 5 && ((mc[3] == 8 && mc[65] == 1) || (mc[3] == 4 && mc[65] == 2))) {
        size_t filesize = mc.getSize();
        if (filesize < 900 || mc[filesize-769] != 12)
            return false;
    }
    // Reserved value; theoretically values other than 0 can be valid
    // if the image was created by some old version of Paintbrush, but
    // it's unlikely such pictures would be manipulated by SLADE3, so
    // instead we use it to cull false positives.
    if (mc[64] != 0)
        return false;
    // Padding filler bits; theoretically they might be set to garbage
    // values but again it's better to use them to cull false positives.
    for (size_t i = 74; i < 128; ++i)
        if (mc[i] != 0)
            return false;
    // Min/Max fields
    int16_t offsx, offsy, limx, limy, width, height;
    offsx = (int16_t) (mc[ 4] + (mc[ 5]<<8));
    offsy = (int16_t) (mc[ 6] + (mc[ 7]<<8));
    limx  = (int16_t) (mc[ 8] + (mc[ 9]<<8));
    limy  = (int16_t) (mc[10] + (mc[11]<<8));
    width = 1 + limx - offsx; height = 1 + limy - offsy;
    // Compute number of bytes needed per scanline, and account for possible padding
    int16_t bnpsl = (width * mc[3]) / 8; if (bnpsl % 2) bnpsl++;
    // Bytes per scanline field is always an even number and should correspond to guessed value
    int16_t bpsl = (int16_t) (mc[66] + (mc[67]<<8));
    if (bpsl%2 || bpsl != bnpsl)
        return false;
    // Passed all tests, so this seems to be a valid PCX
    return true;
}

bool EntryDataFormat::detectTga(MemChunk& mc) {
    // Size check for the header
    if (mc.getSize() < 18)
        return false;

    // Check dimensions, both ZDoom and Vavoom refuse to load TGA
    // with image sizes greater than 2048 so let's use that as well
    uint16_t width  = mc[12] + (mc[13]<<8);
    uint16_t height = mc[14] + (mc[15]<<8);
    if (width > 2048 || height > 2048)
        return false;

    // Check image type, must be a value between 1 and 3 or 9 and 11
    if (mc[2] == 0 || mc[2] > 11 || (mc[2] > 3 && mc[2] < 9))
        return false;

    // The colormap bool must be 0 or 1
    if (mc[1] != 0 && mc[1] != 1)
        return false;

    // Bits per pixel can be 8, 15, 16, 24 or 32
    if (mc[16] != 8 && mc[16] != 15 && mc[16] != 16 && mc[16] !=24 && mc[16] !=32)
        return false;

    // ZDoom and Vavoom both refuse exotic directions in the descriptor, so same
    if ((mc[17] & 16) != 0)
        return false;

    return true;
}

bool EntryDataFormat::detectTiff(MemChunk& mc) {
    // Check size, minimum size is 26 if I'm not mistaken:
    // 8 for the image header, +2 for at least one image
    // file directory, +12 for at least one directory entry,
    // +4 for a NULL offset for the next IFD
    size_t size = mc.getSize();
    if (size < 26)
        return false;
    // First two bytes must be identical, and either II or MM
    if (mc[0] != mc[1] || (mc[0] != 0x49 && mc[0] != 0x4D))
        return false;
    bool littleendian = (mc[0] == 'I');
    // The value of 42 (0x2A) is present in the next two bytes,
    // in the given endianness
    if (42 != (littleendian ?
        wxUINT16_SWAP_ON_BE((const uint16_t)(mc[2])) :
        wxUINT16_SWAP_ON_LE((const uint16_t)(mc[2]))))
        return false;
    // First offset must be on a word boundary (therefore, %2 == 0) and
    // somewhere within the file, but not in the header of course.
    size_t offset = (littleendian ?
        wxUINT32_SWAP_ON_BE((const uint32_t)(mc[4])) :
        wxUINT32_SWAP_ON_LE((const uint32_t)(mc[4])));
    if (offset < 8 || offset >= size || offset %2)
        return false;
    // Check the first IFD for validity
    uint16_t numentries = (littleendian ?
        wxUINT16_SWAP_ON_BE((const uint16_t)(mc[offset])) :
        wxUINT16_SWAP_ON_LE((const uint16_t)(mc[offset])));
    if (offset + 6 + (numentries * 12) > size)
        return false;
    // Okay, it seems valid so far
    return true;
}

bool EntryDataFormat::detectJpeg(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 128) {
        // Check for JPEG header
        if ((mc[6] == 'J' && mc[7] == 'F' && mc[8] == 'I' && mc[9] == 'F') ||
                (mc[6] == 'E' && mc[7] == 'x' && mc[8] == 'i' && mc[9] == 'f')) {
            if (mc[0] == 255 && mc[1] == 216 && mc[2] == 255) {
                return true;
            }
        }
    }

    return false;
}

bool EntryDataFormat::detectDoomGfx(MemChunk& mc) {
    const uint8_t* data = mc.getData();

    // Check size
    if (mc.getSize() > sizeof(patch_header_t)) {
        const patch_header_t *header = (const patch_header_t *)data;

        // Check header values are 'sane'
        if (header->height > 0 && header->height < 4096 &&
                header->width > 0 && header->width < 4096 &&
                header->top > -2000 && header->top < 2000 &&
                header->left > -2000 && header->left < 2000) {
            uint32_t *col_offsets = (uint32_t *)((const uint8_t *)data + sizeof(patch_header_t));

            // Check there is room for needed column pointers
            if (mc.getSize() < sizeof(patch_header_t) + (header->width * sizeof(uint32_t)))
                return false;

            // Check column pointers are within range
            for (int a = 0; a < header->width; a++) {
                if (col_offsets[a] > mc.getSize() || col_offsets[a] < sizeof(patch_header_t))
                    return false;
            }

            // Passed all checks, so probably is doom gfx
            return true;
        }
    }

    return false;
}

bool EntryDataFormat::detectDoomGfxAlpha(MemChunk& mc) {
    // Get entry data
    const uint8_t* data = mc.getData();

    // Check size
    if (mc.getSize() > sizeof(oldpatch_header_t)) {
        // Check that it ends on a FF byte
        if (mc[mc.getSize() -1] != 0xFF)
            return false;

        const oldpatch_header_t *header = (const oldpatch_header_t *)data;

        // Check header values are 'sane'
        if (header->width > 0 && header->height > 0) {
            uint16_t col_offsets[255]; // Old format headers do not allow dimensions greater than 255.
            for (uint8_t a = 0; a < header->width; a++) {
                const uint8_t * offsetpos = data + sizeof(oldpatch_header_t) + a * sizeof(uint16_t);
                const uint16_t * colofsa = (uint16_t *)(offsetpos);
                col_offsets[a] = wxUINT16_SWAP_ON_BE(*colofsa);
            }

            // Check there is room for needed column pointers
            if (mc.getSize() < sizeof(oldpatch_header_t) + (header->width * sizeof(uint16_t)))
                return false;

            // Check column pointers are within range
            for (int a = 0; a < header->width; a++) {
                if (col_offsets[a] > mc.getSize() || col_offsets[a] < sizeof(oldpatch_header_t))
                    return false;
            }

            // Passed all checks, so probably is doom gfx
            return true;
        }
    }

    return false;
}

bool EntryDataFormat::detectDoomGfxBeta(MemChunk& mc) {
    // Check size
    if (mc.getSize() <= sizeof(patch_header_t))
        return false;

    const uint8_t* data = mc.getData();

    // Check that it ends on a FF byte.
    if (mc[mc.getSize() -1] != 0xFF) {
        // The lumps in the beta have sometimes up to three garbage 00 bytes; probably a question of byte alignment.
        for (uint8_t i = 1; i < 4; i++) {
            if (mc[mc.getSize() - i] == 0xFF)
                // Cool, we found the ending byte so it's okay.
                break;
            else if (mc[mc.getSize() - i] != 0x00)
                // It's not 00 and it's not FF, so it's a wrong byte.
                return false;
        }
    }

    const patch_header_t *header = (const patch_header_t *)data;

    // Check header values are 'sane'
    if (header->height > 0 && header->height < 4096 &&
            header->width > 0 && header->width < 4096 &&
            header->top > -2000 && header->top < 2000 &&
            header->left > -2000 && header->left < 2000) {
        uint16_t *col_offsets = (uint16_t *)((const uint8_t *)data + sizeof(patch_header_t));

        // Check there is room for needed column pointers
        if (mc.getSize() < sizeof(patch_header_t) + (header->width * sizeof(uint16_t)))
            return false;

        // Check column pointers are within range
        for (int a = 0; a < header->width; a++) {
            if (col_offsets[a] > mc.getSize() || col_offsets[a] < sizeof(patch_header_t))
                return false;
        }

        // Passed all checks, so probably is doom gfx
        return true;
    }

    return false;
}

/* The following is the documentation about sneas from
 * the DeuTex source:
 *  The snea format was used for certain graphics in Doom
 *  alpha 0.4 and 0.5. It consists in a 2-byte header
 *  followed by an interleaved bitmap. The first byte, W, is
 *  the quarter of the width. The second byte, H is the
 *  height. The bitmap is made of 4xWxH bytes. The first WxH
 *  bytes contain the bitmap for columns 0, 4, 8, etc. The
 *  next WxH bytes contain the bitmap for columns 1, 5, 9,
 *  etc., and so on. No transparency.
 */
bool EntryDataFormat::detectDoomGfxSnea(MemChunk& mc) {
    // Check size
    if (mc.getSize() < 2)
        return false;

    const uint8_t* data = mc.getData();
    uint8_t qwidth = data[0]; // quarter of width
    uint8_t height = data[1];
    if (mc.getSize() != (2 + (4 * qwidth * height)) &&
        // The TITLEPIC in the Doom Press-Release Beta has
        // two extraneous null bytes at the end.
        (qwidth != 80 || height != 200 || mc.getSize() != 64004))
        return false;
    return true;
}

/* This format is used in Doom alpha 0.2. DeuTex doesn't know it,
 * but it seems a really simple format, basically a eight-byte
 * header for size and offsets followed by a raw format dump.
 * Therefore I christened it the ARAH format: Alpha Raw And Header.
 * The header has the same format as the final patch format.
 * To be honest, I'm not actually sure there are offset fields
 * since those values always seem to be set to 0, but hey.
 */
bool EntryDataFormat::detectDoomGfxArah(MemChunk& mc) {
    if (mc.getSize() < sizeof(patch_header_t))
        return false;

    const uint8_t* data = mc.getData();
    const patch_header_t *header = (const patch_header_t *)data;

    // Check header values are 'sane'
    if (!(header->height > 0 && header->height < 4096 &&
        header->width > 0 && header->width < 4096 &&
        header->top > -2000 && header->top < 2000 &&
        header->left > -2000 && header->left < 2000))
        return false;

    // Check the size matches
    if (mc.getSize() != (sizeof(patch_header_t) + (header->width * header->height)))
        return false;

    return true;
}

bool EntryDataFormat::detectPlanar(MemChunk& mc) {
    // 640x480 4-bit graphic with 48-bit, 16-color palette.
    if (mc.getSize() != 153648)
        return false;
    return true;
}

bool EntryDataFormat::detect4bitChunk(MemChunk& mc) {
    if (mc.getSize() != 32 && mc.getSize() != 184)
        return false;
    return true;
}

bool EntryDataFormat::detectImgz(MemChunk& mc) {
    // A format created by Randy Heit and used by some crosshairs in ZDoom.
    uint32_t size = mc.getSize();

    if (size < sizeof(imgz_header_t))
        return false;

    const uint8_t* data = mc.getData();
    const imgz_header_t *header = (const imgz_header_t *)data;

    // Check signature
    if (header->magic[0] != 'I' || header->magic[1] != 'M' ||
        header->magic[2] != 'G' || header->magic[3] != 'Z')
        return false;

    // Check that values are sane
    if (header->width == 0xFFFF || !(header->width | header->height))
        return false;

    // The reserved values should all be null
    for (uint8_t i = 0; i < 11 ; ++i)
        if (header->reserved[i]) return false;

    // This is probably a genuine IMGZ
    return true;
}

extern uint32_t n_valid_flat_sizes;
extern uint32_t valid_flat_size[][2];

bool EntryDataFormat::detectDoomFlat(MemChunk& mc) {
    // Not too sure how I should go about detecting this - just checking size as
    // it is now seems too cheap, but checking both size and position in the
    // archive could make things confusing for the user. Blah.
    uint32_t size = mc.getSize();

    for (size_t i = 0; i < n_valid_flat_sizes; ++i) {
        if (size == valid_flat_size[i][0]*valid_flat_size[i][1])
            return true;
    }
    if (detectTranslationTable(mc)) return true;
    return !(size < 320 || size % 320);
}

// A data format found while rifling through some Legacy mods,
// specifically High Tech Hell 2. It seems to be how it works.
bool EntryDataFormat::detectDoomLegacy(MemChunk& mc) {
    uint32_t size = mc.getSize();
    if (size < 9)
        return false;
    // These three values must all be zeroes
    if (mc[2] | mc[6] | mc[7])
        return false;
    if (mc[3] > 4)
        return false;
    uint8_t bpp = (mc[3]?mc[3]:1);
    uint16_t width  = mc[0] + (mc[1]<<8);
    uint16_t height = mc[4] + (mc[5]<<8);
    if (size != (8 + width * height * bpp))
        return false;
    return true;
}

bool EntryDataFormat::detectTranslationTable (MemChunk& mc) {
    // Translation tables and colormaps are essentially the same thing.
    // Can't rely on size because Inkworks adds a signature at the end:
    // "This lump was created by The Cookie Monsters InkWorks for DOOM (ver x.y)"
    uint32_t size = mc.getSize();
    if (size > 8704) {
        if (size < 8776)
            return false;
        bool inkworks = true;
        const char* compare = "This lump was created by The Cookie Monsters InkWorks for DOOM";
        for (size_t i = 0; i < 62; ++i) {
            if (mc[8704+i] != compare[i]) {
                inkworks = false;
                break;
            }
        }
        return inkworks;
    }
    return !(size < 256 || size % 256);
}

bool EntryDataFormat::detectPalette(MemChunk& mc) {
    // Some palettes have crap added to them which makes them
    // not a clean multiple. However, the minimum size should
    // still be 768!
    if (mc.getSize() < 768)
        return false;
    return true;
}

bool EntryDataFormat::detectWad(MemChunk& mc) {
    return WadArchive::isWadArchive(mc);
}

bool EntryDataFormat::detectZip(MemChunk& mc) {
    return ZipArchive::isZipArchive(mc);
}

bool EntryDataFormat::detectMus(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 16) {
        // Check for MUS header
        if (mc[0] == 'M' && mc[1] == 'U' && mc[2] == 'S' && mc[3] == 0x1A)
            return true;
    }

    return false;
}

bool EntryDataFormat::detectMidi(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 16) {
        // Check for MIDI header
        if (mc[0] == 'M' && mc[1] == 'T' && mc[2] == 'h' && mc[3] == 'd')
            return true;
    }

    return false;
}

bool EntryDataFormat::detectModIt(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 32) {
        // Check for IT header
        if (mc[0] == 'I' && mc[1] == 'M' && mc[2] == 'P' && mc[3] == 'M')
            return true;
    }

    return false;
}

bool EntryDataFormat::detectModXm(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 80) {
        // Check for mod header
        char temp[17] = "";
        memcpy(temp, mc.getData(), 17);
        if (!s_fmt(_T("%s"), temp).Cmp(_T("Extended module: "))) {
            if (mc[37] == 0x1a) {
                return true;
            }
        }
    }

    return false;
}

bool EntryDataFormat::detectModS3m(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 60) {
        // Check for s3m header
        if (mc[44] == 'S' && mc[45] == 'C' && mc[46] == 'R' && mc[47] == 'M')
            return true;
    }

    return false;
}

bool EntryDataFormat::detectModMod(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 1084) {
        // Check format
        if (mc[950] >= 1 && mc[950] <= 128 && mc[951] == 127) {
            if ((mc[1080] == 'M' && mc[1081] == '.' && mc[1082] == 'K' && mc[1083] == '.') ||
                    (mc[1080] == 'M' && mc[1081] == '!' && mc[1082] == 'K' && mc[1083] == '!') ||
                    (mc[1080] == 'F' && mc[1081] == 'L' && mc[1082] == 'T' && mc[1083] == '4') ||
                    (mc[1080] == 'F' && mc[1081] == 'L' && mc[1082] == 'T' && mc[1083] == '8') ||
                    (mc[1081] == 'C' && mc[1082] == 'H' && mc[1083] == 'N')) {
                return true;
            }
        }
    }

    return false;
}

bool EntryDataFormat::detectSndDoom(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 8) {
        // Check header
        uint16_t head, samplerate, samples, tail;
        mc.seek(0, SEEK_SET);
        mc.read(&head, 2);
        mc.read(&samplerate, 2);
        mc.read(&samples, 2);
        mc.read(&tail, 2);

        if (head == 3 && tail == 0 && samples <= mc.getSize() - 8 && samples > 4 && mc.getSize() <= 65543)
            return true;
    }

    return false;
}

bool EntryDataFormat::detectSndSpeaker(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check header: the first two bytes must always be null
        if (mc[0] | mc[1])
            return false;
        // Next is the number of samples (LE uint16_t), and
        // each sample is a single byte, so the size can be
        // checked easily.
        if (mc.getSize() == 4 + (mc[2]+(mc[3]<<8)))
            return true;
    }
    return false;
}

bool EntryDataFormat::detectSndWav(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 8) {
        // Check for wav header
        if (mc[0] == 'R' && mc[1] == 'I' && mc[2] == 'F' && mc[3] == 'F')
            return true;
    }

    return false;
}

bool EntryDataFormat::detectSndOgg(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for OGG Vorbis header -- a lot more tests could be made
        // to make sure the data is valid, though.
        // Maybe later when a mediaplayer is actually implemented...
        if (mc[0] == 'O' && mc[1] == 'g' && mc[2] == 'g' && mc[3] == 'S')
            return true;
    }
    return false;
}

bool EntryDataFormat::detectSndFlac(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for FLAC header. Same comment as for detectSndOgg.
        if (mc[0] == 'f' && mc[1] == 'L' && mc[2] == 'a' && mc[3] == 'C')
            return true;
    }
    return false;
}

bool EntryDataFormat::detectTextureX(MemChunk& mc) {
    // Not the best test in the world. But a text-based texture lump ought
    // to fail it every time; as it would be interpreted as too high a number.
    const uint8_t * data = mc.getData();
    uint32_t ntex = data[0] + (data[1]<<8) + (data[2]<<16) + (data[3]<<24);
    if ((int32_t) ntex < 0)
        return false;
    if (mc.getSize() < (ntex * 24))
        return false;
    return true;
}

bool EntryDataFormat::detectPnames(MemChunk& mc) {
    // It's a pretty simple format alright
    const uint8_t * data = mc.getData();
    uint32_t number = data[0] + (data[1]<<8) + (data[2]<<16) + (data[3]<<24);
    if ((int32_t) number < 0)
        return false;
    if (mc.getSize() != (4 + number * 8))
        return false;
    return true;
}

bool EntryDataFormat::detectAnimated(MemChunk& mc) {
    if (mc.getSize() > sizeof(animated_t)) {
        size_t numentries = mc.getSize()/sizeof(animated_t);
        // The last entry can be incomplete, as it may stop right
        // after the declaration of its type. So if the size is not
        // a perfect multiple, then the last entry is incomplete.
        size_t lastentry = (mc.getSize()%numentries ? numentries : numentries - 1);

        // Check that the last entry ends on an ANIM_STOP type
        if (mc[lastentry*sizeof(animated_t)] == ANIM_STOP)
            return true;
    }
    return false;
}

bool EntryDataFormat::detectSwitches(MemChunk& mc) {
    if (mc.getSize() > sizeof(switches_t)) {
        size_t numentries = mc.getSize()/sizeof(switches_t);

        // Check that the last entry ends on a SWCH_STOP type
        if (((mc[numentries*sizeof(switches_t) -1]<<8)
            + mc[numentries*sizeof(switches_t) -2]) == SWCH_STOP)
            return true;
    }
    return false;
}

bool EntryDataFormat::detectFontM(MemChunk& mc) {
    // Monochrome, monospaced bitmap font.
    // Each character is one-byte wide, and there are 256 of them,
    // so the height can be obtained from the total size
    if (mc.getSize() % 256)
        return false;
    if (mc.getSize() / 256 < 6 || mc.getSize() / 256 > 36)
        return false;
    return true;
}

bool EntryDataFormat::detectFont0(MemChunk& mc) {
    if (mc.getSize() <= 0x302)
        return false;

    const uint16_t * gfx_data = (const uint16_t *) mc.getData();

    size_t height = wxINT16_SWAP_ON_BE(gfx_data[0]);

    size_t datasize = mc.getSize() - 0x302;
    if (datasize % height)
        return false;

    // It seems okay so far. Check that one
    // character does start at offset 0x302.
    // The offsets are themselves between
    // offsets 0x102 and 0x302. Halved for int16_t.
    for (size_t i = 0x81; i < 0x181; ++i)
        if (gfx_data[i] == wxINT16_SWAP_ON_BE(0x302))
            return true;

    // Doesn't seem to be such a file after all.
    return false;
}

bool EntryDataFormat::detectFont1(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for FON1 header
        if (mc[0] == 'F' && mc[1] == 'O' && mc[2] == 'N' && mc[3] == '1')
            return true;
    }
    return false;
}

bool EntryDataFormat::detectFont2(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for FON2 header
        if (mc[0] == 'F' && mc[1] == 'O' && mc[2] == 'N' && mc[3] == '2')
            return true;
    }
    return false;
}

bool EntryDataFormat::detectBMF(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for BMF header
        if (mc[0] == 0xE1 && mc[1] == 0xE6 && mc[2] == 0xD5 && mc[3] == 0x1A)
            return true;
    }
    return false;
}

bool EntryDataFormat::detectZGLNodes(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for ZGLN header
        if (mc[0] == 'Z' && mc[1] == 'G' && mc[2] == 'L' && mc[3] == 'N')
            return true;
    }
    return false;
}

bool EntryDataFormat::detectZGLNodes2(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for ZGL2 header
        if (mc[0] == 'Z' && mc[1] == 'G' && mc[2] == 'L' && mc[3] == '2')
            return true;
    }
    return false;
}

// Model formats. More checks could probably be made...
bool EntryDataFormat::detectDMD(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for DMDM header
        if (mc[0] == 'D' && mc[1] == 'M' && mc[2] == 'D' && mc[3] == 'M')
            return true;
    }
    return false;
}

bool EntryDataFormat::detectMDL(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for IDPO header
        if (mc[0] == 'I' && mc[1] == 'D' && mc[2] == 'P' && mc[3] == 'O')
            return true;
    }
    return false;
}

bool EntryDataFormat::detectMD2(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for IDP2 header
        if (mc[0] == 'I' && mc[1] == 'D' && mc[2] == 'P' && mc[3] == '2')
            return true;
    }
    return false;
}

bool EntryDataFormat::detectMD3(MemChunk& mc) {
    // Check size
    if (mc.getSize() > 4) {
        // Check for IDP3 header
        if (mc[0] == 'I' && mc[1] == 'D' && mc[2] == 'P' && mc[3] == '3')
            return true;
    }
    return false;
}
