From a34e6fe1cd30cdd95dc708934f3b21385af2eefe Mon Sep 17 00:00:00 2001 From: Kuba Niegowski Date: Mon, 20 Aug 2012 23:06:44 +0200 Subject: [PATCH] added support for all color types (but still only 8 bits/sample) --- .gitignore | 1 - examples/test/img/PngSuite.LICENSE | 9 +++ examples/test/img/PngSuite.README | 25 +++++++ examples/test/img/basn0g08.png | Bin 0 -> 138 bytes examples/test/img/basn2c08.png | Bin 0 -> 145 bytes examples/test/img/basn3p08.png | Bin 0 -> 1286 bytes examples/test/img/basn4a08.png | Bin 0 -> 126 bytes examples/test/img/basn6a08.png | Bin 0 -> 184 bytes examples/test/img/f00n0g08.png | Bin 0 -> 319 bytes examples/test/img/f00n2c08.png | Bin 0 -> 2475 bytes examples/test/img/f01n0g08.png | Bin 0 -> 321 bytes examples/test/img/f01n2c08.png | Bin 0 -> 1180 bytes examples/test/img/f02n0g08.png | Bin 0 -> 355 bytes examples/test/img/f02n2c08.png | Bin 0 -> 1729 bytes examples/test/img/f03n0g08.png | Bin 0 -> 389 bytes examples/test/img/f03n2c08.png | Bin 0 -> 1291 bytes examples/test/img/f04n0g08.png | Bin 0 -> 269 bytes examples/test/img/f04n2c08.png | Bin 0 -> 985 bytes examples/test/img/tbrn2c08.png | Bin 0 -> 1633 bytes examples/test/img/tp0n0g08.png | Bin 0 -> 719 bytes examples/test/img/tp0n2c08.png | Bin 0 -> 1594 bytes examples/test/img/tp0n3p08.png | Bin 0 -> 1476 bytes examples/test/img/tp1n3p08.png | Bin 0 -> 1483 bytes examples/test/list.html | 38 ++++++++++ examples/test/test.js | 36 ++++++++++ examples/test2.js | 2 +- lib/filter.js | 96 +++++++++++++++++++------ lib/parser.js | 108 +++++++++++++++++++++++++++-- lib/png.js | 13 +++- 29 files changed, 296 insertions(+), 32 deletions(-) create mode 100644 examples/test/img/PngSuite.LICENSE create mode 100644 examples/test/img/PngSuite.README create mode 100644 examples/test/img/basn0g08.png create mode 100644 examples/test/img/basn2c08.png create mode 100644 examples/test/img/basn3p08.png create mode 100644 examples/test/img/basn4a08.png create mode 100644 examples/test/img/basn6a08.png create mode 100644 examples/test/img/f00n0g08.png create mode 100644 examples/test/img/f00n2c08.png create mode 100644 examples/test/img/f01n0g08.png create mode 100644 examples/test/img/f01n2c08.png create mode 100644 examples/test/img/f02n0g08.png create mode 100644 examples/test/img/f02n2c08.png create mode 100644 examples/test/img/f03n0g08.png create mode 100644 examples/test/img/f03n2c08.png create mode 100644 examples/test/img/f04n0g08.png create mode 100644 examples/test/img/f04n2c08.png create mode 100644 examples/test/img/tbrn2c08.png create mode 100644 examples/test/img/tp0n0g08.png create mode 100644 examples/test/img/tp0n2c08.png create mode 100644 examples/test/img/tp0n3p08.png create mode 100644 examples/test/img/tp1n3p08.png create mode 100644 examples/test/list.html create mode 100644 examples/test/test.js diff --git a/.gitignore b/.gitignore index 24cd046..3c3629e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ node_modules -*.png diff --git a/examples/test/img/PngSuite.LICENSE b/examples/test/img/PngSuite.LICENSE new file mode 100644 index 0000000..8d4d1d0 --- /dev/null +++ b/examples/test/img/PngSuite.LICENSE @@ -0,0 +1,9 @@ +PngSuite +-------- + +Permission to use, copy, modify and distribute these images for any +purpose and without fee is hereby granted. + + +(c) Willem van Schaik, 1996, 2011 + diff --git a/examples/test/img/PngSuite.README b/examples/test/img/PngSuite.README new file mode 100644 index 0000000..3ef8f24 --- /dev/null +++ b/examples/test/img/PngSuite.README @@ -0,0 +1,25 @@ + PNGSUITE +---------------- + + testset for PNG-(de)coders + created by Willem van Schaik +------------------------------------ + +This is a collection of graphics images created to test the png applications +like viewers, converters and editors. All (as far as that is possible) +formats supported by the PNG standard are represented. + +The suite consists of the following files: + +- PngSuite.README - this file +- PngSuite.LICENSE - the PngSuite is freeware +- PngSuite.png - image with PngSuite logo +- PngSuite.tgz - archive of all PNG testfiles +- PngSuite.zip - same in .zip format for PCs + + +-------- + (c) Willem van Schaik + willem@schaik.com + Calgary, April 2011 + diff --git a/examples/test/img/basn0g08.png b/examples/test/img/basn0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..23c82379a29ff4b99806bbbd2e2342c8fd97ee67 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk@BpAX3RW*PVOS+@4BLidG0>c;6;(>fePZ!6K ziaE(C2`UUC949vOu(I~>b7=nfE^nVuX&@tFa7u7Oddi~87#=p(p8gM~{{27yqy1T- hp#)Io!PL|g7KVVQ{|ZeX-G~HP;_2$=vd$@?2>|oDDeM3M literal 0 HcmV?d00001 diff --git a/examples/test/img/basn2c08.png b/examples/test/img/basn2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..db5ad15865f56e48e4bae5b43661d2dbc4e847e3 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1SJ1Ryj={WSkfJR9T^zg78t&m77yfmc)B=- zRLpsM^&lsM0S}Wy>zj#xw-*UpyJ&w|_~YC|?Jc}4)(u=DKV%lXeNyXF;n2v$@6|4U rsD)ibtrx; literal 0 HcmV?d00001 diff --git a/examples/test/img/basn3p08.png b/examples/test/img/basn3p08.png new file mode 100644 index 0000000000000000000000000000000000000000..0ddad07e5f5de86a61bf43d8b89e138d7f1ea8ad GIT binary patch literal 1286 zcmWks4NMkw7=KO>3}y1F=z>r=LEEca@LnZf*~BA0ROZ5~$d#4)lIa>n+tGAx#s~NCh;!h=Q?&7t5~~Lk>mL*|1x+L`Ivp6mn?kJ^kK$c6a~%|NrOteLPR)ru^*4 zh?oc>ipx)wHw!xP<||VqG2mh2yNQ1IZKr30Xr(I7PBXU z(o_;ftk^?X5O*qmM)+A^aUR*s!>r3PlcI=3mc_D63M-aHQVj83+hHDKi)~wG8A%eb zMRFVzAa0kL4aW(lxy(-(A3@r7{KRdCcI^9^ zBwSWlMY4uMp(p@%T`0C7K$rnonuoRmLY9xP#5bTx(RKJi zCYfG^*s^*-{Ro^e4Kgw{Dlmv)JpjQ5bKwF@CLI|%59=nhA>e#HJh5GNjRLr(&Jco- zL=roU($L^w70~)&xPh+uFV&-K!K0w3W-9Hy@g@HWXL3ML4|%5ULen8 zlT@|D2@;VI*iada4446_ptp_#Sul*Cx7Y6>PlSiq8TyN-q=y}cXZX&@20)p=ihIP{CfA$Z*4W@ zEr$zzJ<~t_(0G1&!T9U{_Iz>DPFy@Dgq4(i*+1}U*ZiG1m)32#<4sRFJ5!AP>yZ}L zzdq~5lB&|C6*=qgy?nj!is#SN$*Gwo6M?qJgKJtd1_tvb_xS3qJuRh&eH)f1f0J@< z)4uq(Z_li{H~+s=+3L-xjU7X)ZvEUC-CLA+t^7d7$jI)tsK~;c&XdnBOC5Txp}1)@ zusm-vWl2G`{dnN}K>pDE=;yi{rVB@Y3B-HrtGOePxNz#}j}FD`z3|nlwikX+ZZ56= zAY&lKTUG9w&2^VN89D}o5=^>%~&6ID5>`0fk%7K&zZcY&F#znJTW|E zB5&cFwM~ly35&;HdZq5*>W9rM<&V4Wr%mNt{B`@CxYpR8I;^7!?Tc=wu6t&Du2Ec< zKIiz-xXN3dttqGahAW20Qo6MzgSk7e_{!(?CKyw`*?j|NY=7wG%F`JaWZ(VOm8CUr z$$no_)1uMK%W6)nN!IrL6EB>puUj#i+1xg}<&qUPnY6#j4&NW^MpZNn{t+Cq+^l@L JEAySt{s-!kV`~5a literal 0 HcmV?d00001 diff --git a/examples/test/img/basn4a08.png b/examples/test/img/basn4a08.png new file mode 100644 index 0000000000000000000000000000000000000000..3e13052201c9f8b90172ea2491b18d6d121c2786 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtq=#3k+XOiwE*eJzX3_ zD&{2rIe*{)W9ys@6GNprI`<_tn04&i_AxF_G>~EoF-$NKa6jCj#n!|2C_^IPFayJV XErr@6uUk(54Pfwe^>bP0l+XkK+-D@M literal 0 HcmV?d00001 diff --git a/examples/test/img/basn6a08.png b/examples/test/img/basn6a08.png new file mode 100644 index 0000000000000000000000000000000000000000..e6087387639b9cefaaafb696e29a8bd910ee0680 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmUKs7M+U~W1%@xC#RK{Io-U3d z6?5KRGvsP8;BkAXo|56e@Vk8|OTXfgyGLCsWP@G=X#A1))wtQkXb@LjH|PH@<7U}X zR(Ix8Y%6~9Ml4|WGnG@SZHQ?Kc`Uubi9hC!9z&%<$E5#{7BHGEsCHnVVk5wElR+}T f%%Pr9`U69dg47%_{vAF*s~J39{an^LB{Ts5$SFGl literal 0 HcmV?d00001 diff --git a/examples/test/img/f00n0g08.png b/examples/test/img/f00n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..45a007596753f6627224931755c073a3362be88c GIT binary patch literal 319 zcmV-F0l@x=P)N8=ISR z4CLwk<95#Vg>&ou?4IBK-OKf4I=h+Q-Yu4^`-jJ;=a<*F_w~o;*Jiu>-k0SMV?!`9 z1Vck`We6?}!N3q)7=l6z!b$|W5>ORnBHWgrk_!4FAm#v-gL4rOlDZRAQhFl5C-ouJ zT{shgf4PuS-IlHh@Hud2s6Ob305=7HTh$nC5#jVOMRm%l2)`fuP_1(!!tE!01i`Tg zNcxC^mI$IC_VFh;N<~=u^=Vc`@;_)KBFl?^KZrv^P&WiMLvUaSEP*Ak#4p5s%2-gQ R&b9ym002ovPDHLkV1h+qhR^^2 literal 0 HcmV?d00001 diff --git a/examples/test/img/f00n2c08.png b/examples/test/img/f00n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..d6a1ffff62eb0f1f1dcdb4ba2b1d30473d3adacd GIT binary patch literal 2475 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 literal 0 HcmV?d00001 diff --git a/examples/test/img/f01n0g08.png b/examples/test/img/f01n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..4a1107b4637642335b8ec7b8e1856dc0ba7dab70 GIT binary patch literal 321 zcmV-H0lxl;P)}T4b;N0E z3!a!0=lJ%5$Eg%oz?c7nM_Pz6fDfO-!!(E~0KEA*c%UmW2WDfu_({31E3v>N-{Hyc z!o4_%Y@;b2{kGgyCmt~K_ux)+Vvc)%F>XgE7N{D;Epg%*RfD)GPQ0RO5I3R|@2DEY z_29%Oss?dQ2JwUcSEewBLHsU3nZgtbQQmYZ7(-i7*cJ?I3zBU?bOg~6L`VDql~F8% T6Mw4;00000NkvXXu0mjfmy?8r literal 0 HcmV?d00001 diff --git a/examples/test/img/f01n2c08.png b/examples/test/img/f01n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..26fee958ce7e62a59843205ad34f86a525718595 GIT binary patch literal 1180 zcmV;N1Y`S&P)Qj4`pI zFjkU)u{F?Akfo*B!a}174J9nsV(#3X+5PQ?pp&O~&o{|^n{V!Obi%NV*_mQj=dbpv zm_B(tFHYo4wlii|=dbiix4xT4UZ{eGTtw$J**>tSy6N}n|vqif78L&$byRK9f1$SzrLzUf{!*^r3k$774rXm_7!8f1Q2+ z=C=8j8BA;b>93ttmB!R4Gqr2#)Il4ngL#p|9QHl^o9+4V^!;`CWzciKaJiBz*2s-A z%Q~e~hNeLo)I~S+8N27*(|0^}KLTZc)b*DYt70WpQX@6;tlY_+JY<94KKc3jyKkHx zc~$=bes_90V0+^67$}#lCtg&T@Kv!ADxnb@aaQcaP8xdm`scunQ;gUj^(pYH(^C;! zNn5y!L|KC#`k`FGPq->y@fF|j4L>V%d?yTrfgi+0@98t($EU{=wvxAS)ubd$_PkV3 z!A+>5imOt?H8kTouFDPFK!bmL?KbeO)596d+rNC?VU*+1#52gCK!FJ=R8*lsgBd#N zFko=|Nq}~GkP6E2D88M@l8GXUm_!xTsfy-kVs>rq&*Z3{>ZqRPX`b1u2fF{_*^dDC$unBQ(Ew)&lzW^YzR^hz^JI^CidP9to*K@y zNDItSJ$~`R-vM{)Cyb~i-{XO3q;i~yCk82yJm$&k5=WK56seJ#sF9XvnK_+adK+*z zf5tFI)>7;!5IcJyUb1-f+PNSFERrJ@DN!XcC2FQ7s?jpdPCtJOaPPm$D2$0wv{X9^ zWaZ)t@yIozCq+^qMJ$rnCC-%0l&Qw=-{Go9xBkqiT4p;6#CFmU*E%r}BWWdJiJY-a zF^Vx6Z~f)!f}4M1bjGY@*ij%CA&7a#dtxL;QaWQsUcZ|{DNGZ!QmbmEH8z2;34}4U zEce==fUtrOcu$DLNKC}F#?F@|D_EgSluD^gm7PG?1j0Nt7TXI1ibI5i_qeUYM`9wZ zHAc+m{muoO$dyvD%1$6`0-+Ag%UwbcF5n#U_<-~Hh>wJXPsDV-gPixfkS9{*C=fP* zFb&F3UG{zuavL5Oa2^-&5ueTk!)M~U--S34D@TE_2?QJDp|V`eAXY9N+By{R372qb zf6pNl!i29J1;Qo}(jX4E_qp%Fz4^!GobzySIy|o?)B5V>_Wt4V>G|dL?fv8P>$@@5`4A$18fipC zj4{?)>#TR)dmloGF-Am6L9i(ZNIDP1wql`V1IXeb3GF@N^}7L$OLT?eW035 z>s-(z0SrY%YCz?nO#+xF1yoYnBznj5E`aJnr^KQQpxV+di7ue_plgdhP^rb}TH<8U z-_)#002ovPDHLkV1l$} BmFfTh literal 0 HcmV?d00001 diff --git a/examples/test/img/f02n2c08.png b/examples/test/img/f02n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..e590f1234816946731c677d0b353e2db5a08d71b GIT binary patch literal 1729 zcmV;y20r-x*}n2M`}#}vjc?j3 z-?s05&wlVj`|(fh7r(S$|JMHaC;Q7^?O*?~d&{=IVSD>_5?Nc!ER3!g3n}x;oHDCS zE7M9tnNlW|No7L0po}Y{%BV7;)RZA*NEuWHlu$uIF{MyCN=M0+Oi>NpMWV~bQp%#T zpv)_?%8W9jOe<4Ly-ylf#ww|%3|Gvc5-LF-)9o>#n>V*ev}9aNS<tNOUgyIH` zG-q7aJ|<;Bs%p}n(NLyR>cV6>o0KtOR2fOBDK%kO8B8li!+3&t(p()kWp0LO#<-$= zOvf4WkAB#DDgP)1#^?QNplUNhH+K4K#)MH}M8lng?S#!1>#?oI+;=QHd&_Y* zvQ2ag-A04p0Z)8E@cI#Yj2@#AdWt&Kp)E8)6V#)Eh6mnu6Sfn!T5QC&9<$>3pR;Ah zn~`mxSA%AGv*B#jvEq6SSw}a}hv?(JmFIitK6;2Y(MP>%q^zct!qYa9w`0$dr1uwhW0Zhu#4`YC3A2lof%qhmB?1mex?MvA0uiC*F<|9wjtewjbMGY&*`j zoNYQ=i;4%x3bKm)ELbUlhe-cy&Q~LkkWkfBOvHTK5^pVU&KE8zqNF%!6-RN=jJt=f zyYIStuDcy|)=2IKN9FDBuxB>$Tlj7K4t|&RE`A?>fIq}HX*X$yq{F5)WCR(dJ%%60 zUobyOQYUH9nkJsLcn-IKTf$xH1ii7(+IyZFAaXuHLUf39$aL7GW-`)eOjt5$$&|Gk z7SC8bXKudx>~4AcfL#|Bg#}?=m=$J(8L0w9n3UeL9uLU|&_U86bQr0b)M$_5M@xoe zf}~Ds%Hl?G{lDey;l^hyT6)`NFITQS5g;L1KsJC5kPe`O$dJh}?HYch$0Xw<6ZZU{ zd$-?t0XK_VuxLS_2oUXUsK?Ay2?S&T8dk=j$q?;fe2=lO{-L*jZof!e$2D-%xH*gF z^n8Gvsp5t2h@l@X8zXow7$3|f20{E)r!yT=R8p8tOF$?p``zg4{drQ+FJ#q^ho zXy)BBQMAcvVzRW z3^h_v5Ric9p5w+1ZrERCgI8Y-UVAOLeLHyLjo{85+yt&}QC+$AHbz)d7DMt5 zd6zUtb0njk;WJuFoZ^&7I1!H8G(892_Pp&Rww>5!%hqFCjqSd(WoK`>;%;>AP46PR z$UY&RE}af}mn)!IyrepUKyIwR{8>j(~{{02>UU6F*}Ye$EIT~(g*w> XLp~IzS7kjt00000NkvXXu0mjfY;#J> literal 0 HcmV?d00001 diff --git a/examples/test/img/f03n0g08.png b/examples/test/img/f03n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..ed01e2923c92fd8b8786524c6d6841365a44b9de GIT binary patch literal 389 zcmV;00eb$4P)4Zd45D^U_MS@TiGz2aVLCXUNp&Fi;&<&!6t`aRYNwm-e(L$HR7llUs_2v2Lp?04i2#w>5 zCjFHgoS}>OqWhKs;-;4%0XoyCYd;H{ChLTAkL z`Nnmc1cXl84@#vy84@~$6^JKJlZ=Ubk`d9uF>y~YB0kwMamU0Lt#&uLFSbqGG0ztr z+6kZrX%qLj_#)n+{rCF=MU%cN0ReDq=R?P^VtFOGwjP)u6|4v*CxG_LFwq4OLVH6N jD*7N)_#jLSK#2GUV`p4Ky#5P000000NkvXXu0mjfx;dtp literal 0 HcmV?d00001 diff --git a/examples/test/img/f03n2c08.png b/examples/test/img/f03n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..758115059d78260f7485521b83a864d4a930be84 GIT binary patch literal 1291 zcmV+m1@!ufP)=&S9{TIAi*MDSax9$V&z4Gt?ul6?wozPIOm-?GqbzHVVL0@-rxKGKhOL8k5O_q zSFpv3t*o}I*V_9Zvg_8{M;@~qp0pb`*{3(#=eF8yFWQ%0wy%ua*LT{9H|_38yXP&t z_Z_?MUHjhq_P_`B;30eDsQu(qd+fM9al)Sb+AZ}0v>o^z(58vARqwd=u@6n@Pmke1XD_3x{N{!lS^S@Mz)_} zdJOa7^M*h)z+aJKlpUap>FUU*babUGt;6i!o}sK%&_Ml_0}Q1o&Mu`O$?Cq66Q@JT z3RxIYM!*w1@Du|XA%l7Q)eI$}3>DD;e|4H6l$4TCgo02|@B=KrQ z@Wkm5Gr226kv_(nB^X7=$b&B_9m1$G>KKWRgkdJ$$Rs9|g_2{8Ez5|#T1H2TVa9h$ z(j;+7%SwO->aXp@3<>@U&;J{qzZIUl8J_zyJbOJn`+IoiYIx>K`1Q0sy`|S$qy4Ql z0v=}L_DlonP=h(73bQba+*O)>Gz;H^EtdX#W}j_9D|OAoJhWjRA~5T>Ndu`v9p<2x zV$3LYKl;cP4%*<5UG=dYJ8U03Vjuo4ycMs0P50HI0S#zE(=pl(GY{sz&C+xa)e;>z z1~aNPzjM$1t-?9LR-*64P#mG-1*D8@fZ(*yqnYop#)_J&`RW&@^-8p-T}(?iQxc|RDc*( z<`4s3eE1|ejyabvT}B)cWe8L&9Y4_UCg9tx=>U_B7``SQ&NPmDBN;&XQlhP3n_*jascABYwWa1geh;>x-+i4(U_Y8$pQBrmp@_v#) zgF2F8aQOzn)E_eOLYJ|y`CQzx3-$nmLD=V&A(sP5g05dja_!i}_ zgIDirr|I{mZhX~}7YtBA6@@6ph=h6QI6&Kt{O(YUr$lPFM|Gd{aIa#L7cd2c1x1(E z(Q=Gs10<^TF-)&&>U0cv)zz`6SBo;LJ%(}H?`NdF>L`))0fxOAVsvH`hUsg)nABw~ zucMi=tL~(v8Fzi|4FCoh!(J`gSItz-2XxH%{{y9tm%W$Hmi_<$002ovPDHLkV1gMt BbC>`C literal 0 HcmV?d00001 diff --git a/examples/test/img/f04n0g08.png b/examples/test/img/f04n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..663fdae3e7d906df7379d92621a7a951313705cc GIT binary patch literal 269 zcmV+o0rLKdP){e2x4DAd1)!+NJ)f5B{T9psOdMM) z%F+|8FY)0+3~^>3vs1_&)hG|SqQp{zQhWvt^p*^yfsjOBNTM$!(HFu%2m|o|7A8yw TA(>!-00000NkvXXu0mjf-K%M) literal 0 HcmV?d00001 diff --git a/examples/test/img/f04n2c08.png b/examples/test/img/f04n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..3c8b5116e72a63a3de8e0c1892c147071d0269e7 GIT binary patch literal 985 zcmV;~119{5P)hvyJ!8utT1VEc>UN*1Tj!qJPN}IY>N=sRACLdrt)_N=Jy&nmRP0foi1T3q z1vs!^NS8tnTiC(|3Cm|k`D(`N4+4W;;{3xH5HR3=UuuoS4K!$rOa`(R z?R*&X`GvfR1n&u#ACUWVNrjF@+CUA>kh2DD{mP;k>FRtL8*-Oa0-8az@Zi?_D?6u0xgjeiedR*>(yJr`MN%ucekr3 zWi?2)HMNKXi#p_|&$f}^7s7eRdN|{jt0Vw}4uOnAlX>OyYx{;(h32S_hezhCE(Fab znDm|v`WGp9zt{od@3wLWe5y}twl%v9eNEpS4jt=K5jm_s#Yobzz%^iBf5O6mQ4IVB z1gSS#SEq}Q@Y^iry7D|7u$1$9vV7%>V~{k^6C{`$4zP=FjwZm`$rGS zvDv1V?}l%U4QyZyYY4D{53qy=jUGER5T*mg4DDFWy$X8(2FG?szK8L%=^pMOKo~6M z$j~Pc+wCNgX-nw*aZjf2VMtF87IxrAsgQ{`|D+q<6)@}&$53fBJv+1hHpj`E}Y00000NkvXX Hu0mjft5eU! literal 0 HcmV?d00001 diff --git a/examples/test/img/tbrn2c08.png b/examples/test/img/tbrn2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..5cca0d621047cacf1637cf7d77e997d51cc6b15a GIT binary patch literal 1633 zcmV-n2A=teP))6_}Akuqmh*5X4X^rIbM;BH-v?$kU01p_ErCl=u4~ zL7fbz&H-~9!(}3aFu`RZW&unzb50QkgK2!RYsr=o3t~2tT^d3tzx&+X@9uj)%)Vj6 z{|IpB&Yj-g-pR?y{}^!Z-o3WAwzRagh=_<-fB!T`$I~7jJzDL9k&%A|7#|<+>gvkP z&5eqRQiO&cb#=`%Gt&SnAO*+-su`xq!J$j392p#Z_UzeG0aH^`SFc_zD=UkSkAGjG zNZGY3d;R({hG_tbfDeIqE;r1MUWVZftDkNW!h zs;jG$lamt?5{`w2W;;5Ta5(kAS>OWD3k(34fhLB@x3Eyz+ozkGX8`3uA)t^*Vq;_J zARVu%si6?50P_I-{r&0b>GXAy-pZYvJ_kMn+JSRiZt1pd#bWVg8=D~(>oza}`~v)> zM}7e)8HRFA`iDhFM^mix0K>z>DwQfHCnqyAGc`3;6%f#2ZhqFvO5^8uBq=H7FUwFU zT6XLhvbG*uwdz+cchJo2l$~8_P|)B15EmC05)$I?@88+kIS+9E{(W+tk&&UwQ56&v z(A`o(AH0rH_Tk~-0RaJGvDnww_wL=h^8j=?>6z)a6}IeCY}aO2b*Z|fq@=L0@WhD| zsSDdty^(jSiA*M&bM5WzEtks;bWvVj9&?GoHDC(zc6o7eG4)bKMMY_8X?Aw@u?6h# z;lshf`|a#hY<3Bkd&JHz$kWs3`0?Wg0OXPTF&CY{G^|Igi;9ZKH36!ss;DvOr&_J1 zx~1t&sZ>(M4;(lkk?c1!`x@w{b_L!AqU`OZt*xyF0OXE$lBa8(+d4*aQ!-UaQ=##! z_w+pDSx{e4UteEaTT3@Y0IErFaIj1kyl&n1z;8e!i?yF&L_nC8m3(Mu$N-?Zxp_n7 z2DAX*=>Wn$A?4)L>VvOzv*1+iR99Em(9l2wMRh0dROro{PXe>RH6x>UEG*vQa@TOV zQlU`t^yyOrfcExwL7@Om)cL>za2|4U%W^%=c<5%V3NB?X6h0+EjKsu5@-7xf85_?~ z_(n!?E-s$Cckkx$Tm=FtNq~V#ChO_xan5qaMSv9N2jF-3*7yqRh3Ek)Au1KoO;8fV zprIvzKyXeU{%KoVxrc`zkCz5CFib&h?McIcn>TN|Dcy8{RDkAq5^L3Kg|$LmUsXU< zBBJ4(W03sGWO5UeaSET!R&3c4%;9JOl9gkorlAz5VF1mVSE84$J}Q`0nqU|>1Di@4 ze5+F&_hR?T%1UBTp~Aw#cJ55qhku#R59RT^^+74-!fSSE~<7VgEJh?uUa0qm; z8Ez47t52=QkANEJ0t(=x^_iQy^73*TT0XxG7zGZwyYCSQ1YB+maEUU=$|_zAke{D# zTyIS3>>TO5U9}y3y6WrNG#}mt-ZU1(ApHmo3|zUggX&{s6zS#V<>Yh_y5_4hF$wDK z?p_S=`P`~WeyGw#>B+X26iZPz^D41kPE3=O0g4z6qf*N)=*PsGE4-+(Dp2{ zw2Zxeeeh*hh5=+_V`EuaSwV3@IIpj54kWn}jYdNZ8e`JrO`E(~ENUAnPWZ-+iMMY3 zY|zhwfLVQ0wY0S8#Df-Q7G&8n5<6nh7)vA)kx0bn+nAbqczMM?d^oX?lf?jYc4O#< zON|S4tujMN`;Hh?Jz7|PetuiGZY4pbYg^pItKUTv6B8tGw0Wp##Go?l literal 0 HcmV?d00001 diff --git a/examples/test/img/tp0n0g08.png b/examples/test/img/tp0n0g08.png new file mode 100644 index 0000000000000000000000000000000000000000..333465fcdc9f10f7f25b2d999b558f5421983ecc GIT binary patch literal 719 zcmV;=0xe{x-64Dw5ISbDJfGPNXYF1fsnx~?7~M3eMD*m6rOMo0;2$rUW>-c(^**S*Ycd0zuX+u!1|S9WB+#F78QX<>lo? ziQz$h-hRnIWoQ!H=elq>2fX`s$g4Md}>$Ugu1e*ygBpcmqZ3DNb_5HNEsBtg8Fz$MsRgsRcUEt!R)#7 z@*=Hdg|%Ijgaqfp6x>M8@W|(*DezA>78ATBV zGiJ?6^pq7`pj8TmNNXtGQ7M(fr#kNOGpUKtO+a# zE}lAlTDXoRkAt?j2v0jgK~H>oU`AO)UQprWsr_L}qI~YALPA1E5ej}SPEJnGOv?!@ zojAEOR7Ob9QdC4?8%mP9keiy8ksVOlKd~`Xk)KCEK=mA2ntaoimYx|<+}mFjqR+?8 zZTJ8q(f(PLp6*}V-CGiDD=qBv7F)8vQWR0&(VZLQZ(jZjd%k$Tpt-FhJuqOwUu^jT z1pXapZA%Q=jx2U BP!RwC literal 0 HcmV?d00001 diff --git a/examples/test/img/tp0n2c08.png b/examples/test/img/tp0n2c08.png new file mode 100644 index 0000000000000000000000000000000000000000..fc6e42cb420fd08ecd78340256157fa5f8a22934 GIT binary patch literal 1594 zcmV-A2F3Y_P)u542F>)wJ;-zU<0Ta5X4X^rIbM; zBH-v?$kU01p_ErCl=u4~L7fbz&H-~9!(}3aFu`RZW&unzb50QkgK2zirzKlPEQpyV zJ88Z&UwhB*+;h+QpNot)Z1^7mZr{G$*Vi{SHT9YSckkY9Z*NaePmhd@j0*@zcXT}E z>DjB%+#enNPk@PuiSF+1yu7^V=xBLZ*b!IPd^0mOpafEZETD#AngxPxg<^DQ=;_m^ zO9f0%PhYumrM$d6AtB*?xjc2}&YX4Y${D5+CG4W_vSdOD(DVN&-oB_@QeZU}a320`R0!vG! zgF}Y7c_vT+6ajLvI4&-Z7Si(C+FA;c5-<-iFfc$*`Z-x=6;4i{1D^pMz*&|p+q$(x zB)Vj4J8WQZ3z!6c0e;dUzW@{rLwimBm&L@yP^|L+BO@b9r7|}+H!CYEEiFwM7}#lU ze#Y8b?eBj$IXU%j%aqGow{IV|u^C^v@>iA}GBZ1AZ=V(%{LdfavLmWItxn1d>CixU>w z(z&H&q%@~cmeiGMuLdu#(_V!Qg$)f2b#--gLIj|kgoK1hr6FtAeh>TxG#MD|V;DCe z+}c_;JUpxi(9+VfzG^*Mf$y{cVZV^}t ze*#wx4d1b}e2ZmQv#dlY6hC?LL=T{&qk~_>M>ADEa39m2fL{qvo7rko-xdG82;t3ZKJ~Z{8fjKg!o$ON?8wlCe~HHnv#{{d1tq7Cl~vHp z%#3~jNv`NUkyhKvAxIVA8=wbFDWm}$)k06v92)E2}b{Rj#QTCt*&@?&Ti zD zl4Z+2B9B~dgtK!fhf@n&;PLjfw||-Og6SEVLqkKcv9UCP1w{gUs+$RUkfbMoF`VR)x@ASCQaVB z(Z|4m%7&5?v0+2f&6_{#^|K%#LswL-t*u(|pn;hUX^xb{ju_O&VzJoG&5g&iH8u70 z_D*>4U~(ZRivi~B`tWs^S{JHXMW%x09Wf|-G_d^r{kLq{LV`-iwz!9v--{+ECrRLF z@=(%OV07*qoM6N<$f`h#14gdfE literal 0 HcmV?d00001 diff --git a/examples/test/img/tp0n3p08.png b/examples/test/img/tp0n3p08.png new file mode 100644 index 0000000000000000000000000000000000000000..69a69e5872234d96cab4cbb017a0933fbfedba81 GIT binary patch literal 1476 zcmWlXc~H^`6vv-Om}J3dn5OOMOgg5aIm=3#R_~R8*9gm+#ueDlIJqsFg@0;tH{|b8}HqQ5Jw$Ebasl zi9{wQqx{s={QP`?_T1du%K+m5+1c6W&Yc6O&&;#KYi za0xyG{0*U@p&=n5OeT{~rxS7s!NI{ht9Awk26}jqu-LA432IQH$P*->1%a<=E7fhf7KmpiNEL?|$g$1|@ z&=;ZU0fm$KWEP7BFz+mN_CD$D>KXyBfJUPQ1qHz$U@Noz`t>V3 z0Y5*#_4Rf5=AAr|%l))v3zbTRZXmD;`udA>dIa18XhRr(3s9%iK@&&<11kswKn|(| zCKfuzi4TRu*jp4GWDgcp#{666_U|?<$;@lL6fyrT=v@~MF43;U zZ$6b_)kkb?TQRlFx@L1DFHuvCdiGRV@qSb5o3SyX=dqWIo~SD}lgtU8-0hinIc|l^ zwZpyIy{+Kp3qku~jyuQS{wOJTffqk}ylg!rGf@@8WYp~qRTEe@i_6M#f}U2WR@4MfM)1HJRjPCMx~ z7uM(-p3*y>&A)fhi1A3;cS(L+J1;&pqWL&it>CX0-+eBqO{=g-lKzNGvG(`sNqtRF zeg3%mDzvL|F3Eho_0DyETn8H%dc!?dA!#0>Q=Vr9#{-Ga&|1#6CAW+Q0sfY$`N-&; z^0c=#@%4)8jy6X3lL6u3JAW=?c#tm>K2a$#(Q?|Uz}T^+pWADD@MB|q8>&Xr948aj zsY1|Z7&ad@u4wr4W%TE{WS7U&Rh^yI#(OsCtq$vQ3|A*M_uLm%-A~M)I@BiVUyS#YR$&g!`CNx58tIE z|3D@=NLJY$Q%;J12ZU?1w#&^2c5EzDN05DZLoa2szJ*SEwwg0|Mem<$Yn1cWcz^cq z-}lxrB6iz%k1R&3=>`|KS%};k)l(YskH!jI!g#-(&O>3hx)5(GX8X3fe_&q16?&Zr z)72bEymR&OySDOI3mZ0C3tSEiO=8X3u^BG}uBukDWrMyZ$LQ%Y4sr7@il=hRi%!IK N0G~qvls0mN@PBi2fm#3n literal 0 HcmV?d00001 diff --git a/examples/test/img/tp1n3p08.png b/examples/test/img/tp1n3p08.png new file mode 100644 index 0000000000000000000000000000000000000000..a6c9f35a86271c056e955f637a8769381eb03827 GIT binary patch literal 1483 zcmWlXdpOez7{_0ijw~Xj6ZLfH5mEEBP|@KrEtkTuS}m>SI;>1?8{6D(v$V!$$}kk^ z;zXQM92O%H=ShmnbXw(ZQ8_r3^Xq+{_x=9)zVGMz<@$KL>7tBL0HEvPj`Ks*k)Uu?Q@xn6z>Z3lMM-Q#6tfUZ$jg9xOySS8oYSdsZ?58S}Ku90Gh5`xl#{MR8%wt zP*_-43Lq2;*RS7_pPzr}(xrd%E)}>Vg+~H{0|EmB;S209 z+JEZQsgoy9!bij)vJ2CNNF)M$vKCsqg}Grc6c_?OKR+KIALs+qBGU~U&cS2w^z{7x z{X6{3T?w5=n_Ror-Q69U!8X)ZUHvP8K!G~|wFu*%2C7slr~p15FS4}-9)W zgA1TkDj@~(fB8jCjUG%S0R(${)B5}SM@HTPu)4duH*Un5nj+Sda5!dbYwOg=2pWA9 zg`xngv~oCl+wa{*R;b1Lc@x0-<4`CPvRn@w_UQh+Ac}Mk^OKb>f7-E19*W;}xs}~! zRlIciNyF__FM9f7*5I)-+cbPa1|k-TrQvsONlsb*)pnz$h0|UcNA3@z)MNfwE}Uv0 zIbFH+_Zk14HEp3y&g@1-ft^E-J#CK+WhE5TXruYlt&^-N^P3g#I=H!w`R}L=sT9s{ zCuD1uhCdG)aY*zhVd3F}HZMyY{g2C62iLwz8h1Q_?PFhSvbid>^O4P?YqRlh((eZd z#_aspCH=EBx%*CRO=qIG-J;L_AlZKBgiu)@&Tb|Ii=AapW?Zqp>gYA)sH#J5XB+h; zk9wYVqsyC_bvIrV9&w7WX>VWUAVpP~na{j&$UYNXX^m&}Uyx5RnnjA&4L3VdD!1H_ zD#Iq{ZueA8l;TIb`kpn$X5SsBHj?FpV!HrYcY~@^RN}pDGk;X^V&G~0qorYaOP*rv z^qN~4t3n!C(Ta6lUVkRto3S5$_!4xZm;=Uxwl-UlXk<^TD! zwrXx-kZ%7r>OqrnxrwlgbC>i*G{g?VCRx6GHc+-!v-|w+aMq(Z)3<$!sgDrNgW zt{66;txYft&kQV}Qtm74k`-qO{C2WMU5|#0wUn?oyC~|ghKx56YPk5`Xp_O#x8g2M X(5+n&l!#upArS?SL*BSr7fRay;V71Q literal 0 HcmV?d00001 diff --git a/examples/test/list.html b/examples/test/list.html new file mode 100644 index 0000000..1e3aa12 --- /dev/null +++ b/examples/test/list.html @@ -0,0 +1,38 @@ + + + + PNG Test + + + +

Basic

+ grayscale
+ color
+ paletted
+ grayscale + alpha
+ color + alpha
+ +

Image filtering

+ grayscale, filter 0
+ color, filter 0
+ grayscale, filter 1
+ color, filter 1
+ grayscale, filter 2
+ color, filter 2
+ grayscale, filter 3
+ color, filter 3
+ grayscale, filter 4
+ color, filter 4
+ +

Transparency

+ grayscale, not transparent
+ color, not transparent
+ paletted, not transparent
+ color, transparent
+ paletted, transparent
+ + diff --git a/examples/test/test.js b/examples/test/test.js new file mode 100644 index 0000000..5e59d6d --- /dev/null +++ b/examples/test/test.js @@ -0,0 +1,36 @@ + +var fs = require('fs'), + PNG = require('pngjs').PNG; + + +fs.readdir(__dirname + '/img/', function(err, files) { + if (err) throw err; + + for (var i = 0; i < files.length; i++) { + + if (!files[i].match(/\.png$/i)) + continue; + + fs.createReadStream(__dirname + '/img/' + files[i]) + .pipe(new PNG()) + .on('parsed', function() { + + if (this.gamma) { + for (var y = 0; y < this.height; y++) { + for (var x = 0; x < this.width; x++) { + var idx = (this.width * y + x) << 2; + + for (var i = 0; i < 3; i++) { + var sample = this.data[idx + i] / 255; + sample = Math.pow(sample, 1 / this.gamma); + sample = Math.pow(sample, 1 / 2.2); + this.data[idx + i] = Math.round(sample * 255); + } + } + } + } + + this.pack(); + }).pipe(fs.createWriteStream(__dirname + '/out/' + files[i])); + } +}); diff --git a/examples/test2.js b/examples/test2.js index fe46892..466bd1b 100755 --- a/examples/test2.js +++ b/examples/test2.js @@ -5,7 +5,7 @@ var fs = require('fs'), var png = new PNG({ - filterType: 4 + filterType: -1 }), src = fs.createReadStream(process.argv[2]), dst = fs.createWriteStream(process.argv[3] || 'out.png'); diff --git a/lib/filter.js b/lib/filter.js index 379a65f..3b8ec7e 100644 --- a/lib/filter.js +++ b/lib/filter.js @@ -55,58 +55,112 @@ Filter.prototype.prepare = function(width, height, type) { this.height = height; }; -Filter.prototype.unfilter = function(rawData) { +Filter.prototype.unfilter = function(rawData, Bpp) { var pxLineLength = this.width << 2, - rawLineLength = pxLineLength + 1, + rawLineLength = this.width * Bpp + 1, pxData = new Buffer(pxLineLength * this.height); for (var y = 0; y < this.height; y++) { var rawRowPos = rawLineLength * y + 1, pxRowPos = y * pxLineLength, - pxUpRowPos = pxRowPos - pxLineLength, filter = rawData[rawRowPos - 1]; + if (filter == 0) { - rawData.copy(pxData, pxRowPos, rawRowPos, rawRowPos + pxLineLength); + for (var x = 0; x < this.width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = rawRowPos + x * Bpp; + + for (var i = 0; i < Bpp; i++) + pxData[pxPos + i] = rawData[rawPos + i]; + } } else if (filter == 1) { - for (var x = 0; x < pxLineLength; x++) { + for (var x = 0; x < this.width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = rawRowPos + x * Bpp; - var left = x >= 4 ? pxData[pxRowPos + x - 4] : 0; - pxData[pxRowPos + x] = rawData[rawRowPos + x] + left; + for (var i = 0; i < Bpp; i++) { + var left = x > 0 ? pxData[pxPos + i - 4] : 0; + pxData[pxPos + i] = rawData[rawPos + i] + left; + } } } else if (filter == 2) { - for (var x = 0; x < pxLineLength; x++) { + for (var x = 0; x < this.width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = rawRowPos + x * Bpp; - var up = y > 0 ? pxData[pxUpRowPos + x] : 0; - pxData[pxRowPos + x] = rawData[rawRowPos + x] + up; + for (var i = 0; i < Bpp; i++) { + var up = y > 0 ? pxData[pxPos - pxLineLength + i] : 0; + pxData[pxPos + i] = rawData[rawPos + i] + up; + } } } else if (filter == 3) { - for (var x = 0; x < pxLineLength; x++) { + for (var x = 0; x < this.width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = rawRowPos + x * Bpp; - var left = x >= 4 ? pxData[pxRowPos + x - 4] : 0, - up = y > 0 ? pxData[pxUpRowPos + x] : 0; + for (var i = 0; i < Bpp; i++) { + var left = x > 0 ? pxData[pxPos + i - 4] : 0, + up = y > 0 ? pxData[pxPos - pxLineLength + i] : 0; - pxData[pxRowPos + x] = rawData[rawRowPos + x] - + Math.floor((left + up) / 2); + pxData[pxPos + i] = rawData[rawPos + i] + + Math.floor((left + up) / 2); + } } } else if (filter == 4) { - for (var x = 0; x < pxLineLength; x++) { + for (var x = 0; x < this.width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = rawRowPos + x * Bpp; - var left = x >= 4 ? pxData[pxRowPos + x - 4] : 0, - up = y > 0 ? pxData[pxUpRowPos + x] : 0, - upLeft = x >= 4 && y > 0 ? pxData[pxUpRowPos + x - 4] : 0; + for (var i = 0; i < Bpp; i++) { + var left = x > 0 ? pxData[pxPos + i - 4] : 0, + up = y > 0 ? pxData[pxPos - pxLineLength + i] : 0, + upLeft = x > 0 && y > 0 + ? pxData[pxPos - pxLineLength + i - 4] : 0; - pxData[pxRowPos + x] = rawData[rawRowPos + x] - + PaethPredictor(left, up, upLeft) + pxData[pxPos + i] = rawData[rawPos + i] + + PaethPredictor(left, up, upLeft) + } } } } + + // expand data to 32 bit + for (var y = 0; y < this.height; y++) { + var pxRowPos = y * pxLineLength; + + if (Bpp == 1) { // L + for (var x = 0; x < this.width; x++) { + var pxPos = pxRowPos + (x << 2); + + pxData[pxPos + 1] = pxData[pxPos + 2] = pxData[pxPos]; + pxData[pxPos + 3] = 0xff; + } + + } else if (Bpp == 2) { // LA + for (var x = 0; x < this.width; x++) { + var pxPos = pxRowPos + (x << 2); + + pxData[pxPos + 3] = pxData[pxPos + 1]; + pxData[pxPos + 1] = pxData[pxPos + 2] = pxData[pxPos]; + } + + } else if (Bpp == 3) { // RGB + for (var x = 0; x < this.width; x++) { + var pxPos = pxRowPos + (x << 2); + + pxData[pxPos + 3] = 0xff; + } + + } // else RGBA + } + return pxData; }; diff --git a/lib/parser.js b/lib/parser.js index ed7b3bf..08117d7 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -32,6 +32,13 @@ var signature = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; var TYPE_IHDR = 0x49484452; var TYPE_IEND = 0x49454e44; var TYPE_IDAT = 0x49444154; +var TYPE_PLTE = 0x504c5445; +var TYPE_tRNS = 0x74524e53; +var TYPE_gAMA = 0x67414d41; + +var COLOR_PALETTE = 1; +var COLOR_COLOR = 2; +var COLOR_ALPHA = 4; var Parser = module.exports = function(options) { @@ -43,10 +50,17 @@ var Parser = module.exports = function(options) { this._hasIHDR = false; this._hasIEND = false; + // input flags + this._palette = []; + this._colorType = 0; + this._chunks = {}; this._chunks[TYPE_IHDR] = this._parseIHDR.bind(this); this._chunks[TYPE_IEND] = this._parseIEND.bind(this); this._chunks[TYPE_IDAT] = this._parseIDAT.bind(this); + this._chunks[TYPE_PLTE] = this._parsePLTE.bind(this); + this._chunks[TYPE_tRNS] = this._parseTRNS.bind(this); + this._chunks[TYPE_gAMA] = this._parseGAMA.bind(this); this._compress = new Compress(options); this._filter = new Filter(options); @@ -60,9 +74,7 @@ Parser.prototype._initCompress = function() { this._compress.on('error', this.emit.bind(this, 'error')); this._compress.on('deflated', this._packData.bind(this)); - this._compress.on('inflated', function(data) { - this.emit('parsed', this._filter.unfilter(data)); - }.bind(this)); + this._compress.on('inflated', this._unfilter.bind(this)); }; Parser.prototype._parse = function(data) { @@ -111,6 +123,47 @@ Parser.prototype._packData = function(data) { this.emit('end'); }; +Parser.prototype._unfilter = function(data) { + + // expand data to 32 bit depending on colorType + if (this._colorType == 0) { // L + data = this._filter.unfilter(data, 1); // 1 Bpp + + } else if (this._colorType == 2) { // RGB + data = this._filter.unfilter(data, 3); // 3 Bpp + + } else if (this._colorType == 3) { // I + data = this._filter.unfilter(data, 1); // 1 Bpp + + // use values fom palette + var pxLineLength = this.width << 2; + + for (var y = 0; y < this.height; y++) { + var pxRowPos = y * pxLineLength; + + for (var x = 0; x < this.width; x++) { + var pxPos = pxRowPos + (x << 2), + color = this._palette[data[pxPos]]; + + for (var i = 0; i < 4; i++) + data[pxPos + i] = color[i]; + } + } + + } else if (this._colorType == 4) { // LA + data = this._filter.unfilter(data, 2); // 2 Bpp + + } else if (this._colorType == 6) { // RGBA + data = this._filter.unfilter(data, 4); // 4 Bpp + + } else throw new Error('Unsupported color type'); + + this.emit('parsed', data); +}; + + + + Parser.prototype._parseChunk = function(data, idx) { if (this._hasIEND) @@ -154,6 +207,8 @@ Parser.prototype._parseChunk = function(data, idx) { } else if (!ancillary) throw new Error('Unsupported critical chunk type ' + name); + // else + // console.log('Ignoring chunk', name, type.toString(16)); return idx; }; @@ -189,12 +244,12 @@ Parser.prototype._parseIHDR = function(data) { // ); if (depth != 8) - throw new Error('Unsupported bit depth'); - if (colorType != 6) - throw new Error('Unsupported color type'); + throw new Error('Unsupported bit depth ' + depth); if (interlace != 0) throw new Error('Unsupported interlace method'); + this._colorType = colorType; + this._compress.prepareInflate(compr); this._filter.prepare(width, height, filter); @@ -218,7 +273,48 @@ Parser.prototype._packIHDR = function(width, height) { }; +Parser.prototype._parsePLTE = function(data) { + + var entries = Math.floor(data.length / 3); + // console.log('Palette:', entries); + + for (var i = 0; i < entries; i++) { + this._palette.push([ + data.readUInt8(i * 3), + data.readUInt8(i * 3 + 1), + data.readUInt8(i * 3 + 2 ), + 0xff + ]); + } +}; + +Parser.prototype._parseTRNS = function(data) { + + // palette + if (this._colorType == 3) { + if (this._palette.length == 0) + throw new Error('Transparency chunk must be after palette'); + + if (data.length > this._palette.length) + throw new Error('More transparent colors than palette size'); + + for (var i = 0; i < this._palette.length; i++) + this._palette[i][3] = i < data.length ? data.readUInt8(i) : 0xff; + } + + // for colorType 0 (grayscale) and 2 (rgb) + // there might be one gray/color defined as transparent +}; + +Parser.prototype._parseGAMA = function(data) { + this.emit('gamma', data.readUInt32BE(0) / 100000); +}; + Parser.prototype._parseIDAT = function(data) { + + if (this._colorType == 3 && this._palette.length == 0) + throw new Error('Expected palette not found'); + this._compress.writeInflate(data); }; diff --git a/lib/png.js b/lib/png.js index 00cf3d1..693db79 100644 --- a/lib/png.js +++ b/lib/png.js @@ -26,7 +26,7 @@ var util = require('util'), var PNG = exports.PNG = function(options) { - Parser.call(this, options); + Parser.call(this, options = options || {}); this.width = options.width || 0; this.height = options.height || 0; @@ -34,12 +34,15 @@ var PNG = exports.PNG = function(options) { this.data = this.width > 0 && this.height > 0 ? new Buffer(4 * this.width * this.height) : null; - this.on('metadata', this._metadata.bind(this)); + this.gamma = 0; this.readable = this.writable = true; this._buffers = []; this._buffLen = 0; + this.on('metadata', this._metadata.bind(this)); + this.on('gamma', this._gamma.bind(this)); + this.on('parsed', function(data) { this.data = data; }.bind(this)); @@ -93,6 +96,10 @@ PNG.prototype._metadata = function(width, height) { this.data = null; }; +PNG.prototype._gamma = function(gamma) { + this.gamma = gamma; +}; + PNG.prototype.bitblt = function(dst, sx, sy, w, h, dx, dy) { var src = this; @@ -100,7 +107,7 @@ PNG.prototype.bitblt = function(dst, sx, sy, w, h, dx, dy) { if (sx > src.width || sy > src.height || sx + w > src.width || sy + h > src.height) throw new Error('bitblt reading outside image'); - if (dy > dst.width || dy > dst.height + if (dx > dst.width || dy > dst.height || dx + w > dst.width || dy + h > dst.height) throw new Error('bitblt writing outside image');