From a22f5611de16a31385f0b2c5cc23d6117a0fe3c4 Mon Sep 17 00:00:00 2001 From: Philip Searle Date: Sat, 13 Nov 2010 21:45:11 +0000 Subject: [PATCH] Fix support for interlaced 1/2/4/8/16-bit greyscale and interlaced 8-bit truecolour PNG files. --- basis/images/png/png-tests.factor | 6 ++ basis/images/png/png.factor | 84 ++++++++++++++------------ extra/images/testing/png/basi0g01.fig | Bin 0 -> 1081 bytes extra/images/testing/png/basi0g01.png | Bin 0 -> 217 bytes extra/images/testing/png/basi0g02.fig | Bin 0 -> 1081 bytes extra/images/testing/png/basi0g02.png | Bin 0 -> 154 bytes extra/images/testing/png/basi0g04.fig | Bin 0 -> 1081 bytes extra/images/testing/png/basi0g04.png | Bin 0 -> 247 bytes extra/images/testing/png/basi0g08.fig | Bin 0 -> 1081 bytes extra/images/testing/png/basi0g08.png | Bin 0 -> 254 bytes extra/images/testing/png/basi0g16.fig | Bin 0 -> 2106 bytes extra/images/testing/png/basi0g16.png | Bin 0 -> 299 bytes extra/images/testing/png/basi2c08.fig | Bin 0 -> 3131 bytes extra/images/testing/png/basi2c08.png | Bin 0 -> 315 bytes 14 files changed, 52 insertions(+), 38 deletions(-) create mode 100644 extra/images/testing/png/basi0g01.fig create mode 100644 extra/images/testing/png/basi0g01.png create mode 100644 extra/images/testing/png/basi0g02.fig create mode 100644 extra/images/testing/png/basi0g02.png create mode 100644 extra/images/testing/png/basi0g04.fig create mode 100644 extra/images/testing/png/basi0g04.png create mode 100644 extra/images/testing/png/basi0g08.fig create mode 100644 extra/images/testing/png/basi0g08.png create mode 100644 extra/images/testing/png/basi0g16.fig create mode 100644 extra/images/testing/png/basi0g16.png create mode 100644 extra/images/testing/png/basi2c08.fig create mode 100644 extra/images/testing/png/basi2c08.png diff --git a/basis/images/png/png-tests.factor b/basis/images/png/png-tests.factor index 25815c7017..7edb8d753e 100644 --- a/basis/images/png/png-tests.factor +++ b/basis/images/png/png-tests.factor @@ -7,6 +7,12 @@ IN: images.png.tests ! The subset of the suite that should work given the current implementation. "vocab:images/testing/png" [ + "basi0g01.png" decode-test + "basi0g02.png" decode-test + "basi0g04.png" decode-test + "basi0g08.png" decode-test + "basi0g16.png" decode-test + "basi2c08.png" decode-test "basn0g01.png" decode-test "basn0g02.png" decode-test "basn0g04.png" decode-test diff --git a/basis/images/png/png.factor b/basis/images/png/png.factor index 2135d3fc96..2a77d13068 100644 --- a/basis/images/png/png.factor +++ b/basis/images/png/png.factor @@ -147,10 +147,7 @@ ERROR: unimplemented-color-type image ; ERROR: bad-filter n ; -:: reverse-interlace-none ( byte-array loading-png -- array ) - byte-array bs: :> bs - loading-png width>> :> width - loading-png height>> :> height +:: read-scanlines ( bit-reader loading-png width height -- array ) loading-png png-components-per-pixel :> #components loading-png bit-depth>> :> bit-depth bit-depth :> depth! @@ -163,65 +160,76 @@ ERROR: bad-filter n ; ] when height [ - 8 bs bs:read dup 0 4 between? [ bad-filter ] unless - count [ depth bs bs:read ] replicate swap prefix - 8 bs bs:align + 8 bit-reader bs:read dup 0 4 between? [ bad-filter ] unless + count [ depth bit-reader bs:read ] replicate swap prefix + 8 bit-reader bs:align ] replicate #components bit-depth 16 = [ 2 * ] when reverse-png-filter ; +:: reverse-interlace-none ( byte-array loading-png -- array ) + byte-array bs: :> bs + loading-png width>> :> width + loading-png height>> :> height + + bs loading-png width height read-scanlines ; + +: adam7-subimage-height ( png-height pass -- subimage-height ) + [ starting-row nth + ] keep + row-increment nth /i ; + +: adam7-subimage-width ( png-width pass -- subimage-width ) + [ starting-col nth + ] keep + col-increment nth /i ; + +:: read-adam7-subimage ( bit-reader loading-png pass -- lines ) + loading-png height>> pass adam7-subimage-height :> height + loading-png width>> pass adam7-subimage-width :> width + + bit-reader loading-png width height read-scanlines ; + :: reverse-interlace-adam7 ( byte-array loading-png -- byte-array ) byte-array bs: :> bs loading-png height>> :> height loading-png width>> :> width loading-png bit-depth>> :> bit-depth - loading-png png-components-per-pixel :> #bytes - width height #bytes * * width :> image + loading-png png-components-per-pixel :> #bytes! + width height * f width :> image + + bit-depth 16 = [ + #bytes 2 * #bytes! + ] when 0 :> row! 0 :> col! 0 :> pass! [ pass 7 < ] [ - pass starting-row nth row! - [ - row height < - ] [ - pass starting-col nth col! - [ - col width < - ] [ - row - col + bs loading-png pass read-adam7-subimage - pass block-height nth - height row - min + #bytes - pass block-width nth - width col - min + pass starting-row nth row! + pass starting-col nth col! + [ + [ row col f f ] dip image visit - bit-depth bs bs:read - image - visit + col pass col-increment nth + col! + col width >= [ + pass starting-col nth col! + row pass row-increment nth + row! + ] when + ] each - col pass col-increment nth + col! - ] while - row pass row-increment nth + row! - ] while - pass 1 + pass! + pass 1 + pass! ] while - bit-depth 16 = [ - image { } concat-as - [ 2 >be ] map B{ } concat-as - ] [ - image B{ } concat-as - ] if ; + image concat B{ } concat-as ; ERROR: unimplemented-interlace ; : uncompress-bytes ( loading-png -- bitstream ) [ inflate-data ] [ ] [ interlace-method>> ] tri { { interlace-none [ reverse-interlace-none ] } - { interlace-adam7 [ "adam7 is broken" throw reverse-interlace-adam7 ] } + { interlace-adam7 [ reverse-interlace-adam7 ] } [ unimplemented-interlace ] } case ; diff --git a/extra/images/testing/png/basi0g01.fig b/extra/images/testing/png/basi0g01.fig new file mode 100644 index 0000000000000000000000000000000000000000..d79f71b46926a63b1cf0e8306e6d1fd8889f1f43 GIT binary patch literal 1081 zcmajcK@P$o5Cu?TypD%(@6roY(-;>mB-9X>nAEjL=uH)77=)qFE=q<6zXLrRJ>Q4! z*6TM8-Q2y@q86j=Nm`>nkIQrF4_7%TIrihEr5%sEz4*4D4Hs<}ZFda&X%&s3CC?29 zt~+vcpOoeYt~qhVBZIqOeCRHzb|XwtogOUA;Z)Wgt%kAmj4?mt!jN;}jJb1WUU2S# zLpxBdwN~*M?*A0t$l4$K3$9AjFe06y@1s;bWp^fD(%UCw90gYuOm_mC%H8oy0plJ;|yaa?KmnAMk`(G6*LxZMYGklX_CXw8pz)!~XsE z{R_l;B%iO@S+Mxi#d|k1W1jAhOum0pYrW6>o9eGz=B2dXkDg=peCAH+`yAT7-d7m? zpD=neuC5Ya_iW0gUZXDEgTe~DWM4fgQ!vM literal 0 HcmV?d00001 diff --git a/extra/images/testing/png/basi0g02.fig b/extra/images/testing/png/basi0g02.fig new file mode 100644 index 0000000000000000000000000000000000000000..3953ef55c12e6bc9ff5a62a64fe14e4e76f9634a GIT binary patch literal 1081 zcmWG3FK*4uO-xTMZi7&Xt%*$q3knvL7dQIkHW8tf$}#joChMzVRnQ3j?5kiw~WR={qr1hoC5$A))k)s literal 0 HcmV?d00001 diff --git a/extra/images/testing/png/basi0g02.png b/extra/images/testing/png/basi0g02.png new file mode 100644 index 0000000000000000000000000000000000000000..ce09821ef101b65b2aa653931416c72923ccab09 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk`Bp9=o@yY{fmUKs7M+U~W1%@xC#RK_)o-U3d z6?2jUl3pY*JS=M4oiJze;et03Q>IK~Gc?O{N#DFKJ@&l7SH)M%%o7ftVn}g$DCX>; zkRs^i5p-N&*DHI8!;%tAJO+*|%*(hAE|_G=Fej+Nw{_diTA<+!p00i_>zopr0NF1v AeEp(av-3!JU+WSfPmKWxcm*WdnORjS{_@N!|YxK1hke% rk8fnVcLM>f<&o1Gy4`1hfY$P`bdJsLyFfr|c~Bn1W%oNEptU>z;sf)L literal 0 HcmV?d00001 diff --git a/extra/images/testing/png/basi0g04.png b/extra/images/testing/png/basi0g04.png new file mode 100644 index 0000000000000000000000000000000000000000..3853273f93e5960e0642ca62f6d6ce7433654928 GIT binary patch literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk^Bp9DO`>`KLv!pxvIx;Y}EiimBEgr~U=jq}Y zQZXmBFHrE1fq;v+j0h02$h25#lnT63xZ-%g@gNW$aGWTh62d&wbH=%|b$8yp-97vE z;Z29Oxt6;AKCTefnOkLOe zceV31xk&buuP3aOvK_8v?mNu>)5yI*ti8x;zv2JpMH=2qx2(%fUX!Y@wwPzh+iJE; se9X+5d(#!(S{O|*V`01GC)_Bn-uQauWnXqNpvxINUHx3vIVCg!0HVJkiH(a-NK8sj zNli=7$jr*l$<50zC@d;2DJ?6nsI024sjaJTXl!b3X>Duo=Fw*EFmcl4DO0CS zpD}aR>^XDi&0nx^(c&dbmn~nha@FcJYuBycuyNDoEnBy3-?4Mo?mc_=?LTnv(BUIT zj~zd8^3>@wXV0C#aPiXRD_5^wzj5={?K^kx-GA`#(c>pipFMx^^404%Z{NND@bS~< zFJHfX|MBzJ?>~S4{r~s(&+lJ9e|-P;^~>i^A3wZ*_x8=}S1(^YfA;jr<3|r4+`o7C z&h1+_Z(P52^~&W-7cZPYclONbQzuUxKX&xU;X?-x?BBO{&+c72cWmFbb<5^W8#k<9 zw|33yRV!C4U$%6~;zbJ=%%3-R&g@w;XH1_qb;{&P6DRcd_4agkb#}D3wYD@jH8#}O z)z(y3RaTUjm6jA26$0ZXHzzwQGb24MH6=MIF(E!KHYPeMG9o-IG$c4EFu>o>*T>t- z)5G1()y3J#(ZSx%*2db((!$)#)Wq1x&_G{LS4Ue*Q$t-%RYh4zQ9)i#Rz_M%QbJrz fR76-vP=KG0mxr5+lY^a&m4%s!aWwWvdh7!L64eu@ literal 0 HcmV?d00001 diff --git a/extra/images/testing/png/basi0g08.png b/extra/images/testing/png/basi0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..faed8bec445f282d68534af38ceb4006a55c3e86 GIT binary patch literal 254 zcmV8fu|I&j2dyvG3;`TGSdQ=U^x!+b$IgQ- z%948O0A52IVpoLha#x{@#6j?c@GG?{M!ifiZzGp>{_zn~uB074kac%~7}Qq~d6eokll}xVf^ke` zE=yR;HuiCx3*6)puldAJebz1Q*HTiFk(?BwB$cR5V_MUhUidSJQA}Vu^H|1uwsU}! zT;euQc*7TdD_&Q$QwvBYTPHinL@UFGVR!HR{ovc66sN0~yL#CNrBwtYR~}Il@`4ai15w=evICu})~6rjed( zGn?hKBR8csvsq3%%BN&zHp^*8ImBO_eJV2m literal 0 HcmV?d00001 diff --git a/extra/images/testing/png/basi0g16.png b/extra/images/testing/png/basi0g16.png new file mode 100644 index 0000000000000000000000000000000000000000..a9f28165efd4a6eaab890f3f46eaab0812614046 GIT binary patch literal 299 zcmV+`0o4A9P)kMw|y20kXn4P1fk&um!5HR4i(o|AwZ6~LzrfePT$2C@a*GO>pzD`W+JMY+o{~OMQc&lm=3iqj(vZoAg56v)&@pF xpiv;U26q|-VrxJe1@ZNXf_(7)M8WX7;00Eg?uiut|NZ~~002ovPDHLkV1i{YdSU zKEelh5AWbDG(!_K!W(!Eub=_yp$=-H242Docn;5?8mgcYD&Q$RfyeL&9>N1ChcdVi z_uwwvf!lBkN}&X9!VM^f>u?RO!WFm-m!Jp=p#bvXBIH3XT!8a%4$i_E$boFgg42)* z8ITTXkP0bq3QocaNQUEZ43Z!b5+EMp;3&jG3`D~bh=Riq2@wzuhu|O_fc>x!_Cgr! zflvs6-4F~x5D2?qCj@{$?11gC4g6p$_`(+O0dEk%X7B<}@Bnvk16SAtF5nCs!3j2i zBdiApum?L>2ez;l*1&480c%(VR_4p1jxZ~7zRT@7Gz)uNW)-|f({Sdy=rJ^sIRZDtE;Q6t*xo4dHM3?ix)4RKY#x0*|X~E>Z+=$ z%F4=$ii)RCpFVl=>n%a<-)Dk>@}EG#T2D9F#xzj*Ot zUS3{qZtjH(7tWtQf9~A5vuDqqIddi_Cnq~QJ1Z;e^y$-?nVA_G8R_ZiX=!Pxsi`R` zDW^`II(hQsi4!N1lar4hKYr}kv81G=#KgpegoOC`__(;ZqeqX%#>U3P#6(9&A31U) zDk|#m;lq)Ukr5FQ;o;$j4jnpp@Zf<12lnsZzi;2Zy?ghDg@x_evnMn(G$bTs_wL=n z!NEa6L4kpRyLRo`xpQYgK!Cr$|Bf9ywr}6QZQC|KKfkS8xBB|}ZrQTM$H&Lp+gl(I zY~H-t%gf8t)6>Jl!`6s#R82Rx4MoT(M$>rKP2Xg@w7fxtW=n zsj2Dm<;#~XTefuRQWF!CB}Fe=IH6^&7M75S66q|tXVobIx}a^oH1j@^y$;JwY9ahv@|s}r%jtSb?Ve9 zQ>ILwJbBWjNg5g&>gwuhYHF&gsuL$poG@X6ii*nk@#Dvh8#i|B*fC?qC@U+E9zA;0 zs8J(Fj#N@oQdCq_P*9MUmme`=gq)n*@ZrOU4I4Ie=ulZ%Ss59bAwz~pOG^(PJXlIf zYS5rT0|yQqFkpbBq@;v|MF0N%`}OPBw{PD*efo%ti}&u`TTD!>SFc{8qM{-qBErJL ILPA3S0KfGQp#T5? literal 0 HcmV?d00001 diff --git a/extra/images/testing/png/basi2c08.png b/extra/images/testing/png/basi2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..2aab44d42b23d59d48601b109a795d9ba70d6ab8 GIT binary patch literal 315 zcmV-B0mS}^P)?-TFZBK`N@L-n zZIKuYb8U;nSX9Mrl^A36r{K12&k3mj^Z%lhjX;s*Jg960iexztW-CxinU-MA*#;OZ zngOW30HtIErtRT^u_8M_CF3kj<3j{vMRtJ6I<2P3n{$R*t1rNmk`0g=AU|E-;g=04 zMQ4L1&-<_M{L=