bool MusBinOutput::WriteElementAttr( const MusElement *element ) { Write( &element->liaison , 1 ); Write( &element->dliai , 1 ); Write( &element->fliai , 1 ); Write( &element->lie_up , 1 ); Write( &element->rel , 1 ); Write( &element->drel , 1 ); Write( &element->frel , 1 ); Write( &element->oct , 1 ); Write( &element->dimin , 1 ); Write( &element->grp , 1 ); Write( &element->_shport , 1 ); Write( &element->ligat , 1 ); Write( &element->ElemInvisible , 1 ); Write( &element->pointInvisible , 1 ); Write( &element->existDebord , 1 ); Write( &element->fligat , 1 ); Write( &element->notschowgrp , 1 ); Write( &element->cone , 1 ); Write( &element->liaisonPointil , 1 ); Write( &element->reserve1 , 1 ); Write( &element->reserve2 , 1 ); Write( &element->ottava , 1 ); uint16 = wxUINT16_SWAP_ON_BE( element->durNum ); Write( &uint16, 2 ); uint16 = wxUINT16_SWAP_ON_BE( element->durDen ); Write( &uint16, 2 ); uint16 = wxUINT16_SWAP_ON_BE( element->offset ); Write( &uint16, 2 ); int32 = wxINT32_SWAP_ON_BE( element->xrel ); Write( &int32, 4 ); return true; }
bool MusBinInput::ReadElementAttr( MusElement *element ) { Read( &element->liaison , 1 ); Read( &element->dliai , 1 ); Read( &element->fliai , 1 ); Read( &element->lie_up , 1 ); Read( &element->rel , 1 ); Read( &element->drel , 1 ); Read( &element->frel , 1 ); Read( &element->oct , 1 ); Read( &element->dimin , 1 ); Read( &element->grp , 1 ); Read( &element->_shport , 1 ); Read( &element->ligat , 1 ); Read( &element->ElemInvisible , 1 ); Read( &element->pointInvisible , 1 ); Read( &element->existDebord , 1 ); Read( &element->fligat , 1 ); Read( &element->notschowgrp , 1 ); Read( &element->cone , 1 ); Read( &element->liaisonPointil , 1 ); Read( &element->reserve1 , 1 ); Read( &element->reserve2 , 1 ); Read( &element->ottava , 1 ); Read( &uint16, 2 ); element->durNum = wxUINT16_SWAP_ON_BE( uint16 ); Read( &uint16, 2 ); element->durDen = wxUINT16_SWAP_ON_BE( uint16 ); Read( &uint16, 2 ); element->offset = wxUINT16_SWAP_ON_BE( uint16 ); Read( &int32, 4 ); element->xrel = wxINT32_SWAP_ON_BE( int32 ); return true; }
bool CWAVFileWriter::open() { m_length = 0U ; m_file = new wxFFile(m_fileName.c_str(), wxT("wb")); bool ret = m_file->IsOpened(); if (!ret) { wxLogError(wxT("WAVFileWriter: could not open the file %s in WAVFileWriter"), m_fileName.c_str()); delete m_file; m_file = NULL; return false; } m_file->Write("RIFF", 4); // 4 bytes, file signature m_offset1 = m_file->Tell(); wxUint32 uint32 = 0; m_file->Write(&uint32, sizeof(wxUint32)); // 4 bytes, length of file, filled in later m_file->Write("WAVE", 4); // 4 bytes, RIFF file type m_file->Write("fmt ", 4); // 4 bytes, chunk signature uint32 = wxUINT32_SWAP_ON_BE(wxUint32(16)); m_file->Write(&uint32, sizeof(wxUint32)); // 4 bytes, length of "fmt " chunk wxUint16 uint16; if (m_sampleWidth == 8U || m_sampleWidth == 16U) uint16 = wxUINT16_SWAP_ON_BE(wxUint16(1)); // 2 bytes, integer PCM/uncompressed else uint16 = wxUINT16_SWAP_ON_BE(wxUint16(3)); // 2 bytes, float PCM/uncompressed m_file->Write(&uint16, sizeof(uint16)); uint16 = wxUINT16_SWAP_ON_BE(wxUint16(m_channels)); m_file->Write(&uint16, sizeof(uint16)); // 2 bytes, no of channels uint32 = wxUINT32_SWAP_ON_BE(wxUint32(m_sampleRate)); m_file->Write(&uint32, sizeof(wxUint32)); // 4 bytes, sample rate uint32 = wxUINT32_SWAP_ON_BE(wxUint32(m_sampleRate * m_channels * m_sampleWidth / 8U)); m_file->Write(&uint32, sizeof(wxUint32)); // 4 bytes, average bytes per second uint16 = wxUINT16_SWAP_ON_BE(wxUint16(m_channels * m_sampleWidth / 8U)); m_file->Write(&uint16, sizeof(uint16)); // 2 bytes, block alignment uint16 = wxUINT16_SWAP_ON_BE(wxUint16(m_sampleWidth)); m_file->Write(&uint16, sizeof(uint16)); // 2 bytes, significant bits per sample m_file->Write("data", 4); // 4 bytes, chunk signature m_offset2 = m_file->Tell(); uint32 = 0U; m_file->Write(&uint32, sizeof(wxUint32)); // 4 bytes, length of "data" chunk, filled in later return true; }
bool wxSound::LoadWAV(const wxUint8 *data, size_t length, bool copyData) { WAVEFORMAT waveformat; wxUint32 ul; if (length < 32 + sizeof(WAVEFORMAT)) return false; memcpy(&waveformat, &data[FMT_INDEX + 4], sizeof(WAVEFORMAT)); waveformat.uiSize = wxUINT32_SWAP_ON_BE(waveformat.uiSize); waveformat.uiFormatTag = wxUINT16_SWAP_ON_BE(waveformat.uiFormatTag); waveformat.uiChannels = wxUINT16_SWAP_ON_BE(waveformat.uiChannels); waveformat.ulSamplesPerSec = wxUINT32_SWAP_ON_BE(waveformat.ulSamplesPerSec); waveformat.ulAvgBytesPerSec = wxUINT32_SWAP_ON_BE(waveformat.ulAvgBytesPerSec); waveformat.uiBlockAlign = wxUINT16_SWAP_ON_BE(waveformat.uiBlockAlign); waveformat.uiBitsPerSample = wxUINT16_SWAP_ON_BE(waveformat.uiBitsPerSample); if (memcmp(data, "RIFF", 4) != 0) return false; if (memcmp(&data[WAVE_INDEX], "WAVE", 4) != 0) return false; if (memcmp(&data[FMT_INDEX], "fmt ", 4) != 0) return false; if (memcmp(&data[FMT_INDEX + waveformat.uiSize + 8], "data", 4) != 0) return false; memcpy(&ul,&data[FMT_INDEX + waveformat.uiSize + 12], 4); ul = wxUINT32_SWAP_ON_BE(ul); //WAS: if (ul + FMT_INDEX + waveformat.uiSize + 16 != length) if (ul + FMT_INDEX + waveformat.uiSize + 16 > length) return false; if (waveformat.uiFormatTag != WAVE_FORMAT_PCM) return false; if (waveformat.ulSamplesPerSec != waveformat.ulAvgBytesPerSec / waveformat.uiBlockAlign) return false; m_data = new wxSoundData; m_data->m_channels = waveformat.uiChannels; m_data->m_samplingRate = waveformat.ulSamplesPerSec; m_data->m_bitsPerSample = waveformat.uiBitsPerSample; m_data->m_samples = ul / (m_data->m_channels * m_data->m_bitsPerSample / 8); m_data->m_dataBytes = ul; if (copyData) { m_data->m_dataWithHeader = new wxUint8[length]; memcpy(m_data->m_dataWithHeader, data, length); } else m_data->m_dataWithHeader = (wxUint8*)data; m_data->m_data = (&m_data->m_dataWithHeader[FMT_INDEX + waveformat.uiSize + 8]); return true; }
bool MusBinInput::ReadFileHeader( MusFileHeader *header ) { Read( &int32, 4 ); m_flag = wxINT32_SWAP_ON_BE( int32 ); Read( &int32, 4 ); m_vmaj = wxINT32_SWAP_ON_BE( int32 ); Read( &int32, 4 ); m_vmin = wxINT32_SWAP_ON_BE( int32 ); Read( &int32, 4 ); m_vrev = wxINT32_SWAP_ON_BE( int32 ); Read( &uint16, 2 ); header->nbpage = wxUINT16_SWAP_ON_BE( uint16 ); // nbpage Read( &uint16, 2 ); header->nopage = wxUINT16_SWAP_ON_BE( uint16 ); // nopage Read( &uint16, 2 ); header->noligne = wxUINT16_SWAP_ON_BE( uint16 ); // noligne Read( &uint32, 4 ); header->xpos = wxUINT32_SWAP_ON_BE( uint32 ); // xpso Read( &header->param.orientation, 1 ); // param - orientation Read( &header->param.EpLignesPortee, 1 ); // param - epLignesPortee header->param.EpLignesPortee = 1; Read( &header->param.EpQueueNote, 1 ); // param - epQueueNotes header->param.EpQueueNote = 2; Read( &header->param.EpBarreMesure, 1 ); // param - epBarreMesure Read( &header->param.EpBarreValeur, 1 ); // param - epBarreValeur Read( &header->param.EpBlancBarreValeur, 1 ); // param - epBlancBarreValeur Read( &int32, 4 ); header->param.pageFormatHor = wxINT32_SWAP_ON_BE( int32 ); // param - pageFormatHor Read( &int32, 4 ); header->param.pageFormatVer = wxINT32_SWAP_ON_BE( int32 ); // param - pageFormatVer Read( &int16, 2 ); header->param.MargeSOMMET = wxINT16_SWAP_ON_BE( int16 ); // param - margeSommet Read( &int16, 2 ); header->param.MargeGAUCHEIMPAIRE = wxINT16_SWAP_ON_BE( int16 ); // param - margeGaucheImpaire Read( &int16, 2 ); header->param.MargeGAUCHEPAIRE = wxINT16_SWAP_ON_BE( int16 ); // param - margeGauchePaire Read( &header->param.rapportPorteesNum, 1 ); // rpPorteesNum Read( &header->param.rapportPorteesDen, 1 ); // rpPorteesDen Read( &header->param.rapportDiminNum, 1 ); // rpDiminNum Read( &header->param.rapportDiminDen, 1 ); // rpDiminDen Read( &header->param.hampesCorr, 1 ); // hampesCorr header->param.hampesCorr = 1; if ( AxFile::FormatVersion(m_vmaj, m_vmin, m_vrev) < AxFile::FormatVersion(1, 6, 1) ) return true; // following values where added in 1.6.1 // 1.6.1 Read( &int32, 4 ); header->param.notationMode = wxINT32_SWAP_ON_BE( int32 ); return true; }
bool CDVAPController::writeHeader(const CHeaderData& header) { m_streamId++; unsigned char buffer[50U]; ::memcpy(buffer, DVAP_HEADER, DVAP_HEADER_LEN); wxUint16 sid = wxUINT16_SWAP_ON_BE(m_streamId); ::memcpy(buffer + 2U, &sid, sizeof(wxUint16)); buffer[4U] = 0x80U; buffer[5U] = 0U; ::memset(buffer + 6U, ' ', RADIO_HEADER_LENGTH_BYTES); buffer[6U] = header.getFlag1(); buffer[7U] = header.getFlag2(); buffer[8U] = header.getFlag3(); wxString rpt2 = header.getRptCall2(); for (unsigned int i = 0U; i < rpt2.Len() && i < LONG_CALLSIGN_LENGTH; i++) buffer[i + 9U] = rpt2.GetChar(i); wxString rpt1 = header.getRptCall1(); for (unsigned int i = 0U; i < rpt1.Len() && i < LONG_CALLSIGN_LENGTH; i++) buffer[i + 17U] = rpt1.GetChar(i); wxString your = header.getYourCall(); for (unsigned int i = 0U; i < your.Len() && i < LONG_CALLSIGN_LENGTH; i++) buffer[i + 25U] = your.GetChar(i); wxString my1 = header.getMyCall1(); for (unsigned int i = 0U; i < my1.Len() && i < LONG_CALLSIGN_LENGTH; i++) buffer[i + 33U] = my1.GetChar(i); wxString my2 = header.getMyCall2(); for (unsigned int i = 0U; i < my2.Len() && i < SHORT_CALLSIGN_LENGTH; i++) buffer[i + 41U] = my2.GetChar(i); CCCITTChecksumReverse cksum; cksum.update(buffer + 6U, RADIO_HEADER_LENGTH_BYTES - 2U); cksum.result(buffer + 45U); m_framePos = 0U; m_seq = 0U; wxMutexLocker locker(m_mutex); unsigned int space = m_txData.freeSpace(); if (space < 48U) return false; unsigned char len = DVAP_HEADER_LEN; m_txData.addData(&len, 1U); m_txData.addData(buffer, DVAP_HEADER_LEN); return true; }
/* ChasmBinArchive::isChasmBinArchive * Checks if the given data is a valid Chasm bin archive *******************************************************************/ bool ChasmBinArchive::isChasmBinArchive(MemChunk& mc) { // Check given data is valid if (mc.getSize() < HEADER_SIZE) { return false; } // Read bin header and check it char magic[4] = {}; mc.read(magic, sizeof magic); if ( magic[0] != 'C' || magic[1] != 'S' || magic[2] != 'i' || magic[3] != 'd') { return false; } uint16_t num_entries = 0; mc.read(&num_entries, sizeof num_entries); num_entries = wxUINT16_SWAP_ON_BE(num_entries); return num_entries > MAX_ENTRY_COUNT || (HEADER_SIZE + ENTRY_SIZE * MAX_ENTRY_COUNT) <= mc.getSize(); }
// ----------------------------------------------------------------------------- // Checks if the file at [filename] is a valid Chasm bin archive // ----------------------------------------------------------------------------- bool ChasmBinArchive::isChasmBinArchive(string filename) { // Open file for reading wxFile file(filename); // Check it opened ok if (!file.IsOpened() || file.Length() < HEADER_SIZE) { return false; } // Read bin header and check it char magic[4] = {}; file.Read(magic, sizeof magic); if (magic[0] != 'C' || magic[1] != 'S' || magic[2] != 'i' || magic[3] != 'd') { return false; } uint16_t num_entries = 0; file.Read(&num_entries, sizeof num_entries); num_entries = wxUINT16_SWAP_ON_BE(num_entries); return num_entries > MAX_ENTRY_COUNT || (HEADER_SIZE + ENTRY_SIZE * MAX_ENTRY_COUNT) <= static_cast<uint32_t>(file.Length()); }
bool MusBinOutput::WriteFileHeader( const MusFileHeader *header ) { int32 = wxINT32_SWAP_ON_BE( m_flag ); Write( &int32, 4 ); int32 = wxINT32_SWAP_ON_BE( AxApp::s_version_major ); Write( &int32, 4 ); int32 = wxINT32_SWAP_ON_BE( AxApp::s_version_minor ); Write( &int32, 4 ); int32 = wxINT32_SWAP_ON_BE( AxApp::s_version_revision ); Write( &int32, 4 ); uint16 = wxUINT16_SWAP_ON_BE( header->nbpage ); // nbpage Write( &uint16, 2 ); uint16 = wxUINT16_SWAP_ON_BE( header->nopage ); // nopage Write( &uint16, 2 ); uint16 = wxUINT16_SWAP_ON_BE( header->noligne ); // noligne Write( &uint16, 2 ); uint32 = wxUINT32_SWAP_ON_BE( header->xpos ); // xpso Write( &uint32, 4 ); Write( &header->param.orientation, 1 ); // param - orientation Write( &header->param.EpLignesPortee, 1 ); // param - epLignesPortee Write( &header->param.EpQueueNote, 1 ); // param - epQueueNotes Write( &header->param.EpBarreMesure, 1 ); // param - epBarreMesure Write( &header->param.EpBarreValeur, 1 ); // param - epBarreValeur Write( &header->param.EpBlancBarreValeur, 1 ); // param - epBlancBarreValeur int32 = wxINT32_SWAP_ON_BE( header->param.pageFormatHor ); // param - pageFormatHor Write( &int32, 4 ); int32 = wxINT32_SWAP_ON_BE( header->param.pageFormatVer ); // param - pageFormatVer Write( &int32, 4 ); int16 = wxINT16_SWAP_ON_BE( header->param.MargeSOMMET ); // param - margeSommet Write( &int16, 2 ); int16 = wxINT16_SWAP_ON_BE( header->param.MargeGAUCHEIMPAIRE ); // param - margeGaucheImpaire Write( &int16, 2 ); int16 = wxINT16_SWAP_ON_BE( header->param.MargeGAUCHEPAIRE ); // param - margeGauchePaire Write( &int16, 2 ); Write( &header->param.rapportPorteesNum, 1 ); // rpPorteesNum Write( &header->param.rapportPorteesDen, 1 ); // rpPorteesDen Write( &header->param.rapportDiminNum, 1 ); // rpDiminNum Write( &header->param.rapportDiminDen, 1 ); // rpDiminDen Write( &header->param.hampesCorr, 1 ); // hampesCorr int32 = wxINT32_SWAP_ON_BE( header->param.notationMode ); // param - pageFormatVer Write( &int32, 4 ); return true; }
wxUint16 wxDataInputStream::Read16() { wxUint16 i16; m_input->Read(&i16, 2); if (m_be_order) return wxUINT16_SWAP_ON_LE(i16); else return wxUINT16_SWAP_ON_BE(i16); }
bool MusBinInput::ReadSymbol( MusSymbol *symbol ) { ReadElementAttr( symbol ); Read( &symbol->flag , 1 ); we also need to convert LEIPZIG_METER_SYMB_CUT into METER_SYMB_CUT for IND_MES Read( &symbol->calte , 1 ); Read( &symbol->carStyle , 1 ); Read( &symbol->carOrient , 1 ); Read( &symbol->fonte , 1 ); Read( &symbol->s_lie_l , 1 ); Read( &symbol->point , 1 ); Read( &uint16, 2 ); symbol->code = wxUINT16_SWAP_ON_BE( uint16 ); Read( &uint16, 2 ); symbol->l_ptch = wxUINT16_SWAP_ON_BE( uint16 ); Read( &int32, 4 ); symbol->dec_y = wxINT32_SWAP_ON_BE( int32 ); if ( symbol->IsLyric() ) ReadLyric( symbol ); return true; }
bool MusBinOutput::WriteSymbol( const MusSymbol *symbol ) { Write( &symbol->TYPE, 1 ); WriteElementAttr( symbol ); Write( &symbol->flag , 1 ); Write( &symbol->calte , 1 ); Write( &symbol->carStyle , 1 ); Write( &symbol->carOrient , 1 ); Write( &symbol->fonte , 1 ); Write( &symbol->s_lie_l , 1 ); Write( &symbol->point , 1 ); uint16 = wxUINT16_SWAP_ON_BE( symbol->code ); Write( &uint16, 2 ); uint16 = wxUINT16_SWAP_ON_BE( symbol->l_ptch ); Write( &uint16, 2 ); int32 = wxINT32_SWAP_ON_BE( symbol->dec_y ); Write( &int32, 4 ); // if ( symbol->IsLyric() ) // To be fixed ?? if ( (symbol->flag == CHAINE) && (symbol->fonte == LYRIC) ) WriteLyric( symbol ); return true; }
unsigned int CDVTOOLFileReader::read(unsigned char* buffer, unsigned int length, DVTFR_TYPE& type) { wxASSERT(buffer != 0); wxASSERT(length > 0U); wxUint16 uint16; size_t n = m_file.Read(&uint16, sizeof(wxUint16)); if (n != sizeof(wxUint16)) return 0U; wxUint16 len = wxUINT16_SWAP_ON_BE(uint16) - 15U; if (len > length) return 0U; unsigned char bytes[FIXED_DATA_LENGTH]; n = m_file.Read(bytes, DSVT_SIGNATURE_LENGTH); if (n != DSVT_SIGNATURE_LENGTH) return 0U; if (::memcmp(bytes, DSVT_SIGNATURE, DSVT_SIGNATURE_LENGTH) != 0) return 0U; char flag; n = m_file.Read(&flag, 1U); if (n != 1U) return 0U; type = (flag == HEADER_FLAG) ? DVTFR_HEADER : DVTFR_DETAIL; n = m_file.Read(bytes, FIXED_DATA_LENGTH); if (n != FIXED_DATA_LENGTH) return 0U; n = m_file.Read(&flag, 1U); if (n != 1U) return 0U; if (type == DVTFR_DETAIL) { if ((flag & TRAILER_MASK) == TRAILER_MASK) type = DVTFR_TRAILER; } n = m_file.Read(buffer, len); if (n != len) return 0U; return len; }
bool CDVAPController::writeData(const unsigned char* data, unsigned int length, bool end) { unsigned char buffer[20U]; ::memcpy(buffer + 0U, DVAP_DATA, DVAP_DATA_LEN); if (::memcmp(data + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES) == 0) m_framePos = 0U; wxUint16 sid = wxUINT16_SWAP_ON_BE(m_streamId); ::memcpy(buffer + 2U, &sid, sizeof(wxUint16)); buffer[4U] = m_framePos; buffer[5U] = m_seq; if (end) buffer[4U] |= 0x40U; ::memcpy(buffer + 6U, data, DV_FRAME_LENGTH_BYTES); wxMutexLocker locker(m_mutex); unsigned int space = m_txData.freeSpace(); if (space < 19U) { wxLogMessage(wxT("Out of space in the DVAP TX queue")); return false; } unsigned char len = DVAP_DATA_LEN; m_txData.addData(&len, 1U); m_txData.addData(buffer, DVAP_DATA_LEN); m_framePos++; m_seq++; return true; }
bool CSoundFileReader::open(float sampleRate, unsigned int blockSize) { m_blockSize = blockSize; m_read = 0U; m_file = new wxFFile(m_fileName.c_str(), wxT("rb")); bool ret = m_file->IsOpened(); if (!ret) { wxLogError(wxT("SoundFileReader: could not open the WAV file %s."), m_fileName.c_str()); delete m_file; m_file = NULL; return false; } unsigned char buffer[4]; unsigned int n = m_file->Read(buffer, 4); if (n != 4U || ::memcmp(buffer, "RIFF", 4) != 0) { wxLogError(wxT("SoundFileReader: %s has no \"RIFF\" signature."), m_fileName.c_str()); return false; } n = m_file->Read(buffer, 4); if (n != 4U) { wxLogError(wxT("SoundFileReader: %s is corrupt, cannot read the file length."), m_fileName.c_str()); return false; } n = m_file->Read(buffer, 4); if (n != 4U || ::memcmp(buffer, "WAVE", 4) != 0) { wxLogError(wxT("SoundFileReader: %s has no \"WAVE\" header."), m_fileName.c_str()); return false; } n = m_file->Read(buffer, 4); if (n != 4U || ::memcmp(buffer, "fmt ", 4) != 0) { wxLogError(wxT("SoundFileReader: %s has no \"fmt \" chunk."), m_fileName.c_str()); return false; } wxUint32 uint32; n = m_file->Read(&uint32, sizeof(wxUint32)); wxUint32 length = wxUINT32_SWAP_ON_BE(uint32); if (n != sizeof(wxUint32) || length < 16U) { wxLogError(wxT("SoundFileReader: %s is corrupt, cannot read the WAVEFORMATEX structure length."), m_fileName.c_str()); return false; } wxUint16 uint16; n = m_file->Read(&uint16, sizeof(wxUint16)); wxUint16 compCode = wxUINT16_SWAP_ON_BE(uint16); if (n != sizeof(wxUint16) || (compCode != FORMAT_PCM && compCode != FORMAT_IEEE_FLOAT)) { wxLogError(wxT("SoundFileReader: %s is not PCM or IEEE Float format, is %u."), m_fileName.c_str(), compCode); return false; } n = m_file->Read(&uint16, sizeof(wxUint16)); m_channels = wxUINT16_SWAP_ON_BE(uint16); if (n != sizeof(wxUint16) || m_channels > 2U) { wxLogError(wxT("SoundFileReader: %s has %u channels, more than 2."), m_fileName.c_str(), m_channels); return false; } n = m_file->Read(&uint32, sizeof(wxUint32)); wxUint32 samplesPerSec = wxUINT32_SWAP_ON_BE(uint32); if (n != sizeof(wxUint32) || samplesPerSec != sampleRate) { wxLogError(wxT("SoundFileReader: %s has sample rate %lu, not %.0f"), m_fileName.c_str(), (unsigned long)samplesPerSec, sampleRate); return false; } n = m_file->Read(&uint32, sizeof(wxUint32)); if (n != sizeof(wxUint32)) { wxLogError(wxT("SoundFileReader: %s is corrupt, cannot read the average bytes per second"), m_fileName.c_str()); return false; } n = m_file->Read(&uint16, sizeof(wxUint16)); if (n != sizeof(wxUint16)) { wxLogError(wxT("SoundFileReader: %s is corrupt, cannot read the block align."), m_fileName.c_str()); return false; } n = m_file->Read(&uint16, sizeof(wxUint16)); if (n != sizeof(wxUint16)) { wxLogError(wxT("SoundFileReader: %s is corrupt, cannot read the bitsPerSample."), m_fileName.c_str()); return false; } wxUint16 bitsPerSample = wxUINT16_SWAP_ON_BE(uint16); if (bitsPerSample == 8U && compCode == FORMAT_PCM) { m_format = FORMAT_8BIT; } else if (bitsPerSample == 16U && compCode == FORMAT_PCM) { m_format = FORMAT_16BIT; } else if (bitsPerSample == 32U && compCode == FORMAT_IEEE_FLOAT) { m_format = FORMAT_32BIT; } else { wxLogError(wxT("SoundFileReader: %s has sample width %u and format %u."), m_fileName.c_str(), bitsPerSample, compCode); return false; } // Now drain any extra bytes of data if (length > 16U) m_file->Seek(length - 16U, wxFromCurrent); n = m_file->Read(buffer, 4); if (n != 4U || ::memcmp(buffer, "data", 4) != 0) { wxLogError(wxT("SoundFileReader: %s has no \"data\" chunk."), m_fileName.c_str()); return false; } n = m_file->Read(&uint32, sizeof(wxUint32)); if (n != sizeof(wxUint32)) { wxLogError(wxT("SoundFileReader: %s is corrupt, cannot read the \"data\" chunk size"), m_fileName.c_str()); return false; } m_length = wxUINT32_SWAP_ON_BE(uint32); // Get the current location so we can rewind if needed m_offset = m_file->Tell(); switch (m_format) { case FORMAT_8BIT: m_buffer8 = new wxUint8[m_blockSize * m_channels]; break; case FORMAT_16BIT: m_buffer16 = new wxInt16[m_blockSize * m_channels]; break; case FORMAT_32BIT: m_buffer32 = new wxFloat32[m_blockSize * m_channels]; break; } m_buffer = new float[m_blockSize * 2U]; return CThreadReader::open(sampleRate, blockSize); }
/** * Help Browser tries to read the contents of the * file by interpreting a .hhp file in the Archiv. * For .chm doesnt include such a file, we need * to rebuild the information based on stored * system-files. */ void wxChmInputStream::CreateHHPStream() { wxFileName file; bool topic = false; bool hhc = false; bool hhk = false; wxInputStream *i; wxMemoryOutputStream *out; const char *tmp; // Try to open the #SYSTEM-File and create the HHP File out of it // see http://bonedaddy.net/pabs3/chmspec/0.1.2/Internal.html#SYSTEM if ( ! m_chm->Contains(_T("/#SYSTEM")) ) { #ifdef DEBUG wxLogDebug(_("Archive doesnt contain #SYSTEM file")); #endif return; } else { file = wxFileName(_T("/#SYSTEM")); } if ( CreateFileStream(_T("/#SYSTEM")) ) { // New stream for writing a memory area to simulate the // .hhp-file out = new wxMemoryOutputStream(); tmp = "[OPTIONS]\r\n"; out->Write((const void *) tmp, strlen(tmp)); wxUint16 code; wxUint16 len; void *buf; // use the actual stream for reading i = m_contentStream; /* Now read the contents, and try to get the needed information */ // First 4 Bytes are Version information, skip i->SeekI(4); while (!i->Eof()) { // Read #SYSTEM-Code and length i->Read(&code, 2); code = wxUINT16_SWAP_ON_BE( code ) ; i->Read(&len, 2); len = wxUINT16_SWAP_ON_BE( len ) ; // data buf = malloc(len); i->Read(buf, len); switch (code) { case 0: // CONTENTS_FILE tmp = "Contents file="; hhc=true; break; case 1: // INDEX_FILE tmp = "Index file="; hhk = true; break; case 2: // DEFAULT_TOPIC tmp = "Default Topic="; topic = true; break; case 3: // TITLE tmp = "Title="; break; // case 6: // COMPILED_FILE // tmp = "Compiled File="; // break; case 7: // COMPILED_FILE tmp = "Binary Index=YES\r\n"; out->Write( (const void *) tmp, strlen(tmp)); tmp = NULL; break; case 4: // STRUCT SYSTEM INFO tmp = NULL ; if ( len >= 28 ) { char *structptr = (char*) buf ; // LCID at position 0 wxUint32 dummy = *((wxUint32 *)(structptr+0)) ; wxUint32 lcid = wxUINT32_SWAP_ON_BE( dummy ) ; wxString msg ; msg.Printf(_T("Language=0x%X\r\n"),lcid) ; out->Write(msg.c_str() , msg.Length() ) ; } break ; default: tmp=NULL; } if (tmp) { out->Write((const void *) tmp, strlen(tmp)); out->Write(buf, strlen((char*)buf)); out->Write("\r\n", 2); } free(buf); buf=NULL; } // Free the old data which wont be used any more delete m_contentStream; if (m_content) free (m_content); // Now add entries which are missing if ( !hhc && m_chm->Contains(_T("*.hhc")) ) { tmp = "Contents File=*.hhc\r\n"; out->Write((const void *) tmp, strlen(tmp)); } if ( !hhk && m_chm->Contains(_T("*.hhk")) ) { tmp = "Index File=*.hhk\r\n"; out->Write((const void *) tmp, strlen(tmp)); } // Now copy the Data from the memory out->SeekO(0, wxFromEnd); m_size = out->TellO(); out->SeekO(0, wxFromStart); m_content = (char *) malloc (m_size+1); out->CopyTo(m_content, m_size); m_content[m_size]='\0'; m_size++; m_contentStream = new wxMemoryInputStream(m_content, m_size); delete out; } }
/* GZipArchive::open * Reads gzip format data from a MemChunk * Returns true if successful, false otherwise *******************************************************************/ bool GZipArchive::open(MemChunk& mc) { // Minimal metadata size is 18: 10 for header, 8 for footer size_t mds = 18; size_t size = mc.getSize(); if (mds > size) return false; // Read header uint8_t header[4]; mc.read(header, 4); // Check for GZip header; we'll only accept deflated gzip files // and reject any field using unknown flags if ((!(header[0] == GZIP_ID1 && header[1] == GZIP_ID2 && header[2] == GZIP_DEFLATE)) || (header[3] & GZIP_FLG_FUNKN)) return false; bool ftext, fhcrc, fxtra, fname, fcmnt; ftext = (header[3] & GZIP_FLG_FTEXT) ? true : false; fhcrc = (header[3] & GZIP_FLG_FHCRC) ? true : false; fxtra = (header[3] & GZIP_FLG_FXTRA) ? true : false; fname = (header[3] & GZIP_FLG_FNAME) ? true : false; fcmnt = (header[3] & GZIP_FLG_FCMNT) ? true : false; flags = header[3]; mc.read(&mtime, 4); mtime = wxUINT32_SWAP_ON_BE(mtime); mc.read(&xfl, 1); mc.read(&os, 1); // Skip extra fields which may be there if (fxtra) { uint16_t xlen; mc.read(&xlen, 2); xlen = wxUINT16_SWAP_ON_BE(xlen); mds += xlen + 2; if (mds > size) return false; mc.exportMemChunk(xtra, mc.currentPos(), xlen); mc.seek(xlen, SEEK_CUR); } // Skip past name, if any string name; if (fname) { char c; do { mc.read(&c, 1); if (c) name += c; ++mds; } while (c != 0 && size > mds); } else { // Build name from filename name = getFilename(false); wxFileName fn(name); if (!fn.GetExt().CmpNoCase("tgz")) fn.SetExt("tar"); else if (!fn.GetExt().CmpNoCase("gz")) fn.ClearExt(); name = fn.GetFullName(); } // Skip past comment if (fcmnt) { char c; do { mc.read(&c, 1); if (c) comment += c; ++mds; } while (c != 0 && size > mds); wxLogMessage("Archive %s says:\n %s", CHR(getFilename(true)), CHR(comment)); } // Skip past CRC 16 check if (fhcrc) { uint8_t* crcbuffer = new uint8_t[mc.currentPos()]; memcpy(crcbuffer, mc.getData(), mc.currentPos()); uint32_t fullcrc = Misc::crc(crcbuffer, mc.currentPos()); delete[] crcbuffer; uint16_t hcrc; mc.read(&hcrc, 2); hcrc = wxUINT16_SWAP_ON_BE(hcrc); mds += 2; if (hcrc != (fullcrc & 0x0000FFFF)) { wxLogMessage("CRC-16 mismatch for GZip header"); } } // Header is over if (mds > size || mc.currentPos() + 8 > size) return false; // Let's create the entry setMuted(true); ArchiveEntry* entry = new ArchiveEntry(name, size - mds); MemChunk xdata; if (Compression::GZipInflate(mc, xdata)) { entry->importMemChunk(xdata); } else { delete entry; setMuted(false); return false; } getRoot()->addEntry(entry); EntryType::detectEntryType(entry); entry->setState(0); setMuted(false); setModified(false); announce("opened"); // Finish return true; }
/* GZipArchive::isGZipArchive * Checks if the file at [filename] is a valid GZip archive *******************************************************************/ bool GZipArchive::isGZipArchive(string filename) { // Open file for reading wxFile file(filename); // Minimal metadata size is 18: 10 for header, 8 for footer size_t mds = 18; // Check it opened ok if (!file.IsOpened() || file.Length() < mds) { return false; } size_t size = file.Length(); // Read header uint8_t header[4]; file.Read(header, 4); bool ftext, fhcrc, fxtra, fname, fcmnt; ftext = (header[3] & GZIP_FLG_FTEXT) ? true : false; fhcrc = (header[3] & GZIP_FLG_FHCRC) ? true : false; fxtra = (header[3] & GZIP_FLG_FXTRA) ? true : false; fname = (header[3] & GZIP_FLG_FNAME) ? true : false; fcmnt = (header[3] & GZIP_FLG_FCMNT) ? true : false; // Check for GZip header; we'll only accept deflated gzip files // and reject any field using unknown flags if ((!(header[0] == GZIP_ID1 && header[1] == GZIP_ID2 && header[2] == GZIP_DEFLATE)) || (header[3] & GZIP_FLG_FUNKN)) { return false; } uint32_t mtime; file.Read(&mtime, 4); uint8_t xfl; file.Read(&xfl, 1); uint8_t os; file.Read(&os, 1); // Skip extra fields which may be there if (fxtra) { uint16_t xlen; file.Read(&xlen, 2); xlen = wxUINT16_SWAP_ON_BE(xlen); mds += xlen + 2; if (mds > size) return false; file.Seek(xlen, wxFromCurrent); } // Skip past name if (fname) { string name; char c; do { file.Read(&c, 1); if (c) name += c; ++mds; } while (c != 0 && size > mds); } // Skip past comment if (fcmnt) { string comment; char c; do { file.Read(&c, 1); if (c) comment += c; ++mds; } while (c != 0 && size > mds); } // Skip past CRC 16 check if (fhcrc) { uint16_t hcrc; file.Read(&hcrc, 2); mds += 2; } // Header is over if (mds > size) return false; // If it's passed to here it's probably a gzip file return true; }
bool wxBMPHandler::SaveDib(wxImage *image, wxOutputStream& stream, bool verbose, bool IsBmp, bool IsMask) { wxCHECK_MSG( image, false, wxT("invalid pointer in wxBMPHandler::SaveFile") ); if ( !image->Ok() ) { if ( verbose ) { wxLogError(_("BMP: Couldn't save invalid image.")); } return false; } // get the format of the BMP file to save, else use 24bpp unsigned format = wxBMP_24BPP; if ( image->HasOption(wxIMAGE_OPTION_BMP_FORMAT) ) format = image->GetOptionInt(wxIMAGE_OPTION_BMP_FORMAT); wxUint16 bpp; // # of bits per pixel int palette_size; // # of color map entries, ie. 2^bpp colors // set the bpp and appropriate palette_size, and do additional checks if ( (format == wxBMP_1BPP) || (format == wxBMP_1BPP_BW) ) { bpp = 1; palette_size = 2; } else if ( format == wxBMP_4BPP ) { bpp = 4; palette_size = 16; } else if ( (format == wxBMP_8BPP) || (format == wxBMP_8BPP_GREY) || (format == wxBMP_8BPP_RED) || (format == wxBMP_8BPP_PALETTE) ) { // need to set a wxPalette to use this, HOW TO CHECK IF VALID, SIZE? if ((format == wxBMP_8BPP_PALETTE) #if wxUSE_PALETTE && !image->HasPalette() #endif // wxUSE_PALETTE ) { if ( verbose ) { wxLogError(_("BMP: wxImage doesn't have own wxPalette.")); } return false; } bpp = 8; palette_size = 256; } else // you get 24bpp { format = wxBMP_24BPP; bpp = 24; palette_size = 0; } unsigned width = image->GetWidth(); unsigned row_padding = (4 - int(width*bpp/8.0) % 4) % 4; // # bytes to pad to dword unsigned row_width = int(width * bpp/8.0) + row_padding; // # of bytes per row struct { // BitmapHeader: wxUint16 magic; // format magic, always 'BM' wxUint32 filesize; // total file size, inc. headers wxUint32 reserved; // for future use wxUint32 data_offset; // image data offset in the file // BitmapInfoHeader: wxUint32 bih_size; // 2nd part's size wxUint32 width, height; // bitmap's dimensions wxUint16 planes; // num of planes wxUint16 bpp; // bits per pixel wxUint32 compression; // compression method wxUint32 size_of_bmp; // size of the bitmap wxUint32 h_res, v_res; // image resolution in pixels-per-meter wxUint32 num_clrs; // number of colors used wxUint32 num_signif_clrs;// number of significant colors } hdr; wxUint32 hdr_size = 14/*BitmapHeader*/ + 40/*BitmapInfoHeader*/; hdr.magic = wxUINT16_SWAP_ON_BE(0x4D42/*'BM'*/); hdr.filesize = wxUINT32_SWAP_ON_BE( hdr_size + palette_size*4 + row_width * image->GetHeight() ); hdr.reserved = 0; hdr.data_offset = wxUINT32_SWAP_ON_BE(hdr_size + palette_size*4); hdr.bih_size = wxUINT32_SWAP_ON_BE(hdr_size - 14); hdr.width = wxUINT32_SWAP_ON_BE(image->GetWidth()); if ( IsBmp ) { hdr.height = wxUINT32_SWAP_ON_BE(image->GetHeight()); } else { hdr.height = wxUINT32_SWAP_ON_BE(2 * image->GetHeight()); } hdr.planes = wxUINT16_SWAP_ON_BE(1); // always 1 plane hdr.bpp = wxUINT16_SWAP_ON_BE(bpp); hdr.compression = 0; // RGB uncompressed hdr.size_of_bmp = wxUINT32_SWAP_ON_BE(row_width * image->GetHeight()); // get the resolution from the image options or fall back to 72dpi standard // for the BMP format if not specified int hres, vres; switch ( GetResolutionFromOptions(*image, &hres, &vres) ) { default: wxFAIL_MSG( wxT("unexpected image resolution units") ); // fall through case wxIMAGE_RESOLUTION_NONE: hres = vres = 72; // fall through to convert it to correct units case wxIMAGE_RESOLUTION_INCHES: // convert resolution in inches to resolution in centimeters hres = (int)(10*mm2inches*hres); vres = (int)(10*mm2inches*vres); // fall through to convert it to resolution in meters case wxIMAGE_RESOLUTION_CM: // convert resolution in centimeters to resolution in meters hres *= 100; vres *= 100; break; } hdr.h_res = wxUINT32_SWAP_ON_BE(hres); hdr.v_res = wxUINT32_SWAP_ON_BE(vres); hdr.num_clrs = wxUINT32_SWAP_ON_BE(palette_size); // # colors in colormap hdr.num_signif_clrs = 0; // all colors are significant if ( IsBmp ) { if (// VS: looks ugly but compilers tend to do ugly things with structs, // like aligning hdr.filesize's ofset to dword :( // VZ: we should add padding then... !stream.Write(&hdr.magic, 2) || !stream.Write(&hdr.filesize, 4) || !stream.Write(&hdr.reserved, 4) || !stream.Write(&hdr.data_offset, 4) ) { if (verbose) { wxLogError(_("BMP: Couldn't write the file (Bitmap) header.")); } return false; } } if ( !IsMask ) { if ( !stream.Write(&hdr.bih_size, 4) || !stream.Write(&hdr.width, 4) || !stream.Write(&hdr.height, 4) || !stream.Write(&hdr.planes, 2) || !stream.Write(&hdr.bpp, 2) || !stream.Write(&hdr.compression, 4) || !stream.Write(&hdr.size_of_bmp, 4) || !stream.Write(&hdr.h_res, 4) || !stream.Write(&hdr.v_res, 4) || !stream.Write(&hdr.num_clrs, 4) || !stream.Write(&hdr.num_signif_clrs, 4) ) { if (verbose) { wxLogError(_("BMP: Couldn't write the file (BitmapInfo) header.")); } return false; } } wxPalette *palette = NULL; // entries for quantized images wxUint8 *rgbquad = NULL; // for the RGBQUAD bytes for the colormap wxImage *q_image = NULL; // destination for quantized image // if <24bpp use quantization to reduce colors for *some* of the formats if ( (format == wxBMP_1BPP) || (format == wxBMP_4BPP) || (format == wxBMP_8BPP) || (format == wxBMP_8BPP_PALETTE) ) { // make a new palette and quantize the image if (format != wxBMP_8BPP_PALETTE) { q_image = new wxImage(); // I get a delete error using Quantize when desired colors > 236 int quantize = ((palette_size > 236) ? 236 : palette_size); // fill the destination too, it gives much nicer 4bpp images wxQuantize::Quantize( *image, *q_image, &palette, quantize, 0, wxQUANTIZE_FILL_DESTINATION_IMAGE ); } else { #if wxUSE_PALETTE palette = new wxPalette(image->GetPalette()); #endif // wxUSE_PALETTE } int i; unsigned char r, g, b; rgbquad = new wxUint8 [palette_size*4]; for (i = 0; i < palette_size; i++) { #if wxUSE_PALETTE if ( !palette->GetRGB(i, &r, &g, &b) ) #endif // wxUSE_PALETTE r = g = b = 0; rgbquad[i*4] = b; rgbquad[i*4+1] = g; rgbquad[i*4+2] = r; rgbquad[i*4+3] = 0; } } // make a 256 entry greyscale colormap or 2 entry black & white else if ( (format == wxBMP_8BPP_GREY) || (format == wxBMP_8BPP_RED) || (format == wxBMP_1BPP_BW) ) { rgbquad = new wxUint8 [palette_size*4]; for ( int i = 0; i < palette_size; i++ ) { // if 1BPP_BW then the value should be either 0 or 255 wxUint8 c = (wxUint8)((i > 0) && (format == wxBMP_1BPP_BW) ? 255 : i); rgbquad[i*4] = rgbquad[i*4+1] = rgbquad[i*4+2] = c; rgbquad[i*4+3] = 0; } } // if the colormap was made, then it needs to be written if (rgbquad) { if ( !IsMask ) { if ( !stream.Write(rgbquad, palette_size*4) ) { if (verbose) { wxLogError(_("BMP: Couldn't write RGB color map.")); } delete[] rgbquad; #if wxUSE_PALETTE delete palette; #endif // wxUSE_PALETTE delete q_image; return false; } } delete []rgbquad; } // pointer to the image data, use quantized if available wxUint8 *data = (wxUint8*) image->GetData(); if (q_image) if (q_image->Ok()) data = (wxUint8*) q_image->GetData(); wxUint8 *buffer = new wxUint8[row_width]; memset(buffer, 0, row_width); int y; unsigned x; long int pixel; for (y = image->GetHeight() -1; y >= 0; y--) { if ( format == wxBMP_24BPP ) // 3 bytes per pixel red,green,blue { for ( x = 0; x < width; x++ ) { pixel = 3*(y*width + x); buffer[3*x ] = data[pixel+2]; buffer[3*x + 1] = data[pixel+1]; buffer[3*x + 2] = data[pixel]; } } else if ((format == wxBMP_8BPP) || // 1 byte per pixel in color (format == wxBMP_8BPP_PALETTE)) { for (x = 0; x < width; x++) { pixel = 3*(y*width + x); #if wxUSE_PALETTE buffer[x] = (wxUint8)palette->GetPixel( data[pixel], data[pixel+1], data[pixel+2] ); #else // FIXME: what should this be? use some std palette maybe? buffer[x] = 0; #endif // wxUSE_PALETTE } } else if ( format == wxBMP_8BPP_GREY ) // 1 byte per pix, rgb ave to grey { for (x = 0; x < width; x++) { pixel = 3*(y*width + x); buffer[x] = (wxUint8)(.299*data[pixel] + .587*data[pixel+1] + .114*data[pixel+2]); } } else if ( format == wxBMP_8BPP_RED ) // 1 byte per pixel, red as greys { for (x = 0; x < width; x++) { buffer[x] = (wxUint8)data[3*(y*width + x)]; } } else if ( format == wxBMP_4BPP ) // 4 bpp in color { for (x = 0; x < width; x+=2) { pixel = 3*(y*width + x); // fill buffer, ignore if > width #if wxUSE_PALETTE buffer[x/2] = (wxUint8)( ((wxUint8)palette->GetPixel(data[pixel], data[pixel+1], data[pixel+2]) << 4) | (((x+1) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+3], data[pixel+4], data[pixel+5]) )) ); #else // FIXME: what should this be? use some std palette maybe? buffer[x/2] = 0; #endif // wxUSE_PALETTE } } else if ( format == wxBMP_1BPP ) // 1 bpp in "color" { for (x = 0; x < width; x+=8) { pixel = 3*(y*width + x); #if wxUSE_PALETTE buffer[x/8] = (wxUint8)( ((wxUint8)palette->GetPixel(data[pixel], data[pixel+1], data[pixel+2]) << 7) | (((x+1) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+3], data[pixel+4], data[pixel+5]) << 6)) | (((x+2) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+6], data[pixel+7], data[pixel+8]) << 5)) | (((x+3) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+9], data[pixel+10], data[pixel+11]) << 4)) | (((x+4) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+12], data[pixel+13], data[pixel+14]) << 3)) | (((x+5) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+15], data[pixel+16], data[pixel+17]) << 2)) | (((x+6) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+18], data[pixel+19], data[pixel+20]) << 1)) | (((x+7) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+21], data[pixel+22], data[pixel+23]) )) ); #else // FIXME: what should this be? use some std palette maybe? buffer[x/8] = 0; #endif // wxUSE_PALETTE } } else if ( format == wxBMP_1BPP_BW ) // 1 bpp B&W colormap from red color ONLY { for (x = 0; x < width; x+=8) { pixel = 3*(y*width + x); buffer[x/8] = (wxUint8)( (((wxUint8)(data[pixel] /128.)) << 7) | (((x+1) > width) ? 0 : (((wxUint8)(data[pixel+3] /128.)) << 6)) | (((x+2) > width) ? 0 : (((wxUint8)(data[pixel+6] /128.)) << 5)) | (((x+3) > width) ? 0 : (((wxUint8)(data[pixel+9] /128.)) << 4)) | (((x+4) > width) ? 0 : (((wxUint8)(data[pixel+12]/128.)) << 3)) | (((x+5) > width) ? 0 : (((wxUint8)(data[pixel+15]/128.)) << 2)) | (((x+6) > width) ? 0 : (((wxUint8)(data[pixel+18]/128.)) << 1)) | (((x+7) > width) ? 0 : (((wxUint8)(data[pixel+21]/128.)) )) ); } } if ( !stream.Write(buffer, row_width) ) { if (verbose) { wxLogError(_("BMP: Couldn't write data.")); } delete[] buffer; #if wxUSE_PALETTE delete palette; #endif // wxUSE_PALETTE delete q_image; return false; } } delete[] buffer; #if wxUSE_PALETTE delete palette; #endif // wxUSE_PALETTE delete q_image; return true; }
bool MusBinOutput::WriteStaff( const MusStaff *staff ) { unsigned int k; uint32 = wxUINT32_SWAP_ON_BE( staff->nblement ); Write( &uint32, 4 ); uint16 = wxUINT16_SWAP_ON_BE( staff->voix ); Write( &uint16, 2 ); uint16 = wxUINT16_SWAP_ON_BE( staff->noGrp ); Write( &uint16, 2 ); uint16 = wxUINT16_SWAP_ON_BE( staff->totGrp ); Write( &uint16, 2 ); uint16 = wxUINT16_SWAP_ON_BE( staff->noLigne ); Write( &uint16, 2 ); uint16 = wxUINT16_SWAP_ON_BE( staff->no ); Write( &uint16, 2 ); Write( &staff->armTyp, 1 ); Write( &staff->armNbr, 1 ); Write( &staff->notAnc, 1 ); Write( &staff->grise, 1 ); Write( &staff->invisible, 1 ); uint16 = wxUINT16_SWAP_ON_BE( staff->ecart ); Write( &uint16, 2 ); Write( &staff->vertBarre, 1 ); Write( &staff->brace, 1 ); Write( &staff->pTaille, 1 ); int32 = wxINT32_SWAP_ON_BE( staff->indent ); Write( &int32, 4 ); Write( &staff->indentDroite, 1 ); Write( &staff->portNbLine, 1 ); Write( &staff->accol, 1 ); Write( &staff->accessoire, 1 ); uint16 = wxUINT16_SWAP_ON_BE( staff->reserve ); Write( &uint16, 2 ); for (k = 0;k < staff->nblement ; k++ ) { if ( staff->m_elements[k].IsNote() ) { WriteNote( (MusNote*)&staff->m_elements[k] ); } else if ( staff->m_elements[k].IsSymbol() ) { WriteSymbol( (MusSymbol*)&staff->m_elements[k] ); } else if ( staff->m_elements[k].IsNeume() ) { WriteNeume( (MusNeume*)&staff->m_elements[k] ); } if ( m_flag == MUS_BIN_ARUSPIX_CMP ) { MusElement *elem = &staff->m_elements[k]; int32 = wxINT32_SWAP_ON_BE( (int)elem->m_im_filename.Length() ); Write( &int32, 4 ); Write( elem->m_im_filename.c_str(), (int)elem->m_im_filename.Length() + 1 ); int32 = wxINT32_SWAP_ON_BE( elem->m_im_staff ); Write( &int32, 4 ); int32 = wxINT32_SWAP_ON_BE( elem->m_im_pos ); Write( &int32, 4 ); int32 = wxINT32_SWAP_ON_BE( elem->m_cmp_flag ); Write( &int32, 4 ); } } return true; }
void Extract(bool bits16, bool sign, bool stereo, bool bigendian, bool offset, char *rawData, int dataSize, float *data1, float *data2, int *len1, int *len2) { int rawCount = 0; int dataCount1 = 0; int dataCount2 = 0; int i; *len1 = 0; *len2 = 0; if (offset && bits16) { /* Special case so as to not flip stereo channels during analysis */ if (stereo && !bigendian) { rawData += 3; dataSize -= 3; } else { rawData++; dataSize--; } } if (bits16) { if (sign && bigendian) while (rawCount + 1 < dataSize) { /* 16-bit signed BE */ data1[dataCount1] = (wxINT16_SWAP_ON_LE(*((signed short *) &rawData[rawCount]))) / 32768.0; dataCount1++; rawCount += 2; } if (!sign && bigendian) while (rawCount + 1 < dataSize) { /* 16-bit unsigned BE */ data1[dataCount1] = (wxUINT16_SWAP_ON_LE(*((unsigned short *) &rawData[rawCount]))) / 32768.0 - 1.0; dataCount1++; rawCount += 2; } if (sign && !bigendian) while (rawCount + 1 < dataSize) { /* 16-bit signed LE */ data1[dataCount1] = (wxINT16_SWAP_ON_BE(*((signed short *) &rawData[rawCount]))) / 32768.0; dataCount1++; rawCount += 2; } if (!sign && !bigendian) while (rawCount + 1 < dataSize) { /* 16-bit unsigned LE */ data1[dataCount1] = (wxUINT16_SWAP_ON_BE(*((unsigned short *) &rawData[rawCount]))) / 32768.0 - 1.0; dataCount1++; rawCount += 2; } } else { /* 8-bit */ if (sign) { while (rawCount < dataSize) { /* 8-bit signed */ data1[dataCount1++] = (*(signed char *) (&rawData[rawCount++])) / 128.0; } } else { while (rawCount < dataSize) { /* 8-bit unsigned */ data1[dataCount1++] = (*(unsigned char *) &rawData[rawCount++]) / 128.0 - 1.0; } } } if (stereo) { dataCount1 /= 2; for(i=0; i<dataCount1; i++) { data2[i] = data1[2*i+1]; data1[i] = data1[2*i]; } dataCount2 = dataCount1; } *len1 = dataCount1; *len2 = dataCount2; }
bool DetectTextEncoding(const char* buffer, size_t len, wxFontEncoding& encoding, unsigned int& BOM_len) { wxASSERT(buffer); if (!buffer || len == 0) return false; const char* buff_ptr = buffer; const char* buff_end = &buffer[len]; wxFontEncoding enc = wxFONTENCODING_DEFAULT; // Check if the buffer starts with a BOM (Byte Order Marker) if (len >= 2) { if (len >= 4 && memcmp(buffer, "\xFF\xFE\x00\x00", 4) == 0) {enc = wxFONTENCODING_UTF32LE; BOM_len = 4;} else if (len >= 4 && memcmp(buffer, "\x00\x00\xFE\xFF", 4) == 0) {enc = wxFONTENCODING_UTF32BE; BOM_len = 4;} else if (memcmp(buffer, "\xFF\xFE", 2) == 0) {enc = wxFONTENCODING_UTF16LE; BOM_len = 2;} else if (memcmp(buffer, "\xFE\xFF", 2) == 0) {enc = wxFONTENCODING_UTF16BE; BOM_len = 2;} else if (len >= 3 && memcmp(buffer, "\xEF\xBB\xBF", 3) == 0) {enc = wxFONTENCODING_UTF8; BOM_len = 3;} else if (len >= 5 && memcmp(buffer, "\x2B\x2F\x76\x38\x2D", 5) == 0) {enc = wxFONTENCODING_UTF7; BOM_len = 5;} buff_ptr += BOM_len; } // If the file starts with a leading < (less) sign, it is probably an XML file // and we can determine the encoding by how the sign is encoded. if (enc == wxFONTENCODING_DEFAULT && len >= 2) { if (len >= 4 && memcmp(buffer, "\x3C\x00\x00\x00", 4) == 0) enc = wxFONTENCODING_UTF32LE; else if (len >= 4 && memcmp(buffer, "\x00\x00\x00\x3C", 4) == 0) enc = wxFONTENCODING_UTF32BE; else if (memcmp(buffer, "\x3C\x00", 2) == 0) enc = wxFONTENCODING_UTF16LE; else if (memcmp(buffer, "\x00\x3C", 2) == 0) enc = wxFONTENCODING_UTF16BE; } // Unicode Detection if (enc == wxFONTENCODING_DEFAULT) { unsigned int null_byte_count = 0; unsigned int utf_bytes = 0; unsigned int good_utf_count = 0; unsigned int bad_utf_count = 0; unsigned int bad_utf32_count = 0; unsigned int bad_utf16_count = 0; unsigned int nl_utf32le_count = 0; unsigned int nl_utf32be_count = 0; unsigned int nl_utf16le_count = 0; unsigned int nl_utf16be_count = 0; while (buff_ptr != buff_end) { if (*buff_ptr == 0) ++null_byte_count; // Detect UTF-8 by scanning for invalid sequences if (utf_bytes == 0) { if ((*buff_ptr & 0xC0) == 0x80 || *buff_ptr == 0) ++bad_utf_count; else { utf_bytes = utf8_len(*buff_ptr) - 1; if (utf_bytes > 3) { ++bad_utf_count; utf_bytes = 0; } } } else if ((*buff_ptr & 0xC0) == 0x80) { --utf_bytes; if (utf_bytes == 0) ++good_utf_count; } else { ++bad_utf_count; utf_bytes = 0; } // Detect UTF-32 by scanning for newlines (and lack of null chars) if ((uintptr_t)buff_ptr % 4 == 0 && buff_ptr+4 <= buff_end) { if (*((wxUint32*)buff_ptr) == 0) ++bad_utf32_count; if (*((wxUint32*)buff_ptr) == wxUINT32_SWAP_ON_BE(0x0A)) ++nl_utf32le_count; if (*((wxUint32*)buff_ptr) == wxUINT32_SWAP_ON_LE(0x0A)) ++nl_utf32be_count; } // Detect UTF-16 by scanning for newlines (and lack of null chars) if ((uintptr_t)buff_ptr % 2 == 0 && buff_ptr+4 <= buff_end) { if (*((wxUint16*)buff_ptr) == 0) ++bad_utf16_count; if (*((wxUint16*)buff_ptr) == wxUINT16_SWAP_ON_BE(0x0A)) ++nl_utf16le_count; if (*((wxUint16*)buff_ptr) == wxUINT16_SWAP_ON_LE(0x0A)) ++nl_utf16be_count; } ++buff_ptr; } if (bad_utf_count == 0) enc = wxFONTENCODING_UTF8; else if (bad_utf32_count == 0 && nl_utf32le_count > len / 400) enc = wxFONTENCODING_UTF32LE; else if (bad_utf32_count == 0 && nl_utf32be_count > len / 400) enc = wxFONTENCODING_UTF32BE; else if (bad_utf16_count == 0 && nl_utf16le_count > len / 200) enc = wxFONTENCODING_UTF16LE; else if (bad_utf16_count == 0 && nl_utf16be_count > len / 200) enc = wxFONTENCODING_UTF16BE; else if (null_byte_count) return false; // Maybe this is a binary file? } // If we can't detect encoding and it does not contain null bytes just set it to the default encoding. if (enc == wxFONTENCODING_DEFAULT) enc = wxFONTENCODING_SYSTEM; encoding = enc; return true; }
/* GZipArchive::write * Writes the gzip archive to a MemChunk * Returns true if successful, false otherwise *******************************************************************/ bool GZipArchive::write(MemChunk& mc, bool update) { // Clear current data mc.clear(); if (numEntries() == 1) { MemChunk stream; if (Compression::GZipDeflate(getEntry(0)->getMCData(), stream, 9)) { const uint8_t* data = stream.getData(); uint32_t working = 0; size_t size = stream.getSize(); if (size < 18) return false; // zlib will have given us a minimal header, so we make our own uint8_t header[4]; header[0] = GZIP_ID1; header[1] = GZIP_ID2; header[2] = GZIP_DEFLATE; header[3] = flags; mc.write(header, 4); // Update mtime if the file was modified if (getEntry(0)->getState()) { mtime = ::wxGetLocalTime(); } // Write mtime working = wxUINT32_SWAP_ON_BE(mtime); mc.write(&working, 4); // Write other stuff mc.write(&xfl, 1); mc.write(&os, 1); // Any extra content that may have been there if (flags & GZIP_FLG_FXTRA) { uint16_t xlen = wxUINT16_SWAP_ON_BE(xtra.getSize()); mc.write(&xlen, 2); mc.write(xtra.getData(), xtra.getSize()); } // File name, if not extrapolated from archive name if (flags & GZIP_FLG_FNAME) { mc.write(CHR(getEntry(0)->getName()), getEntry(0)->getName().length()); uint8_t zero = 0; mc.write(&zero, 1); // Terminate string } // Comment, if there were actually one if (flags & GZIP_FLG_FCMNT) { mc.write(CHR(comment), comment.length()); uint8_t zero = 0; mc.write(&zero, 1); // Terminate string } // And finally, the half CRC, which we recalculate if (flags & GZIP_FLG_FHCRC) { uint32_t fullcrc = Misc::crc(mc.getData(), mc.getSize()); uint16_t hcrc = (fullcrc & 0x0000FFFF); hcrc = wxUINT16_SWAP_ON_BE(hcrc); mc.write(&hcrc, 2); } // Now that the pleasantries are dispensed with, // let's get with the meat of the matter return mc.write(data + 10, size - 10); } } return false; }
bool OCPN_Sound::LoadWAV(const wxUint8 *data, size_t length, bool copyData) { // the simplest wave file header consists of 44 bytes: // // 0 "RIFF" // 4 file size - 8 // 8 "WAVE" // // 12 "fmt " // 16 chunk size | // 20 format tag | // 22 number of channels | // 24 sample rate | WAVEFORMAT // 28 average bytes per second | // 32 bytes per frame | // 34 bits per sample | // // 36 "data" // 40 number of data bytes // 44 (wave signal) data // // so check that we have at least as much if ( length < 44 ) return false; WAVEFORMAT waveformat; memcpy(&waveformat, &data[FMT_INDEX + 4], sizeof(WAVEFORMAT)); waveformat.uiSize = wxUINT32_SWAP_ON_BE(waveformat.uiSize); waveformat.uiFormatTag = wxUINT16_SWAP_ON_BE(waveformat.uiFormatTag); waveformat.uiChannels = wxUINT16_SWAP_ON_BE(waveformat.uiChannels); waveformat.ulSamplesPerSec = wxUINT32_SWAP_ON_BE(waveformat.ulSamplesPerSec); waveformat.ulAvgBytesPerSec = wxUINT32_SWAP_ON_BE(waveformat.ulAvgBytesPerSec); waveformat.uiBlockAlign = wxUINT16_SWAP_ON_BE(waveformat.uiBlockAlign); waveformat.uiBitsPerSample = wxUINT16_SWAP_ON_BE(waveformat.uiBitsPerSample); // get the sound data size wxUint32 ul; memcpy(&ul, &data[FMT_INDEX + waveformat.uiSize + 12], 4); ul = wxUINT32_SWAP_ON_BE(ul); if ( length < ul + FMT_INDEX + waveformat.uiSize + 16 ) return false; if (memcmp(data, "RIFF", 4) != 0) return false; if (memcmp(&data[WAVE_INDEX], "WAVE", 4) != 0) return false; if (memcmp(&data[FMT_INDEX], "fmt ", 4) != 0) return false; if (memcmp(&data[FMT_INDEX + waveformat.uiSize + 8], "data", 4) != 0) return false; if (waveformat.uiFormatTag != WAVE_FORMAT_PCM) return false; if (waveformat.ulSamplesPerSec != waveformat.ulAvgBytesPerSec / waveformat.uiBlockAlign) return false; m_osdata = new OCPNSoundData; m_osdata->m_dataWithHeader = NULL; m_osdata->m_channels = waveformat.uiChannels; m_osdata->m_samplingRate = waveformat.ulSamplesPerSec; m_osdata->m_bitsPerSample = waveformat.uiBitsPerSample; m_osdata->m_samples = ul / (m_osdata->m_channels * m_osdata->m_bitsPerSample / 8); m_osdata->m_dataBytes = ul; if (copyData) { m_osdata->m_dataWithHeader = new wxUint8[length]; memcpy(m_osdata->m_dataWithHeader, data, length); } else m_osdata->m_dataWithHeader = (wxUint8*)data; m_osdata->m_data = (&m_osdata->m_dataWithHeader[FMT_INDEX + waveformat.uiSize + 8]); return true; }
/* GZipArchive::isGZipArchive * Checks if the given data is a valid GZip archive *******************************************************************/ bool GZipArchive::isGZipArchive(MemChunk& mc) { // Minimal metadata size is 18: 10 for header, 8 for footer size_t mds = 18; size_t size = mc.getSize(); if (size < mds) return false; // Read header uint8_t header[4]; mc.read(header, 4); // Check for GZip header; we'll only accept deflated gzip files // and reject any field using unknown flags if (!(header[0] == GZIP_ID1 && header[1] == GZIP_ID2 && header[2] == GZIP_DEFLATE) || (header[3] & GZIP_FLG_FUNKN)) return false; bool ftext, fhcrc, fxtra, fname, fcmnt; ftext = (header[3] & GZIP_FLG_FTEXT) ? true : false; fhcrc = (header[3] & GZIP_FLG_FHCRC) ? true : false; fxtra = (header[3] & GZIP_FLG_FXTRA) ? true : false; fname = (header[3] & GZIP_FLG_FNAME) ? true : false; fcmnt = (header[3] & GZIP_FLG_FCMNT) ? true : false; uint32_t mtime; mc.read(&mtime, 4); uint8_t xfl; mc.read(&xfl, 1); uint8_t os; mc.read(&os, 1); // Skip extra fields which may be there if (fxtra) { uint16_t xlen; mc.read(&xlen, 2); xlen = wxUINT16_SWAP_ON_BE(xlen); mds += xlen + 2; if (mds > size) return false; mc.seek(xlen, SEEK_CUR); } // Skip past name, if any if (fname) { string name; char c; do { mc.read(&c, 1); if (c) name += c; ++mds; } while (c != 0 && size > mds); } // Skip past comment if (fcmnt) { string comment; char c; do { mc.read(&c, 1); if (c) comment += c; ++mds; } while (c != 0 && size > mds); } // Skip past CRC 16 check if (fhcrc) { uint16_t hcrc; mc.read(&hcrc, 2); mds += 2; } // Header is over if (mds > size || mc.currentPos() + 8 > size) return false; // If it's passed to here it's probably a gzip file return true; }
wxDataInputStream::wxDataInputStream(wxInputStream& s, const wxMBConv& conv) : m_input(&s), m_be_order(false), m_conv(conv.Clone()) #else wxDataInputStream::wxDataInputStream(wxInputStream& s) : m_input(&s), m_be_order(false) #endif { } wxDataInputStream::~wxDataInputStream() { #if wxUSE_UNICODE delete m_conv; #endif // wxUSE_UNICODE } #if wxHAS_INT64 wxUint64 wxDataInputStream::Read64() { wxUint64 tmp; Read64(&tmp, 1); return tmp; } #endif // wxHAS_INT64 wxUint32 wxDataInputStream::Read32() { wxUint32 i32; m_input->Read(&i32, 4); if (m_be_order) return wxUINT32_SWAP_ON_LE(i32); else return wxUINT32_SWAP_ON_BE(i32); } wxUint16 wxDataInputStream::Read16() { wxUint16 i16; m_input->Read(&i16, 2); if (m_be_order) return wxUINT16_SWAP_ON_LE(i16); else return wxUINT16_SWAP_ON_BE(i16); } wxUint8 wxDataInputStream::Read8() { wxUint8 buf; m_input->Read(&buf, 1); return (wxUint8)buf; } double wxDataInputStream::ReadDouble() { #if wxUSE_APPLE_IEEE char buf[10]; m_input->Read(buf, 10); return ConvertFromIeeeExtended((const wxInt8 *)buf); #else return 0.0; #endif }
bool MusBinInput::ReadStaff( MusStaff *staff ) { unsigned int k; Read( &uint32, 4 ); staff->nblement = wxUINT32_SWAP_ON_BE( uint32 ); Read( &uint16, 2 ); staff->voix = wxUINT16_SWAP_ON_BE( uint16 ); Read( &uint16, 2 ); staff->noGrp = wxUINT16_SWAP_ON_BE( uint16 ); Read( &uint16, 2 ); staff->totGrp = wxUINT16_SWAP_ON_BE( uint16 ); Read( &uint16, 2 ); staff->noLigne = wxUINT16_SWAP_ON_BE( uint16 ); Read( &uint16, 2 ); staff->no = wxUINT16_SWAP_ON_BE( uint16 ); Read( &staff->armTyp, 1 ); Read( &staff->armNbr, 1 ); Read( &staff->notAnc, 1 ); //staff->notAnc = true;// force notation ancienne Read( &staff->grise, 1 ); Read( &staff->invisible, 1 ); Read( &uint16, 2 ); staff->ecart = wxUINT16_SWAP_ON_BE( uint16 ); Read( &staff->vertBarre, 1 ); Read( &staff->brace, 1 ); Read( &staff->pTaille, 1 ); Read( &int32, 4 ); staff->indent = wxINT32_SWAP_ON_BE( int32 ); Read( &staff->indentDroite, 1 ); Read( &staff->portNbLine, 1 ); Read( &staff->accol, 1 ); Read( &staff->accessoire, 1 ); Read( &uint16, 2 ); staff->reserve = wxUINT16_SWAP_ON_BE( uint16 ); unsigned char c; for ( k = 0; k < staff->nblement; k++ ) { Read( &c, 1 ); if ( c == NOTE ) { MusNote *note = new MusNote(); note->no = k; ReadNote( note ); /* //Test code if ( (int)note->m_lyrics.GetCount() == 0 ){ MusSymbol *lyric = new MusSymbol(); lyric->flag = CHAINE; lyric->fonte = LYRIC; lyric->m_debord_str = "z"; lyric->xrel = note->xrel - 10; lyric->dec_y = - STAFF_OFFSET; //Add define for height lyric->offset = note->offset; lyric->m_note_ptr = note; note->m_lyrics.Add( lyric ); MusSymbol *lyric2 = new MusSymbol(); lyric2->flag = CHAINE; lyric2->fonte = LYRIC; lyric2->m_debord_str = "d"; lyric2->xrel = note->xrel; lyric2->dec_y = - STAFF_OFFSET; //Add define for height lyric2->offset = note->offset; lyric2->m_note_ptr = note; note->m_lyrics.Add( lyric2 ); } */ staff->m_elements.Add( note ); } else if ( c == SYMB ) { MusSymbol *symbol = new MusSymbol(); symbol->no = k; ReadSymbol( symbol ); staff->m_elements.Add( symbol ); } else if ( c == NEUME ) { MusNeume *neume = new MusNeume(); ReadNeume( neume ); staff->m_elements.Add( neume ); } if ( m_flag == MUS_BIN_ARUSPIX_CMP ) { MusElement *elem = &staff->m_elements.Last(); Read( &int32, 4 ); Read( elem->m_im_filename.GetWriteBuf( wxINT32_SWAP_ON_BE( int32 ) + 1 ) , wxINT32_SWAP_ON_BE( int32 ) + 1 ); elem->m_im_filename.UngetWriteBuf(); Read( &int32, 4 ); elem->m_im_staff = wxINT32_SWAP_ON_BE( int32 ); Read( &int32, 4 ); elem->m_im_pos = wxINT32_SWAP_ON_BE( int32 ); Read( &int32, 4 ); elem->m_cmp_flag = wxINT32_SWAP_ON_BE( int32 ); } } return true; }
// ----------------------------------------------------------------------------- // Reads Chasm bin format data from a MemChunk // Returns true if successful, false otherwise // ----------------------------------------------------------------------------- bool ChasmBinArchive::open(MemChunk& mc) { // Check given data is valid if (mc.getSize() < HEADER_SIZE) { return false; } // Read .bin header and check it char magic[4] = {}; mc.read(magic, sizeof magic); if (magic[0] != 'C' || magic[1] != 'S' || magic[2] != 'i' || magic[3] != 'd') { LOG_MESSAGE(1, "ChasmBinArchive::open: Opening failed, invalid header"); Global::error = "Invalid Chasm bin header"; return false; } // Stop announcements (don't want to be announcing modification due to entries being added etc) setMuted(true); uint16_t num_entries = 0; mc.read(&num_entries, sizeof num_entries); num_entries = wxUINT16_SWAP_ON_BE(num_entries); // Read the directory UI::setSplashProgressMessage("Reading Chasm bin archive data"); for (uint16_t i = 0; i < num_entries; ++i) { // Update splash window progress UI::setSplashProgress(static_cast<float>(i) / num_entries); // Read entry info char name[NAME_SIZE] = {}; mc.read(name, sizeof name); uint32_t size; mc.read(&size, sizeof size); size = wxUINT32_SWAP_ON_BE(size); uint32_t offset; mc.read(&offset, sizeof offset); offset = wxUINT32_SWAP_ON_BE(offset); // Check offset+size if (offset + size > mc.getSize()) { LOG_MESSAGE(1, "ChasmBinArchive::open: Bin archive is invalid or corrupt (entry goes past end of file)"); Global::error = "Archive is invalid and/or corrupt"; setMuted(false); return false; } // Convert Pascal to zero-terminated string memmove(name, name + 1, sizeof name - 1); name[sizeof name - 1] = '\0'; // Create entry ArchiveEntry* const entry = new ArchiveEntry(name, size); entry->exProp("Offset") = static_cast<int>(offset); entry->setLoaded(false); entry->setState(0); rootDir()->addEntry(entry); } // Detect all entry types UI::setSplashProgressMessage("Detecting entry types"); vector<ArchiveEntry*> all_entries; getEntryTreeAsList(all_entries); MemChunk edata; for (size_t i = 0; i < all_entries.size(); ++i) { // Update splash window progress UI::setSplashProgress(static_cast<float>(i) / num_entries); // Get entry ArchiveEntry* const entry = all_entries[i]; // Read entry data if it isn't zero-sized if (entry->getSize() > 0) { // Read the entry data mc.exportMemChunk(edata, static_cast<int>(entry->exProp("Offset")), entry->getSize()); entry->importMemChunk(edata); } // Detect entry type EntryType::detectEntryType(entry); fixBrokenWave(entry); // Unload entry data if needed if (!archive_load_data) { entry->unloadData(); } // Set entry to unchanged entry->setState(0); } // Setup variables setMuted(false); setModified(false); announce("opened"); UI::setSplashProgressMessage(""); return true; }
// Stolen from https://github.com/etexteditor/e/blob/master/src/Strings.cpp // and: https://github.com/etexteditor/e/blob/master/src/Utf.cpp // Copyright (c) 2009, Alexander Stigsen, e-texteditor.com (All rights reserved) // http://www.e-texteditor.com/ bool EncodingDetector::DetectEncodingEx(const wxByte* buffer, size_t size) { if (!buffer || size == 0) return false; const wxByte* buff_ptr = buffer; const wxByte* buff_end = &buffer[size]; wxFontEncoding enc = wxFONTENCODING_DEFAULT; // Check if the buffer starts with a BOM (Byte Order Marker) if (size >= 2) { if (size >= 4 && memcmp(buffer, "\xFF\xFE\x00\x00", 4) == 0) { enc = wxFONTENCODING_UTF32LE; m_BOMSizeInBytes = 4; m_UseBOM = true; } else if (size >= 4 && memcmp(buffer, "\xFE\xFF\x00\x00", 4) == 0) { // FE FF 00 00 UCS-4, unusual octet order BOM (3412) // X-ISO-10646-UCS-4-3412 can not (yet) be handled by wxWidgets enc = (wxFontEncoding)-1; } else if (size >= 4 && memcmp(buffer, "\x00\x00\xFE\xFF", 4) == 0) { enc = wxFONTENCODING_UTF32BE; m_BOMSizeInBytes = 4; m_UseBOM = true; } else if (size >= 4 && memcmp(buffer, "\x00\x00\xFF\xFE", 4) == 0) { // 00 00 FF FE UCS-4, unusual octet order BOM (2143) // X-ISO-10646-UCS-4-2143 can not (yet) be handled by wxWidgets enc = (wxFontEncoding)-1; } else if ( memcmp(buffer, "\xFF\xFE", 2) == 0) { enc = wxFONTENCODING_UTF16LE; m_BOMSizeInBytes = 2; m_UseBOM = true; } else if ( memcmp(buffer, "\xFE\xFF", 2) == 0) { enc = wxFONTENCODING_UTF16BE; m_BOMSizeInBytes = 2; m_UseBOM = true; } else if (size >= 3 && memcmp(buffer, "\xEF\xBB\xBF", 3) == 0) { enc = wxFONTENCODING_UTF8; m_BOMSizeInBytes = 3; m_UseBOM = true; } else if (size >= 5 && memcmp(buffer, "\x2B\x2F\x76\x38\x2D", 5) == 0) { enc = wxFONTENCODING_UTF7; m_BOMSizeInBytes = 5; m_UseBOM = true; } buff_ptr += m_BOMSizeInBytes; } // If the file starts with a leading < (less) sign, it is probably an XML file // and we can determine the encoding by how the sign is encoded. if (enc == wxFONTENCODING_DEFAULT && size >= 2) { if (size >= 4 && memcmp(buffer, "\x3C\x00\x00\x00", 4) == 0) enc = wxFONTENCODING_UTF32LE; else if (size >= 4 && memcmp(buffer, "\x00\x00\x00\x3C", 4) == 0) enc = wxFONTENCODING_UTF32BE; else if ( memcmp(buffer, "\x3C\x00", 2) == 0) enc = wxFONTENCODING_UTF16LE; else if ( memcmp(buffer, "\x00\x3C", 2) == 0) enc = wxFONTENCODING_UTF16BE; } // Unicode Detection if (enc == wxFONTENCODING_DEFAULT) { unsigned int null_byte_count = 0; unsigned int utf_bytes = 0; unsigned int good_utf_count = 0; unsigned int bad_utf_count = 0; unsigned int bad_utf32_count = 0; unsigned int bad_utf16_count = 0; unsigned int nl_utf32le_count = 0; unsigned int nl_utf32be_count = 0; unsigned int nl_utf16le_count = 0; unsigned int nl_utf16be_count = 0; while (buff_ptr != buff_end) { if (*buff_ptr == 0) ++null_byte_count; // Detect UTF-8 by scanning for invalid sequences if (utf_bytes == 0) { if ((*buff_ptr & 0xC0) == 0x80 || *buff_ptr == 0) ++bad_utf_count; else { const char c = *buff_ptr; utf_bytes = 5; // invalid length if ((c & 0x80) == 0x00) utf_bytes = 1; else if ((c & 0xE0) == 0xC0) utf_bytes = 2; else if ((c & 0xF0) == 0xE0) utf_bytes = 3; else if ((c & 0xF8) == 0xF0) utf_bytes = 4; if (utf_bytes > 3) { ++bad_utf_count; utf_bytes = 0; } } } else if ((*buff_ptr & 0xC0) == 0x80) { --utf_bytes; if (utf_bytes == 0) ++good_utf_count; } else { ++bad_utf_count; utf_bytes = 0; } // Detect UTF-32 by scanning for newlines (and lack of null chars) if ((wxUIntPtr)buff_ptr % 4 == 0 && buff_ptr+4 <= buff_end) { if (*((wxUint32*)buff_ptr) == 0 ) ++bad_utf32_count; if (*((wxUint32*)buff_ptr) == wxUINT32_SWAP_ON_BE(0x0A)) ++nl_utf32le_count; if (*((wxUint32*)buff_ptr) == wxUINT32_SWAP_ON_LE(0x0A)) ++nl_utf32be_count; } // Detect UTF-16 by scanning for newlines (and lack of null chars) if ((wxUIntPtr)buff_ptr % 2 == 0 && buff_ptr+4 <= buff_end) { if (*((wxUint16*)buff_ptr) == 0) ++bad_utf16_count; if (*((wxUint16*)buff_ptr) == wxUINT16_SWAP_ON_BE(0x0A)) ++nl_utf16le_count; if (*((wxUint16*)buff_ptr) == wxUINT16_SWAP_ON_LE(0x0A)) ++nl_utf16be_count; } ++buff_ptr; } if (bad_utf_count == 0) enc = wxFONTENCODING_UTF8; else if (bad_utf32_count == 0 && nl_utf32le_count > size / 400) enc = wxFONTENCODING_UTF32LE; else if (bad_utf32_count == 0 && nl_utf32be_count > size / 400) enc = wxFONTENCODING_UTF32BE; else if (bad_utf16_count == 0 && nl_utf16le_count > size / 200) enc = wxFONTENCODING_UTF16LE; else if (bad_utf16_count == 0 && nl_utf16be_count > size / 200) enc = wxFONTENCODING_UTF16BE; else if (null_byte_count) return false; // Maybe this is a binary file? } if (enc != wxFONTENCODING_DEFAULT) { m_Encoding = enc; // Success. return true; } // If we can't detect encoding and it does not contain null bytes // just ignore it and try backup-procedures (Mozilla) later... return false; }