Hi Carlos,<br><br> Thank you for your valuable suggestions. I made the changes according to that. I attached a new patch with this.<br><br>- 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. <br>
<br>- 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.<br><br>Please give suggestions again.<br><br>Thanks<br>--<br>A Srinivas<br><br><div class="gmail_quote">
On Mon, Mar 21, 2011 at 12:30 AM, <span dir="ltr"><<a href="mailto:poppler-request@lists.freedesktop.org">poppler-request@lists.freedesktop.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Send poppler mailing list submissions to<br>
<a href="mailto:poppler@lists.freedesktop.org">poppler@lists.freedesktop.org</a><br>
<br>
To subscribe or unsubscribe via the World Wide Web, visit<br>
<a href="http://lists.freedesktop.org/mailman/listinfo/poppler" target="_blank">http://lists.freedesktop.org/mailman/listinfo/poppler</a><br>
or, via email, send a message with subject or body 'help' to<br>
<a href="mailto:poppler-request@lists.freedesktop.org">poppler-request@lists.freedesktop.org</a><br>
<br>
You can reach the person managing the list at<br>
<a href="mailto:poppler-owner@lists.freedesktop.org">poppler-owner@lists.freedesktop.org</a><br>
<br>
When replying, please edit your Subject line so it is more specific<br>
than "Re: Contents of poppler digest..."<br>
<br>
<br>
Today's Topics:<br>
<br>
1. Re: [PATCH] Simplify the GCC compiler flags/warnings<br>
(Albert Astals Cid)<br>
2. Re: glib/poppler-annot.cc glib/poppler-annot.h<br>
poppler/Annot.cc poppler/Annot.h (Carlos Garcia Campos)<br>
<br>
<br>
----------------------------------------------------------------------<br>
<br>
Message: 1<br>
Date: Sun, 20 Mar 2011 13:59:24 +0000<br>
From: Albert Astals Cid <<a href="mailto:aacid@kde.org">aacid@kde.org</a>><br>
Subject: Re: [poppler] [PATCH] Simplify the GCC compiler<br>
flags/warnings<br>
To: <a href="mailto:poppler@lists.freedesktop.org">poppler@lists.freedesktop.org</a><br>
Message-ID: <<a href="mailto:201103201359.24744.aacid@kde.org">201103201359.24744.aacid@kde.org</a>><br>
Content-Type: Text/Plain; charset="iso-8859-1"<br>
<br>
A Diumenge, 13 de mar? de 2011, Albert Astals Cid va escriure:<br>
> A Diumenge, 13 de mar? de 2011, Pino Toscano va escriure:<br>
> > Alle domenica 13 marzo 2011, Albert Astals Cid ha scritto:<br>
> > > A Dissabte, 12 de mar? de 2011, Pino Toscano va escriure:<br>
> > > > Alle sabato 12 marzo 2011, Hib Eris ha scritto:<br>
> > > > > Two more remarks:<br>
> > > > ><br>
> > > > > +if test "x$GCC" == xyes; then<br>
> > > > > + extra_cxxflags="-Wall -Wno-write-strings -Woverloaded-virtual<br>
> > > > > \ + -Wnon-virtual-dtor -Wcast-align<br>
> > > > > -fno-exceptions \ + -fno-check-new -fno-common"<br>
> > > > > + case "$enable_compile_warnings" in<br>
> > > > > + yes)<br>
> > > > > + extra_cxxflags="$extra_cxxflags \<br>
> > > > > + -D_XOPEN_SOURCE=600 -D_BSD_SOURCE \<br>
> > > > > + -W -Wno-long-long -Wundef -Wconversion<br>
> > > > > -Wpointer-arith \ + -Wwrite-strings<br>
> > > > > -Wformat-security \<br>
> > > > > + -Wmissing-format-attribute"<br>
> > > > > + ;;<br>
> > > > > + esac<br>
> > > > > + CXXFLAGS="$extra_cxxflags $CXXFLAGS"<br>
> > > > > +fi<br>
> > > > ><br>
> > > > ><br>
> > > > > 1. In the 'yes' case, you end up with both -Wno-write-strings<br>
> > > > > and -Wwrite-strings, it is at least not obvious which one the<br>
> > > > > compiler will pick.<br>
> > > ><br>
> > > > The last of course.<br>
> > ><br>
> > > I disagree with that. It will result in people sending patches to<br>
> > > move all char * to const char* which adds nothing but noise to the<br>
> > > git history.<br>
> ><br>
> > -Write-strings is in the new "yes", which is the equivalent of the<br>
> > current "kde", so nothing changes for the default configuration.<br>
><br>
> True, but the current "kde" is something noone uses, if you name it "enable<br>
> warnings" everyone will think it is our default "warnings" setting.<br>
<br>
Since it seems noone else cares i'd suggest you go my "simple" way with only<br>
one set of warnings, if we ever need more we can reintroduce the other "yes"<br>
warnings.<br>
<br>
Albert<br>
<br>
><br>
> Albert<br>
><br>
> > > I'd just scrap the "extra warnings" setting and by default enable the<br>
> > > ones we think make sense and that's it.<br>
> ><br>
> > That may be another idea -- other opinions?<br>
><br>
> _______________________________________________<br>
> poppler mailing list<br>
> <a href="mailto:poppler@lists.freedesktop.org">poppler@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/poppler" target="_blank">http://lists.freedesktop.org/mailman/listinfo/poppler</a><br>
<br>
<br>
------------------------------<br>
<br>
Message: 2<br>
Date: Sun, 20 Mar 2011 16:16:26 +0100<br>
From: Carlos Garcia Campos <<a href="mailto:carlosgc@gnome.org">carlosgc@gnome.org</a>><br>
Subject: Re: [poppler] glib/poppler-annot.cc glib/poppler-annot.h<br>
poppler/Annot.cc poppler/Annot.h<br>
To: aacid <<a href="mailto:aacid@kemper.freedesktop.org">aacid@kemper.freedesktop.org</a>><br>
Cc: poppler <<a href="mailto:poppler@lists.freedesktop.org">poppler@lists.freedesktop.org</a>><br>
Message-ID: <1300629799-sup-5028@charizard><br>
Content-Type: text/plain; charset="utf8"<br>
<br>
Excerpts from aacid's message of jue mar 17 21:10:41 +0100 2011:<br>
> glib/poppler-annot.cc | 33 ++++<br>
> glib/poppler-annot.h | 5<br>
> poppler/Annot.cc | 377 ++++++++++++++++++++++++++++++++++++++++++++++++++<br>
> poppler/Annot.h | 2<br>
> 4 files changed, 417 insertions(+)<br>
><br>
> New commits:<br>
> commit 66575c990f379871e4b796befc899de178332670<br>
> Author: Srinivas Adicherla <<a href="mailto:srinivas.adicherla@gmail.com">srinivas.adicherla@gmail.com</a>><br>
> Date: Thu Mar 17 20:14:05 2011 +0000<br>
><br>
> Patch for embedding videos in to the pdf<br>
><br>
> diff --git a/glib/poppler-annot.cc b/glib/poppler-annot.cc<br>
> index 62a0879..c714288 100644<br>
> --- a/glib/poppler-annot.cc<br>
> +++ b/glib/poppler-annot.cc<br>
> @@ -332,6 +332,39 @@ _poppler_annot_screen_new (Annot *annot)<br>
> return poppler_annot;<br>
> }<br>
<br>
I'm sorry I didn't find the time to review previous patches and I was<br>
on vacation when Albert asked for approval before commiting it. There<br>
are some problems with the patch, I'll comment inline.<br>
<br>
> +/**<br>
> + * poppler_annot_screen_new:<br>
> + * @doc: a #PopplerDocument<br>
> + * @rect: a #PopplerRectangle<br>
> + * @video_file: pass the path of the video to be embed<br>
> + * @mimetype: pass the mimetype of the video to put in the Media Clip Dictionary<br>
> + * @img_file: pass png/jpeg image file for poster<br>
> + *<br>
> + * Creates a new Screen annotation that will be<br>
> + * located on @rect when added to a page. See<br>
> + * poppler_page_add_annot()<br>
> + *<br>
> + * Return value: A newly created #PopplerAnnotScreen annotation<br>
> + *<br>
> + * Since: 0.18<br>
> + */<br>
> +PopplerAnnot *<br>
> +poppler_annot_screen_new (PopplerDocument *doc,<br>
> + PopplerRectangle *rect,<br>
> + const char* video_file,<br>
> + const char* mimetype,<br>
> + const char* img_file)<br>
<br>
A screen annotation can be used to trigger any action, not only<br>
rendition actions. This should be just<br>
<br>
PopplerAnnot *<br>
poppler_annot_screen_new (PopplerDocument *doc, PopplerRectangle<br>
*rect);<br>
<br>
And another method to set the action<br>
poppler_annot_screen_set_action(), since the activation action is not<br>
required in a screen annotation.<br>
<br>
> +{<br>
> + AnnotScreen *annot;<br>
> + PDFRectangle pdf_rect(rect->x1, rect->y1,<br>
> + rect->x2, rect->y2);<br>
> +<br>
> + annot = new AnnotScreen (doc->doc->getXRef(), &pdf_rect, doc->doc->getCatalog());<br>
> + if (annot->setAction(video_file, mimetype, img_file))<br>
> + return _poppler_annot_screen_new ((Annot*)annot);<br>
> + else<br>
> + return NULL;<br>
<br>
This function should never return NULL, since the action is optional<br>
there could be a screen annot without an action.<br>
<br>
> +<br>
> +GBool AnnotScreen::setAction(const char *video_file, const char *mimetype, const char *img_file) {<br>
<br>
There's a AnnotScreen::getAction() method that returns the LinkAction<br>
associated with the annotation, but this method doesn't update the<br>
current annotation action. Since the action might be of any type, I<br>
think this should be<br>
<br>
void AnnotScreen::setAction(LinkAction *action)<br>
<br>
if the annotation already had an action it will be replaced by the new<br>
one and the annot dictionary will be updated using Annot::update()<br>
<br>
> + if (!video_file) {<br>
> + error(-1, "Need to pass the video file");<br>
> + return gFalse;<br>
> + }<br>
> +<br>
> + FILE *fs;<br>
> + unsigned int size = 0;<br>
> + if (!(fs = fopen(video_file, "rb"))) {<br>
> + error(-1, "Couldn't open video file '%s'", video_file);<br>
> + return gFalse;<br>
> + }<br>
> + fseek(fs, 0, SEEK_END);<br>
> + size = ftell(fs);<br>
> +<br>
> + // Extract the video name from the file uri<br>
> + const char *video_name = strrchr(video_file, '/');<br>
> + if (video_name) {<br>
> + video_name++;<br>
> + } else {<br>
> + video_name = video_file;<br>
> + }<br>
> +<br>
> + Object obj1, obj2, obj3, obj4;<br>
> +<br>
> + annotObj.dictSet("T", obj1.initString(new GooString(video_name))); // title<br>
<br>
This should be another method AnnotScreen::setTitle() instead of<br>
always using the vodeo name. Since this is optional it's not a problem<br>
if the entry is not present unless the user explicitely calls setTitle()<br>
<br>
> + annotObj.dictSet("Contents", obj2.initString(new GooString(video_name))); // alternate text to be dispalyed for the<br>
> annotation<br>
<br>
The same here, we already have Annot::setContents(), use it to make sure<br>
the contents are correctly encoded and that the contents variable is<br>
correctly updated.<br>
<br>
> + annotObj.dictSet("F", obj3.initInt(4)); // No Zoom<br>
<br>
4 is the bit position within the flag word, not the value itself. The<br>
spec doesn't say<br>
<br>
> + Object formXObj;<br>
> + formXObj.initDict(xref);<br>
> +<br>
> + formXObj.dictSet("Type", obj1.initName("XObject"));<br>
> + formXObj.dictSet("Subtype", obj2.initName("Form"));<br>
> +<br>
> + Object bbox;<br>
> + bbox.initArray(xref);<br>
> + bbox.arrayAdd(obj1.initReal(0.0000));<br>
> + bbox.arrayAdd(obj2.initReal(0.0000));<br>
> + bbox.arrayAdd(obj3.initReal(1.0000));<br>
> + bbox.arrayAdd(obj4.initReal(1.0000));<br>
> + formXObj.dictSet("BBox", &bbox);<br>
<br>
why is BBox 0, 0, 1, 1, shouldn't you use the annotation rectangle?<br>
something like<br>
<br>
bbox[0] = bbox[1] = 0;<br>
bbox[2] = rect->x2 - rect->x1;<br>
bbox[3] = rect->y2 - rect->y1;<br>
<br>
not that we already have Annot::createForm() that might help here<br>
too.<br>
<br>
> + Ref imgRef;<br>
> + Object imgXObj;<br>
> + imgXObj.initDict(xref);<br>
> + imgXObj.dictSet("Type", obj1.initName("XObject"));<br>
> + imgXObj.dictSet("Subtype", obj2.initName("Image"));<br>
> +<br>
> + if (img_file) { //show the poster, else do not show anything<br>
> + FILE *imgfp;<br>
> + if (!(imgfp = fopen(img_file, "rb"))) {<br>
> + error(-1, "Couldn't open file: %s", img_file);<br>
> + return gFalse;<br>
> + }<br>
> + unsigned char h[10];<br>
> + fread(h, 1, 10, imgfp);<br>
> + fseek(imgfp, 0, SEEK_SET);<br>
> +<br>
> + MemStream *imgStream = NULL;<br>
> + // Load the stream from the png file<br>
> + if (h[0] == 0x89 && h[1] == 0x50 && h[2] == 0x4E && h[3] == 0x47) {<br>
> + imgStream = load_from_png (imgfp, &imgXObj);<br>
> + // Load the stream from the jpeg file<br>
> + } else if(h[0] == 0xFF && h[1] == 0xD8 && h[6] == 0x4A && h[7] == 0x46 && h[8] == 0x49 && h[9] == 0x46) {<br>
> + imgStream = load_from_jpeg (imgfp, &imgXObj);<br>
> + } else {<br>
> + error(-1, "Image format cannot be supported, only png/jpeg\n");<br>
> + return gFalse;<br>
> + }<br>
> +<br>
> + if (!imgStream) {<br>
> + obj1.free();<br>
> + obj2.free();<br>
> + obj3.free();<br>
> + obj4.free();<br>
> + bbox.free();<br>
> + imgXObj.free();<br>
> + return gFalse;<br>
<br>
the AP entry is optional, you can have a screen annotation with a<br>
rendition action associated that doesn't have an appearance stream, so<br>
I don't think we should return here.<br>
<br>
> + }<br>
> +<br>
> + obj1.initStream(imgStream);<br>
> + imgRef = xref->addIndirectObject(&obj1);<br>
> +<br>
> + obj2.initDict(xref); // Image XObject<br>
> + obj2.dictSet("Im1", obj3.initRef(imgRef.num, imgRef.gen));<br>
> + obj4.initDict(xref);<br>
> + obj4.dictSet("XObject", &obj2);<br>
> +<br>
> + formXObj.dictSet("Resources", &obj4);<br>
> +<br>
> + GooString *newString = new GooString();<br>
> + newString->append("/Im1 Do");<br>
> + formXObj.dictSet("Length", obj1.initInt(newString->getLength()));<br>
> +<br>
> + MemStream *fstream = new MemStream(copyString(newString->getCString()), 0, newString->getLength(), &formXObj);<br>
> + fstream->setNeedFree(gTrue);<br>
> + delete(newString);<br>
> +<br>
> + obj1.initStream(fstream);<br>
> + Ref appRef = xref->addIndirectObject(&obj1);<br>
> +<br>
> + obj2.initDict(xref);<br>
> + obj2.dictSet("N", obj3.initRef(appRef.num, appRef.gen));<br>
> + obj2.dictSet("R", obj3.initRef(appRef.num, appRef.gen));<br>
<br>
The spec says:<br>
<br>
"The AP entry refers to an appearance dictionary (see Table 168) whose<br>
normal appearance provides the<br>
visual appearance for a screen annotation that shall be used for<br>
printing and default display when a media<br>
clip is not being played. If AP is not present, the screen annotation<br>
shall not have a default visual<br>
appearance and shall not be printed."<br>
<br>
it talks about the normal appearance, I don't think we need to set<br>
the rollover appearance too.<br>
<br>
> + annotObj.dictSet("AP", &obj2);<br>
<br>
I think this should be moved to a generic method Annot::setAppearanceFromImage(const char *imageFile);<br>
or something like that.<br>
<br>
> + formXObj.initDict(xref);<br>
> + formXObj.dictSet("Type", obj3.initName("XObject"));<br>
> + formXObj.dictSet("Subtype", obj4.initName("Form"));<br>
> +<br>
> + bbox.initArray(xref);<br>
> + bbox.arrayAdd(obj1.initReal(0.0000));<br>
> + bbox.arrayAdd(obj2.initReal(0.0000));<br>
> + bbox.arrayAdd(obj3.initReal(1.0000));<br>
> + bbox.arrayAdd(obj4.initReal(1.0000));<br>
> + formXObj.dictSet("BBox", &bbox);<br>
<br>
Why 0, 0, 1, 1 here again?<br>
<br>
> + obj2.initDict(xref);<br>
> + obj2.dictSet("Im1", obj3.initRef(imgRef.num, imgRef.gen));<br>
> + obj1.initDict(xref);<br>
> + obj1.dictSet("XObject", &obj2);<br>
> + formXObj.dictSet("Resources", &obj1);<br>
> +<br>
> + newString = new GooString();<br>
> + newString->append("/Im1 Do");<br>
> + formXObj.dictSet("Length", obj1.initInt(newString->getLength()));<br>
> +<br>
> + fstream = new MemStream(copyString(newString->getCString()), 0, newString->getLength(), &formXObj);<br>
> + fstream->setNeedFree(gTrue);<br>
> + delete(newString);<br>
> +<br>
> + obj1.initStream(fstream);<br>
> + appRef = xref->addIndirectObject(&obj1);<br>
> +<br>
> + obj2.initDict(xref); // MK dictionary<br>
> + obj2.dictSet("I", obj3.initRef(appRef.num, appRef.gen));<br>
> + annotObj.dictSet("MK", &obj2);<br>
<br>
There's a AnnotScreen::getAppearCharacs() method that should refelct<br>
this change too<br>
<br>
> + }<br>
> +<br>
> + // Rendition Action to be add<br>
> + Object actionDict;<br>
> + actionDict.initDict(xref);<br>
> + actionDict.dictSet("Type", obj1.initName("Action"));<br>
> + actionDict.dictSet("S", obj2.initName("Rendition"));<br>
> + actionDict.dictSet("OP", obj3.initInt(0));<br>
<br>
OP = 0 means: play the rendition specified by R, associating it with<br>
the annotation specified by AN, which makes AN a required field. AN<br>
should be an indirect reference to the screen annotation.<br>
<br>
I think we could add a new constructor to LinkRendition() that takes<br>
the required fields of a rendition action like we currenlty do with<br>
annotations. Then this method would simply take the action object and<br>
update the A entry with the indirect reference to the action.<br>
<br>
> + // Media Rendition<br>
> + Object MRendition;<br>
> + MRendition.initDict(xref);<br>
> + MRendition.dictSet("S", obj1.initName("MR"));<br>
> + MRendition.dictSet("N", obj2.initString(new GooString(video_name)));<br>
<br>
Same here, we could have a new constructor for MediaRendition that<br>
creates the new media rendition object.<br>
<br>
> + // Media Clip Dictionary<br>
> + Object MClipDict;<br>
> + MClipDict.initDict(xref);<br>
> + MClipDict.dictSet("S", obj1.initName("MCD"));<br>
> + MClipDict.dictSet("N", obj2.initString(new GooString(video_name)));<br>
> +<br>
> + if (mimetype) {<br>
> + MClipDict.dictSet("CT", obj3.initString(new GooString(mimetype)));<br>
> + }<br>
> +<br>
> + obj4.initString(new GooString("TEMPACCESS"));<br>
> + obj1.initDict(xref);<br>
> + obj1.dictSet("TF", &obj4);<br>
> + MClipDict.dictSet("P", &obj1);<br>
> +<br>
> + // File Specification Dictionary<br>
> + Object fsDict;<br>
> + fsDict.initDict(xref);<br>
> + fsDict.dictSet("Type", obj1.initName("Filespec"));<br>
> + fsDict.dictSet("F", obj2.initName((char*)video_name));<br>
> + fsDict.dictSet("UF", obj3.initName((char*)video_name));<br>
<br>
The UF entry should be encoded using PDFDocEncoding or UTF-16BE with a<br>
leading byte-order marker (as defined in 7.9.2.2, "Text String Type").<br>
<br>
> +<br>
> + obj3.initDict(xref); // file stream eictionary<br>
> + obj3.dictSet("DL", obj1.initInt(size));<br>
> + obj3.dictSet("Length", obj2.initInt(size));<br>
> +<br>
> + FileStream *stream = new FileStream(fs, 0, 0, size, &obj3);<br>
> + obj1.initStream(stream);<br>
> +<br>
> + Ref newRef;<br>
> + newRef = xref->addIndirectObject(&obj1);<br>
> + obj2.initRef(newRef.num, newRef.gen);<br>
> + obj1.initDict(xref);<br>
> + obj1.dictSet("F", &obj2);<br>
> + fsDict.dictSet("EF", &obj1);<br>
<br>
This code could be useful for other annots, like FileAttachment<br>
annotations, so I think it could be moved to a protected method in<br>
Annot, something like<br>
<br>
void Annot::createFilespec(const char *filename);<br>
<br>
> + newRef = xref->addIndirectObject(&fsDict);<br>
> + obj1.initRef(newRef.num, newRef.gen);<br>
> + MClipDict.dictSet("D", &obj1);<br>
> +<br>
> + newRef = xref->addIndirectObject(&MClipDict);<br>
> + obj1.initRef(newRef.num, newRef.gen);<br>
> + MRendition.dictSet("C", &obj1);<br>
> +<br>
> + newRef = xref->addIndirectObject(&MRendition);<br>
> + obj1.initRef(newRef.num, newRef.gen);<br>
> + actionDict.dictSet("R", &obj1);<br>
> +<br>
> + newRef = xref->addIndirectObject(&actionDict);<br>
> + obj1.initRef(newRef.num, newRef.gen);<br>
> + annotObj.dictSet("A", &obj1);<br>
> +<br>
> + return gTrue;<br>
> +}<br>
> +<br>
<br>
Thank you very much for the patch, and sorry again for not reviewing<br>
it before.<br>
<br>
Regards,<br>
--<br>
Carlos Garcia Campos<br>
PGP key: <a href="http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462" target="_blank">http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462</a><br>
-------------- next part --------------<br>
A non-text attachment was scrubbed...<br>
Name: signature.asc<br>
Type: application/pgp-signature<br>
Size: 198 bytes<br>
Desc: not available<br>
URL: <<a href="http://lists.freedesktop.org/archives/poppler/attachments/20110320/5c61136e/attachment-0001.pgp" target="_blank">http://lists.freedesktop.org/archives/poppler/attachments/20110320/5c61136e/attachment-0001.pgp</a>><br>
<br>
------------------------------<br>
<br>
_______________________________________________<br>
poppler mailing list<br>
<a href="mailto:poppler@lists.freedesktop.org">poppler@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/poppler" target="_blank">http://lists.freedesktop.org/mailman/listinfo/poppler</a><br>
<br>
<br>
End of poppler Digest, Vol 73, Issue 27<br>
***************************************<br>
</blockquote></div><br>