source: trunk/poppler/mypoppler/poppler/Rendition.cc @ 461

Last change on this file since 461 was 461, checked in by Silvan Scherrer, 11 years ago

poppler update to 0.14.2

File size: 9.4 KB
Line 
1//*********************************************************************************
2//                               Rendition.cc
3//---------------------------------------------------------------------------------
4//
5//---------------------------------------------------------------------------------
6// Hugo Mercier <hmercier31[at]gmail.com> (c) 2008
7// Pino Toscano <pino@kde.org> (c) 2008
8// Carlos Garcia Campos <carlosgc@gnome.org> (c) 2010
9//
10// This program is free software; you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation; either version 2 of the License, or
13// (at your option) any later version.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program; if not, write to the Free Software
22// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23//*********************************************************************************
24
25#include <math.h>
26#include "Rendition.h"
27#include "FileSpec.h"
28
29MediaWindowParameters::MediaWindowParameters() {
30  // default values
31  type = windowEmbedded;
32  width = -1;
33  height = -1;
34  relativeTo = windowRelativeToDocument;
35  XPosition = 0.5;
36  YPosition = 0.5;
37  hasTitleBar = gTrue;
38  hasCloseButton = gTrue;
39  isResizeable = gTrue;
40}
41
42MediaWindowParameters::~MediaWindowParameters() {
43}
44
45void MediaWindowParameters::parseFWParams(Object* obj) {
46  Object tmp;
47
48  if (obj->dictLookup("D", &tmp)->isArray()) {
49    Array * dim = tmp.getArray();
50   
51    if (dim->getLength() >= 2) {
52      Object dd;
53      if (dim->get(0, &dd)->isInt()) {
54        width = dd.getInt();
55      }
56      dd.free();
57      if (dim->get(1, &dd)->isInt()) {
58        height = dd.getInt();
59      }
60      dd.free();
61    }
62  }
63  tmp.free();
64
65  if (obj->dictLookup("RT", &tmp)->isInt()) {
66    int t = tmp.getInt();
67    switch(t) {
68    case 0: relativeTo = windowRelativeToDocument; break;
69    case 1: relativeTo = windowRelativeToApplication; break;
70    case 2: relativeTo = windowRelativeToDesktop; break;
71    }
72  }
73  tmp.free();
74
75  if (obj->dictLookup("P",&tmp)->isInt()) {
76    int t = tmp.getInt();
77
78    switch(t) {
79    case 0: // Upper left
80      XPosition = 0.0;
81      YPosition = 0.0;
82      break;
83    case 1: // Upper Center
84      XPosition = 0.5;
85      YPosition = 0.0;
86      break;
87    case 2: // Upper Right
88      XPosition = 1.0;
89      YPosition = 0.0;
90      break;
91    case 3: // Center Left
92      XPosition = 0.0;
93      YPosition = 0.5;
94      break;
95    case 4: // Center
96      XPosition = 0.5;
97      YPosition = 0.5;
98      break;
99    case 5: // Center Right
100      XPosition = 1.0;
101      YPosition = 0.5;
102      break;
103    case 6: // Lower Left
104      XPosition = 0.0;
105      YPosition = 1.0;
106      break;
107    case 7: // Lower Center
108      XPosition = 0.5;
109      YPosition = 1.0;
110      break;
111    case 8: // Lower Right
112      XPosition = 1.0;
113      YPosition = 1.0;
114      break;
115    }
116  }
117  tmp.free();
118
119  if (obj->dictLookup("T", &tmp)->isBool()) {
120    hasTitleBar = tmp.getBool();
121  }
122  tmp.free();
123  if (obj->dictLookup("UC", &tmp)->isBool()) {
124    hasCloseButton = tmp.getBool();
125  }
126  tmp.free();
127  if (obj->dictLookup("R", &tmp)->isInt()) {
128    isResizeable = (tmp.getInt() != 0);
129  }
130  tmp.free();
131
132}
133
134MediaParameters::MediaParameters() {
135  // instanciate to default values
136
137  volume = 100;
138  fittingPolicy = fittingUndefined;
139  autoPlay = gTrue;
140  repeatCount = 1.0;
141  opacity = 1.0;
142  showControls = gFalse;
143  duration = 0;
144}
145
146MediaParameters::~MediaParameters() {
147}
148
149void MediaParameters::parseMediaPlayParameters(Object* obj) {
150 
151  Object tmp;
152
153  if (obj->dictLookup("V", &tmp)->isInt()) {
154    volume = tmp.getInt();
155  }
156  tmp.free();
157
158  if (obj->dictLookup("C", &tmp)->isBool()) {
159    showControls = tmp.getBool();
160  }
161  tmp.free();
162
163  if (obj->dictLookup("F", &tmp)->isInt()) {
164    int t = tmp.getInt();
165   
166    switch(t) {
167    case 0: fittingPolicy = fittingMeet; break;
168    case 1: fittingPolicy = fittingSlice; break;
169    case 2: fittingPolicy = fittingFill; break;
170    case 3: fittingPolicy = fittingScroll; break;
171    case 4: fittingPolicy = fittingHidden; break;
172    case 5: fittingPolicy = fittingUndefined; break;
173    }
174  }
175  tmp.free();
176
177  // duration parsing
178  // duration's default value is set to 0, which means : intrinsinc media duration
179  if (obj->dictLookup("D", &tmp)->isDict()) {
180    Object oname, ddict, tmp2;
181    if (tmp.dictLookup("S", &oname)->isName()) {
182      char* name = oname.getName();
183      if (!strcmp(name, "F"))
184        duration = -1; // infinity
185      else if (!strcmp(name, "T")) {
186        if (tmp.dictLookup("T", &ddict)->isDict()) {
187          if (ddict.dictLookup("V", &tmp2)->isNum()) {
188            duration = Gulong(tmp2.getNum());
189          }
190          tmp2.free();
191        }
192        ddict.free();
193      }
194    }
195    oname.free();
196  }
197  tmp.free();
198
199
200  if (obj->dictLookup("A", &tmp)->isBool()) {
201    autoPlay = tmp.getBool();
202  }
203  tmp.free();
204
205  if (obj->dictLookup("RC", &tmp)->isNum()) {
206    repeatCount = tmp.getNum();
207  }
208  tmp.free();
209
210}
211
212void MediaParameters::parseMediaScreenParameters(Object* obj) {
213  Object tmp;
214
215  if (obj->dictLookup("W", &tmp)->isInt()) {
216    int t = tmp.getInt();
217   
218    switch(t) {
219    case 0: windowParams.type = MediaWindowParameters::windowFloating; break;
220    case 1: windowParams.type = MediaWindowParameters::windowFullscreen; break;
221    case 2: windowParams.type = MediaWindowParameters::windowHidden; break;
222    case 3: windowParams.type = MediaWindowParameters::windowEmbedded; break;
223    }
224  }
225  tmp.free();
226
227  // background color
228  if (obj->dictLookup("B", &tmp)->isArray()) {
229    Array* color = tmp.getArray();
230
231    Object component;
232   
233    color->get(0, &component);
234    bgColor.r = component.getNum();
235    component.free();
236
237    color->get(1, &component);
238    bgColor.g = component.getNum();
239    component.free();
240
241    color->get(2, &component);
242    bgColor.b = component.getNum();
243    component.free();
244  }
245  tmp.free();
246
247
248  // opacity
249  if (obj->dictLookup("O", &tmp)->isNum()) {
250    opacity = tmp.getNum();
251  }
252  tmp.free();
253
254  if (windowParams.type == MediaWindowParameters::windowFloating) {
255    Object winDict;
256    if (obj->dictLookup("F",&winDict)->isDict()) {
257      windowParams.parseFWParams(&winDict);
258    }
259    winDict.free();
260  }
261}
262
263MediaRendition::~MediaRendition() {
264  if (fileName)
265    delete fileName;
266  if (contentType)
267    delete contentType;
268
269  if (embeddedStream && (!embeddedStream->decRef())) {
270    delete embeddedStream;
271  }
272}
273
274MediaRendition::MediaRendition(Object* obj) {
275  Object tmp, tmp2;
276  GBool hasClip = gFalse;
277
278  ok = gTrue;
279  fileName = NULL;
280  contentType = NULL;
281  isEmbedded = gFalse;
282  embeddedStream = NULL;
283
284  //
285  // Parse media clip data
286  //
287  if (obj->dictLookup("C", &tmp2)->isDict()) { // media clip
288    hasClip = gTrue;
289    if (tmp2.dictLookup("S", &tmp)->isName()) {
290      if (!strcmp(tmp.getName(), "MCD")) { // media clip data
291        Object obj1, obj2;
292        if (tmp2.dictLookup("D", &obj1)->isDict()) {
293          if (obj1.dictLookup("F", &obj2)->isString()) {
294            fileName = obj2.getString()->copy();
295          }
296          obj2.free();
297          if (obj1.dictLookup("EF", &obj2)->isDict()) {
298            Object embedded;
299            if (obj2.dictLookup("F", &embedded)->isStream()) {
300              isEmbedded = gTrue;
301              embeddedStream = embedded.getStream();
302              // "copy" stream
303              embeddedStream->incRef();
304            }
305            embedded.free();
306          }
307          obj2.free();
308
309          // TODO: D might be a form XObject too
310        } else {
311          error (-1, "Invalid Media Clip Data");
312          ok = gFalse;
313        }
314        obj1.free();
315
316        // FIXME: ignore CT if D is a form XObject
317        if (tmp2.dictLookup("CT", &obj1)->isString()) {
318          contentType = obj1.getString()->copy();
319        }
320        obj1.free();
321      } else if (!strcmp(tmp.getName(), "MCS")) { // media clip data
322        // TODO
323      }
324    } else {
325      error (-1, "Invalid Media Clip");
326      ok = gFalse;
327    }
328    tmp.free();
329  }
330  tmp2.free();
331
332  if (!ok)
333    return;
334
335  //
336  // parse Media Play Parameters
337  if (obj->dictLookup("P", &tmp2)->isDict()) { // media play parameters
338    Object params;
339    if (tmp2.dictLookup("MH", &params)->isDict()) {
340      MH.parseMediaPlayParameters(&params);
341    }
342    params.free();
343    if (tmp2.dictLookup("BE", &params)->isDict()) {
344      BE.parseMediaPlayParameters(&params);
345    }
346    params.free();
347  } else if (hasClip) {
348    error (-1, "Invalid Media Rendition");
349    ok = gFalse;
350  }
351  tmp2.free();
352
353  //
354  // parse Media Screen Parameters
355  if (obj->dictLookup("SP", &tmp2)->isDict()) { // media screen parameters
356    Object params;
357    if (tmp2.dictLookup("MH", &params)->isDict()) {
358      MH.parseMediaScreenParameters(&params);
359    }
360    params.free();
361    if (tmp2.dictLookup("BE", &params)->isDict()) {
362      BE.parseMediaScreenParameters(&params);
363    }
364    params.free();
365  }
366  tmp2.free();
367}
368
369void MediaRendition::outputToFile(FILE* fp) {
370  if (!isEmbedded)
371    return;
372
373  embeddedStream->reset();
374
375  while (1) {
376    int c = embeddedStream->getChar();
377    if (c == EOF)
378      break;
379   
380    fwrite(&c, 1, 1, fp);
381  }
382 
383}
384
385MediaRendition *MediaRendition::copy() {
386  // call default copy constructor
387  MediaRendition* new_media = new MediaRendition(*this);
388
389  if (contentType)
390    new_media->contentType = contentType->copy();
391  if (fileName)
392    new_media->fileName = fileName->copy();
393
394  if (new_media->embeddedStream)
395    new_media->embeddedStream->incRef();
396
397  return new_media;
398}
399
400// TODO: SelectorRendition
Note: See TracBrowser for help on using the repository browser.