void GBAMGMStateLoaded(struct GBARRContext* rr, const struct GBASerializedState* state) { struct GBAMGMContext* mgm = (struct GBAMGMContext*) rr; if (rr->isRecording(rr)) { if (state->associatedStreamId != mgm->streamId) { _loadStream(mgm, state->associatedStreamId); _incrementStream(mgm, true); } else { _finishSegment(mgm); } _markRerecord(mgm); } else if (rr->isPlaying(rr)) { _loadStream(mgm, state->associatedStreamId); _skipSegment(mgm); } }
bool _skipSegment(struct GBAMGMContext* mgm) { mgm->nextTime = 0; while (_readTag(mgm, mgm->movieStream) != TAG_EOF); if (!mgm->nextTime || !_loadStream(mgm, mgm->nextTime)) { _streamEndReached(mgm); return false; } return true; }
void _streamEndReached(struct GBAMGMContext* mgm) { if (!mgm->d.isPlaying(&mgm->d)) { return; } uint32_t endStreamId = mgm->streamId; mgm->d.stopPlaying(&mgm->d); if (mgm->autorecord) { mgm->isRecording = true; _loadStream(mgm, endStreamId); _incrementStream(mgm, false); } }
bool GBAMGMStartPlaying(struct GBARRContext* rr, bool autorecord) { if (rr->isRecording(rr) || rr->isPlaying(rr)) { return false; } struct GBAMGMContext* mgm = (struct GBAMGMContext*) rr; mgm->isPlaying = true; if (!_loadStream(mgm, 1)) { mgm->isPlaying = false; return false; } mgm->autorecord = autorecord; return true; }
bool _incrementStream(struct GBAMGMContext* mgm, bool recursive) { uint32_t newStreamId = mgm->maxStreamId + 1; uint32_t oldStreamId = mgm->streamId; if (mgm->d.isRecording(&mgm->d) && mgm->movieStream) { if (!_markStreamNext(mgm, newStreamId, recursive)) { return false; } } if (!_loadStream(mgm, newStreamId)) { return false; } GBALog(0, GBA_LOG_DEBUG, "[RR] New segment: %u", newStreamId); _emitMagic(mgm, mgm->movieStream); mgm->maxStreamId = newStreamId; _emitTag(mgm, mgm->movieStream, TAG_PREVIOUSLY); mgm->movieStream->write(mgm->movieStream, &oldStreamId, sizeof(oldStreamId)); _emitTag(mgm, mgm->movieStream, TAG_BEGIN); mgm->metadataFile->seek(mgm->metadataFile, mgm->maxStreamIdOffset, SEEK_SET); mgm->metadataFile->write(mgm->metadataFile, &mgm->maxStreamId, sizeof(mgm->maxStreamId)); mgm->previously = oldStreamId; return true; }
bool _markStreamNext(struct GBAMGMContext* mgm, uint32_t newStreamId, bool recursive) { if (mgm->movieStream->seek(mgm->movieStream, -sizeof(newStreamId) - 1, SEEK_END) < 0) { return false; } uint8_t tagBuffer; if (mgm->movieStream->read(mgm->movieStream, &tagBuffer, 1) != 1) { return false; } if (tagBuffer != TAG_NEXT_TIME) { return false; } if (mgm->movieStream->write(mgm->movieStream, &newStreamId, sizeof(newStreamId)) != sizeof(newStreamId)) { return false; } if (recursive) { if (mgm->movieStream->seek(mgm->movieStream, 0, SEEK_SET) < 0) { return false; } if (!_verifyMagic(mgm, mgm->movieStream)) { return false; } _readTag(mgm, mgm->movieStream); if (_readTag(mgm, mgm->movieStream) != TAG_PREVIOUSLY) { return false; } if (mgm->previously == 0) { return true; } uint32_t currentStreamId = mgm->streamId; if (!_loadStream(mgm, mgm->previously)) { return false; } return _markStreamNext(mgm, currentStreamId, mgm->previously); } return true; }
/** * Adds an data item (<d> tag) in the AbiWord document for the specified image. * * Code mainly from Dom Lachowicz and/or Robert Staudinger. * * @param rDataId Receives the id that has been given to the added data item. * @param ppAtts The attributes of a <draw:image> element. */ bool ODi_Abi_Data::addImageDataItem(UT_String& rDataId, const gchar** ppAtts) { const gchar* pHRef = UT_getAttribute ("xlink:href", ppAtts); UT_return_val_if_fail(pHRef,false); // If we have a string smaller then this we are in trouble. File corrupted? UT_return_val_if_fail((strlen(pHRef) >= 10 /*10 == strlen("Pictures/a")*/), false); UT_Error error = UT_OK; UT_ByteBuf img_buf; GsfInfile* pPictures_dir; FG_Graphic* pFG = NULL; const UT_ByteBuf* pPictData = NULL; UT_uint32 imageID; // The subdirectory that holds the picture. e.g: "ObjectReplacements" or "Pictures" UT_String dirName; // The file name of the picture. e.g.: "Object 1" or "10000201000000D100000108FF0E3707.png" UT_String fileName; const std::string id = m_href_to_id[pHRef]; if (!id.empty()) { // This image was already added. // Use the existing data item id. rDataId = id; return true; } // Get a new, unique, ID. imageID = m_pAbiDocument->getUID(UT_UniqueId::Image); UT_String_sprintf(rDataId, "%d", imageID); // Add this id to the list UT_DebugOnly<href_id_map_t::iterator> iter = m_href_to_id .insert(m_href_to_id.begin(), href_id_map_t::value_type(pHRef, rDataId.c_str())); UT_ASSERT((href_id_map_t::iterator)iter != m_href_to_id.end()); _splitDirectoryAndFileName(pHRef, dirName, fileName); pPictures_dir = GSF_INFILE(gsf_infile_child_by_name(m_pGsfInfile, dirName.c_str())); UT_return_val_if_fail(pPictures_dir, false); // Loads img_buf error = _loadStream(pPictures_dir, fileName.c_str(), img_buf); g_object_unref (G_OBJECT (pPictures_dir)); if (error != UT_OK) { return false; } // Builds pImporter from img_buf error = IE_ImpGraphic::loadGraphic (img_buf, IEGFT_Unknown, &pFG); if ((error != UT_OK) || !pFG) { // pictData is already freed in ~FG_Graphic return false; } // Builds pPictData from pFG // TODO: can we get back a vector graphic? pPictData = pFG->getBuffer(); if (!pPictData) { // i don't think that this could ever happen, but... UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return false; } // // Create the data item. // if (!m_pAbiDocument->createDataItem(rDataId.c_str(), false, pPictData, pFG->getMimeType(), NULL)) { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return false; } return true; }
/** * Adds an data item (<d> tag) in the AbiWord document for the specified image. * * Code mainly from Dom Lachowicz and/or Robert Staudinger. * * @param rDataId Receives the id that has been given to the added data item. * @param ppAtts The attributes of a <draw:image> element. */ bool ODi_Abi_Data::addObjectDataItem(UT_String& rDataId, const gchar** ppAtts, int& pto_Type) { const gchar* pHRef = UT_getAttribute ("xlink:href", ppAtts); UT_return_val_if_fail(pHRef,false); // If we have a string smaller then this we are in trouble. File corrupted? UT_return_val_if_fail((strlen(pHRef) >= 10 /*10 == strlen("Pictures/a")*/), false); UT_Error error = UT_OK; UT_ByteBuf *object_buf; GsfInfile* pObjects_dir; UT_uint32 objectID; // The subdirectory that holds the picture. e.g: "ObjectReplacements" or "Pictures" UT_String dirName; // The file name of the picture. e.g.: "Object 1" or "10000201000000D100000108FF0E3707.png" UT_String fileName; const std::string id = m_href_to_id[pHRef]; if (!id.empty()) { // This object was already added. // Use the existing data item id. rDataId = id; return true; } // Get a new, unique, ID. objectID = m_pAbiDocument->getUID(UT_UniqueId::Math); UT_String_sprintf(rDataId, "MathLatex%d", objectID); // Add this id to the list UT_DebugOnly<href_id_map_t::iterator> iter = m_href_to_id .insert(m_href_to_id.begin(), href_id_map_t::value_type(pHRef, rDataId.c_str())); UT_ASSERT((href_id_map_t::iterator)iter != m_href_to_id.end()); _splitDirectoryAndFileName(pHRef, dirName, fileName); if (fileName.empty ()) fileName = "content.xml"; pObjects_dir = GSF_INFILE(gsf_infile_child_by_name(m_pGsfInfile, dirName.c_str())); UT_return_val_if_fail(pObjects_dir, false); // Loads object_buf object_buf = new UT_ByteBuf (); error = _loadStream(pObjects_dir, fileName.c_str(), *object_buf); g_object_unref (G_OBJECT (pObjects_dir)); if (error != UT_OK) { delete object_buf; return false; } // check to ensure that we're seeing math. this can probably be made smarter. static const char math_header[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE math:math"; if ((object_buf->getLength () > strlen (math_header)) && (strncmp ((const char*)object_buf->getPointer (0), math_header, strlen (math_header)) != 0)) { delete object_buf; return false; } // // Create the data item. // if (!m_pAbiDocument->createDataItem(rDataId.c_str(), false, object_buf, "application/mathml+xml", NULL)) { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return false; } pto_Type = PTO_Math; return true; }