Beispiel #1
0
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);
	}
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);
	}
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
/**
 * 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;
}
Beispiel #8
0
/**
 * 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;
}