From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Evgeny Zajcev Newsgroups: gmane.emacs.devel Subject: Re: Loading svg from memory using custom filename for base_uri Date: Thu, 3 Dec 2020 18:47:37 +0300 Message-ID: References: <83a7inq77f.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="0000000000002d893005b5914807" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="32405"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Thu Dec 03 16:48:55 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kkqql-0008Jg-5S for ged-emacs-devel@m.gmane-mx.org; Thu, 03 Dec 2020 16:48:55 +0100 Original-Received: from localhost ([::1]:53200 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kkqqk-0007vL-8G for ged-emacs-devel@m.gmane-mx.org; Thu, 03 Dec 2020 10:48:54 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:58374) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kkqpn-00078i-B9 for emacs-devel@gnu.org; Thu, 03 Dec 2020 10:47:55 -0500 Original-Received: from mail-lj1-x229.google.com ([2a00:1450:4864:20::229]:36466) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kkqpl-0001CH-19; Thu, 03 Dec 2020 10:47:55 -0500 Original-Received: by mail-lj1-x229.google.com with SMTP id a1so1699069ljq.3; Thu, 03 Dec 2020 07:47:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=4JM9TPQVF4XN40oyGRegdxnGLQu+s7AtabRor6/I8Kg=; b=eWPXMu1uVXJl4Zs1thFQkg7h/mOXgryTC9bFdHQqNqDMXm3szimBFTQdQf8gesmgrJ NcPTEdYiC69oiAhETb898eAHtjxO4mm5nsXuy00JdiQHZvfQea1Bh7iOrPY530SY4QSm c0kV1BtjRAKgjZ90SUxqrH0ScyA+P0JZo9QBoz+q698IJ2UgbQt5F6ebROligozQ5uap sniA42CONDqm6HZnfh+23f7RzGGpc+QqWl5G4g65NXRzxBNd7XZdyshOrPL1Z8cBvLHg unW64y9F/IzSVW/8QdEG6dQashNZ7MXHzeACuTFmEuw5PjyuGBlCr/zoCw9oPJJFRLX7 NFEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=4JM9TPQVF4XN40oyGRegdxnGLQu+s7AtabRor6/I8Kg=; b=EM4rVMNs/3rFkExaI1o0X6eg2h+ir8wjj7ASyD/hYfHoAuhTh+dOufXVS/1sqwpD7K ygivnBYi0N59H7Fsw11HxY35Wkxeu0IG2o8wC49QysTqgHDnk08IKH+E2X0kRzWGlrQ+ GdrGdaiOzF3wrV4Cxr8yVwOUM+TlO6WWdtsJoBxuuJnPUu1gLuOxE6MI+Q5oAUIKFKkI ckqLr2pXJApP7cVFgla0MoTWeI71A4Ky4n1wWLHt+JaB0HPTgsJUuQvZLWZgRVgwfhlK vv17PGbyifUc6nxiLwlvwvjSwzh4L2Y2S1FV2Sh577xBJIVPXyjQM/peIAT7KhCB++kF 43IA== X-Gm-Message-State: AOAM531lo5eW/ZCREze/pD8ksrKIy4ap4jpXYeJSjSHiE3HJz/xt604X eMh4AHWtJf58aBTcHWNChwWuoQJPuwb+42/QteCHgZxXBeM= X-Google-Smtp-Source: ABdhPJz4/sf4Bid+kh13ryiopS5CS5bV4qwjn16rFSOThlEDySD4qXHzxU2+LMhkxEfxLlmq5xybe9XcfbX1bTLWcTc= X-Received: by 2002:a2e:b013:: with SMTP id y19mr1517328ljk.50.1607010469375; Thu, 03 Dec 2020 07:47:49 -0800 (PST) In-Reply-To: Received-SPF: pass client-ip=2a00:1450:4864:20::229; envelope-from=lg.zevlg@gmail.com; helo=mail-lj1-x229.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:260224 Archived-At: --0000000000002d893005b5914807 Content-Type: multipart/alternative; boundary="0000000000002d892e05b5914805" --0000000000002d892e05b5914805 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable =D0=BF=D0=BD, 25 =D1=84=D0=B5=D0=B2=D1=80. 2019 =D0=B3. =D0=B2 13:23, Evgen= y Zajcev : > > > =D1=81=D0=B1, 23 =D1=84=D0=B5=D0=B2=D1=80. 2019 =D0=B3. =D0=B2 10:45, Eli= Zaretskii : > >> > From: Evgeny Zajcev >> > Date: Sat, 23 Feb 2019 01:01:02 +0300 >> > >> > Currently, when SVG image is loaded with `svg_load` it first examines >> :file value and only if :file is missing it >> > looks for :data, using current buffer's filename (if any) as base_uri >> > >> > Would not it be better to check for :data first and if present, then >> use :file as value for base_uri? Falling back >> > to current buffer filename in case :file is missing >> > >> > Unfortunately embedding raster images into svg with base64 encoding, >> using `svg-embed` is slow. >> >> I don't think I understand what you are saying here. The test whether >> an image spec specifies a file or not is just 2 lines of C: >> >> > Ah, sorry, let me explain in more details. SVG has ability embedding > raster images using "image" node with "xlink:href" attribute pointing to > the filename to embed. rsvg library disallows absolute path names in > "xlin:href" due to security reasons. To refer the filename with rsvg you > need to setup base_filename (aka base_uri) and then point to the file > relatively to this base_filename. If you load .svg from filename, then > this filename is used as base_filename, but if you load SVG from memory y= ou > need to specify base_uri explicitly. > > `svg-embed` from svg.el does not bother with base_uri stuff and just > embeds raster images using base64 trick: it reads content of the file, > encode it with base64 and inserts encoded data into "image" node. This i= s > relative slow thing to do. > > To suppress this base64 trick, I want "xlink:href" to point directly to > filename, so I need some way to explicitly specify base_uri for rsvg to > use. svg_load() from "image.c" uses `:file` as base_uri if loading from > filename, and current buffer's filename if loading from memory via `:data= `. > > I want to load svg `:data` from memory and specify base_uri, using image'= s > `:file` attribute. This is not possible right now because `:file` > attribute is examined first in svg_load() function > > > /* If IMG->spec specifies a file name, create a non-file spec from it. >> */ >> file_name =3D image_spec_value (img->spec, QCfile, NULL); >> if (STRINGP (file_name)) >> { >> [load an image from file...] >> } >> /* Else its not a file, it's a lisp object. Load the image from a >> lisp object rather than a file. */ >> else >> { >> [load an image from data...] >> } >> >> And image_spec_value just walks a Lisp list looking for ':file': >> >> static Lisp_Object >> image_spec_value (Lisp_Object spec, Lisp_Object key, bool *found) >> { >> Lisp_Object tail; >> >> eassert (valid_image_p (spec)); >> >> for (tail =3D XCDR (spec); >> CONSP (tail) && CONSP (XCDR (tail)); >> tail =3D XCDR (XCDR (tail))) >> { >> if (EQ (XCAR (tail), key)) >> { >> if (found) >> *found =3D 1; >> return XCAR (XCDR (tail)); >> } >> } >> >> So I don't see how reversing the order would speed up SVG loading. >> What did I miss? >> > `:file' property is hardly could be used for this, because it is used in many different places beside svg, so I come up with next solution, introducing `:base-uri' image property to explicitly set base_uri for embedding images into svg To test this feature, copy any .jpg image to /tmp/soviet.jpg and eval in scratch (insert-image '(image :type svg :data " " :scale= 1.0 :base-uri "/tmp/soviet.jpg" :width 100 :height 100 :ascent center)) svg with embedded image should be inserted. To check where or not Emacs supports this feature use: (obarray-get c-keywords-obarray :base-uri) This could be used to fallback to base64 encoding trick in older Emacs Thanks --=20 lg --0000000000002d892e05b5914805 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
=D0=BF=D0=BD, 25 =D1=84=D0=B5=D0=B2= =D1=80. 2019 =D0=B3. =D0=B2 13:23, Evgeny Zajcev <lg.zevlg@gmail.com>:

=D1=81=D0= =B1, 23 =D1=84=D0=B5=D0=B2=D1=80. 2019 =D0=B3. =D0=B2 10:45, Eli Zaretskii = <eliz@gnu.org>:=
> From: Evge= ny Zajcev <lg.ze= vlg@gmail.com>
> Date: Sat, 23 Feb 2019 01:01:02 +0300
>
> Currently, when SVG image is loaded with `svg_load` it first examines = :file value and only if :file is missing it
> looks for :data, using current buffer's filename (if any) as base_= uri
>
> Would not it be better to check for :data first and if present, then u= se :file as value for base_uri?=C2=A0 Falling back
> to current buffer filename in case :file is missing
>
> Unfortunately embedding raster images into svg with base64 encoding, u= sing `svg-embed` is slow.

I don't think I understand what you are saying here.=C2=A0 The test whe= ther
an image spec specifies a file or not is just 2 lines of C:


Ah, sorry, let me explain in more deta= ils.=C2=A0 SVG has ability embedding raster images using "image" = node with "xlink:href" attribute pointing to the filename to embe= d.=C2=A0 rsvg library disallows absolute path names in "xlin:href"= ; due to security reasons.=C2=A0 To refer the filename with rsvg you need t= o setup base_filename (aka base_uri) and then point to the file relatively = to this base_filename.=C2=A0 If you load .svg from filename, then this file= name is used as base_filename, but if you load SVG from memory you need to = specify base_uri explicitly.

`svg-embed` from svg.= el does not bother with base_uri stuff and just embeds raster images using = base64 trick: it reads content of the file, encode it with base64 and inser= ts encoded data into "image" node.=C2=A0 This is relative slow th= ing to do.

To suppress this base64 trick, I want &= quot;xlink:href" to point directly to filename, so I need some way to = explicitly specify base_uri for rsvg to use.=C2=A0 svg_load() from "im= age.c" uses `:file` as base_uri if loading from filename, and current = buffer's filename if loading from memory via `:data`.

I want to load svg `:data` from memory and specify base_uri, using = image's `:file` attribute.=C2=A0 This is not possible right now because= `:file` attribute is examined first in svg_load() function

<= /div>

=C2=A0 /* If IMG->spec specifies a file name, create a non-file spec fro= m it.=C2=A0 */
=C2=A0 file_name =3D image_spec_value (img->spec, QCfile, NULL);
=C2=A0 if (STRINGP (file_name))
=C2=A0 =C2=A0 {
=C2=A0 =C2=A0 =C2=A0 [load an image from file...]
=C2=A0 =C2=A0 }
=C2=A0 /* Else its not a file, it's a lisp object.=C2=A0 Load the image= from a
=C2=A0 =C2=A0 =C2=A0lisp object rather than a file.=C2=A0 */
=C2=A0 else
=C2=A0 =C2=A0 {
=C2=A0 =C2=A0 =C2=A0 [load an image from data...]
=C2=A0 =C2=A0 }

And image_spec_value just walks a Lisp list looking for ':file':
=C2=A0 static Lisp_Object
=C2=A0 image_spec_value (Lisp_Object spec, Lisp_Object key, bool *found) =C2=A0 {
=C2=A0 =C2=A0 Lisp_Object tail;

=C2=A0 =C2=A0 eassert (valid_image_p (spec));

=C2=A0 =C2=A0 for (tail =3D XCDR (spec);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0CONSP (tail) && CONSP (XCDR (tail= ));
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tail =3D XCDR (XCDR (tail)))
=C2=A0 =C2=A0 =C2=A0 {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (EQ (XCAR (tail), key))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (found)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *found =3D 1;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return XCAR (XCDR (tail));
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 }

So I don't see how reversing the order would speed up SVG loading.
What did I miss?

`:file' prope= rty is hardly could be used for this, because it is used in many different = places beside svg, so I come up with next solution, introducing `:base-uri&= #39; image property to explicitly set base_uri for embedding images into sv= g

To test this feature, copy any .jpg image to /tmp/soviet.jpg and e= val in scratch

=C2=A0 (insert-image '(image :type svg :data &quo= t;<svg width=3D\"100\" height=3D\"100\" version=3D\&= quot;1.1\" xmlns=3D\"http= ://www.w3.org/2000/svg\" xmlns:xlink=3D\"http://www.w3.org/1999/xlink\"> <image= xlink:href=3D\"soviet.jpg\" height=3D\"40\" width=3D\&= quot;40\" y=3D\"10\" x=3D\"10\"></image>&= lt;/svg>" :scale 1.0 :base-uri "/tmp/soviet.jpg" :width 1= 00 :height 100 :ascent center))

svg with embedded image should be in= serted.

To check where or not Emacs supports this feature use:
=C2=A0 (obarray-get c-keywords-obarray :base-uri)

This could be us= ed to fallback to base64 encoding trick in older Emacs

Thanks
=C2= =A0
--
lg
--0000000000002d892e05b5914805-- --0000000000002d893005b5914807 Content-Type: text/x-patch; charset="US-ASCII"; name="0001-Explicitly-specify-svg-base_uri-using-base-uri-image.patch" Content-Disposition: attachment; filename="0001-Explicitly-specify-svg-base_uri-using-base-uri-image.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_ki90h29g0 RnJvbSA5YTVlZjQ3MDc1MDJlZDM3YzJiZWY2Nzc0ODJjMjdkYjFkY2E3OGI2IE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBaYWpjZXYgRXZnZW55IDx6ZXZsZ0B5YW5kZXgucnU+CkRhdGU6 IFRodSwgMyBEZWMgMjAyMCAxODozNzoxOCArMDMwMApTdWJqZWN0OiBbUEFUQ0hdIEV4cGxpY2l0 bHkgc3BlY2lmeSBzdmcgYmFzZV91cmkgdXNpbmcgYDpiYXNlLXVyaScgaW1hZ2UKIHByb3BlcnR5 CgoqIHNyYy9pbWFnZS5jIChzdmdfbG9hZCk6IENoZWNrIGA6YmFzZS11cmknIGltYWdlIHByb3Bl cnR5IHRvCiAgZXhwbGljaXRseSBzZXQgYmFzZV91cmkgZm9yIGltYWdlcyBlbWJlZGRlZCBpbnRv IFNWRwotLS0KIHNyYy9pbWFnZS5jIHwgNSArKysrLQogc3JjL3hkaXNwLmMgfCAxICsKIDIgZmls ZXMgY2hhbmdlZCwgNSBpbnNlcnRpb25zKCspLCAxIGRlbGV0aW9uKC0pCgpkaWZmIC0tZ2l0IGEv c3JjL2ltYWdlLmMgYi9zcmMvaW1hZ2UuYwppbmRleCA1ZWI0MTMyMjk1Li5mYTgxOGQ1NDQ2IDEw MDY0NAotLS0gYS9zcmMvaW1hZ2UuYworKysgYi9zcmMvaW1hZ2UuYwpAQCAtOTczNyw3ICs5NzM3 LDkgQEAgc3ZnX2xvYWQgKHN0cnVjdCBmcmFtZSAqZiwgc3RydWN0IGltYWdlICppbWcpCiAJICBp bWFnZV9lcnJvciAoIkludmFsaWQgaW1hZ2UgZGF0YSBgJXMnIiwgZGF0YSk7CiAJICByZXR1cm4g MDsKIAl9Ci0gICAgICBvcmlnaW5hbF9maWxlbmFtZSA9IEJWQVIgKGN1cnJlbnRfYnVmZmVyLCBm aWxlbmFtZSk7CisgICAgICBvcmlnaW5hbF9maWxlbmFtZSA9IGltYWdlX3NwZWNfdmFsdWUgKGlt Zy0+c3BlYywgUUNiYXNlX3VyaSwgTlVMTCk7CisgICAgICBpZiAoIVNUUklOR1AgKG9yaWdpbmFs X2ZpbGVuYW1lKSkKKyAgICAgICAgb3JpZ2luYWxfZmlsZW5hbWUgPSBCVkFSIChjdXJyZW50X2J1 ZmZlciwgZmlsZW5hbWUpOwogICAgICAgc3VjY2Vzc19wID0gc3ZnX2xvYWRfaW1hZ2UgKGYsIGlt ZywgU1NEQVRBIChkYXRhKSwgU0JZVEVTIChkYXRhKSwKICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAoTklMUCAob3JpZ2luYWxfZmlsZW5hbWUpID8gTlVMTAogCQkJCSAgIDogU1NE QVRBIChvcmlnaW5hbF9maWxlbmFtZSkpKTsKQEAgLTEwMDAyLDYgKzEwMDA0LDcgQEAgc3ZnX2xv YWRfaW1hZ2UgKHN0cnVjdCBmcmFtZSAqZiwgc3RydWN0IGltYWdlICppbWcsIGNoYXIgKmNvbnRl bnRzLAogICBlYXNzdW1lIChyc3ZnX2hhbmRsZSk7CiAKICAgLyogU2V0IGJhc2VfdXJpIGZvciBw cm9wZXJseSBoYW5kbGluZyByZWZlcmVuY2VkIGltYWdlcyAodmlhICdocmVmJykuCisgICAgIENh biBiZSBleHBsaWNpdGx5IHNwZWNpZmllZCB1c2luZyBgOmJhc2VfdXJpJyBpbWFnZSBwcm9wZXJ0 eS4KICAgICAgU2VlIHJzdmcgYnVnIDU5NjExNCAtICJpbWFnZSByZWZzIGFyZSByZWxhdGl2ZSB0 byBjdXJkaXIsIG5vdCAuc3ZnIGZpbGUiCiAgICAgIDxodHRwczovL2dpdGxhYi5nbm9tZS5vcmcv R05PTUUvbGlicnN2Zy9pc3N1ZXMvMzM+LiAqLwogICBpZiAoZmlsZW5hbWUpCmRpZmYgLS1naXQg YS9zcmMveGRpc3AuYyBiL3NyYy94ZGlzcC5jCmluZGV4IDc2ZWY0MjBhMzYuLjUxNzM1YjI2OWQg MTAwNjQ0Ci0tLSBhL3NyYy94ZGlzcC5jCisrKyBiL3NyYy94ZGlzcC5jCkBAIC0zNDYzMSw2ICsz NDYzMSw3IEBAIHN5bXNfb2ZfeGRpc3AgKHZvaWQpCiAgIERFRlNZTSAoUUNldmFsLCAiOmV2YWwi KTsKICAgREVGU1lNIChRQ3Byb3BlcnRpemUsICI6cHJvcGVydGl6ZSIpOwogICBERUZTWU0gKFFD ZmlsZSwgIjpmaWxlIik7CisgIERFRlNZTSAoUUNiYXNlX3VyaSwgIjpiYXNlLXVyaSIpOwogICBE RUZTWU0gKFFmb250aWZpZWQsICJmb250aWZpZWQiKTsKICAgREVGU1lNIChRZm9udGlmaWNhdGlv bl9mdW5jdGlvbnMsICJmb250aWZpY2F0aW9uLWZ1bmN0aW9ucyIpOwogCi0tIAoyLjI1LjEKCg== --0000000000002d893005b5914807--