[poppler] 5 commits - poppler/Annot.cc poppler/Annot.h poppler/Link.cc poppler/Movie.cc poppler/Movie.h qt4/src
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Mon Mar 8 05:39:11 PST 2010
poppler/Annot.cc | 317 +++++++++++++----------------------------------
poppler/Annot.h | 77 -----------
poppler/Link.cc | 4
poppler/Movie.cc | 269 ++++++++++++++++++++++++++++++++-------
poppler/Movie.h | 35 ++++-
qt4/src/poppler-movie.cc | 11 +
6 files changed, 351 insertions(+), 362 deletions(-)
New commits:
commit a00532f509c19c5455e0db5068db95dd4583e8dd
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Mon Mar 8 14:22:53 2010 +0100
Check for Null instead of None to know whether a dict entry is present
Dict::lookup returns obj->initNull() when the key is not found.
diff --git a/poppler/Movie.cc b/poppler/Movie.cc
index 709ccfb..e51f6b6 100644
--- a/poppler/Movie.cc
+++ b/poppler/Movie.cc
@@ -159,7 +159,7 @@ void MovieParameters::parseMovieActivation(Object* aDict,
int rotationAngleA) {
Object obj1;
- if (!aDict->dictLookup("Start", &obj1)->isNone()) {
+ if (!aDict->dictLookup("Start", &obj1)->isNull()) {
if (obj1.isInt()) {
// If it is representable as an integer (subject to the implementation limit for
// integers, as described in Appendix C), it should be specified as such.
@@ -196,7 +196,7 @@ void MovieParameters::parseMovieActivation(Object* aDict,
}
obj1.free();
- if (!aDict->dictLookup("Duration", &obj1)->isNone()) {
+ if (!aDict->dictLookup("Duration", &obj1)->isNull()) {
if (obj1.isInt()) {
duration.units = obj1.getInt();
}
@@ -483,7 +483,7 @@ Movie::Movie(Object *movieDict, Object *aDict) {
//
// movie poster
//
- if (!movieDict->dictLookupNF("Poster", &poster)->isNone()) {
+ if (!movieDict->dictLookupNF("Poster", &poster)->isNull()) {
if (poster.isRef() || poster.isStream()) {
showPoster = gTrue;
} else if (poster.isBool()) {
commit b51e66c9a7e2f7f39ae1edf8bda02a7bc1ad4ebd
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Mon Mar 8 14:15:22 2010 +0100
[annots] Create appearance stream for Movie Annotations when not defined
See bug #23108
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 411723e..5ee31ac 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -16,7 +16,7 @@
// Copyright (C) 2006 Scott Turner <scotty1024 at mac.com>
// Copyright (C) 2007, 2008 Julien Rebetez <julienr at svn.gnome.org>
// Copyright (C) 2007-2009 Albert Astals Cid <aacid at kde.org>
-// Copyright (C) 2007-2009 Carlos Garcia Campos <carlosgc at gnome.org>
+// Copyright (C) 2007-2010 Carlos Garcia Campos <carlosgc at gnome.org>
// Copyright (C) 2007, 2008 Iñigo MartÃnez <inigomartinez at gmail.com>
// Copyright (C) 2007 Jeff Muizelaar <jeff at infidigm.net>
// Copyright (C) 2008 Pino Toscano <pino at kde.org>
@@ -4080,6 +4080,107 @@ void AnnotMovie::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) {
movieDict.free();
}
+void AnnotMovie::draw(Gfx *gfx, GBool printing) {
+ Object obj;
+
+ if (!isVisible (printing))
+ return;
+
+ if (appearance.isNull() && movie->getShowPoster()) {
+ int width, height;
+ Object poster;
+ movie->getPoster(&poster);
+ movie->getAspect(&width, &height);
+
+ if (width != -1 && height != -1 && !poster.isNone()) {
+ MemStream *mStream;
+
+ appearBuf = new GooString ();
+ appearBuf->append ("q\n");
+ appearBuf->appendf ("{0:d} 0 0 {1:d} 0 0 cm\n", width, height);
+ appearBuf->append ("/MImg Do\n");
+ appearBuf->append ("Q\n");
+
+ Object imgDict;
+ imgDict.initDict(xref);
+ imgDict.dictSet ("MImg", &poster);
+
+ Object resDict;
+ resDict.initDict(xref);
+ resDict.dictSet ("XObject", &imgDict);
+
+ Object formDict, obj1, obj2;
+ formDict.initDict(xref);
+ formDict.dictSet("Length", obj1.initInt(appearBuf->getLength()));
+ formDict.dictSet("Subtype", obj1.initName("Form"));
+ formDict.dictSet("Name", obj1.initName("FRM"));
+ obj1.initArray(xref);
+ obj1.arrayAdd(obj2.initInt(0));
+ obj1.arrayAdd(obj2.initInt(0));
+ obj1.arrayAdd(obj2.initInt(width));
+ obj1.arrayAdd(obj2.initInt(height));
+ formDict.dictSet("BBox", &obj1);
+ obj1.initArray(xref);
+ obj1.arrayAdd(obj2.initInt(1));
+ obj1.arrayAdd(obj2.initInt(0));
+ obj1.arrayAdd(obj2.initInt(0));
+ obj1.arrayAdd(obj2.initInt(1));
+ obj1.arrayAdd(obj2.initInt(-width / 2));
+ obj1.arrayAdd(obj2.initInt(-height / 2));
+ formDict.dictSet("Matrix", &obj1);
+ formDict.dictSet("Resources", &resDict);
+
+ Object aStream;
+ mStream = new MemStream(copyString(appearBuf->getCString()), 0,
+ appearBuf->getLength(), &formDict);
+ mStream->setNeedFree(gTrue);
+ aStream.initStream(mStream);
+ delete appearBuf;
+
+ Object objDict;
+ objDict.initDict(xref);
+ objDict.dictSet ("FRM", &aStream);
+
+ resDict.initDict(xref);
+ resDict.dictSet ("XObject", &objDict);
+
+ appearBuf = new GooString ();
+ appearBuf->append ("q\n");
+ appearBuf->appendf ("0 0 {0:d} {1:d} re W n\n", width, height);
+ appearBuf->append ("q\n");
+ appearBuf->appendf ("0 0 {0:d} {1:d} re W n\n", width, height);
+ appearBuf->appendf ("1 0 0 1 {0:d} {1:d} cm\n", width / 2, height / 2);
+ appearBuf->append ("/FRM Do\n");
+ appearBuf->append ("Q\n");
+ appearBuf->append ("Q\n");
+
+ Object appearDict;
+ appearDict.initDict(xref);
+ appearDict.dictSet("Length", obj1.initInt(appearBuf->getLength()));
+ appearDict.dictSet("Subtype", obj1.initName("Form"));
+ appearDict.dictSet("Resources", &resDict);
+ obj1.initArray(xref);
+ obj1.arrayAdd(obj2.initInt(0));
+ obj1.arrayAdd(obj2.initInt(0));
+ obj1.arrayAdd(obj2.initInt(width));
+ obj1.arrayAdd(obj2.initInt(height));
+ appearDict.dictSet("BBox", &obj1);
+
+ MemStream *appearStream = new MemStream(copyString(appearBuf->getCString()), 0,
+ appearBuf->getLength(), &appearDict);
+ appearStream->setNeedFree(gTrue);
+ appearance.initStream(appearStream);
+ delete appearBuf;
+ }
+ poster.free();
+ }
+
+ // draw the appearance stream
+ appearance.fetch(xref, &obj);
+ gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color, 1,
+ rect->x1, rect->y1, rect->x2, rect->y2);
+ obj.free();
+}
//------------------------------------------------------------------------
// AnnotScreen
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 14cafd0..d4de6f6 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -15,7 +15,7 @@
//
// Copyright (C) 2006 Scott Turner <scotty1024 at mac.com>
// Copyright (C) 2007, 2008 Julien Rebetez <julienr at svn.gnome.org>
-// Copyright (C) 2007-2009 Carlos Garcia Campos <carlosgc at gnome.org>
+// Copyright (C) 2007-2010 Carlos Garcia Campos <carlosgc at gnome.org>
// Copyright (C) 2007, 2008 Iñigo MartÃnez <inigomartinez at gmail.com>
// Copyright (C) 2008 Michael Vrable <mvrable at cs.ucsd.edu>
// Copyright (C) 2008 Hugo Mercier <hmercier31 at gmail.com>
@@ -703,6 +703,8 @@ class AnnotMovie: public Annot {
AnnotMovie(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj);
~AnnotMovie();
+ virtual void draw(Gfx *gfx, GBool printing);
+
GooString* getTitle() { return title; }
Movie* getMovie() { return movie; }
commit fae59411852e5c2c45825c5ea963318f1ed5dc6a
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Mon Mar 8 14:07:09 2010 +0100
Fix handling of poster in Movie
Poster is not always a stream, it can be a boolean too. Also, get the
reference when available instead of fetching the stream.
diff --git a/poppler/Movie.cc b/poppler/Movie.cc
index fab467d..709ccfb 100644
--- a/poppler/Movie.cc
+++ b/poppler/Movie.cc
@@ -432,7 +432,7 @@ void Movie::initialize() {
embeddedStream = NULL;
width = -1;
height = -1;
- posterStream = NULL;
+ showPoster = gFalse;
}
Movie::~Movie() {
@@ -444,9 +444,7 @@ Movie::~Movie() {
if (embeddedStream && (!embeddedStream->decRef())) {
delete embeddedStream;
}
- if (posterStream && (!posterStream->decRef())) {
- delete posterStream;
- }
+ poster.free();
}
Movie::Movie(Object *movieDict, Object *aDict) {
@@ -485,13 +483,15 @@ Movie::Movie(Object *movieDict, Object *aDict) {
//
// movie poster
//
- if (!movieDict->dictLookup("Poster", &obj1)->isNone()) {
- if (obj1.isStream()) {
- // "copy" stream
- posterStream = obj1.getStream();
- posterStream->incRef();
+ if (!movieDict->dictLookupNF("Poster", &poster)->isNone()) {
+ if (poster.isRef() || poster.isStream()) {
+ showPoster = gTrue;
+ } else if (poster.isBool()) {
+ showPoster = obj1.getBool();
+ poster.free();
+ } else {
+ poster.free();
}
- obj1.free();
}
if (aDict->isDict()) {
@@ -621,9 +621,8 @@ Movie* Movie::copy() {
if (new_movie->embeddedStream)
new_movie->embeddedStream->incRef();
-
- if (new_movie->posterStream)
- new_movie->posterStream->incRef();
+
+ poster.copy(&new_movie->poster);
return new_movie;
}
diff --git a/poppler/Movie.h b/poppler/Movie.h
index c49b12c..f601cf1 100644
--- a/poppler/Movie.h
+++ b/poppler/Movie.h
@@ -160,7 +160,8 @@ class Movie {
void outputToFile(FILE*);
void getAspect (int *widthA, int *heightA) { *widthA = width; *heightA = height; }
- Stream* getPosterStream() { return posterStream; }
+ Object *getPoster (Object *obj) { return poster.copy(obj); }
+ GBool getShowPoster () { return showPoster; }
Movie* copy();
@@ -177,7 +178,8 @@ class Movie {
int width; // Aspect
int height; // Aspect
- Stream* posterStream;
+ Object poster;
+ GBool showPoster;
GBool isEmbedded;
commit a451f83d101bf265a1e7e2a17c0b320895e70f4e
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Sun Mar 7 12:22:57 2010 +0100
Save width, height (aspect) in Movie object and provide getAspect() method
diff --git a/poppler/Movie.cc b/poppler/Movie.cc
index 0b4d838..fab467d 100644
--- a/poppler/Movie.cc
+++ b/poppler/Movie.cc
@@ -430,6 +430,8 @@ void Movie::initialize() {
contentType = NULL;
isEmbedded = gFalse;
embeddedStream = NULL;
+ width = -1;
+ height = -1;
posterStream = NULL;
}
@@ -457,7 +459,6 @@ Movie::Movie(Object *movieDict, Object *aDict) {
}
obj1.free();
- int width = 0, height = 0;
if (movieDict->dictLookup("Aspect", &obj1)->isArray()) {
Array* aspect = obj1.getArray();
if (aspect->getLength() >= 2) {
diff --git a/poppler/Movie.h b/poppler/Movie.h
index 7de3518..c49b12c 100644
--- a/poppler/Movie.h
+++ b/poppler/Movie.h
@@ -159,6 +159,7 @@ class Movie {
// write embedded stream to file
void outputToFile(FILE*);
+ void getAspect (int *widthA, int *heightA) { *widthA = width; *heightA = height; }
Stream* getPosterStream() { return posterStream; }
Movie* copy();
@@ -173,6 +174,9 @@ class Movie {
// "Best Effort" parameters
MovieParameters BE;
+ int width; // Aspect
+ int height; // Aspect
+
Stream* posterStream;
GBool isEmbedded;
commit f88d469f860da17055fc4b98b64aef241fcf0185
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Sat Mar 6 12:33:40 2010 +0100
Move Movie objects parsing code from Annot to Movie
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 16eea0d..411723e 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -4049,21 +4049,12 @@ AnnotMovie::AnnotMovie(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj) :
Annot(xrefA, dict, catalog, obj) {
type = typeMovie;
initialize(xrefA, catalog, dict);
-
- movie = new Movie();
- movie->parseAnnotMovie(this);
}
AnnotMovie::~AnnotMovie() {
if (title)
delete title;
- if (fileName)
- delete fileName;
delete movie;
-
- if (posterStream && (!posterStream->decRef())) {
- delete posterStream;
- }
}
void AnnotMovie::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) {
@@ -4077,237 +4068,16 @@ void AnnotMovie::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) {
obj1.free();
Object movieDict;
- Object aDict;
-
- // default values
- fileName = NULL;
- width = 0;
- height = 0;
- rotationAngle = 0;
- rate = 1.0;
- volume = 1.0;
- showControls = false;
- repeatMode = repeatModeOnce;
- synchronousPlay = false;
-
- hasFloatingWindow = false;
- isFullscreen = false;
- FWScaleNum = 1;
- FWScaleDenum = 1;
- FWPosX = 0.5;
- FWPosY = 0.5;
-
if (dict->lookup("Movie", &movieDict)->isDict()) {
- Object obj2;
- if (getFileSpecNameForPlatform(movieDict.dictLookup("F", &obj1), &obj2)) {
- fileName = obj2.getString()->copy();
- obj2.free();
- }
- obj1.free();
-
- if (movieDict.dictLookup("Aspect", &obj1)->isArray()) {
- Array* aspect = obj1.getArray();
- if (aspect->getLength() >= 2) {
- Object tmp;
- if( aspect->get(0, &tmp)->isNum() ) {
- width = (int)floor( aspect->get(0, &tmp)->getNum() + 0.5 );
- }
- tmp.free();
- if( aspect->get(1, &tmp)->isNum() ) {
- height = (int)floor( aspect->get(1, &tmp)->getNum() + 0.5 );
- }
- tmp.free();
- }
- }
- obj1.free();
-
- if (movieDict.dictLookup("Rotate", &obj1)->isInt()) {
- // round up to 90°
- rotationAngle = (((obj1.getInt() + 360) % 360) % 90) * 90;
- }
- obj1.free();
-
- //
- // movie poster
- //
- posterType = posterTypeNone;
- posterStream = NULL;
- if (!movieDict.dictLookup("Poster", &obj1)->isNone()) {
- if (obj1.isBool()) {
- GBool v = obj1.getBool();
- if (v)
- posterType = posterTypeFromMovie;
- }
-
- if (obj1.isStream()) {
- posterType = posterTypeStream;
-
- // "copy" stream
- posterStream = obj1.getStream();
- posterStream->incRef();
- }
-
- obj1.free();
- }
-
+ Object aDict;
+ dict->lookup("A", &aDict);
+ movie = Movie::fromMovie (&movieDict, &aDict);
+ aDict.free();
+ } else {
+ error(-1, "Bad Annot Movie");
+ ok = gFalse;
}
movieDict.free();
-
-
- // activation dictionary parsing ...
-
- if (dict->lookup("A", &aDict)->isDict()) {
- if (!aDict.dictLookup("Start", &obj1)->isNone()) {
- if (obj1.isInt()) {
- // If it is representable as an integer (subject to the implementation limit for
- // integers, as described in Appendix C), it should be specified as such.
-
- start.units = obj1.getInt();
- }
- if (obj1.isString()) {
- // If it is not representable as an integer, it should be specified as an 8-byte
- // string representing a 64-bit twos-complement integer, most significant
- // byte first.
-
- // UNSUPPORTED
- }
-
- if (obj1.isArray()) {
- Array* a = obj1.getArray();
-
- Object tmp;
- a->get(0, &tmp);
- if (tmp.isInt()) {
- start.units = tmp.getInt();
- }
- if (tmp.isString()) {
- // UNSUPPORTED
- }
- tmp.free();
-
- a->get(1, &tmp);
- if (tmp.isInt()) {
- start.units_per_second = tmp.getInt();
- }
- tmp.free();
- }
- }
- obj1.free();
-
- if (!aDict.dictLookup("Duration", &obj1)->isNone()) {
- if (obj1.isInt()) {
- duration.units = obj1.getInt();
- }
- if (obj1.isString()) {
- // UNSUPPORTED
- }
-
- if (obj1.isArray()) {
- Array* a = obj1.getArray();
-
- Object tmp;
- a->get(0, &tmp);
- if (tmp.isInt()) {
- duration.units = tmp.getInt();
- }
- if (tmp.isString()) {
- // UNSUPPORTED
- }
- tmp.free();
-
- a->get(1, &tmp);
- if (tmp.isInt()) {
- duration.units_per_second = tmp.getInt();
- }
- tmp.free();
- }
- }
- obj1.free();
-
- if (aDict.dictLookup("Rate", &obj1)->isNum()) {
- rate = obj1.getNum();
- }
- obj1.free();
-
- if (aDict.dictLookup("Volume", &obj1)->isNum()) {
- volume = obj1.getNum();
- }
- obj1.free();
-
- if (aDict.dictLookup("ShowControls", &obj1)->isBool()) {
- showControls = obj1.getBool();
- }
- obj1.free();
-
- if (aDict.dictLookup("Synchronous", &obj1)->isBool()) {
- synchronousPlay = obj1.getBool();
- }
- obj1.free();
-
- if (aDict.dictLookup("Mode", &obj1)->isName()) {
- char* name = obj1.getName();
- if (!strcmp(name, "Once"))
- repeatMode = repeatModeOnce;
- if (!strcmp(name, "Open"))
- repeatMode = repeatModeOpen;
- if (!strcmp(name, "Repeat"))
- repeatMode = repeatModeRepeat;
- if (!strcmp(name,"Palindrome"))
- repeatMode = repeatModePalindrome;
- }
- obj1.free();
-
- if (aDict.dictLookup("FWScale", &obj1)->isArray()) {
- // the presence of that entry implies that the movie is to be played
- // in a floating window
- hasFloatingWindow = true;
-
- Array* scale = obj1.getArray();
- if (scale->getLength() >= 2) {
- Object tmp;
- if (scale->get(0, &tmp)->isInt()) {
- FWScaleNum = tmp.getInt();
- }
- tmp.free();
- if (scale->get(1, &tmp)->isInt()) {
- FWScaleDenum = tmp.getInt();
- }
- tmp.free();
- }
-
- // detect fullscreen mode
- if ((FWScaleNum == 999) && (FWScaleDenum == 1)) {
- isFullscreen = true;
- }
- }
- obj1.free();
-
- if (aDict.dictLookup("FWPosition", &obj1)->isArray()) {
- Array* pos = obj1.getArray();
- if (pos->getLength() >= 2) {
- Object tmp;
- if (pos->get(0, &tmp)->isNum()) {
- FWPosX = tmp.getNum();
- }
- tmp.free();
- if (pos->get(1, &tmp)->isNum()) {
- FWPosY = tmp.getNum();
- }
- tmp.free();
- }
- }
- }
- aDict.free();
-}
-
-void AnnotMovie::getMovieSize(int& width, int& height) {
- width = this->width;
- height = this->height;
-}
-
-void AnnotMovie::getZoomFactor(int& num, int& denum) {
- num = FWScaleNum;
- denum = FWScaleDenum;
}
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 0059845..14cafd0 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -699,89 +699,18 @@ private:
class AnnotMovie: public Annot {
public:
- enum PosterType {
- posterTypeNone,
- posterTypeStream,
- posterTypeFromMovie
- };
-
- enum RepeatMode {
- repeatModeOnce,
- repeatModeOpen,
- repeatModeRepeat,
- repeatModePalindrome
- };
-
- struct Time {
- Time() { units_per_second = 0; }
- Gulong units;
- int units_per_second; // 0 : defined by movie
- };
-
AnnotMovie(XRef *xrefA, PDFRectangle *rect, Movie *movieA, Catalog *catalog);
AnnotMovie(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj);
~AnnotMovie();
GooString* getTitle() { return title; }
- GooString* getFileName() { return fileName; }
- int getRotationAngle() { return rotationAngle; }
-
- PosterType getPosterType() { return posterType; }
- Stream* getPosterStream() { return posterStream; }
-
- Time getStart() { return start; }
- Time getDuration() { return duration; }
- double getRate() { return rate; }
- double getVolume() { return volume; }
-
- GBool getShowControls() { return showControls; }
- RepeatMode getRepeatMode() { return repeatMode; }
- GBool getSynchronousPlay() { return synchronousPlay; }
-
- GBool needFloatingWindow() { return hasFloatingWindow; }
- GBool needFullscreen() { return isFullscreen; }
-
-
- void getMovieSize(int& width, int& height);
- void getZoomFactor(int& num, int& denum);
- void getWindowPosition(double& x, double& y) { x = FWPosX; y = FWPosY; }
-
Movie* getMovie() { return movie; }
private:
void initialize(XRef *xrefA, Catalog *catalog, Dict *dict);
GooString* title; // T
- GooString* fileName; // Movie/F
-
- int width; // Movie/Aspect
- int height; // Movie/Aspect
- int rotationAngle; // Movie/Rotate
-
- PosterType posterType; // Movie/Poster
- Stream* posterStream;
-
- Time start; // A/Start
- Time duration; // A/Duration
- double rate; // A/Rate
- double volume; // A/Volume
-
- GBool showControls; // A/ShowControls
-
- RepeatMode repeatMode; // A/Mode
-
- GBool synchronousPlay; // A/Synchronous
-
- // floating window
- GBool hasFloatingWindow;
- unsigned short FWScaleNum; // A/FWScale
- unsigned short FWScaleDenum;
- GBool isFullscreen;
-
- double FWPosX; // A/FWPosition
- double FWPosY;
-
- Movie* movie;
+ Movie* movie; // Movie + A
};
diff --git a/poppler/Link.cc b/poppler/Link.cc
index 5f3b8bd..3649d25 100644
--- a/poppler/Link.cc
+++ b/poppler/Link.cc
@@ -712,10 +712,8 @@ LinkRendition::LinkRendition(Object *Obj) {
// retrieve rendition object
Obj->dictLookup("R", &renditionObj);
if (renditionObj.isDict()) {
+ movie = Movie::fromMediaRendition(&renditionObj);
- movie = new Movie();
- movie->parseMediaRendition(&renditionObj);
-
if (screenRef.num == -1) {
error(-1, "Action Rendition : Rendition without Screen Annotation !");
}
diff --git a/poppler/Movie.cc b/poppler/Movie.cc
index e29c64e..0b4d838 100644
--- a/poppler/Movie.cc
+++ b/poppler/Movie.cc
@@ -5,6 +5,7 @@
//---------------------------------------------------------------------------------
// Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
// Pino Toscano <pino at kde.org> (c) 2008
+// Carlos Garcia Campos <carlosgc at gnome.org> (c) 2010
//
// 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
@@ -21,7 +22,9 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//*********************************************************************************
+#include <math.h>
#include "Movie.h"
+#include "FileSpec.h"
#include <GooList.h>
@@ -141,7 +144,8 @@ MovieParameters::MovieParameters() {
repeatCount = 1.0;
opacity = 1.0;
showControls = gFalse;
-
+ synchronousPlay = gFalse;
+ repeatMode = repeatModeOnce;
start.units = 0;
duration.units = 0;
@@ -150,46 +154,162 @@ MovieParameters::MovieParameters() {
MovieParameters::~MovieParameters() {
}
-void MovieParameters::parseAnnotMovie(AnnotMovie* annot) {
- windowParams.relativeTo = MovieWindowParameters::windowRelativeToDesktop;
+void MovieParameters::parseMovieActivation(Object* aDict,
+ int width, int height,
+ int rotationAngleA) {
+ Object obj1;
- if (annot->needFloatingWindow()) {
- windowParams.type = MovieWindowParameters::movieWindowFloating;
+ if (!aDict->dictLookup("Start", &obj1)->isNone()) {
+ if (obj1.isInt()) {
+ // If it is representable as an integer (subject to the implementation limit for
+ // integers, as described in Appendix C), it should be specified as such.
+
+ start.units = obj1.getInt();
+ }
+ if (obj1.isString()) {
+ // If it is not representable as an integer, it should be specified as an 8-byte
+ // string representing a 64-bit twos-complement integer, most significant
+ // byte first.
+
+ // UNSUPPORTED
+ }
+
+ if (obj1.isArray()) {
+ Array* a = obj1.getArray();
+
+ Object tmp;
+ a->get(0, &tmp);
+ if (tmp.isInt()) {
+ start.units = tmp.getInt();
+ }
+ if (tmp.isString()) {
+ // UNSUPPORTED
+ }
+ tmp.free();
+
+ a->get(1, &tmp);
+ if (tmp.isInt()) {
+ start.units_per_second = tmp.getInt();
+ }
+ tmp.free();
+ }
}
- if (annot->needFullscreen()) {
- windowParams.type = MovieWindowParameters::movieWindowFullscreen;
+ obj1.free();
+
+ if (!aDict->dictLookup("Duration", &obj1)->isNone()) {
+ if (obj1.isInt()) {
+ duration.units = obj1.getInt();
+ }
+ if (obj1.isString()) {
+ // UNSUPPORTED
+ }
+
+ if (obj1.isArray()) {
+ Array* a = obj1.getArray();
+
+ Object tmp;
+ a->get(0, &tmp);
+ if (tmp.isInt()) {
+ duration.units = tmp.getInt();
+ }
+ if (tmp.isString()) {
+ // UNSUPPORTED
+ }
+ tmp.free();
+
+ a->get(1, &tmp);
+ if (tmp.isInt()) {
+ duration.units_per_second = tmp.getInt();
+ }
+ tmp.free();
+ }
+ }
+ obj1.free();
+
+ if (aDict->dictLookup("Rate", &obj1)->isNum()) {
+ rate = obj1.getNum();
+ }
+ obj1.free();
+
+ rotationAngle = rotationAngleA;
+
+ if (aDict->dictLookup("Volume", &obj1)->isNum()) {
+ // convert volume to [0 100]
+ volume = int((obj1.getNum() + 1.0) * 50);
}
+ obj1.free();
- 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);
+ if (aDict->dictLookup("ShowControls", &obj1)->isBool()) {
+ showControls = obj1.getBool();
+ }
+ obj1.free();
- double x,y;
- annot->getWindowPosition(x,y);
- windowParams.XPosition = x;
- windowParams.YPosition = y;
+ if (aDict->dictLookup("Synchronous", &obj1)->isBool()) {
+ synchronousPlay = obj1.getBool();
+ }
+ obj1.free();
+
+ if (aDict->dictLookup("Mode", &obj1)->isName()) {
+ char* name = obj1.getName();
+ if (!strcmp(name, "Once")) {
+ repeatMode = repeatModeOnce;
+ } else if (!strcmp(name, "Open")) {
+ repeatMode = repeatModeOpen;
+ } else if (!strcmp(name, "Repeat")) {
+ repeatMode = repeatModeRepeat;
+ repeatCount = 0.0;
+ } else if (!strcmp(name,"Palindrome")) {
+ repeatMode = repeatModePalindrome;
+ }
+ }
+ obj1.free();
- rate = annot->getRate();
- // convert volume to [0 100]
- volume = int((annot->getVolume() + 1.0) * 50);
+ windowParams.relativeTo = MovieWindowParameters::windowRelativeToDesktop;
- AnnotMovie::RepeatMode mode = annot->getRepeatMode();
- if (mode == AnnotMovie::repeatModeRepeat)
- repeatCount = 0.0;
+ int znum = 1, zdenum = 1;
+ if (aDict->dictLookup("FWScale", &obj1)->isArray()) {
+ // the presence of that entry implies that the movie is to be played
+ // in a floating window
+ windowParams.type = MovieWindowParameters::movieWindowFloating;
- showControls = annot->getShowControls();
+ Array* scale = obj1.getArray();
+ if (scale->getLength() >= 2) {
+ Object tmp;
+ if (scale->get(0, &tmp)->isInt()) {
+ znum = tmp.getInt();
+ }
+ tmp.free();
+ if (scale->get(1, &tmp)->isInt()) {
+ zdenum = tmp.getInt();
+ }
+ tmp.free();
+ }
- AnnotMovie::Time tStart = annot->getStart();
- AnnotMovie::Time tDuration = annot->getDuration();
+ // detect fullscreen mode
+ if (znum == 999 && zdenum == 1) {
+ windowParams.type = MovieWindowParameters::movieWindowFullscreen;
+ }
+ }
+ obj1.free();
- start.units = tStart.units;
- start.units_per_second = tStart.units_per_second;
+ windowParams.width = int(width * double(znum) / zdenum);
+ windowParams.height = int(height * double(znum) / zdenum);
- duration.units = tDuration.units;
- duration.units_per_second = tDuration.units_per_second;
+ if (aDict->dictLookup("FWPosition", &obj1)->isArray()) {
+ Array* pos = obj1.getArray();
+ if (pos->getLength() >= 2) {
+ Object tmp;
+ if (pos->get(0, &tmp)->isNum()) {
+ windowParams.XPosition = tmp.getNum();
+ }
+ tmp.free();
+ if (pos->get(1, &tmp)->isNum()) {
+ windowParams.YPosition = tmp.getNum();
+ }
+ tmp.free();
+ }
+ }
+ obj1.free();
}
void MovieParameters::parseMediaPlayParameters(Object* obj) {
@@ -305,7 +425,7 @@ void MovieParameters::parseMediaScreenParameters(Object* obj) {
}
}
-Movie::Movie() {
+void Movie::initialize() {
fileName = NULL;
contentType = NULL;
isEmbedded = gFalse;
@@ -327,26 +447,64 @@ Movie::~Movie() {
}
}
-void Movie::parseAnnotMovie(AnnotMovie* annot) {
- // AnnotMovie is not embedded
- isEmbedded = gFalse;
+Movie::Movie(Object *movieDict, Object *aDict) {
+ initialize();
- fileName = annot->getFileName()->copy();
+ Object obj1, obj2;
+ if (getFileSpecNameForPlatform(movieDict->dictLookup("F", &obj1), &obj2)) {
+ fileName = obj2.getString()->copy();
+ obj2.free();
+ }
+ obj1.free();
+
+ int width = 0, height = 0;
+ if (movieDict->dictLookup("Aspect", &obj1)->isArray()) {
+ Array* aspect = obj1.getArray();
+ if (aspect->getLength() >= 2) {
+ Object tmp;
+ if( aspect->get(0, &tmp)->isNum() ) {
+ width = (int)floor( aspect->get(0, &tmp)->getNum() + 0.5 );
+ }
+ tmp.free();
+ if( aspect->get(1, &tmp)->isNum() ) {
+ height = (int)floor( aspect->get(1, &tmp)->getNum() + 0.5 );
+ }
+ tmp.free();
+ }
+ }
+ obj1.free();
- if (annot->getPosterStream()) {
- posterStream = annot->getPosterStream();
- posterStream->incRef();
+ int rotationAngle = 0;
+ if (movieDict->dictLookup("Rotate", &obj1)->isInt()) {
+ // round up to 90°
+ rotationAngle = (((obj1.getInt() + 360) % 360) % 90) * 90;
+ }
+ obj1.free();
+
+ //
+ // movie poster
+ //
+ if (!movieDict->dictLookup("Poster", &obj1)->isNone()) {
+ if (obj1.isStream()) {
+ // "copy" stream
+ posterStream = obj1.getStream();
+ posterStream->incRef();
+ }
+ obj1.free();
}
- MH.parseAnnotMovie(annot);
- // deep copy of MH to BE
- // (no distinction is made with AnnotMovie)
- memcpy(&BE, &MH, sizeof(MH));
+ if (aDict->isDict()) {
+ MH.parseMovieActivation(aDict, width, height, rotationAngle);
+ // deep copy of MH to BE
+ // (no distinction is made with AnnotMovie)
+ memcpy(&BE, &MH, sizeof(MH));
+ }
}
-void Movie::parseMediaRendition(Object* obj) {
-
+Movie::Movie(Object* obj) {
Object tmp, tmp2;
+
+ initialize();
if (obj->dictLookup("S", &tmp)->isName()) {
if (!strcmp(tmp.getName(), "MR")) { // it's a media rendition
@@ -427,6 +585,15 @@ void Movie::parseMediaRendition(Object* obj) {
}
}
+Movie *Movie::fromMovie(Object *objMovie, Object *objAct)
+{
+ return new Movie (objMovie, objAct);
+}
+
+Movie *Movie::fromMediaRendition(Object *objRend)
+{
+ return new Movie (objRend);
+}
void Movie::outputToFile(FILE* fp) {
embeddedStream->reset();
diff --git a/poppler/Movie.h b/poppler/Movie.h
index 16584ad..7de3518 100644
--- a/poppler/Movie.h
+++ b/poppler/Movie.h
@@ -4,6 +4,7 @@
//
//---------------------------------------------------------------------------------
// Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
+// Carlos Garcia Campos <carlosgc at gnome.org> (c) 2010
//
// 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
@@ -24,7 +25,6 @@
#define _MOVIE_H_
#include "Object.h"
-#include "Annot.h"
class GooList;
@@ -79,8 +79,8 @@ struct MovieParameters {
void parseMediaPlayParameters(Object* playObj);
// parse from a "Media Screen Parameters" dictionary
void parseMediaScreenParameters(Object* screenObj);
- // parse from a AnnotMovie object
- void parseAnnotMovie(AnnotMovie* annot);
+ // parse from a "Movie Activation" dictionary
+ void parseMovieActivation(Object* actObj, int width, int height, int rotationAngle);
enum MovieFittingPolicy {
fittingMeet = 0,
@@ -91,6 +91,13 @@ struct MovieParameters {
fittingUndefined
};
+ enum MovieRepeatMode {
+ repeatModeOnce,
+ repeatModeOpen,
+ repeatModeRepeat,
+ repeatModePalindrome
+ };
+
struct MovieTime {
MovieTime() { units_per_second = 0; }
Gulong units;
@@ -128,16 +135,18 @@ struct MovieParameters {
GBool showControls; // false
+ GBool synchronousPlay; // false
+ MovieRepeatMode repeatMode; // repeatModeOnce
+
MovieWindowParameters windowParams;
};
class Movie {
public:
- Movie();
~Movie();
- void parseAnnotMovie(AnnotMovie* annot);
- void parseMediaRendition(Object* obj);
+ static Movie *fromMovie(Object *objMovie, Object *objAct);
+ static Movie *fromMediaRendition(Object *objRend);
MovieParameters* getMHParameters() { return &MH; }
MovieParameters* getBEParameters() { return &BE; }
@@ -155,6 +164,10 @@ class Movie {
Movie* copy();
private:
+ Movie(Object *objMovie, Object *objAct);
+ Movie(Object *objRend);
+ void initialize();
+
// "Must Honor" parameters
MovieParameters MH;
// "Best Effort" parameters
diff --git a/qt4/src/poppler-movie.cc b/qt4/src/poppler-movie.cc
index 50e60f9..7941be1 100644
--- a/qt4/src/poppler-movie.cc
+++ b/qt4/src/poppler-movie.cc
@@ -48,10 +48,13 @@ MovieObject::MovieObject( AnnotMovie *ann )
{
m_movieData = new MovieData();
m_movieData->m_movieObj = ann->getMovie()->copy();
- ann->getMovieSize( m_movieData->m_size.rwidth(), m_movieData->m_size.rheight() );
- m_movieData->m_rotation = ann->getRotationAngle();
- m_movieData->m_showControls = ann->getShowControls();
- m_movieData->m_playMode = (MovieObject::PlayMode)ann->getRepeatMode();
+
+ MovieParameters *mp = m_movieData->m_movieObj->getMHParameters();
+ m_movieData->m_size.setWidth(mp->windowParams.width);
+ m_movieData->m_size.setHeight(mp->windowParams.height);
+ m_movieData->m_rotation = mp->rotationAngle;
+ m_movieData->m_showControls = mp->showControls;
+ m_movieData->m_playMode = (MovieObject::PlayMode)mp->repeatMode;
}
MovieObject::~MovieObject()
More information about the poppler
mailing list