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 <[email protected]> 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 <[email protected]> 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 <[email protected]> // Copyright (C) 2007, 2008 Julien Rebetez <[email protected]> // Copyright (C) 2007-2009 Albert Astals Cid <[email protected]> -// Copyright (C) 2007-2009 Carlos Garcia Campos <[email protected]> +// Copyright (C) 2007-2010 Carlos Garcia Campos <[email protected]> // Copyright (C) 2007, 2008 Iñigo MartÃnez <[email protected]> // Copyright (C) 2007 Jeff Muizelaar <[email protected]> // Copyright (C) 2008 Pino Toscano <[email protected]> @@ -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 <[email protected]> // Copyright (C) 2007, 2008 Julien Rebetez <[email protected]> -// Copyright (C) 2007-2009 Carlos Garcia Campos <[email protected]> +// Copyright (C) 2007-2010 Carlos Garcia Campos <[email protected]> // Copyright (C) 2007, 2008 Iñigo MartÃnez <[email protected]> // Copyright (C) 2008 Michael Vrable <[email protected]> // Copyright (C) 2008 Hugo Mercier <[email protected]> @@ -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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> (c) 2008 +// Carlos Garcia Campos <[email protected]> (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 <[email protected]> (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()
_______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
