[poppler] Patch for embedding videos in to the pdf

srinivas adicherla srinivas.adicherla at gmail.com
Fri Mar 25 04:42:22 PDT 2011


Hi
  Sorry I didn't attach the patch in previous mail.
  I attached with this mail.

Thanks
--
A Srinivas


On Fri, Mar 25, 2011 at 5:11 PM, srinivas adicherla <
srinivas.adicherla at gmail.com> wrote:

> Hi Carlos,
>
>           Thank you for helping me.
>           I made the changes suggested by you. Please check the patch. Let
> me know for any more changes.
>
> Thanks
> --
> A Srinivas
>
> On Thu, Mar 24, 2011 at 12:30 AM, <poppler-request at lists.freedesktop.org>wrote:
>
>> Send poppler mailing list submissions to
>>        poppler at lists.freedesktop.org
>>
>> To subscribe or unsubscribe via the World Wide Web, visit
>>        http://lists.freedesktop.org/mailman/listinfo/poppler
>> or, via email, send a message with subject or body 'help' to
>>        poppler-request at lists.freedesktop.org
>>
>> You can reach the person managing the list at
>>        poppler-owner at lists.freedesktop.org
>>
>> When replying, please edit your Subject line so it is more specific
>> than "Re: Contents of poppler digest..."
>>
>>
>> Today's Topics:
>>
>>   1. Re: poppler Digest, Vol 73, Issue 27 (Carlos Garcia Campos)
>>   2. Plans to get Javascript support in Poppler.
>>      (jose.aliste at gmail.com)
>>
>>
>> ----------------------------------------------------------------------
>>
>> Message: 1
>> Date: Wed, 23 Mar 2011 15:18:41 +0100
>> From: Carlos Garcia Campos <carlosgc at gnome.org>
>> Subject: Re: [poppler] poppler Digest, Vol 73, Issue 27
>> To: srinivas adicherla <srinivas.adicherla at gmail.com>
>> Cc: poppler <poppler at lists.freedesktop.org>
>> Message-ID: <1300886015-sup-4220 at charizard>
>> Content-Type: text/plain; charset="utf8"
>>
>> Excerpts from srinivas adicherla's message of mi? mar 23 08:30:32 +0100
>> 2011:
>> > Hi Carlos,
>>
>> Hi,
>>
>> >             Thank you for your valuable suggestions. I made the changes
>> > according to that. I attached a new patch with this.
>>
>> Thanks!
>>
>> > -  I have some doubt when setting a 'Rendition' action, we have two
>> options
>> > one is to set 'OP' other one is 'JS'. I am asking the user to pass the
>> > Javascript and set it as a stream here.
>>
>> Since both options are required when the other one is not present, I
>> would add two constructors, one for OP, and another one for JS.
>>
>>  LinkRendition::LinkRendition(XRef *xrefA, MediaRendition *rendition, int
>> operation, Annot *annot);
>>  LinkRendition::LinkRendition(XRef *xrefA, Object *js);
>>
>> > - One more is i wrote a new function 'get_file_name_from_path' is it
>> fine?
>> > what is the good place to add this function.
>>
>> yes, just rename it to follow poppler coding style to something like:
>>
>>  getFileNameFromPath();
>>
>> > Please give suggestions again.
>>
>> See comments below
>>
>> > Thanks
>>
>> Index: poppler-0.16.2/poppler/Link.cc
>> ===================================================================
>> --- poppler-0.16.2/poppler/Link.cc      (revision 12)
>> +++ poppler-0.16.2/poppler/Link.cc      (working copy)
>> @@ -44,6 +44,7 @@
>>  #include "Sound.h"
>>  #include "FileSpec.h"
>>  #include "Rendition.h"
>> +#include "XRef.h"
>>
>>
>>  //------------------------------------------------------------------------
>>  // LinkAction
>> @@ -738,6 +739,32 @@
>>   }
>>  }
>>
>> +LinkRendition::LinkRendition(Annot *annot, const char *video_file,Object
>> *obj) {
>>
>> This method should receive the XRef, and the MediaRendition object
>> already created. See the contructors I suggested above.
>>
>> +  Object obj1;
>> +  XRef *xref = annot->getXRef();
>> +  renditionObj.initDict(xref);
>> +  Ref annotref = annot->getRef();
>> +  renditionObj.dictSet("Type", obj1.initName("Action"));
>> +  renditionObj.dictSet("S", obj1.initName("Rendition"));
>> +  if (obj->isInt()) {
>> +    renditionObj.dictSet("OP", obj);
>> +    renditionObj.dictSet("AN", obj1.initRef(annotref.num, annotref.gen));
>> +  }
>> +  else {
>> +    renditionObj.dictSet("JS", obj);
>> +  }
>> +
>> +  // Media Rendition
>> +  Object MRendition;
>> +  MediaRendition *MR = new MediaRendition(annot, video_file);
>> +  MRendition = MR->getMediaRendition();
>> +
>> +  Ref newRef;
>> +  newRef = xref->addIndirectObject(&MRendition);
>> +  obj->initRef(newRef.num, newRef.gen);
>> +  renditionObj.dictSet("R", &obj1);
>> +}
>> +
>>  LinkRendition::~LinkRendition() {
>>   renditionObj.free();
>>   screenRef.free();
>>
>> Index: poppler-0.16.2/poppler/Rendition.cc
>> ===================================================================
>> --- poppler-0.16.2/poppler/Rendition.cc (revision 12)
>> +++ poppler-0.16.2/poppler/Rendition.cc (working copy)
>> @@ -24,6 +24,7 @@
>>
>>  #include <math.h>
>>  #include "Rendition.h"
>> +#include "XRef.h"
>>  #include "FileSpec.h"
>>
>>  MediaWindowParameters::MediaWindowParameters() {
>> @@ -366,6 +367,40 @@
>>   tmp2.free();
>>  }
>>
>> +MediaRendition::MediaRendition(Annot *annot, const char *mediafile) {
>>
>> Pass the XRef directly instead of passing the annot object just to get
>> the XRef
>>
>> + Object obj1, obj2;
>> +
>> + XRef *xref = annot->getXRef();
>> + mediaRendition.initDict(xref);
>> + mediaRendition.dictSet("S", obj1.initName("MR"));
>> +
>> + // Media Clip Dictionary
>> + Object MClipDict;
>> + MClipDict.initDict(xref);
>> + MClipDict.dictSet("S", obj1.initName("MCD"));
>> +
>> + //if (mimetype)
>> + //MClipDict.dictSet("CT", obj3.initString(new GooString(mimetype)));
>>
>> There's a contentType variable for this, so make sure it's updated so
>> that MediaRendition::getContentType() will work. Why is this commented?
>>
>> + obj1.initString(new GooString("TEMPACCESS"));
>> + obj2.initDict(xref);
>> + obj2.dictSet("TF", &obj1);
>> + MClipDict.dictSet("P", &obj2);
>>
>> The Permissions dictionary is optional, why are you hardcoding
>> TEMPACCESS here? We are not even parsing TF when creating a
>> MediaRendition from an existing dictionary.
>>
>> + // File Specification Dictionary
>> + Object *fsDict;
>> + fsDict = annot->createFilespec(mediafile);
>>
>> As Pino suggested this should probably be moved to FileSpec.cc since
>> it's not specific to annotations.
>>
>> +
>> + Ref newRef;
>> + newRef = xref->addIndirectObject(fsDict);
>> + obj2.initRef(newRef.num, newRef.gen);
>> + MClipDict.dictSet("D", &obj2);
>>
>> You should initialize the fileName, isEmbedded and embeddedStream
>> variables,
>> maybe it's the time to add a FileSpec class so that this methos just
>> receives a FileSpec object instead of a filename.
>>
>> + newRef = xref->addIndirectObject(&MClipDict);
>> + obj2.initRef(newRef.num, newRef.gen);
>> + mediaRendition.dictSet("C", &obj2);
>>
>> ok variable should be initialized to gTrue.
>>
>> +}
>> +
>>  void MediaRendition::outputToFile(FILE* fp) {
>>   if (!isEmbedded)
>>     return;
>> Index: poppler-0.16.2/poppler/Rendition.h
>> ===================================================================
>> --- poppler-0.16.2/poppler/Rendition.h  (revision 12)
>> +++ poppler-0.16.2/poppler/Rendition.h  (working copy)
>> @@ -25,6 +25,7 @@
>>  #define _RENDITION_H_
>>
>>  #include "Object.h"
>> +#include "Annot.h"
>>
>>  struct MediaWindowParameters {
>>
>> @@ -118,6 +119,7 @@
>>  class MediaRendition {
>>  public:
>>   MediaRendition(Object *obj);
>> +  MediaRendition(Annot *annot, const char *mediafile);
>>   ~MediaRendition();
>>
>>   GBool isOk () { return ok; }
>> @@ -128,6 +130,7 @@
>>   GooString* getContentType() { return contentType; }
>>   GooString* getFileName() { return fileName; }
>>
>> +  Object getMediaRendition() {return mediaRendition;}
>>   GBool getIsEmbedded() { return isEmbedded; }
>>   Stream* getEmbbededStream() { return embeddedStream; }
>>   // write embedded stream to file
>> @@ -145,6 +148,7 @@
>>
>>   GBool isEmbedded;
>>
>> +  Object mediaRendition;
>>
>> mediaRendition should be initilized in the other constructor too,
>> simply copy the given object:
>>
>> obj->copy(&mediaRendition);
>>
>>
>>   GooString* contentType;
>>
>>   // if it's embedded
>>
>> Index: poppler-0.16.2/poppler/Annot.cc
>> ===================================================================
>> --- poppler-0.16.2/poppler/Annot.cc     (revision 12)
>> +++ poppler-0.16.2/poppler/Annot.cc     (working copy)
>>
>> +void AnnotScreen::setTitle(GooString *title) {
>> +  if (title)
>> +    title = new GooString(title);
>> +  else
>> +    title = new GooString();
>>
>> save the title as a class attr, and add getTitle() method. Make sure
>> the string is correctly encoded, see Annot::setContents() for example.
>>
>> +  Object obj1;
>> +  obj1.initString(title->copy());
>> +  update ("T", &obj1);
>> +  delete(title);
>> +}
>>
>>
>> +GBool AnnotScreen::setAction(const char* video_file, const char*
>> mimetype, const char* img_file, const char* js) {
>>
>> A screen annot can be used to trigger any action type, not only
>> rendition actions, so this should be something like:
>>
>>  GBool AnnotScreen::setAction(LinkAction *actionA);
>>
>> +  if (!video_file) {
>> +    error(-1, "Need to pass the video file");
>> +    return gFalse;
>> +  }
>> +
>> +  // Extract the video name from the file uri
>> +  const char *video_name = get_file_name_from_path (video_file);
>> +
>> +  Object obj1, obj2, obj3, obj4;
>> +
>> +  GooString *title = new GooString(video_name);
>> +  setTitle(title);
>> +  setContents(title);
>> +  delete(title);
>>
>> title and contents should be set by the caller, the frontends in this
>> case.
>>
>> +  Ref imgRef;
>> +  Object imgXObj;
>> +  imgXObj.initDict(xref);
>> +  imgXObj.dictSet("Type", obj1.initName("XObject"));
>> +  imgXObj.dictSet("Subtype", obj2.initName("Image"));
>> +
>> +  if (img_file) {
>> +    FILE *imgfp;
>> +    if (!(imgfp = fopen(img_file, "rb"))) {
>> +      error(-1, "Couldn't open file: %s",img_file);
>> +      return gFalse;
>> +    }
>> +    unsigned char h[10];
>> +    fread(h, 1, 10, imgfp);
>> +    fseek(imgfp, 0, SEEK_SET);
>> +
>> +    MemStream *imgStream = NULL;
>> +    // Load the stream from the png file
>> +    if (h[0] == 0x89 && h[1] == 0x50 && h[2] == 0x4E && h[3] == 0x47)
>> +      imgStream = load_from_png (imgfp, &imgXObj);
>> +    // Load the stream from the jpeg file
>> +    else if(h[0] == 0xFF && h[1] == 0xD8 && h[6] == 0x4A && h[7] == 0x46
>> && h[8] == 0x49 && h[9] == 0x46)
>> +      imgStream = load_from_jpeg (imgfp, &imgXObj);
>> +    else {
>> +      error(-1, "Image format cannot be supported, only png/jpeg\n");
>> +      return gFalse;
>> +    }
>> +
>> +    if (imgStream) {
>> +      obj2.initStream(imgStream);
>> +      appearBuf = new GooString("/Im1 Do");
>> +      double bbox[4];
>> +      bbox[0] = bbox[1] = 0;
>> +      bbox[2] = bbox[3] = 1;
>> +      createResourcesDict("Im1", &obj2, "GS0", 1.0, NULL, &obj4);
>> +      createForm(bbox, gFalse, &obj4, &obj1);
>> +
>> +      Ref appRef = xref->addIndirectObject(&obj1);
>> +      obj2.initDict(xref);
>> +      obj2.dictSet("N", obj3.initRef(appRef.num, appRef.gen));
>> +      annotObj.dictSet("AP", &obj2);
>> +
>> +      obj2.initStream(imgStream);
>> +      createResourcesDict("Im1", &obj2, "GS0", 1.0, NULL, &obj1);
>> +      createForm(bbox, gFalse, &obj1, &obj4);
>> +      appRef = xref->addIndirectObject(&obj4);
>> +
>> +      obj2.initDict(xref); // MK dictionary
>> +      obj2.dictSet("I", obj3.initRef(appRef.num, appRef.gen));
>> +      annotObj.dictSet("MK", &obj2);
>> +    }
>> +  }
>>
>> I think it would be better to add a generic mehtod to set the annot
>> appearance stream from an image, something like
>> Annot::setAppearanceFromFile() and call it from the frontends instead
>> of doing it here.
>>
>> +  if (js == NULL)
>> +    obj1.initInt(0);
>> +  else {
>> +    obj2.initDict(xref);
>> +    obj2.dictSet("Length", obj3.initInt(strlen(js)));
>> +    MemStream *jsstream = new MemStream(copyString((char*)js), 0,
>> strlen(js), &obj2);
>> +    obj1.initStream(jsstream);
>> +  }
>> +
>> +  LinkRendition *rendition = new LinkRendition(this, video_file, &obj1);
>>
>> You should update the action variable instead.
>>
>> +  Object *renditionObj = rendition->getRenditionObject();
>> +  Ref newRef = xref->addIndirectObject(renditionObj);
>> +  obj1.initRef(newRef.num, newRef.gen);
>>
>> rendition object should be added by the MediaRendition constructor
>> like we currently does for annotations, and here you only need to get
>> the Ref.
>>
>> +  annotObj.dictSet("A", &obj1);
>> +
>> +  return gTrue;
>> +}
>> +
>>
>>  //------------------------------------------------------------------------
>>  // AnnotStamp
>>
>>  //------------------------------------------------------------------------
>> Index: poppler-0.16.2/glib/poppler-annot.cc
>> ===================================================================
>> --- poppler-0.16.2/glib/poppler-annot.cc        (revision 12)
>> +++ poppler-0.16.2/glib/poppler-annot.cc        (working copy)
>> @@ -332,7 +332,52 @@
>>   return poppler_annot;
>>  }
>>
>> +/**
>> + * poppler_annot_screen_new:
>> + * @doc: a #PopplerDocument
>> + * @rect: a #PopplerRectangle
>> + *
>> + * Creates a new Screen annotation that will be
>> + * located on @rect when added to a page. See
>> + * poppler_page_add_annot()
>> + *
>> + * Return value: A newly created #PopplerAnnotScreen annotation
>> + *
>> + */
>> +PopplerAnnot *
>> +poppler_annot_screen_new (PopplerDocument  *doc,
>> +                         PopplerRectangle *rect)
>> +{
>> +  Annot *annot;
>> +  PDFRectangle pdf_rect(rect->x1, rect->y1,
>> +                       rect->x2, rect->y2);
>>
>> +  annot = new AnnotScreen (doc->doc->getXRef(), &pdf_rect,
>> doc->doc->getCatalog());
>> +  return _poppler_annot_screen_new (annot);
>> +}
>> +
>> +/**
>> + * poppler_annot_screen_set_action:
>> + * @poppler_annot: a #PopplerAnnot
>> + * @video_file: pass the path of the video to be embed
>> + * @mimetype: pass the mimetype of the video to put in the Media Clip
>> Dictionary
>> + * @img_file: pass png/jpeg image file for poster
>> + * @js: set the JS as this javascript stream in rendition action else if
>> it is null set OP
>> +
>> + * Set the action for the screen annotation specified @poppler_annot
>> + *
>> + */
>> +void
>> +poppler_annot_screen_set_action (PopplerAnnot *poppler_annot,
>> +                                const char* video_file,
>> +                                const char* mimetype,
>> +                                const char* img_file,
>> +                                const char* js)
>>
>> This is still wrong, you should be able to set any action type to a
>> screen annotation.
>>
>> --
>> Carlos Garcia Campos
>> PGP key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462
>> -------------- next part --------------
>> A non-text attachment was scrubbed...
>> Name: signature.asc
>> Type: application/pgp-signature
>> Size: 198 bytes
>> Desc: not available
>> URL: <
>> http://lists.freedesktop.org/archives/poppler/attachments/20110323/094c9927/attachment-0001.pgp
>> >
>>
>> ------------------------------
>>
>> Message: 2
>> Date: Wed, 23 Mar 2011 13:25:27 -0400
>> From: "jose.aliste at gmail.com" <jose.aliste at gmail.com>
>> Subject: [poppler] Plans to get Javascript support in Poppler.
>> To: poppler at lists.freedesktop.org
>> Cc: Ryan Lewis <me at ryanlewis.net>
>> Message-ID:
>>        <AANLkTin98WAdRNo5OfMjs31zHCdWr2X5rXCVXjwtJRZn at mail.gmail.com>
>> Content-Type: text/plain; charset=ISO-8859-1
>>
>> Hi list,
>>
>> So we are discussing how we can join efforts to start adding poppler
>> support for Javascript in poppler.  With Carlos and Pino, we got some
>> agreements that I want to share with you so you can add comments/
>> regards/ questions/ etc. These are by no mean sealed plans, I only try
>> to account for a summary of the discussion we had yesterday in IRC.
>> The basic plan is:
>>
>> 1. To start a "plain core js" API in C++ that will use poppler core
>> API and will follow as close as possible the PDF JS API [1]
>> 2. Each frontend, glib and qt, can then decide how they will bind
>> these API to their frontends.
>>
>> Notes:
>> a) Of course, will coding 1, we will need to add functionality to core
>> poppler that is not there yet, like for instance, support for
>> Javascript Actions.
>> b) the plain core js api in 1 should be probably very easy, as it
>> should wrap more or less directly from the core poppler, but we choose
>> this way so the code can be shared by Okular and Evince.
>> c) Just for completness, I give more details about the glib frontend,
>> in which I plan to hack: Our idea in 2) is to wrap  the "plain core
>> js" api into a GObject API, and then use the automatic
>> GObject-Javascript glue that (will be) is provided to us by Seed using
>> gobject-introspection (BTW, in this case the Javascript engine comes
>> from Webkit).
>>
>> That's more or less it. Comments/questions/rants/patches welcome.
>>
>> Greets
>>
>> Jos?
>>
>>
>> @Carlos, Pino, if I forget something (or I got something wrong),
>> please add it here.
>>
>>
>> ------------------------------
>>
>> _______________________________________________
>> poppler mailing list
>> poppler at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/poppler
>>
>>
>> End of poppler Digest, Vol 73, Issue 35
>> ***************************************
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/poppler/attachments/20110325/29d504ef/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: srinivas_video_embedd.patch
Type: text/x-patch
Size: 52052 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/poppler/attachments/20110325/29d504ef/attachment-0001.bin>


More information about the poppler mailing list