bool LWOFile::LoadFromMemory(const void *pData, unsigned int iFileSize) { if(pData==NULL || iFileSize==0) { AddError("Loading from memory failed: no data"); return false; } m_pData=(const char*)pData; m_pDataEnd=m_pData+iFileSize; // read main chunk id // unsigned int iID=0; if(!ReadID4(iID) || iID!=ID4("FORM")) { AddError("Main chunk FORM not found!"); return false; } // read main chunk size // unsigned int iMainSize=0; if(!ReadU4(iMainSize)) return false; // read file format // if(!ReadID4(iID)) return false; if(iID!=ID4("LWO2")) { AddError("Format "+ID4ToString(iID)+" is not supported!"); return false; } unsigned int iLayerID=ID4("LAYR"); unsigned int iPointsID=ID4("PNTS"); unsigned int iPolygonsID=ID4("POLS"); unsigned int iVertexMapID=ID4("VMAP"); unsigned int iVertexMapDID=ID4("VMAD"); unsigned int iTagsID=ID4("TAGS"); unsigned int iPTagsID=ID4("PTAG"); unsigned int iSurfID=ID4("SURF"); // while we have data left // while(m_pData<m_pDataEnd) { // get chunk ID // unsigned int iID=0; if(!ReadID4(iID)) return false; // get chunk size // unsigned int iChunkSize=0; if(!ReadU4(iChunkSize)) return false; // attempt to load chunk // LAYR /////////////////// if(iID==iLayerID) { if(!LoadLAYR(iChunkSize)) { AddError("Loading chunk "+ID4ToString(iID)+" failed!"); return false; } } // PNTS /////////////////// else if(iID==iPointsID) { if(!LoadPNTS(iChunkSize)) { AddError("Loading chunk "+ID4ToString(iID)+" failed!"); return false; } } // POLS /////////////////// else if(iID==iPolygonsID) { if(!LoadPOLS(iChunkSize)) { AddError("Loading chunk "+ID4ToString(iID)+" failed!"); return false; } } // VMAP /////////////////// else if(iID==iVertexMapID) { if(!LoadVMAP(iChunkSize)) { AddError("Loading chunk "+ID4ToString(iID)+" failed!"); return false; } } // VMAD /////////////////// else if(iID==iVertexMapDID) { if(!LoadVMAD(iChunkSize)) { AddError("Loading chunk "+ID4ToString(iID)+" failed!"); return false; } } // TAGS /////////////////// else if(iID==iTagsID) { if(!LoadTAGS(iChunkSize)) { AddError("Loading chunk "+ID4ToString(iID)+" failed!"); return false; } } // PTAG /////////////////// else if(iID==iPTagsID) { if(!LoadPTAG(iChunkSize)) { AddError("Loading chunk "+ID4ToString(iID)+" failed!"); return false; } } // SURF /////////////////// else if(iID==iSurfID) { if(!LoadSURF(iChunkSize)) { AddError("Loading chunk "+ID4ToString(iID)+" failed!"); return false; } } // unknown /////////////////// else { AddError("Warning: Unknown chunk ID "+ID4ToString(iID)); m_pData+=iChunkSize; } // quote: If the chunk size is odd, the chunk is followed by a 0 pad byte, // so that the next chunk begins on an even byte boundary. if(iChunkSize%2==1) m_pData+=1; } m_pData=NULL; m_pDataEnd=NULL; return true; }
void LWOReader::ReadCLIP( UInt32 pChunkSize ) { UInt32 dataRead = 0; UInt32 subChunkTag; UInt16 subChunkSize; UInt32 bytesHold; LWClip* newClip = GD_NEW(LWClip, this, "Clip"); dataRead += ReadU4( newClip->mIndex ); // Read all subchunks while( dataRead < pChunkSize ) { if( (pChunkSize - dataRead) < 6 ) { dataRead += Skip( pChunkSize - dataRead ); return; } subChunkTag = ReadSubChunk(subChunkSize); dataRead += sizeof(subChunkTag); // Subchunk tag. dataRead += sizeof(subChunkSize); // Subchunk size. bytesHold = dataRead; switch( subChunkTag ) { case ID_STIL: dataRead += ReadS0( newClip->mStillImage ); break; case ID_XREF: dataRead += ReadVX( newClip->mXRefIndex ); dataRead += ReadS0( newClip->mXRefInstName ); break; case ID_ISEQ: case ID_ANIM: case ID_STCC: case ID_TIME: case ID_CONT: case ID_BRIT: case ID_SATR: case ID_HUE: case ID_GAMM: case ID_NEGA: case ID_IFLT: case ID_PFLT: default: dataRead += Skip( subChunkSize ); break; } // Make sure we've read all subchunk bytes (given by the size). if( (subChunkSize - dataRead + bytesHold) > 0 ) dataRead += Skip( subChunkSize - dataRead + bytesHold ); } mObject->mClips.push_back( newClip ); }