[poppler] poppler/Movie.cc poppler/Movie.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Tue Mar 11 14:49:16 PDT 2008
poppler/Movie.cc | 443 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
poppler/Movie.h | 177 +++++++++++++++++++++
2 files changed, 620 insertions(+)
New commits:
commit a354f7198c493990613a1db131c662ec27948863
Author: Hugo Mercier <hmercier31 at gmail.com>
Date: Tue Mar 11 22:49:00 2008 +0100
Initial Movie support (2)
Now with the forgotten files
diff --git a/poppler/Movie.cc b/poppler/Movie.cc
new file mode 100644
index 0000000..e6215b7
--- /dev/null
+++ b/poppler/Movie.cc
@@ -0,0 +1,443 @@
+//*********************************************************************************
+// 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;
+}
+
+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", ¶ms)->isDict()) {
+ MH.parseMediaPlayParameters(¶ms);
+ }
+ params.free();
+ if (tmp2.dictLookup("BE", ¶ms)->isDict()) {
+ BE.parseMediaPlayParameters(¶ms);
+ }
+ params.free();
+ }
+ tmp2.free();
+ //
+ // parse Media Screen Parameters
+ if (obj->dictLookup("SP", &tmp2)->isDict()) { // media screen parameters
+ Object params;
+ if (tmp2.dictLookup("MH", ¶ms)->isDict()) {
+ MH.parseMediaScreenParameters(¶ms);
+ }
+ params.free();
+ if (tmp2.dictLookup("BE", ¶ms)->isDict()) {
+ BE.parseMediaScreenParameters(¶ms);
+ }
+ 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;
+}
diff --git a/poppler/Movie.h b/poppler/Movie.h
new file mode 100644
index 0000000..16584ad
--- /dev/null
+++ b/poppler/Movie.h
@@ -0,0 +1,177 @@
+//*********************************************************************************
+// Movie.h
+//---------------------------------------------------------------------------------
+//
+//---------------------------------------------------------------------------------
+// Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//*********************************************************************************
+
+#ifndef _MOVIE_H_
+#define _MOVIE_H_
+
+#include "Object.h"
+#include "Annot.h"
+
+class GooList;
+
+
+struct MovieWindowParameters {
+
+ MovieWindowParameters();
+ ~MovieWindowParameters();
+
+ // parse from a floating window parameters dictionary
+ void parseFWParams(Object* obj);
+
+ enum MovieWindowType {
+ movieWindowFloating = 0,
+ movieWindowFullscreen,
+ movieWindowHidden, // ?
+ movieWindowEmbedded
+ };
+
+ enum MovieWindowRelativeTo {
+ windowRelativeToDocument = 0,
+ windowRelativeToApplication,
+ windowRelativeToDesktop
+ };
+
+
+ // DEFAULT VALUE
+
+ MovieWindowType type; // movieWindowEmbedded
+
+
+ int width; // -1
+ int height; // -1
+
+ // floating window position
+ MovieWindowRelativeTo relativeTo; // windowRelativeToDocument (or to desktop)
+ double XPosition; // 0.5
+ double YPosition; // 0.5
+
+ GBool hasTitleBar; // true
+ GBool hasCloseButton; // true
+ GBool isResizeable; // true
+};
+
+
+struct MovieParameters {
+
+ MovieParameters();
+ ~MovieParameters();
+
+ // parse from a "Media Play Parameters" dictionary
+ void parseMediaPlayParameters(Object* playObj);
+ // parse from a "Media Screen Parameters" dictionary
+ void parseMediaScreenParameters(Object* screenObj);
+ // parse from a AnnotMovie object
+ void parseAnnotMovie(AnnotMovie* annot);
+
+ enum MovieFittingPolicy {
+ fittingMeet = 0,
+ fittingSlice,
+ fittingFill,
+ fittingScroll,
+ fittingHidden,
+ fittingUndefined
+ };
+
+ struct MovieTime {
+ MovieTime() { units_per_second = 0; }
+ Gulong units;
+ int units_per_second; // 0 : defined by movie
+ };
+
+ struct Color {
+ double r, g, b;
+ };
+
+ Gushort rotationAngle; // 0
+
+ MovieTime start; // 0
+ MovieTime duration; // 0
+
+ double rate; // 1.0
+
+ int volume; // 100
+
+ // defined in media play parameters, p 770
+ // correspond to 'fit' SMIL's attribute
+ MovieFittingPolicy fittingPolicy; // fittingUndefined
+
+ GBool autoPlay; // true
+
+ // repeat count, can be real values, 0 means forever
+ double repeatCount; // 1.0
+
+ // background color // black = (0.0 0.0 0.0)
+ Color bgColor;
+
+ // opacity in [0.0 1.0]
+ double opacity; // 1.0
+
+
+ GBool showControls; // false
+
+ MovieWindowParameters windowParams;
+};
+
+class Movie {
+ public:
+ Movie();
+ ~Movie();
+
+ void parseAnnotMovie(AnnotMovie* annot);
+ void parseMediaRendition(Object* obj);
+
+ MovieParameters* getMHParameters() { return &MH; }
+ MovieParameters* getBEParameters() { return &BE; }
+
+ GooString* getContentType() { return contentType; }
+ GooString* getFileName() { return fileName; }
+
+ GBool getIsEmbedded() { return isEmbedded; }
+ Stream* getEmbbededStream() { return embeddedStream; }
+ // write embedded stream to file
+ void outputToFile(FILE*);
+
+ Stream* getPosterStream() { return posterStream; }
+
+ Movie* copy();
+
+ private:
+ // "Must Honor" parameters
+ MovieParameters MH;
+ // "Best Effort" parameters
+ MovieParameters BE;
+
+ Stream* posterStream;
+
+ GBool isEmbedded;
+
+ GooString* contentType;
+
+ // if it's embedded
+ Stream* embeddedStream;
+
+ // if it's not embedded
+ GooString* fileName;
+};
+
+#endif
+
More information about the poppler
mailing list