From bbc2f8ffae939eab598f583514fb132d23c11705 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sun, 26 Jan 2020 15:07:18 -0500 Subject: [PATCH] Bug fix: handle ColorSpace lookup for inline images (fixes #392) If the value of /CS in the inline image dictionary was is key in the page's /Resource -> /ColorSpace dictionary, properly resolve it by referencing the proper colorspace, and not just the name, in the external image dictionary. --- ChangeLog | 4 ++++ libqpdf/QPDFPageObjectHelper.cc | 16 ++++++++++++++++ qpdf/qpdf.testcov | 1 + qpdf/qtest/qpdf.test | 12 +++++++++++- .../qpdf/inline-image-colorspace-lookup-out.pdf | Bin 0 -> 1348 bytes .../qpdf/inline-image-colorspace-lookup.pdf | Bin 0 -> 1176 bytes 6 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 qpdf/qtest/qpdf/inline-image-colorspace-lookup-out.pdf create mode 100644 qpdf/qtest/qpdf/inline-image-colorspace-lookup.pdf diff --git a/ChangeLog b/ChangeLog index 68aff3fe..38749752 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2020-01-26 Jay Berkenbilt + * Bug fix: when externalizing inline images, a colorspace value + that was a lookup key in the page's /Resource -> /ColorSpace + dictionary was not properly handled. Fixes #392. + * Add "encrypt" key to the json output. This contains largely the same information as given by --show-encryption but in a consistent, parseable format. diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc index d588c322..01f1d662 100644 --- a/libqpdf/QPDFPageObjectHelper.cc +++ b/libqpdf/QPDFPageObjectHelper.cc @@ -141,6 +141,22 @@ InlineImageTracker::convertIIDict(QPDFObjectHandle odict) } else { + // This is a key in the page's /Resources -> + // /ColorSpace dictionary. We need to look it up + // and use its value as the color space for the + // image. + QPDFObjectHandle colorspace = + resources.getKey("/ColorSpace"); + if (colorspace.isDictionary() && colorspace.hasKey(name)) + { + QTC::TC("qpdf", "QPDFPageObjectHelper colorspace lookup"); + value = colorspace.getKey(name); + } + else + { + resources.warnIfPossible( + "unable to resolve colorspace " + name); + } name.clear(); } if (! name.empty()) diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov index 82ac9684..db3de950 100644 --- a/qpdf/qpdf.testcov +++ b/qpdf/qpdf.testcov @@ -447,3 +447,4 @@ QPDF_encryption same password 1 QPDFWriter stream in ostream 0 QPDFObjectHandle duplicate dict key 0 QPDFWriter no encryption sig contents 0 +QPDFPageObjectHelper colorspace lookup 0 diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index bfc20178..f9bab01f 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -809,7 +809,7 @@ $td->runtest("check pass1 file", show_ntests(); # ---------- $td->notify("--- Inline Images ---"); -$n_tests += 8; +$n_tests += 10; # The file large-inline-image.pdf is a hand-crafted file with several # inline images of various sizes including one that is two megabytes, @@ -853,6 +853,16 @@ $td->runtest("externalize damaged image", $td->runtest("check output", {$td->FILE => "a.pdf"}, {$td->FILE => "damaged-inline-image-out.pdf"}); +$td->runtest("named colorspace", + {$td->COMMAND => + "qpdf --static-id --externalize-inline-images" . + " --ii-min-bytes=0 inline-image-colorspace-lookup.pdf a.pdf"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("check output", + {$td->FILE => "a.pdf"}, + {$td->FILE => "inline-image-colorspace-lookup-out.pdf"}); + my @eii_tests = ( ['inline-images', 80], diff --git a/qpdf/qtest/qpdf/inline-image-colorspace-lookup-out.pdf b/qpdf/qtest/qpdf/inline-image-colorspace-lookup-out.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5fa0ed6c33d8908febb2b7dc6f89fbffac48ce2a GIT binary patch literal 1348 zcmZuxPi)&%7;gm=mB%EiUAhCySFub8!R+T}JFygHrO5(Op$$o;fvO%H=Oy!$*u{27 zI*qMT4m(vHCoW87JHZVxBqT1-4ce|6Vj5zb#9{vg2gD_ajY_b2-;3j>bh9N}{@(BV z-tYVUzUO!$n|qBMphEoHf6hM=2uR?Rj|!<2hy|m@JdiO`1aWe1hJlzde53BvAe|PN zUEx5!93^C&S=$E!;+R$OU-AFkaxc~PneBU^gxkH%DwZ+oG_i_=w?<@0 z=rUlfg5e@CqE%#`GwYhjlQYgZb;m8u7$yTXtdnyP%a?Klv`#3U#u~0;mY5HT5cKXu z`6x3(Tt43*kc^NV9CpshZ)uy;jJUtW?3#ZBk`#Bb>OOPvT{nD|Wu{ZnF8e_WVf8yViWW9|CDnwWp}@{P%X%Xi&fcV0ojRYdiTW_H7+ zizCZdz8e|VKOVdFGrdt*jxUW3pV`@WZE0`;UFa6?`oa5-h-FFy^lmGWUtEM}ebn$+ zM3S zY6=C<<`Bf1K1@eMxW=1AEZ-|IH{&#B9Gkm~CAWAP_V843k-1en;)9adLMq?jW_3wL z=3+Y)bV);C*D#_f+|f;Q{tcFfX8Ky~{#JXi)qbJX9y;5e-?N^4*8J-0%%1-WD+lLZ zzPI?{!2>Ic$4?Gr_O^z1o=*osd*ZMDdqHa?x9}TT4$dwH!RKG3Y8$8apEBLU17n2LJr#)cqh9d+yibF8252#i1Wg$67D`^3jP6a`X574=%+%9p88u`{T1) ztLMfyPCUQfJo)|J_4(5;y??vEZ}+w4dtAEzyUms9N}RVVtjQ`MX4x^zWN)~}9LkuI zq$*4IRByVhDo8*iLE5}PQ&p-$6*gl8r-)x*_hKm4_85`z2yeqtg1?Y$G36<_ijI@G z4W~&@*3;;dF~w}XfeBl zr#$Wbrw1q&Fu;s$rF=d>hhZJE0f&)FKv(UmM}Q7M2PVuq;P+F=h!Y|S=Mn;DgW&)c z(B*pE1~q`sq}Jw=v-R?+B%Dt*9Ar2)5VFfvptuf8%p|VD;9F!lASoQcwZhQC#GI^3 zWSb3^iggmj0W)D*k$R{i;LX+vnV3sLAr^=k$nVEBEK`jj2S`Imc6&tOKYJruaspQ) zqt4j^IN6J9=?Mo}_?>_b3L@2vXR>U^LU0?EJZ@9HmEoS9d=A|673r( zo%*tD+UlmWk*2m$;jW4oix1p?RC+4*u+RPMp$d;K=fuWoiGc+@zt_b++#Q#W%qU9N zTv=K^FhSO$t)H&8Ki=H8p>h3*=C)03bNc68bKT`X8)JKZw?FMT-{0EX;o84kH=630 z_h;peXU+TPCmy=L8sB|)-IimnIp9V=KDhAnqWkLAQ*->MbNePJbGKivy}9w*+dD^R zwMZvh_bx4Jztwj)`lEW$hgs1#{byQUSCu}Wl8Q`ve{cWf!kNwV`kN^*a>SCa z_1Cd$29IgbKcr8&GY&*pAP=@A=P%NbrY>;3GlTgwDwK*X~*kH8Gh@&Km z13HLy=qg%i!Clz(K8DedKcA4akVY{;p_riyh+Z%61sWK_SiFC70V9uz*muJ)mczp` z4CCbgd7^-)Wf)JC@Qe<_BuV)XlbL@o$AWqSdz_3;rD>9>&in=<`fdaiK$itUjZg6M ziYUcIP1JY};)fUVs={b72BDasaeg0^c#UU7MU{j&Bd7utcorgo*JMc+nYiq)CF5p0 S&~h@zC3|Jc<0)MmqW%J_