From 4999209f9ce01c824020f5b68403c5b4b52d3e8c Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sat, 13 Jul 2019 21:26:05 +0200 Subject: [PATCH] Add support for svg --- README.md | 1 + libmat2/images.py | 34 ++- tests/data/dirty.svg | 636 +++++++++++++++++++++++++++++++++++++++ tests/data/embedded.docx | Bin 24601 -> 24316 bytes tests/data/embedded.odt | Bin 33019 -> 32651 bytes tests/test_libmat2.py | 28 +- 6 files changed, 695 insertions(+), 4 deletions(-) create mode 100644 tests/data/dirty.svg diff --git a/README.md b/README.md index d82d12b..5af5220 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ metadata. - `python3-mutagen` for audio support - `python3-gi-cairo` and `gir1.2-poppler-0.18` for PDF support - `gir1.2-gdkpixbuf-2.0` for images support +- `gir1.2-rsvg-2.0` for svg support - `FFmpeg`, optionally, for video support - `libimage-exiftool-perl` for everything else - `bubblewrap`, optionally, for sandboxing diff --git a/libmat2/images.py b/libmat2/images.py index 32a329f..8bef3f8 100644 --- a/libmat2/images.py +++ b/libmat2/images.py @@ -1,18 +1,48 @@ import imghdr import os -from typing import Set +from typing import Set, Dict, Union import cairo import gi gi.require_version('GdkPixbuf', '2.0') -from gi.repository import GdkPixbuf, GLib +gi.require_version('Rsvg', '2.0') +from gi.repository import GdkPixbuf, GLib, Rsvg from . import exiftool # Make pyflakes happy assert Set +class SVGParser(exiftool.ExiftoolParser): + mimetypes = {'image/svg+xml', } + meta_allowlist = {'Directory', 'ExifToolVersion', 'FileAccessDate', + 'FileInodeChangeDate', 'FileModifyDate', 'FileName', + 'FilePermissions', 'FileSize', 'FileType', + 'FileTypeExtension', 'ImageHeight', 'ImageWidth', + 'MIMEType', 'SVGVersion', 'SourceFile', 'ViewBox' + } + + def remove_all(self) -> bool: + svg = Rsvg.Handle.new_from_file(self.filename) + dimensions = svg.get_dimensions() + surface = cairo.SVGSurface(self.output_filename, + dimensions.height, + dimensions.width) + context = cairo.Context(surface) + svg.render_cairo(context) + surface.finish() + return True + + def get_meta(self) -> Dict[str, Union[str, dict]]: + meta = super().get_meta() + + # The namespace is mandatory, but thereis only one bossible. + ns = 'http://www.w3.org/2000/svg' + if meta.get('Xmlns', ns) == ns: + meta.pop('Xmlns') + return meta + class PNGParser(exiftool.ExiftoolParser): mimetypes = {'image/png', } meta_allowlist = {'SourceFile', 'ExifToolVersion', 'FileName', diff --git a/tests/data/dirty.svg b/tests/data/dirty.svg new file mode 100644 index 0000000..e2bde85 --- /dev/null +++ b/tests/data/dirty.svg @@ -0,0 +1,636 @@ + + + + + + Adwaita Icon Template + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + GNOME Design Team + + + mat2's source code + + Adwaita Icon Template + + + mat2 + logo + metadata + + + 2019 07 13 + + + LGPL + + + + + jvoisin + + + mat2-testdata-svg + + English + + This is a test svg image for mat2's testsuite + + + jvoisin, and Rose for the design + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/embedded.docx b/tests/data/embedded.docx index b134724ae59b939dff5432613800263cc7ed8098..615e522df5b4c962f94689ce3f0f315eb16314d5 100644 GIT binary patch delta 770 zcmbPvfbq{>#tm|z^*lRP`Cb1jyvL7;fgyl}fkBvofuTIVC`CUvH6=4qzc{s|v_P+* zvNb3$`?i5V-S_nte;&0g^NWx* zq#peEl=5PAv+nc&&RCNRSv=D98-zm~llL@BMT#`JF4$|5@vZ(r>J2sXS%IJ1q@~-^ zY918o-ib|o=dWBLJ|+Cjv}KP!9&J8xblX&GJ3gCtu~Tw)aGA>f`*umuk?mxA&ZK>{ zd$u^opQ=;S)&5!9;pM9{#p#J{F zd*VIQ>`n77TCeOrt7&+kJ?1CVX2(MwJ|{Wa4l|pFH+j5M*|l%p525cXde#OSuZi5C zKEp4O>A6AhHm*Dy$LCe@A}{%*4CeQ!E#A-{aZ1KCarWN0_=9Jn(!WJ)d4BY|bcB+i zRm1`}b&)lH!cNNgE&0pR!>nrIz;^m**3S8J>Un=(U7x#P;}z94(n)Lhb02t#XBg(p z`u$?6@lxT^yN{+jO^=&0cSGp&O!Jg*htw?$O2@u4Qd$u{xw+OUMj#h?I8kqius3=#|tyirNT>{l5Zj7oT_ErB$I wKe;Vln`v_R022TJ0C#V4WG`)HWNBe9ZDDjW zE^~Hgl~ucLR6z{w`3h@kXD8#=*hT~jBt%086m$^@0TFf)i3sBBIdgdlfsmNuj`#R= z>}%h>|M2tsEBbWt@%ruYaJu6@c64!gbv%E2xIEoGfA)BvJG#C(e>r@O;( z_wd1;``4c?37&`R)7_h!n-BL+PHt~+`>pol$IBBLW1PTZ_j}+6cZlv^;(_z}?bX%k z?ykg?Jlky;(tJF=TPcueGluzxvzs@NwsU^EdpgKj23-x>Z-OEf{k%5q&uhP-zwYlo zUv_k|Q8~H%3!`}bf9mWa{(}*Xwq<*P_-{5M-yWZ6gSW?%9|T|0dx*wOYdXCm@#tL6 zZ7<4QIFuwt&zK3wtece)vr5}nB=H!1q-oo`SC6Pk@aa$`403i?FNCPJXU|D{p57xT z9Bg*#Hb_UeQY|Xu5UdDCkqVX9?A` z#&D&~9&XZ5C9x`=^l1UF9ZoXI4i%|eM;Hvq3{ zO~(up^Iqn7!4tZ{Hc2Y+@?rh&)p#||FU~LiYgu`Ue{ajWgg=&bf#0vcE$hPn&FJ-Z z{%2V;88xrLRI%zMW6~qy)tq5oO-J#X3n6wx!z2=zdba{e&a5>bhSg<(yJLq^y0P-M zh!!%@SVWV_MyhB$%S1Gl9yMF}ntCQ-n3Q^BlU`L!>Il8^E{!|F=p0?Mh^x9!69m?! zV<(k?f52l=8rg>=ub-o*ZC?qPX|e!Q?lW>FEJTzlIJ80Hwn`<-Xp<+UF0*PDqjM?M znmB3B2*mE73#LPbOh8wIn}FP4K?tvI1HKZ8s*Ncln@iGItF1VYShLSL1EP#Xe(j;A zzzy+4NT#l#olOJ9mD{WzPGA?s=X9@ry000000096P008$4 wn}zJt0f6K|$w2_r0RZ<5n}zJtlWATn0yq%UP4vULgh_T>t<80Q;NiUH||9 diff --git a/tests/data/embedded.odt b/tests/data/embedded.odt index 62bf8cc7ccae13d1e2b16ba2f478d33ebed76e0e..c5fffc8951c672d3dd257b0fcc6324693d048823 100644 GIT binary patch delta 1137 zcmey}$khFxadJVT)a0Oq@X4#onHd;37?DKm2&s?tG)#2V?W!`!vby~%}x%<7_6gbMRnlx>ga`EXhhf{O6==8SfED35~ zB*C-z#mcH%fBCHX#7xr)b$|HUyke>@5!n%0G;yE5{v_vsigi7wADxf$ykfB9uC!+m z|3mlhy}wuRUUOQdv+wPOmyDIy%6>#tB&i2KKBc@^-K;x3fHT(QLVXsG^akM&$K*ZD zQjsD}t_${>WPGcCka|PSd{*G+Hfia$w3-Knx_4p|-}x(7h))SWGi}-9k4KwN9Njk6 z+K$iWUF?+H9bBfe|Gr&PbYwf(o-=7*?Vc^p@u%w4bhUq$c6j;fOtJdtWYzT8E9?9s z7ug^E3qv>WxOXq<+}{PcMT&FlE!+B9*PeLKG<(y$i`FZ<&uSVTXpi~HwAt~HhtEll zw!_Tk;Y}XzRCeu~_e1FWik`KB#%m%ssL$|AWO{B8yp1c*#_@TTyvR#FDTDbvYKu4Y zN1T!|O`N?qF8<(|sPu0UTb>`iE*+sHXce)*OOAbF0hTa@Oa&8l;`vAA2vcHZ!YxH`93ScIo#bsrB=C z?){q7oc&^wrpkJo;~P~zc^p6fpj318jK8+AI1w$_OCOZ99z%F7!Kyu*9%PkSt9~W_NeM>v_O9S+-VX@~Q?UCJCm==Ncp@XVmdcwyu$4ddWQbF1LARfHxzPJ+lao z?4ttAKp>#du%&TwFqX{3#h?IIz{nuM(7+p&RLp*rvB9W>r`i%oL-`;pL>MLpO7Vb| zf(e1J$$~XXll$wHxLXn#7?ShzN>cMmCV#5e6ZoITz>u4mmzkDYT%uQ$k~aB3y%vvU z22e1yBvG#-H)rztYAqhmETBLpP^hvXb+SQ&7UQ(Z(G8YdYK068#U+(Fsl}5YHi)p< ISAlE;0Frvu)Bpeg delta 1414 zcma)6Yc$k(7@q&%xQ?A9X)rF$kTGP&xDA`+HcMD!jmwbhxC|3v-Db>0orJ>pp_S0H< z%*aZp4)RUK+pBla1Z#|4p=moCmy}XD1pj3znI)Cn0ueIx5e}U^U`_}XVR$_JwI3eoPUz@^0L@uj(Pd7Xwvb{tJ zW%rY`Us){dpEAi#)!!vf(WVU(lhCrh#=oS#W8ukhtBJ>~br^5UC)3AuB{=DDhrO_C ze4+d0k!oS-N40aSe|DhHm4)DJyp0M`fmcjAr#|)XIv*+t&`}0A1?>qbbX1QrmFE&O}CEZ@PiinUDrvb69a6u zSxvmEZ*NzathKrK9K*XV&4?9E6{Al4F4U9y zUWBpVg>U6&d3Wd)YWqjv>THm>Xa24)u*M1p0=&zNi1pz@Oq4y#bsw5@LmVD{2h9YV+XBb^i2k6E)9xo%~>Nx|=>tY+1T#KOe(g z<2HpBtq-19Iz8hwqDHLvpz%|QqNwoNhPue*`!-!Klt?Y&$O6mAXP?+r`Xq)RTE%=O zw=Y#pjds>m4&3*~3sE;a76%3}#UiVRzxJ=gHS!;}CRDYZ%{%DLI-};L%0zQIx`}LWHHJC!D5;)d(4)E0Hkf($N6@ z^Fec%lZov9qub3JN*oFstI9qJBdi8#o@>WrV6U;AtmPX6*Dk(!>%oc6Da)FO5vfe* zf1qKk>IW%l7`LP+M}NLqGk^EpC;D*b^yci+YiECNWtH%RZru_E1VW~SK!6v}UXTN6 zfz~{vV3q<7KnDd%$>5}XVhI_4nS#3zMbH$W5}%S9oyklmRp^RqqdAJ=z{I~Hfs&la zLW=bh>>zO~ORz-%W5g7=3jz;$1a*WQ>?AfbGdGP1Ci97qFEFR;0Zcv-?nMDbq&+a^ zX$1b)jqMl8S0pnK2>+zm%pcR486+!t%#iVQoS5e|t2e?tZU;_Ax3K*JT0Adq9H zf&Hrfr5T6>FFBqtA_|nrPhIi|Ff~emH3L<7SfIy6!{t%({Wd^?P@t3Zug+i;$l%(6 z6}jYkl;AQRm~jZOV>IZ=!vPB(4oU-lJOj|g(^Z*|m%q=