static unsigned int inline flac_get_metablock_length(unsigned int data)
{
    return LittleEndian(data) & 0x0FFF;
}
Exemple #2
0
// public int ReadInt() [instance] :134
int BinaryReader::ReadInt()
{
    FillBuffer(4);
    return ::g::Uno::Runtime::Implementation::BufferImpl::GetInt(_buffer, 0, LittleEndian());
}
Exemple #3
0
bool module_renderer::ReadITProject(const uint8_t * lpStream, const uint32_t dwMemLength)
//-----------------------------------------------------------------------
{
    UINT i,n,nsmp;
    uint32_t id,len,size;
    uint32_t dwMemPos = 0;
    uint32_t version;

    ASSERT_CAN_READ(12);

    // Check file ID

    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    if(id != ITP_FILE_ID) return false;
    dwMemPos += sizeof(uint32_t);

    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    version = id;
    dwMemPos += sizeof(uint32_t);

    // bad_max supported version
    if(version > ITP_VERSION)
    {
        return false;
    }

    m_nType = MOD_TYPE_IT;

    // Song name

    // name string length
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    len = id;
    dwMemPos += sizeof(uint32_t);

    // name string
    ASSERT_CAN_READ(len);
    if (len <= MAX_SAMPLENAME)
    {
        assign_without_padding(this->song_name, reinterpret_cast<const char *>(lpStream + dwMemPos), len);
        dwMemPos += len;
    }
    else return false;

    // Song comments

    // comment string length
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    dwMemPos += sizeof(uint32_t);
    if(id > UINT16_MAX) return false;

    // allocate and copy comment string
    ASSERT_CAN_READ(id);
    if(id > 0)
    {
        ReadMessage(lpStream + dwMemPos, id - 1, leCR);
    }
    dwMemPos += id;

    // Song global config
    ASSERT_CAN_READ(5*4);

    // m_dwSongFlags
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_dwSongFlags = (id & SONG_FILE_FLAGS);
    dwMemPos += sizeof(uint32_t);

    if(!(m_dwSongFlags & SONG_ITPROJECT)) return false;

    // m_nDefaultGlobalVolume
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nDefaultGlobalVolume = id;
    dwMemPos += sizeof(uint32_t);

    // m_nSamplePreAmp
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nSamplePreAmp = id;
    dwMemPos += sizeof(uint32_t);

    // m_nDefaultSpeed
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nDefaultSpeed = id;
    dwMemPos += sizeof(uint32_t);

    // m_nDefaultTempo
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nDefaultTempo = id;
    dwMemPos += sizeof(uint32_t);

    // Song channels data
    ASSERT_CAN_READ(2*4);

    // m_nChannels
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nChannels = (modplug::tracker::chnindex_t)id;
    dwMemPos += sizeof(uint32_t);
    if(m_nChannels > 127) return false;

    // channel name string length (=MAX_CHANNELNAME)
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    len = id;
    dwMemPos += sizeof(uint32_t);
    if(len > MAX_CHANNELNAME) return false;

    // Channels' data
    for(i=0; i<m_nChannels; i++){
        ASSERT_CAN_READ(3*4 + len);

        // ChnSettings[i].nPan
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        ChnSettings[i].nPan = id;
        dwMemPos += sizeof(uint32_t);

        // ChnSettings[i].dwFlags
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        ChnSettings[i].dwFlags = id;
        dwMemPos += sizeof(uint32_t);

        // ChnSettings[i].nVolume
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        ChnSettings[i].nVolume = id;
        dwMemPos += sizeof(uint32_t);

        // ChnSettings[i].szName
        memcpy(&ChnSettings[i].szName[0],lpStream+dwMemPos,len);
        SetNullTerminator(ChnSettings[i].szName);
        dwMemPos += len;
    }

    // Song mix plugins
    // size of mix plugins data
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    dwMemPos += sizeof(uint32_t);

    // mix plugins
    ASSERT_CAN_READ(id);
    dwMemPos += LoadMixPlugins(lpStream+dwMemPos, id);

    // Song midi config

    // midi cfg data length
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    dwMemPos += sizeof(uint32_t);

    // midi cfg
    ASSERT_CAN_READ(id);
    if (id <= sizeof(m_MidiCfg))
    {
        memcpy(&m_MidiCfg, lpStream + dwMemPos, id);
        SanitizeMacros();
        dwMemPos += id;
    }

    // Song Instruments

    // m_nInstruments
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    m_nInstruments = (modplug::tracker::instrumentindex_t)id;
    if(m_nInstruments > MAX_INSTRUMENTS) return false;
    dwMemPos += sizeof(uint32_t);

    // path string length (=_MAX_PATH)
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    len = id;
    if(len > _MAX_PATH) return false;
    dwMemPos += sizeof(uint32_t);

    // instruments' paths
    for(i=0; i<m_nInstruments; i++){
        ASSERT_CAN_READ(len);
        memcpy(&m_szInstrumentPath[i][0],lpStream+dwMemPos,len);
        SetNullTerminator(m_szInstrumentPath[i]);
        dwMemPos += len;
    }

    // Song Orders

    // size of order array (=MAX_ORDERS)
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    size = id;
    if(size > MAX_ORDERS) return false;
    dwMemPos += sizeof(uint32_t);

    // order data
    ASSERT_CAN_READ(size);
    Order.ReadAsByte(lpStream+dwMemPos, size, dwMemLength-dwMemPos);
    dwMemPos += size;



    // Song Patterns

    ASSERT_CAN_READ(3*4);
    // number of patterns (=MAX_PATTERNS)
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    size = id;
    dwMemPos += sizeof(uint32_t);
    if(size > MAX_PATTERNS) return false;

    // m_nPatternNames
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    const modplug::tracker::patternindex_t numNamedPats = id;
    dwMemPos += sizeof(uint32_t);

    // pattern name string length (=MAX_PATTERNNAME)
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    const uint32_t patNameLen = id;
    dwMemPos += sizeof(uint32_t);

    // m_lpszPatternNames
    ASSERT_CAN_READ(numNamedPats * patNameLen);
    char *patNames = (char *)(lpStream + dwMemPos);
    dwMemPos += numNamedPats * patNameLen;

    // modcommand data length
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    n = id;
    if(n != 6) return false;
    dwMemPos += sizeof(uint32_t);

    for(modplug::tracker::patternindex_t npat=0; npat<size; npat++)
    {
        // Patterns[npat].GetNumRows()
        ASSERT_CAN_READ(4);
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        if(id > MAX_PATTERN_ROWS) return false;
        const modplug::tracker::rowindex_t nRows = id;
        dwMemPos += sizeof(uint32_t);

        // Try to allocate & read only sized patterns
        if(nRows)
        {

            // Allocate pattern
            if(Patterns.Insert(npat, nRows))
            {
                dwMemPos += m_nChannels * Patterns[npat].GetNumRows() * n;
                continue;
            }
            if(npat < numNamedPats && patNameLen > 0)
            {
                Patterns[npat].SetName(patNames, patNameLen);
                patNames += patNameLen;
            }

            // Pattern data
            long datasize = m_nChannels * Patterns[npat].GetNumRows() * n;
            //if (streamPos+datasize<=dwMemLength) {
            if(Patterns[npat].ReadITPdata(lpStream, dwMemPos, datasize, dwMemLength))
            {
                ErrorBox(IDS_ERR_FILEOPEN, NULL);
                return false;
            }
            //memcpy(Patterns[npat],lpStream+streamPos,datasize);
            //streamPos += datasize;
            //}
        }
    }

    // Load embeded samples

    ITSAMPLESTRUCT pis;

    // Read original number of samples
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    if(id > MAX_SAMPLES) return false;
    m_nSamples = (modplug::tracker::sampleindex_t)id;
    dwMemPos += sizeof(uint32_t);

    // Read number of embeded samples
    ASSERT_CAN_READ(4);
    memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
    if(id > MAX_SAMPLES) return false;
    n = id;
    dwMemPos += sizeof(uint32_t);

    // Read samples
    for(i=0; i<n; i++){

        ASSERT_CAN_READ(4 + sizeof(ITSAMPLESTRUCT) + 4);

        // Sample id number
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        nsmp = id;
        dwMemPos += sizeof(uint32_t);

        if(nsmp < 1 || nsmp >= MAX_SAMPLES)
            return false;

        // Sample struct
        memcpy(&pis,lpStream+dwMemPos,sizeof(ITSAMPLESTRUCT));
        dwMemPos += sizeof(ITSAMPLESTRUCT);

        // Sample length
        memcpy(&id,lpStream+dwMemPos,sizeof(uint32_t));
        len = id;
        dwMemPos += sizeof(uint32_t);
        if(dwMemPos >= dwMemLength || len > dwMemLength - dwMemPos) return false;

        // Copy sample struct data (ut-oh... this code looks very familiar!)
        if(pis.id == LittleEndian(IT_IMPS))
        {
            modsample_t *pSmp = &Samples[nsmp];
            memcpy(pSmp->legacy_filename, pis.filename, 12);
            pSmp->flags = 0;
            pSmp->length = 0;
            pSmp->loop_start = pis.loopbegin;
            pSmp->loop_end = pis.loopend;
            pSmp->sustain_start = pis.susloopbegin;
            pSmp->sustain_end = pis.susloopend;
            pSmp->c5_samplerate = pis.C5Speed;
            if(!pSmp->c5_samplerate) pSmp->c5_samplerate = 8363;
            if(pis.C5Speed < 256) pSmp->c5_samplerate = 256;
            pSmp->default_volume = pis.vol << 2;
            if(pSmp->default_volume > 256) pSmp->default_volume = 256;
            pSmp->global_volume = pis.gvl;
            if(pSmp->global_volume > 64) pSmp->global_volume = 64;
            if(pis.flags & 0x10) pSmp->flags |= CHN_LOOP;
            if(pis.flags & 0x20) pSmp->flags |= CHN_SUSTAINLOOP;
            if(pis.flags & 0x40) pSmp->flags |= CHN_PINGPONGLOOP;
            if(pis.flags & 0x80) pSmp->flags |= CHN_PINGPONGSUSTAIN;
            pSmp->default_pan = (pis.dfp & 0x7F) << 2;
            if(pSmp->default_pan > 256) pSmp->default_pan = 256;
            if(pis.dfp & 0x80) pSmp->flags |= CHN_PANNING;
            pSmp->vibrato_type = autovibit2xm[pis.vit & 7];
            pSmp->vibrato_rate = pis.vis;
            pSmp->vibrato_depth = pis.vid & 0x7F;
            pSmp->vibrato_sweep = pis.vir;
            if(pis.length){
                pSmp->length = pis.length;
                if (pSmp->length > MAX_SAMPLE_LENGTH) pSmp->length = MAX_SAMPLE_LENGTH;
                UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U;
                if (pis.flags & 2){
                    flags += 5;
                    if (pis.flags & 4) flags |= RSF_STEREO;
                    pSmp->flags |= CHN_16BIT;
                }
                else{
                    if (pis.flags & 4) flags |= RSF_STEREO;
                }
                // Read sample data
                ReadSample(&Samples[nsmp], flags, (LPSTR)(lpStream+dwMemPos), len);
                dwMemPos += len;
                memcpy(m_szNames[nsmp], pis.name, 26);
            }
        }
    }

    // Load instruments

    CMappedFile f;
    LPBYTE lpFile;

    for(modplug::tracker::instrumentindex_t i = 0; i < m_nInstruments; i++)
    {

        if(m_szInstrumentPath[i][0] == '\0' || !f.Open(m_szInstrumentPath[i])) continue;

        len = f.GetLength();
        lpFile = f.Lock(len);
        if(!lpFile) { f.Close(); continue; }

        ReadInstrumentFromFile(i+1, lpFile, len);
        f.Unlock();
        f.Close();
    }

    // Extra info data

    __int32 fcode = 0;
    const uint8_t * ptr = lpStream + bad_min(dwMemPos, dwMemLength);

    if (dwMemPos <= dwMemLength - 4) {
        fcode = (*((__int32 *)ptr));
    }

    // Embed instruments' header [v1.01]
    if(version >= 0x00000101 && m_dwSongFlags & SONG_ITPEMBEDIH && fcode == 'EBIH')
    {
        // jump embeded instrument header tag
        ptr += sizeof(__int32);

        // set first instrument's header as current
        i = 1;

        // parse file
        while( uintptr_t(ptr - lpStream) <= dwMemLength - 4 && i <= m_nInstruments )
        {

            fcode = (*((__int32 *)ptr));                    // read field code

            switch( fcode )
            {
            case 'MPTS': goto mpts; //:)            // reached end of instrument headers
            case 'SEP@': case 'MPTX':
                ptr += sizeof(__int32);                    // jump code
                i++;                                                    // switch to next instrument
                break;

            default:
                ptr += sizeof(__int32);                    // jump field code
                ReadExtendedInstrumentProperty(Instruments[i], fcode, ptr, lpStream + dwMemLength);
                break;
            }
        }
    }

    //HACK: if we fail on i <= m_nInstruments above, arrive here without having set fcode as appropriate,
    //      hence the code duplication.
    if ( (uintptr_t)(ptr - lpStream) <= dwMemLength - 4 )
    {
        fcode = (*((__int32 *)ptr));
    }

    // Song extensions
mpts:
    if( fcode == 'MPTS' )
        LoadExtendedSongProperties(MOD_TYPE_IT, ptr, lpStream, dwMemLength);

    m_nMaxPeriod = 0xF000;
    m_nMinPeriod = 8;

    if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 2, 50))
    {
        SetModFlag(MSF_COMPATIBLE_PLAY, false);
        SetModFlag(MSF_MIDICC_BUGEMULATION, true);
        SetModFlag(MSF_OLDVOLSWING, true);
    }

    return true;
}
Exemple #4
0
bool module_renderer::SaveITProject(LPCSTR lpszFileName)
//-------------------------------------------------
{
    // Check song type

    if(!(m_dwSongFlags & SONG_ITPROJECT)) return false;

    UINT i,j = 0;
    for(i = 0 ; i < m_nInstruments ; i++) { if(m_szInstrumentPath[i][0] != '\0' || !Instruments[i+1]) j++; }
    if(m_nInstruments && j != m_nInstruments) return false;

    // Open file

    FILE *f;

    if((!lpszFileName) || ((f = fopen(lpszFileName, "wb")) == NULL)) return false;


    // File ID

    uint32_t id = ITP_FILE_ID;
    fwrite(&id, 1, sizeof(id), f);

    id = ITP_VERSION;
    fwrite(&id, 1, sizeof(id), f);

    // Song name

    // name string length
    id = 27;
    fwrite(&id, 1, sizeof(id), f);

    // song name
    char namebuf[27];
    copy_with_padding(namebuf, 27, this->song_name);
    fwrite(namebuf, 1, 27, f);

    // Song comments

    // comment string length
    id = m_lpszSongComments ? strlen(m_lpszSongComments)+1 : 0;
    fwrite(&id, 1, sizeof(id), f);

    // comment string
    if(m_lpszSongComments) fwrite(&m_lpszSongComments[0], 1, strlen(m_lpszSongComments)+1, f);

    // Song global config

    id = (m_dwSongFlags & SONG_FILE_FLAGS);
    fwrite(&id, 1, sizeof(id), f);
    id = m_nDefaultGlobalVolume;
    fwrite(&id, 1, sizeof(id), f);
    id = m_nSamplePreAmp;
    fwrite(&id, 1, sizeof(id), f);
    id = m_nDefaultSpeed;
    fwrite(&id, 1, sizeof(id), f);
    id = m_nDefaultTempo;
    fwrite(&id, 1, sizeof(id), f);

    // Song channels data

    // number of channels
    id = m_nChannels;
    fwrite(&id, 1, sizeof(id), f);

    // channel name string length
    id = MAX_CHANNELNAME;
    fwrite(&id, 1, sizeof(id), f);

    // channel config data
    for(i=0; i<m_nChannels; i++){
        id = ChnSettings[i].nPan;
        fwrite(&id, 1, sizeof(id), f);
        id = ChnSettings[i].dwFlags;
        fwrite(&id, 1, sizeof(id), f);
        id = ChnSettings[i].nVolume;
        fwrite(&id, 1, sizeof(id), f);
        fwrite(&ChnSettings[i].szName[0], 1, MAX_CHANNELNAME, f);
    }

    // Song mix plugins

    // mix plugins data length
    id = SaveMixPlugins(NULL, TRUE);
    fwrite(&id, 1, sizeof(id), f);

    // mix plugins data
    SaveMixPlugins(f, FALSE);

    // Song midi config

    // midi cfg data length
    id = sizeof(MODMIDICFG);
    fwrite(&id, 1, sizeof(id), f);

    // midi cfg
    fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f);

    // Song Instruments

    // number of instruments
    id = m_nInstruments;
    fwrite(&id, 1, sizeof(id), f);

    // path name string length
    id = _MAX_PATH;
    fwrite(&id, 1, sizeof(id), f);

    // instruments' path
    for(i=0; i<m_nInstruments; i++) fwrite(&m_szInstrumentPath[i][0], 1, _MAX_PATH, f);

    // Song Orders

    // order array size
    id = Order.size();
    fwrite(&id, 1, sizeof(id), f);

    // order array
    Order.WriteAsByte(f, id);

    // Song Patterns

    // number of patterns
    id = MAX_PATTERNS;
    fwrite(&id, 1, sizeof(id), f);

    // number of pattern name strings
    modplug::tracker::patternindex_t numNamedPats = Patterns.GetNumNamedPatterns();
    numNamedPats = bad_min(numNamedPats, MAX_PATTERNS);
    id = numNamedPats;
    fwrite(&id, 1, sizeof(id), f);

    // length of a pattern name string
    id = MAX_PATTERNNAME;
    fwrite(&id, 1, sizeof(id), f);
    // pattern name string
    for(modplug::tracker::patternindex_t nPat = 0; nPat < numNamedPats; nPat++)
    {
        char name[MAX_PATTERNNAME];
        MemsetZero(name);
        Patterns[nPat].GetName(name, MAX_PATTERNNAME);
        fwrite(name, 1, MAX_PATTERNNAME, f);
    }

    // modcommand data length
    id = sizeof(modplug::tracker::modevent_t);
    fwrite(&id, 1, sizeof(id), f);

    // patterns data content
    for(UINT npat=0; npat<MAX_PATTERNS; npat++){
        // pattern size (number of rows)
        id = Patterns[npat] ? Patterns[npat].GetNumRows() : 0;
        fwrite(&id, 1, sizeof(id), f);
        // pattern data
        if(Patterns[npat] && Patterns[npat].GetNumRows()) Patterns[npat].WriteITPdata(f);
        //fwrite(Patterns[npat], 1, m_nChannels * Patterns[npat].GetNumRows() * sizeof(modplug::tracker::modcommand_t), f);
    }

    // Song lonely (instrument-less) samples

    // Write original number of samples
    id = m_nSamples;
    fwrite(&id, 1, sizeof(id), f);

    vector<bool> sampleUsed(m_nSamples, false);

    // Mark samples used in instruments
    for(i=0; i<m_nInstruments; i++)
    {
        if(Instruments[i + 1] != nullptr)
        {
            modinstrument_t *p = Instruments[i + 1];
            for(j = 0; j < 128; j++)
            {
                if(p->Keyboard[j] > 0 && p->Keyboard[j] <= m_nSamples)
                    sampleUsed[p->Keyboard[j] - 1] = true;
            }
        }
    }

    // Count samples not used in any instrument
    i = 0;
    for(j = 1; j <= m_nSamples; j++)
        if(!sampleUsed[j - 1] && Samples[j].sample_data) i++;

    id = i;
    fwrite(&id, 1, sizeof(id), f);

    // Write samples not used in any instrument (help, this looks like duplicate code!)
    ITSAMPLESTRUCT itss;
    for(UINT nsmp=1; nsmp<=m_nSamples; nsmp++)
    {
        if(!sampleUsed[nsmp - 1] && Samples[nsmp].sample_data)
        {

            modsample_t *psmp = &Samples[nsmp];
            memset(&itss, 0, sizeof(itss));
            memcpy(itss.filename, psmp->legacy_filename, 12);
            memcpy(itss.name, m_szNames[nsmp], 26);

            itss.id = LittleEndian(IT_IMPS);
            itss.gvl = (uint8_t)psmp->global_volume;
            itss.flags = 0x00;

            if(psmp->flags & CHN_LOOP) itss.flags |= 0x10;
            if(psmp->flags & CHN_SUSTAINLOOP) itss.flags |= 0x20;
            if(psmp->flags & CHN_PINGPONGLOOP) itss.flags |= 0x40;
            if(psmp->flags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80;
            itss.C5Speed = psmp->c5_samplerate;
            if (!itss.C5Speed) itss.C5Speed = 8363;
            itss.length = psmp->length;
            itss.loopbegin = psmp->loop_start;
            itss.loopend = psmp->loop_end;
            itss.susloopbegin = psmp->sustain_start;
            itss.susloopend = psmp->sustain_end;
            itss.vol = (uint8_t)(psmp->default_volume >> 2);
            itss.dfp = (uint8_t)(psmp->default_pan >> 2);
            itss.vit = autovibxm2it[psmp->vibrato_type & 7];
            itss.vis = bad_min(psmp->vibrato_rate, 64);
            itss.vid = bad_min(psmp->vibrato_depth, 32);
            itss.vir = bad_min(psmp->vibrato_sweep, 255); //(psmp->vibrato_sweep < 64) ? psmp->vibrato_sweep * 4 : 255;
            if (psmp->flags & CHN_PANNING) itss.dfp |= 0x80;
            if ((psmp->sample_data) && (psmp->length)) itss.cvt = 0x01;
            UINT flags = RS_PCM8S;

            if(psmp->flags & CHN_STEREO)
            {
                flags = RS_STPCM8S;
                itss.flags |= 0x04;
            }
            if(psmp->flags & CHN_16BIT)
            {
                itss.flags |= 0x02;
                flags = (psmp->flags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S;
            }

            id = nsmp;
            fwrite(&id, 1, sizeof(id), f);

            itss.samplepointer = NULL;
            fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f);

            id = WriteSample(NULL, psmp, flags);
            fwrite(&id, 1, sizeof(id), f);
            WriteSample(f, psmp, flags);
        }
    }
Exemple #5
0
bool PtexReader::open(const char* path, Ptex::String& error)
{
    if (!LittleEndian()) {
        error = "Ptex library doesn't currently support big-endian cpu's";
        return 0;
    }
    _path = path;
    _fp = _io->open(path);
    if (!_fp) {
        std::string errstr = "Can't open ptex file: ";
        errstr += path;
        errstr += "\n";
        errstr += _io->lastError();
        error = errstr.c_str();
        return 0;
    }
    readBlock(&_header, HeaderSize);
    if (_header.magic != Magic) {
        std::string errstr = "Not a ptex file: ";
        errstr += path;
        error = errstr.c_str();
        return 0;
    }
    if (_header.version != 1) {
        char ver[21];
        snprintf(ver, 20, "%d", _header.version);
        std::string errstr = "Unsupported ptex file version (";
        errstr += ver;
        errstr += "): ";
        errstr += path;
        error = errstr.c_str();
        return 0;
    }
    _pixelsize = _header.pixelSize();

    // read extended header
    memset(&_extheader, 0, sizeof(_extheader));
    readBlock(&_extheader, PtexUtils::min(uint32_t(ExtHeaderSize), _header.extheadersize));

    // compute offsets of various blocks
    FilePos pos = tell();
    _faceinfopos = pos;
    pos += _header.faceinfosize;
    _constdatapos = pos;
    pos += _header.constdatasize;
    _levelinfopos = pos;
    pos += _header.levelinfosize;
    _leveldatapos = pos;
    pos += _header.leveldatasize;
    _metadatapos = pos;
    pos += _header.metadatazipsize;
    pos += sizeof(uint64_t); // compatibility barrier
    _lmdheaderpos = pos;
    pos += _extheader.lmdheaderzipsize;
    _lmddatapos = pos;
    pos += _extheader.lmddatasize;

    // edit data may not start immediately if additional sections have been added
    // use value from extheader if present (and > pos)
    _editdatapos = PtexUtils::max(FilePos(_extheader.editdatapos), pos);

    // read basic file info
    readFaceInfo();
    readConstData();
    readLevelInfo();
    readEditData();

    // an error occurred while reading the file
    if (!_ok) {
        error = _error.c_str();
        return 0;
    }

    return 1;
}
Exemple #6
0
void Check(unsigned Type, void* Float, void* Text)
/* Type: 0 for float, 1 for double */
{
    unsigned i = { 0 };
    unsigned char* b = { 0 };
    unsigned char* c = { 0 };

    /* We don't bother freeing this. */
    const char* String = M3toC__SharedTtoS(Text);

    /* Change the indices to always print the bytes in little endian order, for portable output. */
    unsigned x = (LittleEndian() ? 0 : (Type ? 7 : 3));

    if (sizeof(float) != 4)
    {
        printf("double not 8 bytes\n");
        exit(EXIT_FAILURE);
    }

    if (sizeof(double) != 8)
    {
        printf("double not 8 bytes\n");
        exit(EXIT_FAILURE);
    }

    b = (unsigned char*) Float;
    String += strspn(String, " ");
    for (i = 0 ; Strings[i] ; ++i)
    {
        if (strcmp(String, Strings[i]) == 0)
        {
            c = (unsigned char*) (Type ? &Doubles[i] : (void*) &Floats[i]);
            if (memcmp(b, c, (Type ? sizeof(double) : sizeof(float))) != 0)
            {
                if (Type)
                {
                    printf("double mismatch string %s test %x Modula-3 value %f C value %f Modula-3 bytes 0x%02x%02x%02x%02x%02x%02x%02x%02x C bytes 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
                        String, i, (*(double*) Float), Doubles[i],
                        b[0 ^ x], b[1 ^ x], b[2 ^ x], b[3 ^ x], b[4 ^ x], b[5 ^ x], b[6 ^ x], b[7 ^ x],
                        c[0 ^ x], c[1 ^ x], c[2 ^ x], c[3 ^ x], c[4 ^ x], c[5 ^ x], c[6 ^ x], c[7 ^ x]);
                }
                else
                {
                    printf("float mismatch string %s test %x Modula-3 value %f C value %f Modula-3 bytes  0x%02x%02x%02x%02x C bytes 0x%02x%02x%02x%02x\n",
                        String, i, (*(float*) Float), Floats[i],
                        b[0 ^ x], b[1 ^ x], b[2 ^ x], b[3 ^ x],
                        c[0 ^ x], c[1 ^ x], c[2 ^ x], c[3 ^ x]);
                    exit(EXIT_FAILURE);
                }
            }
            else
            {
                if (Type)
                {
                    printf("double match string %s test %x Modula-3 value %f C value %f bytes Modula-3 bytes 0x%02x%02x%02x%02x%02x%02x%02x%02x C bytes 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
                        String, i, (*(double*) Float), Doubles[i],
                        b[0 ^ x], b[1 ^ x], b[2 ^ x], b[3 ^ x], b[4 ^ x], b[5 ^ x], b[6 ^ x], b[7 ^ x],
                        c[0 ^ x], c[1 ^ x], c[2 ^ x], c[3 ^ x], c[4 ^ x], c[5 ^ x], c[6 ^ x], c[7 ^ x]);
                }
                else
                {
                    printf("float match string %s test %x Modula-3 value %f C value %f Modula-3 bytes 0x%02x%02x%02x%02x C bytes 0x%02x%02x%02x%02x\n",
                        String, i, (*(float*) Float), Floats[i],
                        b[0 ^ x], b[1 ^ x], b[2 ^ x], b[3 ^ x],
                        c[0 ^ x], c[1 ^ x], c[2 ^ x], c[3 ^ x]);
                }
            }
            fflush(stdout);
            return;
        }
    }
    printf("string not found %s\n", (Type ? "double" : "float", String));
    exit(EXIT_FAILURE);
}
/* Load BMF file format, function return bitmap font descriptor */
int glfLoadBMFFont(char *FName)
{
	FILE *f;
	char Header[4];
	char FontName[97];
	int i, flag;
	int LEndian;
	float tx, ty, tw, th;
	unsigned char temp, *tp;
	unsigned *texture;	/* Texture image */
	unsigned *mask;	/* Mask texture */
	int twidth, theight, tcomp;	/* Image parameters */
	float *temp_width;

	LEndian = LittleEndian();

	fopen_s(&f, FName, "rb");
	if (f == NULL) return GLF_ERROR; /* Error opening file */

	/* Get header */
	fread(Header, 1, 3, f);
	Header[3] = 0;
	if (strcmp(Header, "BMF")) return GLF_ERROR; /* Not BMF format */

	/* Get font name */
	fread(FontName, 1, 96, f);
	FontName[96] = 0;

	/* Allocate space for temp widths */
	
	temp_width = (float *)malloc(sizeof(float)*256);

	/* Read all 256 symbols information */
	for (i=0; i<256; i++)
	{
		fread(&tx, 4, 1, f);
		fread(&ty, 4, 1, f);
		fread(&tw, 4, 1, f);
		fread(&th, 4, 1, f);

		if (!LEndian)
		{
			tp = (unsigned char *)&tx;
			temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
			temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
			tp = (unsigned char *)&ty;
			temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
			temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
			tp = (unsigned char *)&tw;
			temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
			temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
			tp = (unsigned char *)&th;
			temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
			temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
		}
		
		Symbols[i].x = tx;
		Symbols[i].y = ty;
		Symbols[i].width  = tw;
		Symbols[i].height = th;
		temp_width[i] = tw;
	}

	/* Read texture image from file and build texture */
	texture = read_texture(f, &twidth, &theight, &tcomp);
	/* Generate mask texture */
	mask = texture_to_mask(texture, twidth, theight);

	/* Find unused font descriptor */
	flag = 0;
	for (i=0; i<MAX_FONTS; i++)
		if (bmf_in_use[i] == 0)
		{
			/* Initialize this font */
			bmf_in_use[i] = 1;
			bmf_curfont = i;
			flag = 1;
			break;
		}
	if (!flag) /* Not enought space for new texture */
	{
		fclose(f);
		free(texture);
		free(mask);
		free(temp_width);
		return -1;
	}

	m_widths[bmf_curfont].width = temp_width;

	/* Generating textures for font and mask */
	glGenTextures(1, &bmf_texture[bmf_curfont]);
	glGenTextures(1, &bmf_mask[bmf_curfont]);


	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	/* Build font texture */
	glBindTexture(GL_TEXTURE_2D, bmf_texture[bmf_curfont]);
	glTexImage2D(GL_TEXTURE_2D, 0, 3, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
	
	/* Linear filtering for better quality */
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	
	/* Build mask texture */
	glBindTexture(GL_TEXTURE_2D, bmf_mask[bmf_curfont]);
	glTexImage2D(GL_TEXTURE_2D, 0, 3, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mask);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	free(texture);
	free(mask);
	fclose(f);

	/* Now build list for each symbol */
	list_base[bmf_curfont] = glGenLists(256);
	for (i=0; i<256; i++)
	{
		glNewList(list_base[bmf_curfont]+i, GL_COMPILE);
		
		glBegin(GL_QUADS);
			glTexCoord2f(Symbols[i].x, Symbols[i].y); glVertex2f(0, 0);
			glTexCoord2f(Symbols[i].x+Symbols[i].width, Symbols[i].y); glVertex2f(Symbols[i].width, 0);
			glTexCoord2f(Symbols[i].x+Symbols[i].width, Symbols[i].y+Symbols[i].height); glVertex2f(Symbols[i].width, Symbols[i].height);
			glTexCoord2f(Symbols[i].x, Symbols[i].y+Symbols[i].height); glVertex2f(0, Symbols[i].height);
		glEnd();
		glTranslatef(Symbols[i].width+sym_space, 0, 0);

		glEndList();
		if (Symbols[i].height > m_max_height[bmf_curfont]) m_max_height[bmf_curfont] = Symbols[i].height;
	}
	return bmf_curfont;
}
Exemple #8
0
bool Chunk::loadFromFile()
{
    m_Volume->incStatistic(STATISTIC_CHUNK_LOAD_OPS);

    m_Volume->log(VMAN_LOG_DEBUG, "Loading chunk %s from file ..\n", toString().c_str());

    if(m_Volume->getBaseDir() == NULL)
    {
        assert(!"Probably redundant.");
        return false;
    }

    const int voxelsPerChunk = m_Volume->getVoxelsPerChunk();

    std::string fileName = m_Volume->getChunkFileName(m_ChunkX, m_ChunkY, m_ChunkZ);

    FILE* f = fopen(fileName.c_str(), "rb");
    if(f == NULL)
    {
        m_Volume->log(VMAN_LOG_DEBUG, "%s: File does not exist.\n", fileName.c_str());
        return false;
    }

    try
    {
        // -- Read header --
        ChunkFileHeader header;
        if(fread(&header, sizeof(header), 1, f) != 1)
            throw "Read error in file header.";
        header.version = LittleEndian(header.version);
        header.edgeLength = LittleEndian(header.edgeLength);
        header.layerCount = LittleEndian(header.layerCount);

        m_Volume->log(VMAN_LOG_DEBUG, "version: %d\n", header.version);
        m_Volume->log(VMAN_LOG_DEBUG, "edgeLength: %d\n", header.edgeLength);
        m_Volume->log(VMAN_LOG_DEBUG, "layerCount: %d\n", header.layerCount);

        if(header.version != ChunkFileVersion)
            throw "Incorrect file version.";

        std::vector<ChunkFileLayerInfo> layerInfos(header.layerCount);

        // -- Read layer list --
        for(int i = 0; i < layerInfos.size(); ++i)
        {
            ChunkFileLayerInfo* layerInfo = &layerInfos[i];
            if(fread(layerInfo, sizeof(ChunkFileLayerInfo), 1, f) != 1)
                throw Format("Read error in layer info %d", i);
            layerInfo->voxelSize = LittleEndian(layerInfo->voxelSize);
            layerInfo->revision = LittleEndian(layerInfo->revision);
            layerInfo->fileOffset = LittleEndian(layerInfo->fileOffset);

            m_Volume->log(VMAN_LOG_DEBUG, "[layer %d] name: '%s'\n", i, layerInfo->name);
            m_Volume->log(VMAN_LOG_DEBUG, "[layer %d] voxelSize: %d\n", i, layerInfo->voxelSize);
            m_Volume->log(VMAN_LOG_DEBUG, "[layer %d] revision: %d\n", i, layerInfo->revision);
            m_Volume->log(VMAN_LOG_DEBUG, "[layer %d] fileOffset: %d\n", i, layerInfo->fileOffset);

            if(m_Volume->getLayerIndexByName(layerInfo->name) == -1)
            {
                m_Volume->log(VMAN_LOG_INFO, "%s: Ignoring chunk layer '%s'.\n", fileName.c_str(), layerInfo->name);
            }
        }

        // -- Copy used layers --
        std::vector<char> buffer(voxelsPerChunk * m_Volume->getMaxLayerVoxelSize());
        for(int i = 0; i < m_Layers.size(); ++i)
        {
            const vmanLayer* layer = m_Volume->getLayer(i);
            const ChunkFileLayerInfo* layerInfo = FindChunkLayerByName(layerInfos, layer->name);
            if(layerInfo)
            {
                if(
                    (layer->voxelSize != layerInfo->voxelSize) ||
                    (layer->revision != layerInfo->revision)
                )
                {
                    m_Volume->log(VMAN_LOG_ERROR,"%s: Chunk layer '%s' differs, ignoring it.\n", fileName.c_str(), layer->name);
                    // TODO: Maybe let the application try to import/convert the layer.
                    continue;
                }

                fseek(f, layerInfo->fileOffset, SEEK_SET);
                if(fread(&buffer[0], voxelsPerChunk*layer->voxelSize, 1, f) != 1)
                    throw Format("Read error in layer %d.", i);

                m_Layers[i] = new char[voxelsPerChunk*layer->voxelSize];
                layer->deserializeFn(&buffer[0], m_Layers[i], voxelsPerChunk*layer->voxelSize);
            }
        }
    }
    catch(const std::string e)
    {
        m_Volume->log(VMAN_LOG_ERROR, "%s: %s\n", fileName.c_str(), e.c_str());
        fclose(f);
        clearLayers();
        assert(false);
        return false;
    }

    fclose(f);
    return true;
}
Exemple #9
0
//
//  Read double float from (little-endian) database binary file
//  Automatically adjusts for big-endian processors
//
void ReadDouble (PODFILE *f, double *pData)
{
  pread (pData, sizeof(double), 1, f);
  *pData = LittleEndian(*pData);
}
Exemple #10
0
//
//  Read float from (little-endian) database binary file
//  Automatically adjusts for big-endian processors
//
void ReadFloat (PODFILE *f, float *pData)
{
  pread (pData, sizeof(float), 1, f);
  *pData = LittleEndian(*pData);
}
Exemple #11
0
//
//  Read unsigned short from (little-endian) database binary file
//  Automatically adjusts for big-endian processors
//
void ReadUShort (PODFILE *f, unsigned short *pData)
{
  pread (pData, sizeof(unsigned short), 1, f);
  *pData = LittleEndian(*pData);
}
Exemple #12
0
//
//  Read signed long from binary file
//
void ReadLong (PODFILE *f, long *pData)
{
  pread (pData, sizeof(long), 1, f);
  *pData = LittleEndian(*pData);
}
Exemple #13
0
//
//  Read unsigned long from binary file
//
void ReadULong (PODFILE *f, unsigned long *pData)
{
  pread (pData, sizeof(unsigned long), 1, f);
  *pData = LittleEndian(*pData);
}
Exemple #14
0
// public BinaryWriter(Uno.IO.Stream stream) [instance] :371
void BinaryWriter::ctor_(::g::Uno::IO::Stream* stream)
{
    _stream = stream;
    _buffer = uArray::New(::TYPES[0/*byte[]*/], 64);
    LittleEndian(true);
}
/* 
|	This function read font file and store information in memory
|	Return: GLF_OK - if all OK
|	Return: GLF_ERROR - if any error 
*/
static int ReadFont(char *font_name, struct glf_font *glff)
{

	FILE *fontf;
	char buffer[64];
	int i, j;
	unsigned char temp, code, verts, fcets, lns;
	float tempfx, tempfy;
	unsigned char *tp;
	int LEndian; /* True if little endian machine */

	fopen_s(&fontf, font_name, "rb");
	if (fontf == NULL) return GLF_ERROR;

	fread(buffer, 3, 1, fontf);
	buffer[3] = 0;
	if (strcmp(buffer, "GLF"))
	{
		/* If header is not "GLF" */
		if (console_msg) printf("Error reading font file: incorrect file format\n");
		return GLF_ERROR;
	}

	/* Check for machine type */
	LEndian = LittleEndian();

	fread(glff->font_name, 96, 1, fontf);
	glff->font_name[96] = 0;

	fread(&glff->sym_total, 1, 1, fontf); /* Read total symbols in font */

	for (i=0; i<MAX_FONTS; i++) glff->symbols[i] = NULL;

	for (i=0; i<28; i++) fread(&temp, 1, 1, fontf);  /* Read unused data */

	/* Now start to read font data */
  
	for (i=0; i<glff->sym_total; i++)
	{
		fread(&code, 1, 1, fontf);  /* Read symbol code   */
		fread(&verts, 1, 1, fontf); /* Read vertexs count */
		fread(&fcets, 1, 1, fontf); /* Read facets count  */
		fread(&lns, 1, 1, fontf);   /* Read lines count   */

		if (glff->symbols[code] != NULL) 
		{
			if (console_msg) printf("Error reading font file: encountered symbols in font\n");
			return GLF_ERROR;
		}

		glff->symbols[code] = (struct one_symbol *)malloc(sizeof(struct one_symbol));
		glff->symbols[code]->vdata = (float *)malloc(8*verts);
		glff->symbols[code]->fdata = (unsigned char *)malloc(3*fcets);
		glff->symbols[code]->ldata = (unsigned char *)malloc(lns);

		glff->symbols[code]->vertexs = verts;
		glff->symbols[code]->facets = fcets;
		glff->symbols[code]->lines = lns;

		/* Read vertexs data */
		glff->symbols[code]->leftx = 10;
		glff->symbols[code]->rightx = -10;
		glff->symbols[code]->topy = 10;
		glff->symbols[code]->bottomy = -10;

		for (j=0; j<verts; j++)
		{
			fread(&tempfx, 4, 1, fontf);
			fread(&tempfy, 4, 1, fontf);
          
			/* If machine is bigendian -> swap low and high words in
			tempfx and tempfy */
			if (!LEndian) 
			{
				tp = (unsigned char *)&tempfx;
				temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
				temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
				tp = (unsigned char *)&tempfy;
				temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
				temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
			}
			glff->symbols[code]->vdata[j*2] = tempfx;
			glff->symbols[code]->vdata[j*2+1] = tempfy;

			if (tempfx < glff->symbols[code]->leftx) glff->symbols[code]->leftx = tempfx;
			if (tempfx > glff->symbols[code]->rightx) glff->symbols[code]->rightx = tempfx;
			if (tempfy < glff->symbols[code]->topy) glff->symbols[code]->topy = tempfy;
			if (tempfy > glff->symbols[code]->bottomy) glff->symbols[code]->bottomy = tempfy;
		}
		for (j=0; j<fcets; j++)
			fread(&glff->symbols[code]->fdata[j*3], 3, 1, fontf);
		for (j=0; j<lns; j++)
			fread(&glff->symbols[code]->ldata[j], 1, 1, fontf);
	}
	fclose(fontf);
	return GLF_OK;
}
Exemple #16
0
// public void Write(int value) [instance] :434
void BinaryWriter::Write13(int value)
{
    ::g::Uno::Runtime::Implementation::BufferImpl::SetInt(_buffer, 0, value, LittleEndian());
    uPtr(_stream)->Write(_buffer, 0, 4);
}
Exemple #17
0
bool module_renderer::ReadXM(const uint8_t *lpStream, const uint32_t dwMemLength)
//--------------------------------------------------------------------
{
    XMFILEHEADER xmheader;
    XMSAMPLEHEADER xmsh;
    XMSAMPLESTRUCT xmss;
    uint32_t dwMemPos;

    bool bMadeWithModPlug = false, bProbablyMadeWithModPlug = false, bProbablyMPT109 = false, bIsFT2 = false;

    m_nChannels = 0;
    if ((!lpStream) || (dwMemLength < 0xAA)) return false; // the smallest XM I know is 174 Bytes
    if (_strnicmp((LPCSTR)lpStream, "Extended Module", 15)) return false;

    // look for null-terminated song name - that's most likely a tune made with modplug
    for(int i = 0; i < 20; i++)
        if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true;
    assign_without_padding(this->song_name, reinterpret_cast<const char *>(lpStream + 17), 20);

    // load and convert header
    memcpy(&xmheader, lpStream + 58, sizeof(XMFILEHEADER));
    xmheader.size = LittleEndian(xmheader.size);
    xmheader.xmversion = LittleEndianW(xmheader.xmversion);
    xmheader.orders = LittleEndianW(xmheader.orders);
    xmheader.restartpos = LittleEndianW(xmheader.restartpos);
    xmheader.channels = LittleEndianW(xmheader.channels);
    xmheader.patterns = LittleEndianW(xmheader.patterns);
    xmheader.instruments = LittleEndianW(xmheader.instruments);
    xmheader.flags = LittleEndianW(xmheader.flags);
    xmheader.speed = LittleEndianW(xmheader.speed);
    xmheader.tempo = LittleEndianW(xmheader.tempo);

    m_nType = MOD_TYPE_XM;
    m_nMinPeriod = 27;
    m_nMaxPeriod = 54784;

    if (xmheader.orders > MAX_ORDERS) return false;
    if ((!xmheader.channels) || (xmheader.channels > MAX_BASECHANNELS)) return false;
    if (xmheader.channels > 32) bMadeWithModPlug = true;
    m_nRestartPos = xmheader.restartpos;
    m_nChannels = xmheader.channels;
    m_nInstruments = bad_min(xmheader.instruments, MAX_INSTRUMENTS - 1);
    m_nSamples = 0;
    m_nDefaultSpeed = CLAMP(xmheader.speed, 1, 31);
    m_nDefaultTempo = CLAMP(xmheader.tempo, 32, 512);

    if(xmheader.flags & 1) m_dwSongFlags |= SONG_LINEARSLIDES;
    if(xmheader.flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE;

    Order.ReadAsByte(lpStream + 80, xmheader.orders, dwMemLength - 80);

    dwMemPos = xmheader.size + 60;

    // set this here already because XMs compressed with BoobieSqueezer will exit the function early
    SetModFlag(MSF_COMPATIBLE_PLAY, true);

    if(xmheader.xmversion >= 0x0104)
    {
        if (dwMemPos + 8 >= dwMemLength) return true;
        dwMemPos = ReadXMPatterns(lpStream, dwMemLength, dwMemPos, &xmheader, this);
        if(dwMemPos == 0) return true;
    }

    vector<bool> samples_used; // for removing unused samples
    modplug::tracker::sampleindex_t unused_samples = 0; // dito

    // Reading instruments
    for (modplug::tracker::instrumentindex_t iIns = 1; iIns <= m_nInstruments; iIns++)
    {
        XMINSTRUMENTHEADER pih;
        uint8_t flags[32];
        uint32_t samplesize[32];
        UINT samplemap[32];
        uint16_t nsamples;

        if (dwMemPos + sizeof(uint32_t) >= dwMemLength) return true;
        uint32_t ihsize = LittleEndian(*((uint32_t *)(lpStream + dwMemPos)));
        if (dwMemPos + ihsize > dwMemLength) return true;

        MemsetZero(pih);
        memcpy(&pih, lpStream + dwMemPos, bad_min(sizeof(pih), ihsize));

        if ((Instruments[iIns] = new modinstrument_t) == nullptr) continue;
        memcpy(Instruments[iIns], &m_defaultInstrument, sizeof(modinstrument_t));
        Instruments[iIns]->nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL;
        Instruments[iIns]->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE;

        memcpy(Instruments[iIns]->name, pih.name, 22);
        SpaceToNullStringFixed<22>(Instruments[iIns]->name);

        memset(&xmsh, 0, sizeof(XMSAMPLEHEADER));

        if ((nsamples = pih.samples) > 0)
        {
            /* we have samples, so let's read the rest of this instrument
               the header that is being read here is not the sample header, though,
               it's rather the instrument settings. */

            if (dwMemPos + ihsize >= dwMemLength)
                return true;

            memcpy(&xmsh,
                lpStream + dwMemPos + sizeof(XMINSTRUMENTHEADER),
                bad_min(ihsize - sizeof(XMINSTRUMENTHEADER), sizeof(XMSAMPLEHEADER)));

            xmsh.shsize = LittleEndian(xmsh.shsize);
            if(xmsh.shsize == 0 && bProbablyMadeWithModPlug) bMadeWithModPlug = true;

            for (int i = 0; i < 24; ++i) {
                xmsh.venv[i] = LittleEndianW(xmsh.venv[i]);
                xmsh.penv[i] = LittleEndianW(xmsh.penv[i]);
            }
            xmsh.volfade = LittleEndianW(xmsh.volfade);
            xmsh.midiprogram = LittleEndianW(xmsh.midiprogram);
            xmsh.pitchwheelrange = LittleEndianW(xmsh.pitchwheelrange);

            if(xmsh.midichannel != 0 || xmsh.midienabled != 0 || xmsh.midiprogram != 0 || xmsh.mutecomputer != 0 || xmsh.pitchwheelrange != 0)
                bIsFT2 = true; // definitely not MPT. (or any other tracker)

        }

        if (LittleEndian(pih.size))
            dwMemPos += LittleEndian(pih.size);
        else
            dwMemPos += sizeof(XMINSTRUMENTHEADER);

        memset(samplemap, 0, sizeof(samplemap));
        if (nsamples > 32) return true;
        UINT newsamples = m_nSamples;

        for (UINT nmap = 0; nmap < nsamples; nmap++)
        {
            UINT n = m_nSamples + nmap + 1;
            if (n >= MAX_SAMPLES)
            {
                n = m_nSamples;
                while (n > 0)
                {
                    if (!Samples[n].sample_data)
                    {
                        for (UINT xmapchk=0; xmapchk < nmap; xmapchk++)
                        {
                            if (samplemap[xmapchk] == n) goto alreadymapped;
                        }
                        for (UINT clrs=1; clrs<iIns; clrs++) if (Instruments[clrs])
                        {
                            modinstrument_t *pks = Instruments[clrs];
                            for (UINT ks=0; ks<128; ks++)
                            {
                                if (pks->Keyboard[ks] == n) pks->Keyboard[ks] = 0;
                            }
                        }
                        break;
                    }
                alreadymapped:
                    n--;
                }
#ifndef FASTSOUNDLIB
                // Damn! Too many samples: look for duplicates
                if (!n)
                {
                    if (!unused_samples)
                    {
                        unused_samples = DetectUnusedSamples(samples_used);
                        if (!unused_samples) unused_samples = modplug::tracker::SampleIndexInvalid;
                    }
                    if ((unused_samples) && (unused_samples != modplug::tracker::SampleIndexInvalid))
                    {
                        for (UINT iext=m_nSamples; iext>=1; iext--) if (!samples_used[iext])
                        {
                            unused_samples--;
                            samples_used[iext] = true;
                            DestroySample(iext);
                            n = iext;
                            for (UINT mapchk=0; mapchk<nmap; mapchk++)
                            {
                                if (samplemap[mapchk] == n) samplemap[mapchk] = 0;
                            }
                            for (UINT clrs=1; clrs<iIns; clrs++) if (Instruments[clrs])
                            {
                                modinstrument_t *pks = Instruments[clrs];
                                for (UINT ks=0; ks<128; ks++)
                                {
                                    if (pks->Keyboard[ks] == n) pks->Keyboard[ks] = 0;
                                }
                            }
                            MemsetZero(Samples[n]);
                            break;
                        }
                    }
                }
#endif // FASTSOUNDLIB
            }
            if (newsamples < n) newsamples = n;
            samplemap[nmap] = n;
        }
        m_nSamples = newsamples;
        // Reading Volume Envelope
        modinstrument_t *pIns = Instruments[iIns];
        pIns->midi_program = pih.type;
        pIns->fadeout = xmsh.volfade;
        pIns->default_pan = 128;
        pIns->pitch_pan_center = 5*12;
        SetDefaultInstrumentValues(pIns);
        pIns->nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL;
        pIns->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE;
        if (xmsh.vtype & 1) pIns->volume_envelope.flags |= ENV_ENABLED;
        if (xmsh.vtype & 2) pIns->volume_envelope.flags |= ENV_SUSTAIN;
        if (xmsh.vtype & 4) pIns->volume_envelope.flags |= ENV_LOOP;
        if (xmsh.ptype & 1) pIns->panning_envelope.flags |= ENV_ENABLED;
        if (xmsh.ptype & 2) pIns->panning_envelope.flags |= ENV_SUSTAIN;
        if (xmsh.ptype & 4) pIns->panning_envelope.flags |= ENV_LOOP;
        if (xmsh.vnum > 12) xmsh.vnum = 12;
        if (xmsh.pnum > 12) xmsh.pnum = 12;
        pIns->volume_envelope.num_nodes = xmsh.vnum;
        if (!xmsh.vnum) pIns->volume_envelope.flags &= ~ENV_ENABLED;
        if (!xmsh.pnum) pIns->panning_envelope.flags &= ~ENV_ENABLED;
        pIns->panning_envelope.num_nodes = xmsh.pnum;
        pIns->volume_envelope.sustain_start = pIns->volume_envelope.sustain_end = xmsh.vsustain;
        if (xmsh.vsustain >= 12) pIns->volume_envelope.flags &= ~ENV_SUSTAIN;
        pIns->volume_envelope.loop_start = xmsh.vloops;
        pIns->volume_envelope.loop_end = xmsh.vloope;
        if (pIns->volume_envelope.loop_end >= 12) pIns->volume_envelope.loop_end = 0;
        if (pIns->volume_envelope.loop_start >= pIns->volume_envelope.loop_end) pIns->volume_envelope.flags &= ~ENV_LOOP;
        pIns->panning_envelope.sustain_start = pIns->panning_envelope.sustain_end = xmsh.psustain;
        if (xmsh.psustain >= 12) pIns->panning_envelope.flags &= ~ENV_SUSTAIN;
        pIns->panning_envelope.loop_start = xmsh.ploops;
        pIns->panning_envelope.loop_end = xmsh.ploope;
        if (pIns->panning_envelope.loop_end >= 12) pIns->panning_envelope.loop_end = 0;
        if (pIns->panning_envelope.loop_start >= pIns->panning_envelope.loop_end) pIns->panning_envelope.flags &= ~ENV_LOOP;
        pIns->global_volume = 64;
        for (UINT ienv=0; ienv<12; ienv++)
        {
            pIns->volume_envelope.Ticks[ienv] = (uint16_t)xmsh.venv[ienv*2];
            pIns->volume_envelope.Values[ienv] = (uint8_t)xmsh.venv[ienv*2+1];
            pIns->panning_envelope.Ticks[ienv] = (uint16_t)xmsh.penv[ienv*2];
            pIns->panning_envelope.Values[ienv] = (uint8_t)xmsh.penv[ienv*2+1];
            if (ienv)
            {
                if (pIns->volume_envelope.Ticks[ienv] < pIns->volume_envelope.Ticks[ienv-1])
                {
                    pIns->volume_envelope.Ticks[ienv] &= 0xFF;
                    pIns->volume_envelope.Ticks[ienv] += pIns->volume_envelope.Ticks[ienv-1] & 0xFF00;
                    if (pIns->volume_envelope.Ticks[ienv] < pIns->volume_envelope.Ticks[ienv-1]) pIns->volume_envelope.Ticks[ienv] += 0x100;
                }
                if (pIns->panning_envelope.Ticks[ienv] < pIns->panning_envelope.Ticks[ienv-1])
                {
                    pIns->panning_envelope.Ticks[ienv] &= 0xFF;
                    pIns->panning_envelope.Ticks[ienv] += pIns->panning_envelope.Ticks[ienv-1] & 0xFF00;
                    if (pIns->panning_envelope.Ticks[ienv] < pIns->panning_envelope.Ticks[ienv-1]) pIns->panning_envelope.Ticks[ienv] += 0x100;
                }
            }
        }
        for (UINT j=0; j<96; j++)
        {
            pIns->NoteMap[j+12] = j+1+12;
            if (xmsh.snum[j] < nsamples)
                pIns->Keyboard[j+12] = samplemap[xmsh.snum[j]];
        }
        // Reading samples
        for (UINT ins=0; ins<nsamples; ins++)
        {
            if ((dwMemPos + sizeof(xmss) > dwMemLength)
             || (dwMemPos + xmsh.shsize > dwMemLength)) return true;
            memcpy(&xmss, lpStream + dwMemPos, sizeof(xmss));
            xmss.samplen = LittleEndian(xmss.samplen);
            xmss.loopstart = LittleEndian(xmss.loopstart);
            xmss.looplen = LittleEndian(xmss.looplen);
            dwMemPos += sizeof(XMSAMPLESTRUCT);    // was: dwMemPos += xmsh.shsize; (this fixes IFULOVE.XM)
            flags[ins] = (xmss.type & 0x10) ? RS_PCM16D : RS_PCM8D;
            if (xmss.type & 0x20) flags[ins] = (xmss.type & 0x10) ? RS_STPCM16D : RS_STPCM8D;
            samplesize[ins] = xmss.samplen;
            if (!samplemap[ins]) continue;
            if (xmss.type & 0x10)
            {
                xmss.looplen >>= 1;
                xmss.loopstart >>= 1;
                xmss.samplen >>= 1;
            }
            if (xmss.type & 0x20)
            {
                xmss.looplen >>= 1;
                xmss.loopstart >>= 1;
                xmss.samplen >>= 1;
            }
            if (xmss.samplen > MAX_SAMPLE_LENGTH) xmss.samplen = MAX_SAMPLE_LENGTH;
            if (xmss.loopstart >= xmss.samplen) xmss.type &= ~3;
            xmss.looplen += xmss.loopstart;
            if (xmss.looplen > xmss.samplen) xmss.looplen = xmss.samplen;
            if (!xmss.looplen) xmss.type &= ~3;
            UINT imapsmp = samplemap[ins];
            memcpy(m_szNames[imapsmp], xmss.name, 22);
            SpaceToNullStringFixed<22>(m_szNames[imapsmp]);
            modsample_t *pSmp = &Samples[imapsmp];
            pSmp->length = (xmss.samplen > MAX_SAMPLE_LENGTH) ? MAX_SAMPLE_LENGTH : xmss.samplen;
            pSmp->loop_start = xmss.loopstart;
            pSmp->loop_end = xmss.looplen;
            if (pSmp->loop_end > pSmp->length) pSmp->loop_end = pSmp->length;
            if (pSmp->loop_start >= pSmp->loop_end)
            {
                pSmp->loop_start = pSmp->loop_end = 0;
            }
            if (xmss.type & 3) pSmp->flags |= CHN_LOOP;
            if (xmss.type & 2) pSmp->flags |= CHN_PINGPONGLOOP;
            pSmp->default_volume = xmss.vol << 2;
            if (pSmp->default_volume > 256) pSmp->default_volume = 256;
            pSmp->global_volume = 64;
            if ((xmss.res == 0xAD) && (!(xmss.type & 0x30)))
            {
                flags[ins] = RS_ADPCM4;
                samplesize[ins] = (samplesize[ins]+1)/2 + 16;
            }
            pSmp->nFineTune = xmss.finetune;
            pSmp->RelativeTone = (int)xmss.relnote;
            pSmp->default_pan = xmss.pan;
            pSmp->flags |= CHN_PANNING;
            pSmp->vibrato_type = xmsh.vibtype;
            pSmp->vibrato_sweep = xmsh.vibsweep;
            pSmp->vibrato_depth = xmsh.vibdepth;
            pSmp->vibrato_rate = xmsh.vibrate;
            memcpy(pSmp->legacy_filename, xmss.name, 22);
            SpaceToNullStringFixed<21>(pSmp->legacy_filename);

            if ((xmss.type & 3) == 3)    // MPT 1.09 and maybe newer / older versions set both flags for bidi loops
                bProbablyMPT109 = true;
        }
Exemple #18
0
bool Chunk::saveToFile()
{
    m_Volume->incStatistic(STATISTIC_CHUNK_SAVE_OPS);

    m_Volume->log(VMAN_LOG_DEBUG, "Saving chunk %s to file ..\n", toString().c_str());

    if(m_Volume->getBaseDir() == NULL)
    {
        assert(!"Probably redundant.");
        return false;
    }

    assert(m_Layers.size() > 0);

    const int voxelsPerChunk = m_Volume->getVoxelsPerChunk();

    std::string fileName = m_Volume->getChunkFileName(m_ChunkX, m_ChunkY, m_ChunkZ);

    MakePath(fileName.c_str());

    FILE* f = fopen(fileName.c_str(), "wb"); // TODO: Check
    if(f == NULL)
    {
        m_Volume->log(VMAN_LOG_ERROR, "%s: Can't open file for writing.\n", fileName.c_str());
        return false;
    }

    // -- Write header ---
    ChunkFileHeader header;
    header.version = LittleEndian( ChunkFileVersion );
    header.edgeLength = LittleEndian( m_Volume->getChunkEdgeLength() );
    int usedLayers = 0;
    for(int i = 0; i < m_Layers.size(); ++i)
        if(m_Layers[i] != NULL)
            ++usedLayers;
    header.layerCount = LittleEndian( usedLayers );
    fwrite(&header, sizeof(header), 1, f);

    const uint32_t headerSize = sizeof(ChunkFileHeader) + sizeof(ChunkFileLayerInfo)*usedLayers;

    // -- Write layer list --
    uint32_t fileOffset = headerSize;
    for(int i = 0; i < m_Layers.size(); ++i)
    {
        if(m_Layers[i] != NULL)
        {
            ChunkFileLayerInfo layerInfo;
            const vmanLayer* layer = m_Volume->getLayer(i);

            memset(layerInfo.name, 0, sizeof(layerInfo.name));
            strncpy(layerInfo.name, layer->name, sizeof(layerInfo.name)-1);

            layerInfo.voxelSize = LittleEndian(layer->voxelSize);
            layerInfo.revision = LittleEndian(layer->revision);
            layerInfo.fileOffset = LittleEndian(fileOffset);

            fwrite(&layerInfo, sizeof(layerInfo), 1, f);

            // Calculate layer size
            fileOffset += voxelsPerChunk * layerInfo.voxelSize;
        }
    }

    // -- Write actual layers --
    std::vector<char> buffer(voxelsPerChunk * m_Volume->getMaxLayerVoxelSize()); // TODO: This buffer could be thread local ...
    for(int i = 0; i < m_Layers.size(); ++i)
    {
        if(m_Layers[i] != NULL)
        {
            const vmanLayer* layer = m_Volume->getLayer(i);
            layer->serializeFn(m_Layers[i], &buffer[0], voxelsPerChunk);
            fwrite(&buffer[0], voxelsPerChunk*layer->voxelSize, 1, f); // TODO: Check
        }
    }

    fclose(f);
    unsetModified();
    return true;
}
Exemple #19
0
// Read .XM patterns
uint32_t ReadXMPatterns(const uint8_t *lpStream, uint32_t dwMemLength, uint32_t dwMemPos, XMFILEHEADER *xmheader, module_renderer *pSndFile)
//-------------------------------------------------------------------------------------------------------------------------
{
    uint8_t patterns_used[256];
    uint8_t pattern_map[256];

    memset(patterns_used, 0, sizeof(patterns_used));
    if (xmheader->patterns > MAX_PATTERNS)
    {
        UINT i, j;
        for (i = 0; i < xmheader->orders; i++)
        {
            if (pSndFile->Order[i] < xmheader->patterns) patterns_used[pSndFile->Order[i]] = true;
        }
        j = 0;
        for (i = 0; i < 256; i++)
        {
            if (patterns_used[i]) pattern_map[i] = j++;
        }
        for (i = 0; i < 256; i++)
        {
            if (!patterns_used[i])
            {
                pattern_map[i] = (j < MAX_PATTERNS) ? j : 0xFE;
                j++;
            }
        }
        for (i = 0; i < xmheader->orders; i++)
        {
            pSndFile->Order[i] = pattern_map[pSndFile->Order[i]];
        }
    } else
    {
        for (UINT i = 0; i < 256; i++) pattern_map[i] = i;
    }
    if (dwMemPos + 8 >= dwMemLength) return dwMemPos;
    // Reading patterns
    for (UINT ipat = 0; ipat < xmheader->patterns; ipat++)
    {
        UINT ipatmap = pattern_map[ipat];
        uint32_t dwSize = 0;
        uint16_t rows = 64, packsize = 0;
        dwSize = LittleEndian(*((uint32_t *)(lpStream + dwMemPos)));

        if(xmheader->xmversion == 0x0102)
        {
            rows = *((uint8_t *)(lpStream + dwMemPos + 5)) + 1;
            packsize = LittleEndianW(*((uint16_t *)(lpStream + dwMemPos + 6)));
        }
        else
        {
            rows = LittleEndianW(*((uint16_t *)(lpStream + dwMemPos + 5)));
            packsize = LittleEndianW(*((uint16_t *)(lpStream + dwMemPos + 7)));
        }

        if ((!rows) || (rows > MAX_PATTERN_ROWS)) rows = 64;
        if (dwMemPos + dwSize + 4 > dwMemLength) return 0;
        dwMemPos += dwSize;
        if (dwMemPos + packsize > dwMemLength) return 0;
        modplug::tracker::modevent_t *p;
        if (ipatmap < MAX_PATTERNS)
        {
            if(pSndFile->Patterns.Insert(ipatmap, rows))
                return true;

            if (!packsize) continue;
            p = pSndFile->Patterns[ipatmap];
        } else p = NULL;
        const uint8_t *src = lpStream+dwMemPos;
        UINT j=0;
        for (UINT row=0; row<rows; row++)
        {
            for (UINT chn=0; chn < xmheader->channels; chn++)
            {
                if ((p) && (j < packsize))
                {
                    uint8_t b = src[j++];
                    UINT vol = 0;
                    if (b & 0x80)
                    {
                        if (b & 1) p->note = src[j++];
                        if (b & 2) p->instr = src[j++];
                        if (b & 4) vol = src[j++];
                        //XXXih: gross!!
                        if (b & 8) p->command = (modplug::tracker::cmd_t) src[j++];
                        if (b & 16) p->param = src[j++];
                    } else
                    {
                        p->note = b;
                        p->instr = src[j++];
                        vol = src[j++];
                        //XXXih: gross!!
                        p->command = (modplug::tracker::cmd_t) src[j++];
                        p->param = src[j++];
                    }
                    if (p->note == 97) p->note = NoteKeyOff; else
                    if ((p->note) && (p->note < 97)) p->note += 12;
                    if (p->command | p->param) pSndFile->ConvertModCommand(p);
                    if (p->instr == 0xff) p->instr = 0;
                    if ((vol >= 0x10) && (vol <= 0x50))
                    {
                        p->volcmd = VolCmdVol;
                        p->vol = vol - 0x10;
                    } else
                    if (vol >= 0x60)
                    {
                        UINT v = vol & 0xF0;
                        vol &= 0x0F;
                        p->vol = vol;
                        switch(v)
                        {
                        // 60-6F: Volume Slide Down
                        case 0x60:    p->volcmd = VolCmdSlideDown; break;
                        // 70-7F: Volume Slide Up:
                        case 0x70:    p->volcmd = VolCmdSlideUp; break;
                        // 80-8F: Fine Volume Slide Down
                        case 0x80:    p->volcmd = VolCmdFineDown; break;
                        // 90-9F: Fine Volume Slide Up
                        case 0x90:    p->volcmd = VolCmdFineUp; break;
                        // A0-AF: Set Vibrato Speed
                        case 0xA0:    p->volcmd = VolCmdVibratoSpeed; break;
                        // B0-BF: Vibrato
                        case 0xB0:    p->volcmd = VolCmdVibratoDepth; break;
                        // C0-CF: Set Panning
                        case 0xC0:    p->volcmd = VolCmdPan; p->vol = (vol << 2) + 2; break;
                        // D0-DF: Panning Slide Left
                        case 0xD0:    p->volcmd = VolCmdPanSlideLeft; break;
                        // E0-EF: Panning Slide Right
                        case 0xE0:    p->volcmd = VolCmdPanSlideRight; break;
                        // F0-FF: Tone Portamento
                        case 0xF0:    p->volcmd = VolCmdPortamento; break;
                        }
                    }
                    p++;
                } else
                if (j < packsize)
                {
                    uint8_t b = src[j++];
                    if (b & 0x80)
                    {
                        if (b & 1) j++;
                        if (b & 2) j++;
                        if (b & 4) j++;
                        if (b & 8) j++;
                        if (b & 16) j++;
                    } else j += 4;
                } else break;
            }
        }
        dwMemPos += packsize;
    }
    return dwMemPos;
}
Exemple #20
0
bool CGzipArchive::ExtractFile()
//------------------------------
{
	#define ASSERT_CAN_READ(x) \
	if( dwMemPos > m_dwStreamLen || x > m_dwStreamLen - dwMemPos ) return false;

	if(!IsArchive())
		return false;

	DWORD dwMemPos = 0;
	GZheader *pHeader = (GZheader *)m_lpStream;
	GZtrailer *pTrailer = (GZtrailer *)(m_lpStream + m_dwStreamLen - sizeof(GZtrailer));

	dwMemPos += sizeof(GZheader);

	// Extra block present? (ignore)
	if(pHeader->flags & GZ_FEXTRA)
	{
		ASSERT_CAN_READ(sizeof(uint16_t));
		uint16_t xlen = LittleEndianW(*((uint16_t *)m_lpStream + dwMemPos));
		dwMemPos += sizeof(uint16_t);
		// We skip this.
		ASSERT_CAN_READ(xlen);
		dwMemPos += xlen;
	}

	// Filename present? (ignore)
	if(pHeader->flags & GZ_FNAME)
	{
		do 
		{
			ASSERT_CAN_READ(1);
		} while (m_lpStream[dwMemPos++] != 0);
	}

	// Comment present? (ignore)
	if(pHeader->flags & GZ_FCOMMENT)
	{
		do 
		{
			ASSERT_CAN_READ(1);
		} while (m_lpStream[dwMemPos++] != 0);
	}

	// CRC16 present?
	if(pHeader->flags & GZ_FHCRC)
	{
		ASSERT_CAN_READ(sizeof(uint16_t));
		uint16_t crc16_h = LittleEndianW(*((uint16_t *)m_lpStream + dwMemPos));
		uint16_t crc16_f = (uint16_t)(crc32(0, m_lpStream, dwMemPos) & 0xFFFF);
		dwMemPos += sizeof(uint16_t);
		if(crc16_h != crc16_f)
			return false;
	}

	// Well, this is a bit small when inflated.
	if(pTrailer->isize == 0)
		return false;

	// Check if the deflated data is a bit small as well.
	ASSERT_CAN_READ(sizeof(GZtrailer) + 1);

	// Clear the output buffer, if necessary.
	if(m_pOutputFile != nullptr)
	{
		delete[] m_pOutputFile;
	}

	DWORD destSize = LittleEndian(pTrailer->isize);

	m_pOutputFile = new Bytef[destSize];
	if(m_pOutputFile == nullptr)
		return false;

	// Inflate!
	z_stream strm;
	strm.zalloc = Z_NULL;
	strm.zfree = Z_NULL;
	strm.opaque = Z_NULL;
	strm.avail_in = m_dwStreamLen - (dwMemPos + sizeof(GZtrailer));
	strm.next_in = &m_lpStream[dwMemPos];
	if(inflateInit2(&strm, -15) != Z_OK)
		return false;
	strm.avail_out = destSize;
	strm.next_out = m_pOutputFile;

	int nRetVal = inflate(&strm, Z_NO_FLUSH);
	inflateEnd(&strm);

	// Everything went OK? Check return code, number of written bytes and CRC32.
	if(nRetVal == Z_STREAM_END && destSize == strm.total_out && LittleEndian(pTrailer->crc32) == crc32(0, m_pOutputFile, destSize))
	{
		// Success! :)
		m_dwOutputLen = destSize;
		return true;
	} else
	{
		// Fail :(
		if(m_pOutputFile != nullptr)
		{
			delete[] m_pOutputFile;
		}
		m_pOutputFile = nullptr;
		m_lpStream = nullptr;
		return false;
	}

	#undef ASSERT_CAN_READ
}
Exemple #21
0
bool CEndian::BigEndian()
{
	return(!LittleEndian());
}