inline BOOL write(const U8* item) { ENDIAN_SWAP_32(&item[ 0], &swapped[ 0]); // R ENDIAN_SWAP_32(&item[ 2], &swapped[ 2]); // G ENDIAN_SWAP_32(&item[ 4], &swapped[ 4]); // B return outstream->putBytes(swapped, 6); };
inline void read(U8* item) { instream->getBytes(swapped, 6); ENDIAN_SWAP_32(&swapped[ 0], &item[ 0]); // R ENDIAN_SWAP_32(&swapped[ 2], &item[ 2]); // G ENDIAN_SWAP_32(&swapped[ 4], &item[ 4]); // B };
inline void read(U8* item) { instream->getBytes(swapped, 20); ENDIAN_SWAP_32(&swapped[ 0], &item[ 0]); // x ENDIAN_SWAP_32(&swapped[ 4], &item[ 4]); // y ENDIAN_SWAP_32(&swapped[ 8], &item[ 8]); // z ENDIAN_SWAP_16(&swapped[12], &item[12]); // intensity *((U32*)&item[14]) = *((U32*)&swapped[14]); // bitfield, classification, scan_angle_rank, user_data ENDIAN_SWAP_16(&swapped[18], &item[18]); // point_source_ID };
inline BOOL write(const U8* item) { ENDIAN_SWAP_32(&item[ 0], &swapped[ 0]); // x ENDIAN_SWAP_32(&item[ 4], &swapped[ 4]); // y ENDIAN_SWAP_32(&item[ 8], &swapped[ 8]); // z ENDIAN_SWAP_16(&item[12], &swapped[12]); // intensity *((U32*)&swapped[14]) = *((U32*)&item[14]); // bitfield, classification, scan_angle_rank, user_data ENDIAN_SWAP_16(&item[18], &swapped[18]); // point_source_ID return outstream->putBytes(swapped, 20); };
inline void read(U8* item) { instream->getBytes(swapped, 29); item[0] = swapped[0]; // wavepacket descriptor index ENDIAN_SWAP_64(&swapped[ 1], &item[ 1]); // byte offset to waveform data ENDIAN_SWAP_32(&swapped[ 9], &item[ 9]); // waveform packet size in bytes ENDIAN_SWAP_32(&swapped[13], &item[13]); // return point waveform location ENDIAN_SWAP_32(&swapped[17], &item[17]); // X(t) ENDIAN_SWAP_32(&swapped[21], &item[21]); // Y(t) ENDIAN_SWAP_32(&swapped[25], &item[25]); // Z(t) };
inline BOOL write(const U8* item) { swapped[0] = item[0]; // wavepacket descriptor index ENDIAN_SWAP_64(&item[ 1], &swapped[ 1]); // byte offset to waveform data ENDIAN_SWAP_32(&item[ 9], &swapped[ 9]); // waveform packet size in bytes ENDIAN_SWAP_32(&item[13], &swapped[13]); // return point waveform location ENDIAN_SWAP_32(&item[17], &swapped[17]); // X(t) ENDIAN_SWAP_32(&item[21], &swapped[21]); // Y(t) ENDIAN_SWAP_32(&item[25], &swapped[25]); // Z(t) return outstream->putBytes(swapped, 29); };
uint32 CFileDataIO::ReadUInt32() const { uint32 value = 0; Read(&value, sizeof(uint32)); return ENDIAN_SWAP_32(value); }
int CEncryptedDatagramSocket::EncryptSendServer(uint8_t** ppbyBuf, int nBufLen, uint32_t dwBaseKey) { wxASSERT( thePrefs::IsServerCryptLayerUDPEnabled() ); wxASSERT( dwBaseKey != 0 ); uint16_t nRandomKeyPart = GetRandomUint16(); uint8_t achKeyData[7]; PokeUInt32(achKeyData, dwBaseKey); achKeyData[4] = MAGICVALUE_UDP_CLIENTSERVER; PokeUInt16(achKeyData + 5, nRandomKeyPart); MD5Sum md5(achKeyData, sizeof(achKeyData)); CRC4EncryptableBuffer sendbuffer; sendbuffer.SetKey(md5, true); // create the semi random byte encryption header uint8_t bySemiRandomNotProtocolMarker = 0; int i; for (i = 0; i < 128; i++) { bySemiRandomNotProtocolMarker = GetRandomUint8(); if (bySemiRandomNotProtocolMarker != OP_EDONKEYPROT) { // not allowed values break; } } if (i >= 128) { // either we have _real_ bad luck or the randomgenerator is a bit messed up wxFAIL; bySemiRandomNotProtocolMarker = 0x01; } uint8_t byPadLen = 0; // padding disabled for UDP currently uint32_t nCryptedLen = nBufLen + byPadLen + CRYPT_HEADER_WITHOUTPADDING; uint8_t* pachCryptedBuffer = new uint8_t[nCryptedLen]; pachCryptedBuffer[0] = bySemiRandomNotProtocolMarker; PokeUInt16(pachCryptedBuffer + 1, nRandomKeyPart); uint32_t dwMagicValue = ENDIAN_SWAP_32(MAGICVALUE_UDP_SYNC_SERVER); sendbuffer.RC4Crypt((uint8_t*)&dwMagicValue, pachCryptedBuffer + 3, 4); sendbuffer.RC4Crypt((uint8_t*)&byPadLen, pachCryptedBuffer + 7, 1); for (int j = 0; j < byPadLen; j++){ uint8_t byRand = (uint8_t)rand(); // they actually don't really need to be random, but it doesn't hurt either sendbuffer.RC4Crypt((uint8_t*)&byRand, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + j, 1); } sendbuffer.RC4Crypt(*ppbyBuf, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + byPadLen, nBufLen); delete[] *ppbyBuf; *ppbyBuf = pachCryptedBuffer; theStats::AddUpOverheadCrypt(nCryptedLen - nBufLen); return nCryptedLen; }
bool SoundBuffer::LoadWAV(const std::string & filename, const SoundInfo & sound_device_info, std::ostream & error_output) { if (loaded) Unload(); name = filename; FILE *fp; unsigned int size; fp = fopen(filename.c_str(), "rb"); if (fp) { char id[5]; //four bytes to hold 'RIFF' if (fread(id,sizeof(char),4,fp) != 4) return false; //read in first four bytes id[4] = '\0'; if (!strcmp(id,"RIFF")) { //we had 'RIFF' let's continue if (fread(&size,sizeof(unsigned int),1,fp) != 1) return false; //read in 32bit size value size = ENDIAN_SWAP_32(size); if (fread(id,sizeof(char),4,fp)!= 4) return false; //read in 4 byte string now if (!strcmp(id,"WAVE")) { //this is probably a wave file since it contained "WAVE" if (fread(id,sizeof(char),4,fp)!= 4) return false; //read in 4 bytes "fmt "; if (!strcmp(id,"fmt ")) { unsigned int format_length, sample_rate, avg_bytes_sec; short format_tag, channels, block_align, bits_per_sample; if (fread(&format_length, sizeof(unsigned int),1,fp) != 1) return false; format_length = ENDIAN_SWAP_32(format_length); if (fread(&format_tag, sizeof(short), 1, fp) != 1) return false; format_tag = ENDIAN_SWAP_16(format_tag); if (fread(&channels, sizeof(short),1,fp) != 1) return false; channels = ENDIAN_SWAP_16(channels); if (fread(&sample_rate, sizeof(unsigned int), 1, fp) != 1) return false; sample_rate = ENDIAN_SWAP_32(sample_rate); if (fread(&avg_bytes_sec, sizeof(unsigned int), 1, fp) != 1) return false; avg_bytes_sec = ENDIAN_SWAP_32(avg_bytes_sec); if (fread(&block_align, sizeof(short), 1, fp) != 1) return false; block_align = ENDIAN_SWAP_16(block_align); if (fread(&bits_per_sample, sizeof(short), 1, fp) != 1) return false; bits_per_sample = ENDIAN_SWAP_16(bits_per_sample); //new wave seeking code //find data chunk bool found_data_chunk = false; long filepos = format_length + 4 + 4 + 4 + 4 + 4; int chunknum = 0; while (!found_data_chunk && chunknum < 10) { fseek(fp, filepos, SEEK_SET); //seek to the next chunk if (fread(id, sizeof(char), 4, fp) != 4) return false; //read in 'data' if (fread(&size, sizeof(unsigned int), 1, fp) != 1) return false; //how many bytes of sound data we have size = ENDIAN_SWAP_32(size); if (!strcmp(id,"data")) { found_data_chunk = true; } else { filepos += size + 4 + 4; } chunknum++; } if (chunknum >= 10) { //cerr << __FILE__ << "," << __LINE__ << ": Sound file contains more than 10 chunks before the data chunk: " + filename << std::endl; error_output << "Couldn't find wave data in first 10 chunks of " << filename << std::endl; return false; } sound_buffer = new char[size]; if (fread(sound_buffer, sizeof(char), size, fp) != size) return false; //read in our whole sound data chunk #if SDL_BYTEORDER == SDL_BIG_ENDIAN if (bits_per_sample == 16) { for (unsigned int i = 0; i < size/2; i++) { //cout << "preswap i: " << sound_buffer[i] << "preswap i+1: " << sound_buffer[i+1] << std::endl; //short preswap = ((short *)sound_buffer)[i]; ((short *)sound_buffer)[i] = ENDIAN_SWAP_16(((short *)sound_buffer)[i]); //cout << "postswap i: " << sound_buffer[i] << "postswap i+1: " << sound_buffer[i+1] << std::endl; //cout << (int) i << "/" << (int) size << std::endl; //short postswap = ((short *)sound_buffer)[i]; //cout << preswap << "/" << postswap << std::endl; } } //else if (bits_per_sample != 8) else { error_output << "Sound file with " << bits_per_sample << " bits per sample not supported" << std::endl; return false; } #endif info = SoundInfo(size/(bits_per_sample/8), sample_rate, channels, bits_per_sample/8); SoundInfo original_info(size/(bits_per_sample/8), sample_rate, channels, bits_per_sample/8); loaded = true; SoundInfo desired_info(original_info.samples, sound_device_info.frequency, original_info.channels, sound_device_info.bytespersample); //ConvertTo(desired_info); if (desired_info == original_info) { } else { error_output << "SOUND FORMAT:" << std::endl; original_info.DebugPrint(error_output); error_output << "DESIRED FORMAT:" << std::endl; desired_info.DebugPrint(error_output); //throw EXCEPTION(__FILE__, __LINE__, "Sound file isn't in desired format: " + filename); //cerr << __FILE__ << "," << __LINE__ << ": Sound file isn't in desired format: " + filename << std::endl; error_output << "Sound file isn't in desired format: "+filename << std::endl; return false; } } else { //throw EXCEPTION(__FILE__, __LINE__, "Sound file doesn't have \"fmt \" header: " + filename); //cerr << __FILE__ << "," << __LINE__ << ": Sound file doesn't have \"fmt \" header: " + filename << std::endl; error_output << "Sound file doesn't have \"fmt\" header: "+filename << std::endl; return false; } } else { //throw EXCEPTION(__FILE__, __LINE__, "Sound file doesn't have WAVE header: " + filename); //cerr << __FILE__ << "," << __LINE__ << ": Sound file doesn't have WAVE header: " + filename << std::endl; error_output << "Sound file doesn't have WAVE header: "+filename << std::endl; return false; } } else { //throw EXCEPTION(__FILE__, __LINE__, "Sound file doesn't have RIFF header: " + filename); //cerr << __FILE__ << "," << __LINE__ << ": Sound file doesn't have WAVE header: " + filename << std::endl; error_output << "Sound file doesn't have RIFF header: "+filename << std::endl; return false; } fclose(fp); } else { //throw EXCEPTION(__FILE__, __LINE__, "Can't open sound file: " + filename); //cerr << __FILE__ << "," << __LINE__ << ": Can't open sound file: " + filename << std::endl; error_output << "Can't open sound file: "+filename << std::endl; return false; } //cout << size << std::endl; return true; }
// Encrypt packet. Key used: // clientHashOrKadID != NULL -> clientHashOrKadID // clientHashOrKadID == NULL && kad && receiverVerifyKey != 0 -> receiverVerifyKey // else -> ASSERT int CEncryptedDatagramSocket::EncryptSendClient(uint8_t **buf, int bufLen, const uint8_t *clientHashOrKadID, bool kad, uint32_t receiverVerifyKey, uint32_t senderVerifyKey) { wxASSERT(theApp->GetPublicIP() != 0 || kad); wxASSERT(thePrefs::IsClientCryptLayerSupported()); wxASSERT(clientHashOrKadID != NULL || receiverVerifyKey != 0); wxASSERT((receiverVerifyKey == 0 && senderVerifyKey == 0) || kad); uint8_t padLen = 0; // padding disabled for UDP currently const uint32_t cryptHeaderLen = padLen + CRYPT_HEADER_WITHOUTPADDING + (kad ? 8 : 0); uint32_t cryptedLen = bufLen + cryptHeaderLen; uint8_t *cryptedBuffer = new uint8_t[cryptedLen]; bool kadRecvKeyUsed = false; uint16_t randomKeyPart = GetRandomUint16(); CRC4EncryptableBuffer sendbuffer; MD5Sum md5; if (kad) { if ((clientHashOrKadID == NULL || CMD4Hash(clientHashOrKadID).IsEmpty()) && receiverVerifyKey != 0) { kadRecvKeyUsed = true; uint8_t keyData[6]; PokeUInt32(keyData, receiverVerifyKey); PokeUInt16(keyData+4, randomKeyPart); md5.Calculate(keyData, sizeof(keyData)); //DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by ReceiverKey (%u)"), nReceiverVerifyKey) ); } else if (clientHashOrKadID != NULL && !CMD4Hash(clientHashOrKadID).IsEmpty()) { uint8_t keyData[18]; md4cpy(keyData, clientHashOrKadID); PokeUInt16(keyData+16, randomKeyPart); md5.Calculate(keyData, sizeof(keyData)); //DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by Hash/NodeID %s"), md4str(pachClientHashOrKadID)) ); } else { delete [] cryptedBuffer; wxFAIL; return bufLen; } } else { uint8_t keyData[23]; md4cpy(keyData, clientHashOrKadID); PokeUInt32(keyData+16, theApp->GetPublicIP()); PokeUInt16(keyData+21, randomKeyPart); keyData[20] = MAGICVALUE_UDP; md5.Calculate(keyData, sizeof(keyData)); } sendbuffer.SetKey(md5, true); // create the semi random byte encryption header uint8_t semiRandomNotProtocolMarker = 0; int i; for (i = 0; i < 128; i++) { semiRandomNotProtocolMarker = GetRandomUint8(); semiRandomNotProtocolMarker = kad ? (semiRandomNotProtocolMarker & 0xFE) : (semiRandomNotProtocolMarker | 0x01); // set the ed2k/kad marker bit if (kad) { // set the ed2k/kad and nodeid/recvkey markerbit semiRandomNotProtocolMarker = kadRecvKeyUsed ? ((semiRandomNotProtocolMarker & 0xFE) | 0x02) : (semiRandomNotProtocolMarker & 0xFC); } else { // set the ed2k/kad marker bit semiRandomNotProtocolMarker = (semiRandomNotProtocolMarker | 0x01); } bool bOk = false; switch (semiRandomNotProtocolMarker) { // not allowed values case OP_EMULEPROT: case OP_KADEMLIAPACKEDPROT: case OP_KADEMLIAHEADER: case OP_UDPRESERVEDPROT1: case OP_UDPRESERVEDPROT2: case OP_PACKEDPROT: break; default: bOk = true; } if (bOk) { break; } } if (i >= 128) { // either we have _real_ bad luck or the randomgenerator is a bit messed up wxFAIL; semiRandomNotProtocolMarker = 0x01; } cryptedBuffer[0] = semiRandomNotProtocolMarker; PokeUInt16(cryptedBuffer + 1, randomKeyPart); uint32_t magicValue = ENDIAN_SWAP_32(MAGICVALUE_UDP_SYNC_CLIENT); sendbuffer.RC4Crypt((uint8_t*)&magicValue, cryptedBuffer + 3, 4); sendbuffer.RC4Crypt((uint8_t*)&padLen, cryptedBuffer + 7, 1); for (int j = 0; j < padLen; j++) { uint8_t byRand = (uint8_t)rand(); // they actually don't really need to be random, but it doesn't hurt either sendbuffer.RC4Crypt((uint8_t*)&byRand, cryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + j, 1); } if (kad) { ENDIAN_SWAP_I_32(receiverVerifyKey); ENDIAN_SWAP_I_32(senderVerifyKey); sendbuffer.RC4Crypt((uint8_t*)&receiverVerifyKey, cryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + padLen, 4); sendbuffer.RC4Crypt((uint8_t*)&senderVerifyKey, cryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + padLen + 4, 4); } sendbuffer.RC4Crypt(*buf, cryptedBuffer + cryptHeaderLen, bufLen); delete [] *buf; *buf = cryptedBuffer; theStats::AddUpOverheadCrypt(cryptedLen - bufLen); return cryptedLen; }
BOOL LASreaderQFIT::read_point_default() { if (p_count < npoints) { try { stream->getBytes((U8*)buffer, version); } catch(...) { fprintf(stderr,"ERROR: reading QFIT point after %u of %u\n", (U32)p_count, (U32)npoints); return FALSE; } if (endian_swap) { ENDIAN_SWAP_32((U8*)&buffer[0]); ENDIAN_SWAP_32((U8*)&buffer[1]); ENDIAN_SWAP_32((U8*)&buffer[2]); ENDIAN_SWAP_32((U8*)&buffer[3]); ENDIAN_SWAP_32((U8*)&buffer[5]); ENDIAN_SWAP_32((U8*)&buffer[6]); ENDIAN_SWAP_32((U8*)&buffer[7]); ENDIAN_SWAP_32((U8*)&buffer[8]); ENDIAN_SWAP_32((U8*)&buffer[9]); if (version >= 48) { ENDIAN_SWAP_32((U8*)&buffer[10]); ENDIAN_SWAP_32((U8*)&buffer[11]); } if (version >= 56) { ENDIAN_SWAP_32((U8*)&buffer[12]); ENDIAN_SWAP_32((U8*)&buffer[13]); } } point.gps_time = 0.001*buffer[0]; point.x = buffer[2]; if (point.x > 180000000) point.x -= 360000000; // convert LARGE positive east longitude to negative point.y = buffer[1]; point.z = buffer[3]; point.intensity = buffer[5]; point.scan_angle_rank = I8_CLAMP(I16_QUANTIZE((0.001*buffer[6])-180.0)); point.set_extra_attribute(scan_azimuth_array_offset, (I32)buffer[6]); point.set_extra_attribute(pitch_array_offset, (I32)buffer[7]); point.set_extra_attribute(roll_array_offset, (I32)buffer[8]); point.set_extra_attribute(pulse_width_array_offset, (U8)buffer[10]); if (!populated_header) { point.compute_coordinates(); // update bounding box if (point.coordinates[0] < header.min_x) header.min_x = point.coordinates[0]; else if (point.coordinates[0] > header.max_x) header.max_x = point.coordinates[0]; if (point.coordinates[1] < header.min_y) header.min_y = point.coordinates[1]; else if (point.coordinates[1] > header.max_y) header.max_y = point.coordinates[1]; if (point.coordinates[2] < header.min_z) header.min_z = point.coordinates[2]; else if (point.coordinates[2] > header.max_z) header.max_z = point.coordinates[2]; } p_count++; return TRUE; } populated_header = TRUE; return FALSE; }
BOOL LASreaderQFIT::open(ByteStreamIn* stream) { U32 i; if (stream == 0) { fprintf(stderr,"ERROR: ByteStreamIn* pointer is zero\n"); return FALSE; } this->stream = stream; // read the QFIT header try { stream->get32bitsLE((U8*)&version); } catch(...) { fprintf(stderr,"ERROR: reading QFIT header\n"); return FALSE; } // is QFIT file little-endian if (version == 40 || version == 48 || version == 56) { little_endian = TRUE; endian_swap = (IS_LITTLE_ENDIAN() == FALSE); } else { ENDIAN_SWAP_32((U8*)&version); if (version == 40 || version == 48 || version == 56) { little_endian = FALSE; endian_swap = (IS_LITTLE_ENDIAN() == TRUE); } else { fprintf(stderr,"ERROR: corrupt QFIT header.\n"); return FALSE; } } // read version bytes until point start offset try { stream->getBytes((U8*)buffer, version); } catch(...) { fprintf(stderr,"ERROR: reading %d bytes until point start offset from QFIT header\n", version); return FALSE; } // read point start offset try { if (little_endian) stream->get32bitsLE((U8*)&offset); else stream->get32bitsBE((U8*)&offset); } catch(...) { fprintf(stderr,"ERROR: reading point start offset from QFIT header\n"); return FALSE; } // seek to end of file find out number of points stream->seekEnd(); npoints = (stream->tell() - offset) / version; // seek back to start of points stream->seek(offset); // populate the header as much as possible sprintf(header.system_identifier, "LAStools (c) by Martin Isenburg"); sprintf(header.generating_software, "via LASreaderQFIT (%d)", LAS_TOOLS_VERSION); header.number_of_point_records = (U32)npoints; header.number_of_points_by_return[0] = header.number_of_point_records; header.extended_number_of_point_records = npoints; header.extended_number_of_points_by_return[0] = npoints; header.x_scale_factor = 0.000001; header.y_scale_factor = 0.000001; header.z_scale_factor = 0.001; header.x_offset = 0; header.y_offset = 0; header.z_offset = 0; try { LASattribute scan_azimuth(LAS_ATTRIBUTE_I32, "scan azimuth", "Scan Azimuth (degrees X 1,000)"); scan_azimuth.set_scale(0.001); scan_azimuth.set_min(0); scan_azimuth.set_max(360000); header.add_extra_attribute(scan_azimuth); } catch(...) { fprintf(stderr,"ERROR: initializing attribute scan_azimuth\n"); return FALSE; } try { LASattribute pitch(LAS_ATTRIBUTE_I32, "pitch", "Pitch (degrees X 1,000)"); pitch.set_scale(0.001); pitch.set_min(-90000); pitch.set_max(90000); header.add_extra_attribute(pitch); } catch(...) { fprintf(stderr,"ERROR: initializing attribute pitch\n"); return FALSE; } try { LASattribute roll(LAS_ATTRIBUTE_I32, "roll", "Roll (degrees X 1,000)"); roll.set_scale(0.001); roll.set_min(-90000); roll.set_max(90000); header.add_extra_attribute(roll); } catch(...) { fprintf(stderr,"ERROR: initializing attribute roll\n"); return FALSE; } if (version == 48) { try { LASattribute pulse_width(LAS_ATTRIBUTE_U8, "pulse width", "Pulse Width (digitizer samples)"); header.add_extra_attribute(pulse_width); } catch(...) { fprintf(stderr,"ERROR: initializing attribute pulse width\n"); return FALSE; } } header.update_extra_bytes_vlr(); // set point type header.point_data_format = 1; header.point_data_record_length = 28 + header.get_total_extra_attributes_size(); // initialize point point.init(&header, header.point_data_format, header.point_data_record_length, &header); // initialize extra attribute offsets scan_azimuth_array_offset = point.attributer->get_extra_attribute_array_offset("scan azimuth"); pitch_array_offset = point.attributer->get_extra_attribute_array_offset("pitch"); roll_array_offset = point.attributer->get_extra_attribute_array_offset("roll"); if (version == 48) { pulse_width_array_offset = point.attributer->get_extra_attribute_array_offset("pulse width"); } // set point count to zero p_count = 0; // approximate bounding box init populated_header = FALSE; if (!read_point()) return FALSE; header.min_x = header.max_x = point.get_x(); header.min_y = header.max_y = point.get_y(); header.min_z = header.max_z = point.get_z(); for (i = header.number_of_point_records/50; i < header.number_of_point_records; i += header.number_of_point_records/50) { if (!seek(i)) return FALSE; if (!read_point()) return FALSE; } return seek(0); }
bool SoundBuffer::LoadWAV(const std::string & filename, const SoundInfo & sound_device_info, std::ostream & error_output) { if (loaded) Unload(); name = filename; std::ifstream file(filename.c_str(), std::ifstream::binary); if (!file) { error_output << "Failed to open sound file: " << filename << std::endl; return false; } // read in first four bytes char id[5] = {'\0'}; file.read(id, 4); if (!file) { error_output << "Failed to read sound file RIFF header: " << filename << std::endl; return false; } if (strcmp(id, "RIFF")) { error_output << "Sound file doesn't have RIFF header: " << filename << std::endl; return false; } // read in 32bit size value unsigned int size = 0; file.read((char*)&size, sizeof(unsigned int)); size = ENDIAN_SWAP_32(size); if (!file) { error_output << "Failed to read sound file size: " << filename << std::endl; return false; } // read in 4 bytes "WAVE" file.read(id, 4); if (!file) { error_output << "Failed to read WAVE header: " << filename << std::endl; return false; } if (strcmp(id, "WAVE")) { error_output << "Sound file doesn't have WAVE header: " << filename << std::endl; return false; } // read in 4 bytes "fmt "; file.read(id, 4); if (!file) { error_output << "Failed to read \"fmt\" header: " << filename << std::endl; return false; } if (strcmp(id, "fmt ")) { error_output << "Sound file doesn't have \"fmt\" header: " << filename << std::endl; return false; } // read sound format unsigned int format_length, sample_rate, avg_bytes_sec; short format_tag, channels, block_align, bits_per_sample; file.read((char*)&format_length, sizeof(unsigned int)); file.read((char*)&format_tag, sizeof(short)); file.read((char*)&channels, sizeof(short)); file.read((char*)&sample_rate, sizeof(unsigned int)); file.read((char*)&avg_bytes_sec, sizeof(unsigned int)); file.read((char*)&block_align, sizeof(short)); file.read((char*)&bits_per_sample, sizeof(short)); if (!file) { error_output << "Failed to read sound format: " << filename << std::endl; return false; } format_length = ENDIAN_SWAP_32(format_length); format_tag = ENDIAN_SWAP_16(format_tag); channels = ENDIAN_SWAP_16(channels); sample_rate = ENDIAN_SWAP_32(sample_rate); avg_bytes_sec = ENDIAN_SWAP_32(avg_bytes_sec); block_align = ENDIAN_SWAP_16(block_align); bits_per_sample = ENDIAN_SWAP_16(bits_per_sample); // find data chunk bool found_data_chunk = false; long filepos = format_length + 4 + 4 + 4 + 4 + 4; int chunknum = 0; while (!found_data_chunk && chunknum < 10) { // seek to the next chunk file.seekg(filepos); // read in 'data' file.read(id, 4); if (!file) return false; // how many bytes of sound data we have file.read((char*)&size, sizeof(unsigned int)); if (!file) return false; size = ENDIAN_SWAP_32(size); if (!strcmp(id, "data")) found_data_chunk = true; else filepos += size + 4 + 4; chunknum++; } if (chunknum >= 10) { error_output << "Couldn't find wave data in first 10 chunks of " << filename << std::endl; return false; } // read in our whole sound data chunk sound_buffer = new char[size]; file.read(sound_buffer, size); if (!file) { error_output << "Failed to read wave data " << filename << std::endl; return false; } #if SDL_BYTEORDER == SDL_BIG_ENDIAN if (bits_per_sample == 16) { for (unsigned int i = 0; i < size / 2; i++) { ((short *)sound_buffer)[i] = ENDIAN_SWAP_16(((short *)sound_buffer)[i]); } } else { error_output << "Sound file with " << bits_per_sample << " bits per sample not supported" << std::endl; return false; } #endif info = SoundInfo(size/(bits_per_sample/8), sample_rate, channels, bits_per_sample/8); loaded = true; SoundInfo original_info(size/(bits_per_sample/8), sample_rate, channels, bits_per_sample/8); SoundInfo desired_info(original_info.samples, sound_device_info.frequency, original_info.channels, sound_device_info.bytespersample); if (!(desired_info == original_info)) { error_output << "SOUND FORMAT:" << std::endl; original_info.DebugPrint(error_output); error_output << "DESIRED FORMAT:" << std::endl; desired_info.DebugPrint(error_output); error_output << "Sound file isn't in desired format: " << filename << std::endl; return false; } return true; }