blob: 66b87dd367dab99958d63ac269facc8023769671 [file] [log] [blame]
//*********************************************************************************
// Movie.cc
//---------------------------------------------------------------------------------
// Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
//
// GNU GENERAL PUBLIC LICENSE - See COPYING.
//*********************************************************************************
#include "Movie.h"
#include <GooList.h>
MovieWindowParameters::MovieWindowParameters() {
// default values
type = movieWindowEmbedded;
width = -1;
height = -1;
relativeTo = windowRelativeToDocument;
XPosition = 0.5;
YPosition = 0.5;
hasTitleBar = gTrue;
hasCloseButton = gTrue;
isResizeable = gTrue;
}
MovieWindowParameters::~MovieWindowParameters() {
}
void MovieWindowParameters::parseFWParams(Object* obj) {
Object tmp;
if (obj->dictLookup("D", &tmp)->isArray()) {
Array * dim = tmp.getArray();
if (dim->getLength() >= 2) {
Object dd;
if (dim->get(0, &dd)->isInt()) {
width = dd.getInt();
}
dd.free();
if (dim->get(1, &dd)->isInt()) {
height = dd.getInt();
}
dd.free();
}
}
tmp.free();
if (obj->dictLookup("RT", &tmp)->isInt()) {
int t = tmp.getInt();
switch(t) {
case 0: relativeTo = windowRelativeToDocument; break;
case 1: relativeTo = windowRelativeToApplication; break;
case 2: relativeTo = windowRelativeToDesktop; break;
}
}
tmp.free();
if (obj->dictLookup("P",&tmp)->isInt()) {
int t = tmp.getInt();
switch(t) {
case 0: // Upper left
XPosition = 0.0;
YPosition = 0.0;
break;
case 1: // Upper Center
XPosition = 0.5;
YPosition = 0.0;
break;
case 2: // Upper Right
XPosition = 1.0;
YPosition = 0.0;
break;
case 3: // Center Left
XPosition = 0.0;
YPosition = 0.5;
break;
case 4: // Center
XPosition = 0.5;
YPosition = 0.5;
break;
case 5: // Center Right
XPosition = 1.0;
YPosition = 0.5;
break;
case 6: // Lower Left
XPosition = 0.0;
YPosition = 1.0;
break;
case 7: // Lower Center
XPosition = 0.5;
YPosition = 1.0;
break;
case 8: // Lower Right
XPosition = 1.0;
YPosition = 1.0;
break;
}
}
tmp.free();
if (obj->dictLookup("T", &tmp)->isBool()) {
hasTitleBar = tmp.getBool();
}
tmp.free();
if (obj->dictLookup("UC", &tmp)->isBool()) {
hasCloseButton = tmp.getBool();
}
tmp.free();
if (obj->dictLookup("R", &tmp)->isInt()) {
isResizeable = (tmp.getInt() != 0);
}
tmp.free();
}
MovieParameters::MovieParameters() {
// instanciate to default values
rotationAngle = 0;
rate = 1.0;
volume = 100;
fittingPolicy = fittingUndefined;
autoPlay = gTrue;
repeatCount = 1.0;
opacity = 1.0;
showControls = gFalse;
start.units = 0;
duration.units = 0;
}
MovieParameters::~MovieParameters() {
}
void MovieParameters::parseAnnotMovie(AnnotMovie* annot) {
windowParams.relativeTo = MovieWindowParameters::windowRelativeToDesktop;
if (annot->needFloatingWindow()) {
windowParams.type = MovieWindowParameters::movieWindowFloating;
}
if (annot->needFullscreen()) {
windowParams.type = MovieWindowParameters::movieWindowFullscreen;
}
int w, h;
int znum, zdenum;
annot->getMovieSize(w, h);
annot->getZoomFactor(znum, zdenum);
windowParams.width = int(w * double(znum) / zdenum);
windowParams.height = int(h * double(znum) / zdenum);
double x,y;
annot->getWindowPosition(x,y);
windowParams.XPosition = x;
windowParams.YPosition = y;
rate = annot->getRate();
// convert volume to [0 100]
volume = int((annot->getVolume() + 1.0) * 50);
AnnotMovie::RepeatMode mode = annot->getRepeatMode();
if (mode == AnnotMovie::repeatModeRepeat)
repeatCount = 0.0;
showControls = annot->getShowControls();
AnnotMovie::Time tStart = annot->getStart();
AnnotMovie::Time tDuration = annot->getDuration();
start.units = tStart.units;
start.units_per_second = tStart.units_per_second;
duration.units = tDuration.units;
duration.units_per_second = tDuration.units_per_second;
}
void MovieParameters::parseMediaPlayParameters(Object* obj) {
Object tmp;
if (obj->dictLookup("V", &tmp)->isInt()) {
volume = tmp.getInt();
}
tmp.free();
if (obj->dictLookup("C", &tmp)->isBool()) {
showControls = tmp.getBool();
}
tmp.free();
if (obj->dictLookup("F", &tmp)->isInt()) {
int t = tmp.getInt();
switch(t) {
case 0: fittingPolicy = fittingMeet; break;
case 1: fittingPolicy = fittingSlice; break;
case 2: fittingPolicy = fittingFill; break;
case 3: fittingPolicy = fittingScroll; break;
case 4: fittingPolicy = fittingHidden; break;
case 5: fittingPolicy = fittingUndefined; break;
}
}
tmp.free();
// duration parsing
// duration's default value is set to 0, which means : intrinsinc media duration
if (obj->dictLookup("D", &tmp)->isDict()) {
Object oname, ddict, tmp2;
if (tmp.dictLookup("S", &oname)->isName()) {
char* name = oname.getName();
if (!strcmp(name, "F"))
duration.units = -1; // infinity
else if (!strcmp(name, "T")) {
if (tmp.dictLookup("T", &ddict)->isDict()) {
if (ddict.dictLookup("V", &tmp2)->isNum()) {
duration.units = Gulong(tmp2.getNum());
}
tmp2.free();
}
ddict.free();
}
}
oname.free();
}
tmp.free();
if (obj->dictLookup("A", &tmp)->isBool()) {
autoPlay = tmp.getBool();
}
tmp.free();
if (obj->dictLookup("RC", &tmp)->isNum()) {
repeatCount = tmp.getNum();
}
tmp.free();
}
void MovieParameters::parseMediaScreenParameters(Object* obj) {
Object tmp;
if (obj->dictLookup("W", &tmp)->isInt()) {
int t = tmp.getInt();
switch(t) {
case 0: windowParams.type = MovieWindowParameters::movieWindowFloating; break;
case 1: windowParams.type = MovieWindowParameters::movieWindowFullscreen; break;
case 2: windowParams.type = MovieWindowParameters::movieWindowHidden; break;
case 3: windowParams.type = MovieWindowParameters::movieWindowEmbedded; break;
}
}
tmp.free();
// background color
if (obj->dictLookup("B", &tmp)->isArray()) {
Array* color = tmp.getArray();
Object component;
color->get(0, &component);
bgColor.r = component.getNum();
component.free();
color->get(1, &component);
bgColor.g = component.getNum();
component.free();
color->get(2, &component);
bgColor.b = component.getNum();
component.free();
}
tmp.free();
// opacity
if (obj->dictLookup("O", &tmp)->isNum()) {
opacity = tmp.getNum();
}
tmp.free();
if (windowParams.type == MovieWindowParameters::movieWindowFloating) {
Object winDict;
if (obj->dictLookup("F",&winDict)->isDict()) {
windowParams.parseFWParams(&winDict);
}
}
}
Movie::Movie() {
fileName = NULL;
contentType = NULL;
isEmbedded = gFalse;
embeddedStream = NULL;
posterStream = NULL;
}
Movie::~Movie() {
if (fileName)
delete fileName;
if (contentType)
delete contentType;
if (embeddedStream && (!embeddedStream->decRef())) {
delete embeddedStream;
}
if (posterStream && (!posterStream->decRef())) {
delete posterStream;
}
}
void Movie::parseAnnotMovie(AnnotMovie* annot) {
// AnnotMovie is not embedded
isEmbedded = gFalse;
fileName = annot->getFileName()->copy();
if (annot->getPosterStream()) {
posterStream = annot->getPosterStream();
posterStream->incRef();
}
MH.parseAnnotMovie(annot);
// deep copy of MH to BE
// (no distinction is made with AnnotMovie)
memcpy(&BE, &MH, sizeof(MH));
}
void Movie::parseMediaRendition(Object* obj) {
Object tmp, tmp2;
if (obj->dictLookup("S", &tmp)->isName()) {
if (!strcmp(tmp.getName(), "MR")) { // it's a media rendition
//
// parse Media Play Parameters
if (obj->dictLookup("P", &tmp2)->isDict()) { // media play parameters
Object params;
if (tmp2.dictLookup("MH", &params)->isDict()) {
MH.parseMediaPlayParameters(&params);
}
params.free();
if (tmp2.dictLookup("BE", &params)->isDict()) {
BE.parseMediaPlayParameters(&params);
}
params.free();
}
tmp2.free();
//
// parse Media Screen Parameters
if (obj->dictLookup("SP", &tmp2)->isDict()) { // media screen parameters
Object params;
if (tmp2.dictLookup("MH", &params)->isDict()) {
MH.parseMediaScreenParameters(&params);
}
params.free();
if (tmp2.dictLookup("BE", &params)->isDict()) {
BE.parseMediaScreenParameters(&params);
}
params.free();
}
tmp2.free();
//
// Parse media clip data
//
if (obj->dictLookup("C", &tmp2)->isDict()) { // media clip
tmp.free();
if (tmp2.dictLookup("S", &tmp)->isName()) {
if (!strcmp(tmp.getName(), "MCD")) { // media clip data
Object obj1, obj2;
if (tmp2.dictLookup("D", &obj1)->isDict()) {
if (obj1.dictLookup("F", &obj2)->isString()) {
fileName = obj2.getString()->copy();
}
obj2.free();
if (!obj1.dictLookup("EF", &obj2)->isNull()) {
tmp.free();
Object mref;
if (!obj2.dictLookupNF("F", &mref)->isNull()) {
isEmbedded = gTrue;
Object embedded;
obj2.dictLookup("F", &embedded);
if (embedded.isStream()) {
embeddedStream = embedded.getStream();
// "copy" stream
embeddedStream->incRef();
}
embedded.free();
}
mref.free();
}
obj2.free();
}
obj1.free();
if (tmp2.dictLookup("CT", &obj1)->isString()) {
contentType = obj1.getString()->copy();
}
obj1.free();
}
}
tmp.free();
}
tmp2.free();
}
}
}
void Movie::outputToFile(FILE* fp) {
embeddedStream->reset();
while (1) {
int c = embeddedStream->getChar();
if (c == EOF)
break;
fwrite(&c, 1, 1, fp);
}
}
Movie* Movie::copy() {
// call default copy constructor
Movie* new_movie = new Movie(*this);
new_movie->contentType = contentType->copy();
new_movie->fileName = fileName->copy();
new_movie->embeddedStream = embeddedStream;
new_movie->embeddedStream->incRef();
new_movie->posterStream = posterStream;
new_movie->posterStream->incRef();
return new_movie;
}