[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", &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;
+}
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