void Loader::LoadVertexList(Stream::IStream& stream) { Stream::EndianAwareFilter filter(stream); WORD wNumVertices = filter.Read16LE(); m_data.m_vecVertices.resize(wNumVertices); if (wNumVertices >= c_uiMaxVertices) throw Exception(_T("invalid number of vertices"), __FILE__, __LINE__); for (WORD w = 0; w<wNumVertices; w++) { Vertex& v = m_data.m_vecVertices[w]; BYTE bFlags = stream.ReadByte(); if ((bFlags & ~(flagSelected | flagSelected2 | flagHidden)) != 0) throw Exception(_T("invalid vertex flags"), __FILE__, __LINE__); float afVertex[3]; afVertex[0] = ReadFloat(stream); afVertex[1] = ReadFloat(stream); afVertex[2] = ReadFloat(stream); char cBoneId = static_cast<char>(stream.ReadByte()); /*BYTE bReferenceCount =*/ stream.ReadByte(); v.m_vPos = Vector3d(afVertex[0], afVertex[1], afVertex[2]); v.m_iJointIndex = cBoneId; } }
void Loader::LoadTriangleList(Stream::IStream& stream) { Stream::EndianAwareFilter filter(stream); WORD wNumTriangles = filter.Read16LE(); m_data.m_vecTriangles.resize(wNumTriangles); if (wNumTriangles >= c_uiMaxTriangles) throw Exception(_T("invalid number of triangles"), __FILE__, __LINE__); for (WORD w = 0; w<wNumTriangles; w++) { TriangleData t; t.wFlags = filter.Read16LE(); if ((t.wFlags & ~(flagSelected | flagSelected2 | flagHidden)) != 0) throw Exception(_T("invalid triangle flags"), __FILE__, __LINE__); t.awVertexIndices[0] = filter.Read16LE(); t.awVertexIndices[1] = filter.Read16LE(); t.awVertexIndices[2] = filter.Read16LE(); if (t.awVertexIndices[0] >= m_data.m_vecVertices.size() || t.awVertexIndices[1] >= m_data.m_vecVertices.size() || t.awVertexIndices[2] >= m_data.m_vecVertices.size()) throw Exception(_T("invalid vertex index value"), __FILE__, __LINE__); for (int i=0; i<3; i++) for (int j=0; j<3; j++) t.afVertexNormals[i][j] = ReadFloat(stream); for (int i=0; i<3; i++) t.s[i] = ReadFloat(stream); for (int i=0; i<3; i++) t.t[i] = ReadFloat(stream); // check bSmoothingGroup t.bSmoothingGroup = stream.ReadByte(); /// 1-32 if (t.bSmoothingGroup < 1 || t.bSmoothingGroup > 32) throw Exception(_T("invalid smooth group value"), __FILE__, __LINE__); t.bGroupIndex = stream.ReadByte(); // copy over to Triangle MilkShape3D::Triangle& tri = m_data.m_vecTriangles[w]; for (int i=0; i<3; i++) { tri.auiVertexIndices[i] = t.awVertexIndices[i]; tri.aNormals[i] = Vector3d( t.afVertexNormals[i][0], t.afVertexNormals[i][1], t.afVertexNormals[i][2]); // reverse t; MilkShape3D stores them in reverse tri.aTex[i] = TexCoord2f(t.s[i], /*1.0f -*/ t.t[i]); } } }
void HexToBinary(stream::IStream& stream, const WString& hexText) { const wchar_t* buffer = hexText.Buffer(); vint count = hexText.Length() / 2; for (vint i = 0; i < count; i++) { vuint8_t byte = (vuint8_t)(HexToInt(buffer[0]) * 16 + HexToInt(buffer[1])); buffer += 2; stream.Write(&byte, 1); } }
void Loader::LoadGroupList(Stream::IStream& stream) { Stream::EndianAwareFilter filter(stream); WORD wNumGroups = filter.Read16LE(); m_data.m_vecGroups.resize(wNumGroups); if (wNumGroups > c_uiMaxGroups) throw Exception(_T("invalid number of groups"), __FILE__, __LINE__); for (WORD w = 0; w<wNumGroups; w++) { GroupData g; g.bFlags = stream.ReadByte(); if ((g.bFlags & ~(flagSelected | flagHidden)) != 0) throw Exception(_T("invalid group flags"), __FILE__, __LINE__); g.cszName = ReadString<32>(stream, _T("error reading group name")); WORD wNumTriangleIndices = filter.Read16LE(); if (wNumTriangleIndices > 0) { m_data.m_vecGroups[w].m_vecTriangleIndices.resize(wNumTriangleIndices); for (WORD i=0; i<wNumTriangleIndices; i++) { WORD wIndex = filter.Read16LE(); if (wIndex >= m_data.m_vecTriangles.size()) throw Exception(_T("invalid triangle index value"), __FILE__, __LINE__); m_data.m_vecGroups[w].m_vecTriangleIndices[i] = wIndex; } } g.cMaterialIndex = static_cast<char>(stream.ReadByte()); m_data.m_vecGroups[w].m_uiMaterialIndex = g.cMaterialIndex; } }
CString ReadString(Stream::IStream& stream, LPCTSTR pszExceptionText) { std::array<char, uiLen+1> aName; aName[uiLen] = 0; DWORD dwBytesRead = 0; bool bRet = stream.Read(&aName[0], uiLen, dwBytesRead); if (!bRet || dwBytesRead != uiLen) throw Exception(pszExceptionText, __FILE__, __LINE__); return CString(&aName[0]); }
Ptr<INativeImage> WindowsImageService::CreateImageFromStream(stream::IStream& stream) { stream::MemoryStream memoryStream; char buffer[65536]; while(true) { vint length=stream.Read(buffer, sizeof(buffer)); memoryStream.Write(buffer, length); if(length!=sizeof(buffer)) { break; } } return CreateImageFromMemory(memoryStream.GetInternalBuffer(), (vint)memoryStream.Size()); }
/// \details reads IEEE754 32-bit float value float Loader::ReadFloat(Stream::IStream& stream) { float fValue = 0.f; DWORD dwBytesRead = 0; bool bRet = stream.Read(&fValue, sizeof(fValue), dwBytesRead); if (!bRet || dwBytesRead != sizeof(fValue)) throw Exception(_T("error reading float value"), __FILE__, __LINE__); // check invalid float values if (_isnan(fValue) || !_finite(fValue)) throw Exception(_T("error reading float value"), __FILE__, __LINE__); return fValue; }
WString BinaryToHex(stream::IStream& stream) { stream::MemoryStream memoryStream; { stream::StreamWriter writer(memoryStream); vuint8_t byte; while (stream.Read(&byte, 1) == 1) { writer.WriteChar(L"0123456789ABCDEF"[byte / 16]); writer.WriteChar(L"0123456789ABCDEF"[byte % 16]); } } memoryStream.SeekFromBegin(0); { stream::StreamReader reader(memoryStream); return reader.ReadToEnd(); } }
void Loader::LoadHeader(Stream::IStream& stream) { Header header; const int iSignatureSize = sizeof(header.aszId); DWORD dwBytesRead = 0; bool bRet = stream.Read(&header.aszId[0], iSignatureSize, dwBytesRead); if (!bRet || dwBytesRead != iSignatureSize || strncmp(header.aszId, c_szHeaderId, iSignatureSize) != 0) throw Exception(_T("invalid header signature"), __FILE__, __LINE__); Stream::EndianAwareFilter filter(stream); header.iVersion = static_cast<int>(filter.Read32LE()); if (header.iVersion != c_iDefaultVersion) throw Exception(_T("invalid header version"), __FILE__, __LINE__); }
void Loader::LoadMaterialsList(Stream::IStream& stream) { Stream::EndianAwareFilter filter(stream); WORD wNumMaterials = filter.Read16LE(); m_data.m_vecMaterials.resize(wNumMaterials); if (wNumMaterials > c_uiMaxMaterials) throw Exception(_T("invalid number of materials"), __FILE__, __LINE__); for (WORD w = 0; w<wNumMaterials; w++) { Material& m = m_data.m_vecMaterials[w]; m.cszName = ReadString<32>(stream, _T("error reading material name")); for (unsigned int i=0; i<4; i++) m.afAmbient[i] = ReadFloat(stream); for (unsigned int i=0; i<4; i++) m.afDiffuse[i] = ReadFloat(stream); for (unsigned int i=0; i<4; i++) m.afSpecular[i] = ReadFloat(stream); for (unsigned int i=0; i<4; i++) m.afEmissive[i] = ReadFloat(stream); m.fShininess = ReadFloat(stream); m.fTransparency = ReadFloat(stream); m.bMode = stream.ReadByte(); m.cszTexture = ReadString<128>(stream, _T("error reading material texture")); m.cszAlphaMap = ReadString<128>(stream, _T("error reading material alpha map")); } }
void OggVorbisFileReader::Read(Stream::IStream& stream) { OggVorbis_File vf; // open file OggVorbisStreamCallbacks callbacks(false, stream.CanSeek()); int iRet = ov_open_callbacks(&stream, &vf, NULL, 0, callbacks); if (iRet == -1) { ov_clear(&vf); throw Exception(_T("Ogg Vorbis: couldn't open file"), __FILE__, __LINE__); } // get metadata { vorbis_info* vi = ov_info(&vf, -1); // vi doesn't need to be freed if (vi == NULL) { ov_clear(&vf); throw Exception(_T("Ogg Vorbis: couldn't get info"), __FILE__, __LINE__); } m_uiChannels = vi->channels; m_uiSamplerate = vi->rate; } // prepare buffer ogg_int64_t ilLength = ov_pcm_total(&vf, -1); // double number of samples when stereo if (m_uiChannels == 2) ilLength <<= 1; ATLASSERT(ilLength >= 0 && ilLength <= std::numeric_limits<size_t>::max()); size_t uiLength = static_cast<size_t>(ilLength); m_vecSamples.resize(uiLength); // read in samples int iCurrentBitstream = 0; bool bEof = false; size_t ulAlreadyRead = 0; while(!bEof) { // read 64k samples at once int iLengthToRead = std::min(int(uiLength - ulAlreadyRead), 65536); if (iLengthToRead == 0) { bEof = true; break; } long lRet = ov_read(&vf, reinterpret_cast<char*>(&m_vecSamples[ulAlreadyRead]), iLengthToRead * 2, // in bytes 0, // big endian: no 2, // size of word 1, // signed: yes &iCurrentBitstream); if (lRet == 0) bEof = true; else if (lRet < 0) { // error in the stream break; } else { // ov_read returns number of bytes written, so divide by size of word ulAlreadyRead += lRet / 2; } } // finished ov_clear(&vf); // when not at EOF, we had an error if (!bEof) throw Exception(_T("Ogg Vorbis: couldn't read samples"), __FILE__, __LINE__); }
/// \see http://tfc.duke.free.fr/old/models/md2.htm void MD2::ModelData::Load(Stream::IStream& stream) { Stream::EndianAwareFilter filter(stream); Header header = { 0 }; header.Read(filter); if ((header.ident != c_uiMagicNumber) && (header.version != c_uiVersion)) throw Exception(_T("invalid MD2 signature"), __FILE__, __LINE__); // initialize member variables m_iNumFrames = header.num_frames; m_iNumXyz = header.num_xyz; m_iNumGlcmds = header.num_glcmds; // allocate memory m_vecVertices.resize(header.num_xyz * header.num_frames); m_vecGlcmds.resize(header.num_glcmds); m_vecLightNormals.resize(header.num_xyz * header.num_frames); m_vecMinBounds.resize(header.num_frames); m_vecMaxBounds.resize(header.num_frames); ///////////////////////////////////////////// // reading file data std::vector<char> buffer(header.num_frames * header.framesize); DWORD dwBytesRead = 0; // TODO read frame endian-independent // read frame data... stream.Seek(header.ofs_frames, Stream::IStream::seekBegin); stream.Read(&buffer[0], buffer.size(), dwBytesRead); if (buffer.size() != dwBytesRead) throw Exception(_T("invalid MD2 content"), __FILE__, __LINE__); // read opengl commands... stream.Seek(header.ofs_glcmds, Stream::IStream::seekBegin); for (size_t i = 0; i < m_vecGlcmds.size(); i++) m_vecGlcmds[i] = static_cast<int>(filter.Read32LE()); ///////////////////////////////////////////// // vertex array initialization for (unsigned int numframe = 0; numframe < header.num_frames; numframe++) { // get frame struct for this Frame* frame = reinterpret_cast<Frame*>(&buffer[header.framesize * numframe]); //ATLTRACE(_T("loading frame %u, [%-16hs]\n"), numframe, frame->name); Vector3d* ptrverts = &m_vecVertices[header.num_xyz * numframe]; unsigned int* ptrnormals = &m_vecLightNormals[header.num_xyz * numframe]; Vector3d vMinBound, vMaxBound; for (unsigned int i = 0; i < header.num_xyz; i++) { Vector3d& v = ptrverts[i]; v = Vector3d( (frame->verts[i].v[0] * frame->scale[0]) + frame->translate[0], (frame->verts[i].v[1] * frame->scale[1]) + frame->translate[1], (frame->verts[i].v[2] * frame->scale[2]) + frame->translate[2]); ptrnormals[i] = frame->verts[i].lightnormalindex; // get min and max bounds vMinBound.X(std::min(v.X(), vMinBound.X())); vMinBound.Y(std::min(v.Y(), vMinBound.Y())); vMinBound.Z(std::min(v.Z(), vMinBound.Z())); vMaxBound.X(std::max(v.X(), vMaxBound.X())); vMaxBound.Y(std::max(v.Y(), vMaxBound.Y())); vMaxBound.Z(std::max(v.Z(), vMaxBound.Z())); } m_vecMinBounds[numframe] = vMinBound; m_vecMaxBounds[numframe] = vMaxBound; } }
void PcxImageReader::Load(Stream::IStream& stream) { // read header PCXHeader header = {0}; DWORD dwRead = 0; stream.Read(&header, sizeof(header), dwRead); // check header if (header.manufacturer != 0x0a) throw Exception(_T("wrong manufacturer number!"), __FILE__, __LINE__); // allocate pixels m_uiWidth = header.xmax - header.xmin + 1; m_uiHeight = header.ymax - header.ymin + 1; m_vecPixels.resize(m_uiWidth * m_uiHeight); // read in palette ULONGLONG ullPos = stream.Position(); BYTE palette[256][3]; stream.Seek(-768LL, Stream::IStream::seekEnd); stream.Read(&palette, sizeof(palette), dwRead); ATLASSERT(dwRead == sizeof(palette)); stream.Seek(static_cast<LONGLONG>(ullPos), Stream::IStream::seekBegin); // read in image // \note only supports 8-bit at the moment unsigned int uiBitcount = header.bitsPerPixel * header.numColorPlanes; if (uiBitcount != 8) throw Exception(_T("wrong bit count!"), __FILE__, __LINE__); // read pixel data for (unsigned int y = 0; y < m_uiHeight; ++y) { Color* pColor = &m_vecPixels[y * m_uiWidth]; unsigned int uiBytesLeft = header.bytesPerScanLine; // decode line unsigned int uiCount = 0; BYTE ubValue = 0; while (uiBytesLeft--) { if (uiCount == 0) { BYTE b = stream.ReadByte(); if (b < 0xc0) { uiCount = 1; ubValue = b; } else { uiCount = b - 0xc0; ubValue = stream.ReadByte(); } } uiCount--; *pColor = Color( palette[ubValue][0], palette[ubValue][1], palette[ubValue][2], 255); // opaque pColor++; } } }
void Loader::LoadJointList(Stream::IStream& stream) { Stream::EndianAwareFilter filter(stream); WORD wNumJoints = filter.Read16LE(); m_data.m_vecJoints.resize(wNumJoints); if (wNumJoints > c_uiMaxJoints) throw Exception(_T("invalid number of joints"), __FILE__, __LINE__); for (WORD wJoint = 0; wJoint<wNumJoints; wJoint++) { Joint& j = m_data.m_vecJoints[wJoint]; j.bFlags = stream.ReadByte(); if ((j.bFlags & ~(flagSelected | flagDirty | flagIsKey)) != 0) throw Exception(_T("invalid joint flags"), __FILE__, __LINE__); j.cszName = ReadString<32>(stream, _T("error reading joint name")); j.cszParentName = ReadString<32>(stream, _T("error reading joint parent name")); float x, y, z; x = ReadFloat(stream); y = ReadFloat(stream); z = ReadFloat(stream); j.rotation = RotAngle3d(x, y, z); x = ReadFloat(stream); y = ReadFloat(stream); z = ReadFloat(stream); j.vPosition = Vector3d(x, y, z); WORD wNumKeyFramesRot = filter.Read16LE(); WORD wNumKeyFramesTrans = filter.Read16LE(); j.RotationKeys().resize(wNumKeyFramesRot); for (WORD wKeyFramesRot=0; wKeyFramesRot<wNumKeyFramesRot; wKeyFramesRot++) { float fTime = ReadFloat(stream); fTime *= m_data.m_animationData.fAnimationFPS; x = ReadFloat(stream); y = ReadFloat(stream); z = ReadFloat(stream); j.RotationKeys()[wKeyFramesRot] = KeyframeRot(fTime, RotAngle3d(x, y, z)); } j.PositionKeys().resize(wNumKeyFramesTrans); for (WORD wKeyFramesTrans=0; wKeyFramesTrans<wNumKeyFramesTrans; wKeyFramesTrans++) { float fTime = ReadFloat(stream); fTime *= m_data.m_animationData.fAnimationFPS; x = ReadFloat(stream); y = ReadFloat(stream); z = ReadFloat(stream); j.PositionKeys()[wKeyFramesTrans] = KeyframeTrans(fTime, Vector3d(x, y, z)); } } }