--- /dev/null
+\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\8c\8a\8c\8c\8a\8c\8c\8a\8ctvt¼º¼üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\8c\8a\8cÌÎÌ\8c\8a\8c\8c\8a\8cÌÎÌ\8c\8a\8cÌÎÌüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\8c\8a\8cüþüDFDìîìDFDüþü\8c\8a\8cüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\8c\8a\8cüþü$"$DFD¼º¼üþü\8c\8a\8cüþüüþüìòüÄÎäÄÎäÄÎäÄÎäìòüüþüüþüüþüüþüüþüüþüÜæôÄÎäÄÎäÄÎäÄÎäüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü¼Æä\94ªÔ\94ªÔ\94ªÔ¤¶ÜÄÎäÄÎäÄÎäÄÎäÄÎäÄÎäÄÎäÄÎäÄÎäÄÎäÄÎäìòüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÌÎÌüþüüþütvtüþüDFDÌÎÌDFDÜÞÜ\8c\8a\8cüþüüþüÜæô\fF\9c\fF\9c\fF\9c\fF\9c¤¶ÜüþüüþüüþüüþüüþüüþüÔÚì\fF\9c\fF\9c\fF\9c\fF\9cÄÎäüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\14N¤\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\fF\9cÄÎäüþüüþüüþüüþüüþüÌÎÌLNL\ 4\ 2\ 4\f\ e\f\^\ÜÞÜüþüüþüüþüìîì,.,üþüüþü¼º¼\8c\8a\8cüþüüþüìîìtvtìîìüþüüþüüþü$Z¬\fF\9c\fF\9c\fF\9cd\8aÄüþüüþüüþüüþüüþüüþüüþü\14N¤\fF\9c\fF\9c\14N¤t\96ÄüþüüþüüþüüþüüþüüþüüþüüþüüþüÄÎä\fB\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9cÄÎäüþüüþüüþüüþü\9c\9e\9c\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\9c\9e\9cüþüüþü|~|\ 4\ 2\ 4üþüüþüüþüÌÎÌ\8c\8a\8c\8c\8a\8c\8c\8a\8cìîìüþüüþüüþüüþüt\96Ä\14N¤\fF\9c\fF\9c\14N¤üþüüþüüþüüþüüþüüþüüþüd\8aÄ\fF\9c\fF\9c\fF\9c$Z¬üþüüþüüþüüþüüþüüþüüþüüþüüþüt\96Ä\fB\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\14N¤Dr´üþüüþüüþüüþüÌÎÌ\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4¼º¼ìîì\f\ e\f\ 4\ 2\ 4¼¾¼üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÄÎä\fF\9c\fF\9c\fF\9c\14N¤ÔÚìüþüüþüüþüüþüüþüüþü¤¶Ü\fF\9c\fF\9c\fF\9c\fF\9cÜæôüþüüþüüþüüþüüþüüþüüþüüþü4f¬\fB\9c\14N¤\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9cÄÎäüþüüþüüþüüþü\1c\1e\1c\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\1c\1e\1clnl\ 4\ 2\ 4\ 4\ 2\ 4\9c\9e\9cüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\14N¤\fF\9c\fF\9c\fF\9ct\96Äüþüüþüüþüüþüüþüüþüìòü\fF\9c\fF\9c\fF\9c\fF\9c\94ªÔüþüüþüüþüüþüüþüüþüüþüÜæô\fF\9c\fF\9c\fF\9c\fF\9cl\8aÄüþüüþüüþüüþüüþü´Âä\fF\9c\fF\9c\fF\9c\fF\9cd\8aÄüþüüþüüþüüþü\9c\9e\9c\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4,.,|~|lnl$"$\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\f\ e\fìîìüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüT~¼\fF\9c\fF\9c\fF\9c4f¬üþüüþüüþüüþüüþüüþüüþüDr´\fF\9c\14N¤\fF\9cT~¼üþüüþüüþüüþüüþüüþüüþü\94ªÔ\fF\9c\fF\9c\fF\9c\fF\9cìòüüþüüþüüþüüþüüþü$Z¬\fF\9c\fF\9c\fF\9c\14N¤ìòüüþüüþüüþüüþü<><\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\9c\9e\9cüþüüþüüþüìîì\^\\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4|~|üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü¤¶Ü\fF\9c\fF\9c\14N¤\fF\9cÜæôüþüüþüüþüüþüüþüüþüd\8aÄ\fF\9c\fF\9c\fF\9c\fF\9cìòüüþüüþüüþüüþüüþüüþüT~¼\fF\9c\fB\9c\fF\9c<j´üþüüþüüþüüþüüþü\84\9eÌ\fF\9c\14N¤\fF\9c\fF\9c\84\9eÌüþüüþüüþüüþüìîì\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\9c\9e\9cüþüüþüüþüüþüüþüüþü\^\\ 4\ 2\ 4\f\ e\fìîìüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüìòü\fF\9c\fF\9c\fF\9c\fF\9c¤¶Üüþüüþüüþüüþüüþüüþü\14N¤\fF\9c\fF\9c\fF\9c\fF\9c¼Æäüþüüþüüþüüþüüþüüþü\fF\9c\fF\9c\14N¤\fF\9c\94ªÔüþüüþüüþüüþüìòü\14N¤\fF\9c\fF\9c\fF\9c$Z¬üþüüþüüþüüþüüþü¬®¬\ 4\ 2\ 4\ 4\ 2\ 4\^\üþüüþüüþüüþüüþüüþüüþüüþü,.,|~|üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü<j´\fF\9c\fF\9c\fF\9cT~¼üþüüþüüþüüþüüþüÔÚì\14N¤\fF\9c\fF\9c\fF\9c\fF\9cd\8aÄüþüüþüüþüüþüüþü¼Æä\fF\9c\fF\9c\fF\9c\fF\9cÔÚìüþüüþüüþüüþüd\8aÄ\fF\9c\fF\9c\fF\9c\fF\9c¼Æäüþüüþüüþüüþüüþü|~|\ 4\ 2\ 4\ 4\ 2\ 4ÜÞÜüþüüþüüþüüþüüþüüþüüþüüþüÌÎÌìîìüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\94ªÔ\fF\9c\fF\9c\fF\9c\fF\9cüþüüþüüþüüþüüþü\84\9eÌ\fF\9c\fF\9c\14N¤\fF\9c\fF\9c$Z¬üþüüþüüþüüþüüþüd\8aÄ\fF\9c\fF\9c\fF\9c$Z¬üþüüþüüþüüþüÄÎä\fF\9c\fF\9c\14N¤\fF\9cDr´üþüüþüüþüüþüüþüüþüLNL\ 4\ 2\ 4LNLüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÔÚì\fF\9c\fF\9c\14N¤\fF\9c´Âäüþüüþüüþüüþü4f¬\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9cÔÚìüþüüþüüþüüþü$Z¬\fF\9c\fF\9c\fF\9ct\96ÄüþüüþüüþüüþüDr´\fF\9c\fF\9c\fF\9c\fF\9cÜæôüþüüþüüþüüþüüþüüþü<><\ 4\ 2\ 4\9c\9e\9cüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü$Z¬\fF\9c\fF\9c\fF\9ct\96ÄüþüüþüüþüÜæô\fF\9c\14N¤\fF\9c\fF\9c\fF\9c\fF\9c\14N¤\84\9eÌüþüüþüüþüÔÚì\fF\9c\fF\9c\fF\9c\fF\9c´Âäüþüüþüüþü¤¶Ü\fF\9c\fF\9c\fF\9c\fF\9cd\8aÄüþüüþüüþüüþüüþüüþüüþü<><\ 4\ 2\ 4ìîìüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüd\8aÄ\fF\9c\fF\9c\fF\9c$Z¬üþüüþüüþü¤¶Ü\fF\9c\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\fF\9c4f¬üþüüþüüþü\94ªÔ\fF\9c\fF\9c\14N¤\14N¤üþüüþüüþüìòü$Z¬\fF\9c\14N¤\fF\9c\fF\9c\fF\9c<j´ÔÚìüþüüþüüþüüþüüþü<><\1c\1e\1cüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü¼Æä\fF\9c\fF\9c\14N¤\fF\9cÔÚìüþüüþüT~¼\fF\9c\fF\9c\14N¤\84\9eÌ\fF\9c\fF\9c\fF\9c\fF\9cìòüüþüüþü<j´\fF\9c\fF\9c\fF\9cT~¼üþüüþüüþü\94ªÔ\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\14N¤\fF\9c\fF\9c¤¶Üüþüüþüüþüüþü<><<><üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\fF\9c\fF\9c\fF\9c\fF\9c\94ªÔüþüüþü\14N¤\fF\9c\fF\9c\fF\9cÜæôT~¼\fF\9c\14N¤\fF\9c¤¶Üüþüìòü\fF\9c\fF\9c\fF\9c\fF\9c¤¶Üüþüüþüüþü\84\9eÌ\14N¤\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c¤¶Üüþüüþüüþü|~|<><üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüT~¼\fF\9c\fF\9c\fF\9cDr´üþü´Âä\fF\9c\fF\9c\fF\9c4f¬üþü\94ªÔ\fF\9c\fF\9c\fF\9cT~¼üþü¤¶Ü\fF\9c\fF\9c\fF\9c\fF\9cÜæôüþüüþüüþüÄÎä\84\9eÌ\84\9eÌ\84\9eÌ4f¬\14N¤\fF\9c\fF\9c\14N¤\fF\9c\14N¤ìòüüþüüþü\9c\9e\9c<><üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü¤¶Ü\fF\9c\14N¤\fF\9c\fF\9cìòüt\96Ä\fF\9c\fF\9c\14N¤t\96ÄüþüÜæô\fF\9c\fF\9c\fF\9c\14N¤üþüd\8aÄ\fF\9c\14N¤\fF\9c<j´üþüüþüüþüüþüüþüüþüüþüüþüüþüÄÎä\14N¤\fF\9c\fF\9c\fF\9c\fF\9c\84\9eÌüþüüþüÜÞÜ<><üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÜæô\fF\9c\fF\9c\fF\9c\fF\9c¤¶Ü$Z¬\fF\9c\fF\9c\fF\9cÔÚìüþüüþü$Z¬\fF\9c\fF\9c\fF\9cÄÎä\14N¤\fF\9c\fF\9c\fF\9c\84\9eÌüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÔÚì\fF\9c\fF\9c\fF\9c\fF\9c\14N¤üþüüþüüþü|~|üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü4f¬\fF\9c\fF\9c\fF\9c<j´\fF\9c\fF\9c\fF\9c\14N¤üþüüþüüþüt\96Ä\14N¤\fF\9c\fF\9c<j´\fF\9c\fF\9c\fF\9c\fF\9cÔÚìüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüd\8aÄ\fF\9c\14N¤\fF\9c\fF\9cÔÚìüþüüþü¼¾¼üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüt\96Ä\14N¤\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9cd\8aÄüþüüþüüþüÄÎä\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c$Z¬üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü´Âä\fF\9c\fF\9c\fF\9c\14N¤\94ªÔüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÔÚì\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\14N¤\fF\9c¼Æäüþüüþüüþüüþü\14N¤\fF\9c\fF\9c\fF\9c\14N¤\fF\9c\fF\9cd\8aÄüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÔÚì\fF\9c\fF\9c\fF\9c\fF\9c\84\9eÌüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\14N¤\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9cìòüüþüüþüüþüüþüd\8aÄ\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c¼Æäüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\14N¤\fF\9c\fF\9c\fF\9c\84\9eÌüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüd\8aÄ\fF\9c\fF\9c\fF\9c\fF\9c\fF\9cT~¼üþüüþüüþüüþüüþü¤¶Ü\fF\9c\14N¤\fF\9c\fF\9c\fF\9c\fF\9cìòüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÜæô\fF\9c\fF\9c\14N¤\fF\9cl\8aļ¾¼üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüìîìüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü¼Æä\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\94ªÔüþüüþüüþüüþüüþüìòü\fF\9c\fF\9c\fF\9c\14N¤\fF\9cT~¼üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÄÎä\fF\9c\fF\9c\fF\9c\fF\9c\84\9eÌLNLüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü<><ÜÞÜüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüìòü\fF\9c\fF\9c\14N¤\fF\9c\fF\9cÜæôüþüüþüüþüüþüüþüüþüDr´\fF\9c\fF\9c\fF\9c\fF\9c\94ªÔüþüüþüüþü¼ÆäT~¼4f¬üþüüþüüþüüþüüþüüþüüþüt\96Ä\fF\9c\14N¤\fF\9c\fF\9cÄÎä\8c\8e\8c|~|üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\8c\8a\8c\ 4\ 2\ 4¬®¬üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüDr´\fF\9c\fF\9c\fF\9c<j´üþüüþüüþüüþüüþüüþüüþü\94ªÔ\fF\9c\fF\9c\fF\9c\fF\9cÜæôüþüüþü4f¬\fF\9c\fF\9c\fF\9c¼Æäüþüüþüüþüüþüüþüìòü$Z¬\fF\9c\fF\9c\fF\9c\fF\9cìòüÜÞÜ\ 4\ 2\ 4\9c\9e\9cüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÌÎÌ\f\ e\f\ 4\ 2\ 4|~|üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\94ªÔ\fF\9c\fF\9c\fF\9ct\96ÄüþüüþüüþüüþüüþüüþüüþüÜæô\fF\9c\fF\9c\fF\9c<j´üþüüþüüþüd\8aÄ\fF\9c\fF\9c\fF\9c\14N¤ÔÚìüþüüþüüþüüþüt\96Ä\fF\9c\fF\9c\fF\9c\fF\9cT~¼üþüüþülnl\ 4\ 2\ 4\9c\9e\9cüþüüþüüþüüþüüþüüþüüþüüþüÌÎÌ\f\ e\f\ 4\ 2\ 4\ 4\ 2\ 4\9c\9e\9cüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÜæô\fF\9c\fF\9c\14N¤ÄÎäüþüüþüüþüüþüüþüüþüüþüüþü$Z¬\14N¤\fF\9ct\96ÄüþüüþüüþüÜæô\14N¤\fF\9c\fF\9c\fF\9c\14N¤\84\9eÌÄÎäÔÚìd\8aÄ\fF\9c\14N¤\fF\9c\fF\9c\14N¤ÄÎäüþüüþüìîì\f\ e\f\ 4\ 2\ 4\8c\8a\8cüþüüþüüþüüþüüþüüþü\8c\8a\8c\f\ e\f\ 4\ 2\ 4\ 4\ 2\ 4,.,üþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü$Z¬\fF\9c\14N¤üþüüþüüþüüþüüþüüþüüþüüþüüþüt\96Ä\fF\9c\fF\9cÄÎäüþüüþüüþüüþü\84\9eÌ\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9cT~¼üþüüþüüþüüþü¬®¬\ 4\ 2\ 4\ 4\ 2\ 4\1c\1e\1clnl¬®¬¬®¬lnl\1c\1e\1c\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\f\ e\fÜÞÜüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüt\96Ä\fF\9cd\8aÄüþüüþüüþüüþüüþüüþüüþüüþüüþüÄÎä\fF\9c\14N¤üþüüþüüþüüþüüþüüþüDr´\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\14N¤\fF\9c\fF\9c\fF\9c\fF\9c4f¬ìòüüþüüþüüþüüþüüþü\9c\9e\9c\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\f\ e\fÌÎÌüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÄÎä\fF\9c¤¶Üüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\14N¤d\8aÄüþüüþüüþüüþüüþüüþüìòül\8aÄ\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c\fF\9c<j´ìòüüþüüþüüþüüþüüþüüþüüþü\9c\9e\9c\f\ e\f\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\1c\1e\1cÌÎÌüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\14N¤ìòüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüd\8aĤ¶ÜüþüüþüüþüüþüüþüüþüüþüüþüÄÎäT~¼\fF\9c\14N¤\fF\9c\fF\9c<j´¤¶ÜüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüÜÞÜlnl,.,\ 4\ 2\ 4\ 4\ 2\ 4<><\8c\8e\8cìîìüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþüüþü\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4\ 4\ 2\ 4
\ No newline at end of file
utc-Dali-Internal-PixelBuffer.cpp
utc-Dali-Lifecycle-Controller.cpp
utc-Dali-TiltSensor.cpp
+ utc-Dali-WbmpLoader.cpp
)
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
if(*bufferPtr != *refBufferPtr)
{
tet_result(TET_FAIL);
- tet_printf("%s Failed in %s at line %d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__);
+ tet_printf("%s Failed in %s at line %d, %u'th buffer (input : %u != expect : %u)\n", __PRETTY_FUNCTION__, __FILE__, __LINE__, i, static_cast<unsigned int>(*bufferPtr), static_cast<unsigned int>(*refBufferPtr));
break;
}
}
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
END_TEST;
}
+int UtcDaliBmpRGB8(void)
+{
+ ImageDetails image(TEST_IMAGE_DIR "/w3c_home_256.bmp", 72u, 48u);
+
+ TestImageLoading(image, BmpLoaders);
+
+ END_TEST;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-test-suite-utils.h>
+#include <stdlib.h>
+#include <iostream>
+
+#include <dali/internal/imaging/common/loader-wbmp.h>
+#include "image-loaders.h"
+
+using namespace Dali;
+
+namespace
+{
+static const LoadFunctions WbmpLoaders(TizenPlatform::LoadWbmpHeader, TizenPlatform::LoadBitmapFromWbmp);
+
+} // Unnamed namespace.
+
+int UtcDaliWbmpLoader(void)
+{
+ ImageDetails image(TEST_IMAGE_DIR "/test-image.wbmp", 32u, 64u);
+
+ TestImageLoading(image, WbmpLoaders);
+
+ END_TEST;
+}
\ No newline at end of file
SET_DEPTH_COMPARE_OP = 1 << 24,
SET_DEPTH_TEST_ENABLE = 1 << 25,
SET_DEPTH_WRITE_ENABLE = 1 << 26,
+ DRAW_NATIVE = 1 << 27,
};
std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op);
{
DRAW,
DRAW_INDEXED,
- DRAW_INDEXED_INDIRECT
+ DRAW_INDEXED_INDIRECT,
+ DRAW_NATIVE
};
Type type{}; ///< Type of the draw call
uint32_t drawCount;
uint32_t stride;
} drawIndexedIndirect;
+
+ struct
+ {
+ Graphics::DrawNativeInfo drawNativeInfo;
+ } drawNative;
};
};
data.bindUniformBuffers = rhs.data.bindUniformBuffers;
break;
}
+ case CommandType::DRAW_NATIVE:
+ {
+ data.draw.type = rhs.data.draw.type;
+ data.draw.drawNative = rhs.data.draw.drawNative;
+ break;
+ }
case CommandType::DRAW:
{
data.draw.type = rhs.data.draw.type;
data.bindPipeline = rhs.data.bindPipeline;
break;
}
+ case CommandType::DRAW_NATIVE:
+ {
+ data.draw.type = rhs.data.draw.type;
+ data.draw.drawNative = rhs.data.draw.drawNative;
+ break;
+ }
case CommandType::DRAW:
{
data.draw.type = rhs.data.draw.type;
mCallStack.PushCall("ExecuteCommandBuffers", "");
}
+ void DrawNative(const Graphics::DrawNativeInfo* drawInfo)
+ {
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::DRAW_NATIVE;
+ auto& cmd = mCommands.back().data.draw;
+ cmd.type = DrawCallDescriptor::Type::DRAW_NATIVE;
+ cmd.drawNative.drawNativeInfo = *drawInfo;
+ mCallStack.PushCall("DrawNative", "");
+ }
+
void Draw(
uint32_t vertexCount,
uint32_t instanceCount,
BindPipeline(currentPipeline);
break;
}
+ case CommandType::DRAW_NATIVE:
+ {
+ auto info = &cmd.data.draw.drawNative.drawNativeInfo;
+ CallbackBase::ExecuteReturn<bool>(*info->callback, info->userData);
+ break;
+ }
case CommandType::DRAW:
{
if(currentPipeline)
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
break;
}
+ case GLES::CommandType::DRAW_NATIVE:
+ {
+ auto* info = &cmd.drawNative.drawNativeInfo;
+
+ mCurrentContext->PrepareForNativeRendering();
+
+ CallbackBase::ExecuteReturn<bool>(*info->callback, info->userData);
+
+ mCurrentContext->RestoreFromNativeRendering();
+ break;
+ }
}
}
}
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "gles-graphics-render-pass.h"
#include "gles-graphics-render-target.h"
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
#include <map>
+
namespace Dali::Graphics::GLES
{
struct Context::Impl
{
- Impl(EglGraphicsController& controller)
+ explicit Impl(EglGraphicsController& controller)
: mController(controller)
{
}
GLStateCache mGlStateCache{}; ///< GL status cache
bool mGlContextCreated{false}; ///< True if the OpenGL context has been created
+
+ EGLContext mNativeDrawContext{0u}; ///< Native rendering EGL context compatible with window context
+
+ EGLSurface mCacheDrawReadSurface{0u}; ///< cached 'read' surface
+ EGLSurface mCacheDrawWriteSurface{0u}; ///< cached 'write' surface
+ EGLContext mCacheEGLGraphicsContext{0u}; ///< cached window context
};
Context::Context(EglGraphicsController& controller)
mImpl = std::make_unique<Impl>(controller);
}
-Context::~Context() = default;
+Context::~Context()
+{
+ // Destroy native rendering context if one exists
+ if(mImpl->mNativeDrawContext)
+ {
+ eglDestroyContext(eglGetCurrentDisplay(), mImpl->mNativeDrawContext);
+ mImpl->mNativeDrawContext = EGL_NO_CONTEXT;
+ }
+}
void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall)
{
}
}
+void Context::PrepareForNativeRendering()
+{
+ // this should be pretty much constant
+ auto display = eglGetCurrentDisplay();
+ auto drawSurface = eglGetCurrentSurface(EGL_DRAW);
+ auto readSurface = eglGetCurrentSurface(EGL_READ);
+ auto context = eglGetCurrentContext();
+
+ // push the surface and context data to the impl
+ // It's needed to restore context
+ if(!mImpl->mCacheEGLGraphicsContext)
+ {
+ mImpl->mCacheDrawWriteSurface = drawSurface;
+ mImpl->mCacheDrawReadSurface = readSurface;
+ mImpl->mCacheEGLGraphicsContext = context;
+ }
+
+ if(!mImpl->mNativeDrawContext)
+ {
+ EGLint configId{0u};
+ EGLint size{0u};
+ eglGetConfigs(display, nullptr, 0, &size);
+ std::vector<EGLConfig> configs;
+ configs.resize(size);
+ eglGetConfigs(display, configs.data(), configs.size(), &size);
+
+ eglQueryContext(display, context, EGL_CONFIG_ID, &configId);
+
+ auto version = int(mImpl->mController.GetGLESVersion());
+
+ std::vector<EGLint> attribs;
+ attribs.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
+ attribs.push_back(version / 10);
+ attribs.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
+ attribs.push_back(version % 10);
+ attribs.push_back(EGL_NONE);
+
+ mImpl->mNativeDrawContext = eglCreateContext(display, configs[configId], EGL_NO_CONTEXT, attribs.data());
+ }
+
+ eglMakeCurrent(display, drawSurface, readSurface, mImpl->mNativeDrawContext);
+}
+
+void Context::RestoreFromNativeRendering()
+{
+ auto display = eglGetCurrentDisplay();
+
+ // bring back original context
+ eglMakeCurrent(display, mImpl->mCacheDrawWriteSurface, mImpl->mCacheDrawReadSurface, mImpl->mCacheEGLGraphicsContext);
+}
+
} // namespace Dali::Graphics::GLES
#define DALI_GRAPHICS_GLES_CONTEXT_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
void InvalidateCachedPipeline(GLES::Pipeline* pipeline);
+ /**
+ * @brief Sets up EGL context for native rendering
+ *
+ * - The native rendering uses dedicated context
+ * - There is one EGL native rendering context per GLES::Context object
+ * - Native rendering context is compatible with the window/surface context
+ * - Native rendering context dies with GLES::Context object
+ *
+ * When native rendering is about to be executed, the dedicated EGL context
+ * is acquired (created or reused) and made current. The Window/Surface context
+ * is cached to be restored afterwards.
+ */
+ void PrepareForNativeRendering();
+
+ /**
+ * @brief Restores window/surface context after native rendering.
+ */
+ void RestoreFromNativeRendering();
+
void ActiveTexture(uint32_t textureBindingIndex);
void BindTexture(GLenum target, BoundTextureType textureTypeId, uint32_t textureId);
void GenerateMipmap(GLenum target);
cmd.drawIndexedIndirect.stride = stride;
}
+void CommandBuffer::DrawNative(const DrawNativeInfo* drawNativeInfo)
+{
+ auto command = mCommandPool->AllocateCommand(CommandType::DRAW_NATIVE);
+ auto& cmd = command->drawNative;
+ memcpy(&cmd.drawNativeInfo, drawNativeInfo, sizeof(DrawNativeInfo));
+}
+
void CommandBuffer::Reset()
{
mCommandPool->Rollback(false);
SET_DEPTH_COMPARE_OP,
SET_DEPTH_TEST_ENABLE,
SET_DEPTH_WRITE_ENABLE,
+ DRAW_NATIVE,
};
/**
{
bool enabled;
} colorMask;
+
+ struct
+ {
+ DrawNativeInfo drawNativeInfo;
+ } drawNative;
};
};
uint32_t stride) override;
/**
+ * @copydoc Dali::Graphics::CommandBuffer::DrawNative
+ */
+ void DrawNative(const DrawNativeInfo* drawNativeInfo) override;
+
+ /**
* @copydoc Dali::Graphics::CommandBuffer::Reset
*/
void Reset() override;
{
DRAW,
DRAW_INDEXED,
- DRAW_INDEXED_INDIRECT
+ DRAW_INDEXED_INDIRECT,
};
Type type{}; ///< Type of the draw call
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return false;
}
- for(unsigned int yPos = 0; yPos < height; yPos++)
+ for(std::uint32_t yPos = 0; yPos < height; ++yPos)
{
- unsigned char* pixelsPtr = NULL;
+ std::uint8_t* pixelsPtr = NULL;
if(topDown)
{
pixelsPtr = pixels + (yPos * rowStride);
DALI_LOG_ERROR("Error reading the BMP image\n");
return false;
}
- for(unsigned int i = 0; i < rowStride; i += 3)
+ for(std::uint32_t i = 0; i < rowStride; i += 3)
{
- unsigned char temp = pixelsPtr[i];
- pixelsPtr[i] = pixelsPtr[i + 2];
- pixelsPtr[i + 2] = temp;
+ std::uint8_t temp = pixelsPtr[i];
+ pixelsPtr[i] = pixelsPtr[i + 2];
+ pixelsPtr[i + 2] = temp;
}
if(padding)
return false;
}
- for(unsigned int yPos = 0; yPos < height; yPos++)
+ for(std::uint32_t yPos = 0; yPos < height; ++yPos)
{
- unsigned char* pixelsPtr = NULL;
+ std::uint8_t* pixelsPtr = NULL;
if(topDown)
{
pixelsPtr = pixels + (yPos * rowStride);
DALI_LOG_ERROR("Error reading the BMP image\n");
return false;
}
- for(unsigned int i = 0; i < rowStride; i += 4)
+ for(std::uint32_t i = 0; i < rowStride; i += 4)
{
- unsigned char temp = pixelsPtr[i];
- pixelsPtr[i] = pixelsPtr[i + 2];
- pixelsPtr[i + 2] = temp;
+ std::uint8_t temp = pixelsPtr[i];
+ pixelsPtr[i] = pixelsPtr[i + 2];
+ pixelsPtr[i + 2] = temp;
}
if(padding)
{
return false;
}
- for(unsigned int yPos = 0; yPos < height; yPos++)
+ for(std::uint32_t yPos = 0; yPos < height; ++yPos)
{
- unsigned char* pixelsPtr;
+ std::uint8_t* pixelsPtr;
if(topDown)
{
// the data in the file is top down, and we store the data top down
DALI_LOG_ERROR("Error reading the BMP image\n");
return false;
}
- for(unsigned int i = 0; i < rowStride; i += 4)
+ for(std::uint32_t i = 0; i < rowStride; i += 4)
{
- unsigned char temp = pixelsPtr[i];
- pixelsPtr[i] = pixelsPtr[i + 2];
- pixelsPtr[i + 2] = temp;
+ std::uint8_t temp = pixelsPtr[i];
+ pixelsPtr[i] = pixelsPtr[i + 2];
+ pixelsPtr[i + 2] = temp;
}
if(padding)
return false;
}
- width = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
- unsigned int rowStride = width * 2;
+ width = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
+ std::uint32_t rowStride = width * 2;
- for(unsigned int i = 0; i < height; i++)
+ for(std::uint32_t i = 0; i < height; ++i)
{
- unsigned char* pixelsPtr = NULL;
+ std::uint8_t* pixelsPtr = NULL;
if(topDown)
{
// the data in the file is top down, and we store the data top down
width = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
- std::vector<char> raw(width * height * 2);
- unsigned int rawStride = width * 2;
- unsigned int rowStride = width * 3;
+ std::vector<std::uint8_t> raw(width * height * 2);
+ std::uint32_t rawStride = width * 2;
+ std::uint32_t rowStride = width * 3;
- char* rawPtr = NULL;
- for(unsigned int j = 0; j < height; j++)
+ std::uint8_t* rawPtr = NULL;
+ for(std::uint32_t j = 0; j < height; ++j)
{
rawPtr = &raw[0] + (j * rawStride);
if(fread(rawPtr, 1, rawStride, fp) != rawStride)
}
}
- for(unsigned int yPos = 0; yPos < height; yPos++)
+ for(std::uint32_t yPos = 0; yPos < height; ++yPos)
{
- unsigned char* pixelsPtr = NULL;
+ std::uint8_t* pixelsPtr = NULL;
if(topDown)
{
// the data in the file is top down, and we store the data top down
pixelsPtr = pixels + (((height - 1) - yPos) * rowStride);
}
- for(unsigned int k = 0; k < width; k++)
+ for(std::uint32_t k = 0; k < width; ++k)
{
- int index = yPos * rawStride + 2 * k;
+ std::uint32_t index = yPos * rawStride + 2 * k;
pixelsPtr[3 * k] = ((raw[index + 1] >> 2) & 0x1F) * 0xFF / 0x1F;
pixelsPtr[3 * k + 1] = (((raw[index + 1] & 0x03) << 3) | (raw[index] >> 5)) * 0xFF / 0x1F;
pixelsPtr[3 * k + 2] = (raw[index] & 0x1F) * 0xFF / 0x1F;
}
width = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
- std::vector<char> raw(width * height * 2);
- unsigned int rawStride = width * 2;
- unsigned int rowStride = width * 3;
+ std::vector<std::uint8_t> raw(width * height * 2);
+ std::uint32_t rawStride = width * 2;
+ std::uint32_t rowStride = width * 3;
- char* rawPtr = NULL;
- for(unsigned int j = 0; j < height; j++)
+ std::uint8_t* rawPtr = NULL;
+ for(std::uint32_t j = 0; j < height; ++j)
{
rawPtr = &raw[0] + (j * rawStride);
if(fread(rawPtr, 1, rawStride, fp) != rawStride)
return false;
}
}
- for(unsigned int i = 0; i < height; i++)
+ for(std::uint32_t i = 0; i < height; ++i)
{
- unsigned char* pixelsPtr = NULL;
+ std::uint8_t* pixelsPtr = NULL;
if(topDown)
{
// the data in the file is top down, and we store the data top down
// the data in the file is bottom up, and we store the data top down
pixelsPtr = pixels + (((height - 1) - i) * rowStride);
}
- for(unsigned int k = 0; k < width; k++)
+ for(std::uint32_t k = 0; k < width; ++k)
{
- int index = i * rawStride + 2 * k;
+ std::uint32_t index = i * rawStride + 2 * k;
pixelsPtr[3 * k] = ((raw[index + 1] >> 2) & 0x1F) * 0xFF / 0x1F;
pixelsPtr[3 * k + 1] = (((raw[index + 1] & 0x03) << 3) | (raw[index] >> 5)) * 0xFF / 0x1F;
pixelsPtr[3 * k + 2] = (raw[index] & 0x1F) * 0xFF / 0x1F;
return false;
}
- unsigned char colorTable[8] = {0};
- char cmd;
- unsigned int fillw = ((width & 63) != 0) ? width + 64 - (width & 63) : width;
- std::vector<char> colorIndex(fillw * height);
- unsigned int rowStride = fillw * 3; // RGB
+ std::uint8_t colorTable[8] = {0};
+ std::uint8_t cmd;
+ std::uint32_t fillw = ((width & 63) != 0) ? width + 64 - (width & 63) : width;
+ std::vector<std::uint8_t> colorIndex(fillw * height);
+ std::uint32_t rowStride = fillw * 3; // RGB
if(fread(colorTable, 1, 8, fp) != 8)
{
return false;
}
- for(unsigned int i = 0; i < fillw * height; i += 8)
+ for(std::uint32_t i = 0; i < fillw * height; i += 8)
{
if(fread(&cmd, 1, 1, fp) != 1)
{
colorIndex[i + 7] = (cmd & 0x01);
}
- for(unsigned int index = 0; index < height; index = index + 1)
+ for(std::uint32_t index = 0; index < height; ++index)
{
- unsigned char* pixelsPtr = NULL;
+ std::uint8_t* pixelsPtr = NULL;
if(topDown)
{
// the data in the file is top down, and we store the data top down
// the data in the file is bottom up, and we store the data top down
pixelsPtr = pixels + (((height - 1) - index) * rowStride);
}
- for(unsigned int j = 0; j < fillw; j++)
+ for(std::uint32_t j = 0; j < fillw; ++j)
{
- unsigned int ctIndex = 0;
+ std::uint32_t ctIndex = 0;
if((fillw * index + j) < (fillw * height))
{
ctIndex = colorIndex[fillw * index + j];
return false;
}
- char colorTable[64];
- char cmd;
- unsigned int fillw = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
- std::vector<char> colorIndex(fillw * height);
- unsigned int rowStride = fillw * 3;
+ std::uint8_t colorTable[64];
+ std::uint8_t cmd;
+ std::uint32_t fillw = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
+ std::vector<std::uint8_t> colorIndex(fillw * height);
+ std::uint32_t rowStride = fillw * 3;
if(fread(colorTable, 1, 64, fp) != 64)
{
return false;
}
- for(unsigned int i = 0; i < fillw * height; i += 2)
+ for(std::uint32_t i = 0; i < fillw * height; i += 2)
{
if(fread(&cmd, 1, 1, fp) != 1)
{
colorIndex[i] = cmd >> 4;
colorIndex[i + 1] = cmd & (0x0F);
}
- unsigned int ctIndex = 0;
+ std::uint32_t ctIndex = 0;
- for(unsigned int index = 0; index < height; index = index + 1)
+ for(std::uint32_t index = 0; index < height; ++index)
{
- unsigned char* pixelsPtr = NULL;
+ std::uint8_t* pixelsPtr = NULL;
if(topDown)
{
// the data in the file is top down, and we store the data top down
// the data in the file is bottom up, and we store the data top down
pixelsPtr = pixels + (((height - 1) - index) * rowStride);
}
- for(unsigned int j = 0; j < fillw; j++)
+ for(std::uint32_t j = 0; j < fillw; ++j)
{
ctIndex = colorIndex[fillw * index + j];
pixelsPtr[3 * j] = colorTable[4 * ctIndex + 2];
return false;
}
- std::vector<char> colorTable(1024);
+ std::vector<std::uint8_t> colorTable(1024);
width = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
- char cmd;
- std::vector<char> colorIndex(width * height);
- unsigned int rowStride = width * 3; //RGB8->RGB24
+ std::vector<std::uint8_t> colorIndex(width * height);
+ std::uint32_t rowStride = width * 3; //RGB8->RGB24
if(fread(&colorTable[0], 1, 1024, fp) != 1024)
{
return false;
}
- for(unsigned int i = 0; i < width * height; i++)
+ if(fread(&colorIndex[0], 1, width * height, fp) != width * height)
{
- if(fread(&cmd, 1, 1, fp) != 1)
- {
- return false;
- }
-
- colorIndex[i] = cmd;
+ return false;
}
- unsigned int ctIndex = 0;
- for(unsigned int index = 0; index < height; index = index + 1)
+ std::uint8_t ctIndex = 0;
+ for(std::uint32_t index = 0; index < height; ++index)
{
- unsigned char* pixelsPtr = NULL;
+ std::uint8_t* pixelsPtr = NULL;
if(topDown)
{
// the data in the file is top down, and we store the data top down
// the data in the file is bottom up, and we store the data top down
pixelsPtr = pixels + (((height - 1) - index) * rowStride);
}
- for(unsigned int j = 0; j < width; j++)
+ for(std::uint8_t j = 0; j < width; ++j)
{
ctIndex = colorIndex[width * index + j];
pixelsPtr[3 * j] = colorTable[4 * ctIndex + 2];
DALI_LOG_ERROR("Error decoding BMP_RLE4 format\n");
return false;
}
- unsigned char* pixelsPtr = pixels;
- width = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
- char cmd[2];
- unsigned int cmdStride = 2;
- char colorTable[64];
- std::vector<char> colorIndex(width * height >> 1);
- std::vector<char> run;
- unsigned int x = 0;
- unsigned int y = 0;
- unsigned int dx = 0;
- unsigned int dy = 0;
+ std::uint8_t* pixelsPtr = pixels;
+ width = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
+ std::uint8_t cmd[2];
+ std::uint32_t cmdStride = 2;
+ std::uint8_t colorTable[64];
+ std::vector<std::uint8_t> colorIndex(width * height >> 1);
+ std::vector<std::uint8_t> run;
+ std::uint32_t x = 0;
+ std::uint32_t y = 0;
+ std::uint32_t dx = 0;
+ std::uint32_t dy = 0;
width += (width & 1);
width = width >> 1;
break;
default:
// decode a literal run
- unsigned int length = cmd[1] & (0xFF);
+ std::uint32_t length = cmd[1] & (0xFF);
//size of run, which is word aligned
- unsigned int bytesize = length;
+ std::uint32_t bytesize = length;
bytesize += (bytesize & 1);
bytesize >>= 1;
bytesize += (bytesize & 1);
{
length += (length & 1);
length >>= 1;
- for(unsigned int i = 0; i < length; i += 1)
+ for(std::uint32_t i = 0; i < length; ++i)
{
colorIndex[(x >> 1) + width * (height - y - 1) + i] = run[i];
}
}
else
{
- for(unsigned int i = 0; i < length; i++)
+ for(std::uint32_t i = 0; i < length; ++i)
{
if((i & 1) == 0) //copy high to low
{
}
else
{
- unsigned int length = cmd[0] & (0xFF);
+ std::uint32_t length = cmd[0] & (0xFF);
if((x & 1) == 0)
{
length += (length & 1);
length >>= 1;
- for(unsigned int i = 0; i < length; i++)
+ for(std::uint32_t i = 0; i < length; ++i)
{
colorIndex[(height - y - 1) * width + i + (x >> 1)] = cmd[1];
}
}
else
{
- for(unsigned int i = 0; i < length; i++)
+ for(std::uint32_t i = 0; i < length; ++i)
{
if((i & 1) == 0)
{
}
}
- int ctIndexHigh = 0;
- int ctIndexLow = 0;
- for(unsigned int index = 0; index < (width * height); index = index + 1)
+ std::uint32_t ctIndexHigh = 0;
+ std::uint32_t ctIndexLow = 0;
+ for(std::uint32_t index = 0; index < (width * height); ++index)
{
ctIndexHigh = colorIndex[index] >> 4;
ctIndexLow = colorIndex[index] & (0x0F);
DALI_LOG_ERROR("Error decoding BMP_RLE8 format\n");
return false;
}
- unsigned char* pixelsPtr = pixels;
- unsigned int x = 0;
- unsigned int y = 0;
- unsigned int cmdStride = 2;
+ std::uint8_t* pixelsPtr = pixels;
+ std::uint32_t x = 0;
+ std::uint32_t y = 0;
+ std::uint32_t cmdStride = 2;
width = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
- std::vector<char> colorTable(1024);
- char cmd[2];
- std::vector<char> colorIndex(width * height);
+ std::vector<std::uint8_t> colorTable(1024);
+ std::uint8_t cmd[2];
+ std::vector<std::uint8_t> colorIndex(width * height);
if(fseek(fp, offset, SEEK_SET))
{
return false;
}
- unsigned int dx = 0;
- unsigned int dy = 0;
- bool finish = false;
- unsigned int length = 0;
- unsigned int copylength = 0;
- std::vector<char> run;
+ std::uint32_t dx = 0;
+ std::uint32_t dy = 0;
+ bool finish = false;
+ std::uint32_t length = 0;
+ std::uint32_t copylength = 0;
+ std::vector<std::uint8_t> run;
while((x + y * width) < width * height)
{
if(finish)
return false;
}
- for(unsigned int i = 0; i < length; i += 1)
+ for(std::uint32_t i = 0; i < length; ++i)
{
colorIndex[x + width * (height - y - 1) + i] = run[i];
}
else
{
length = cmd[0] & (0xFF);
- for(unsigned int i = 0; i < length; i++)
+ for(std::uint32_t i = 0; i < length; ++i)
{
colorIndex[(height - y - 1) * width + x] = cmd[1];
x++;
}
}
}
- int ctIndex = 0;
- for(unsigned int index = 0; index < width * height; index = index + 1)
+ std::uint32_t ctIndex = 0;
+ for(std::uint32_t index = 0; index < width * height; ++index)
{
ctIndex = colorIndex[index];
pixelsPtr[3 * index] = colorTable[4 * ctIndex + 2];
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_LOADER_WBMP");
#endif
+// TODO : We need to determine it in dali-common.h or something else. Currently, we set this value in code level.
+#define DALI_BYTE_ORDER_BIG_ENDIAN 0
+
#define IMG_MAX_SIZE 65536
#define IMG_TOO_BIG(w, h) \
return 0;
}
+// Calculate 4bit integer into 4byte integer
+constexpr std::uint32_t Calculate4BitTo4Byte(const std::uint8_t& input)
+{
+ std::uint32_t output = 0;
+#if DALI_BYTE_ORDER_BIG_ENDIAN
+ output |= static_cast<std::uint32_t>(input & 0x08) << 21;
+ output |= static_cast<std::uint32_t>(input & 0x04) << 14;
+ output |= static_cast<std::uint32_t>(input & 0x02) << 7;
+ output |= static_cast<std::uint32_t>(input & 0x01);
+#else
+ output |= static_cast<std::uint32_t>(input & 0x08) >> 3;
+ output |= static_cast<std::uint32_t>(input & 0x04) << 6;
+ output |= static_cast<std::uint32_t>(input & 0x02) << 15;
+ output |= static_cast<std::uint32_t>(input & 0x01) << 24;
+#endif
+ return output * 0xff;
+}
+
+/**
+ * @brief Calculation result bit-->byte table in compile.
+ * Required memory = 16 * 4byte = 64byte
+ */
+// clang-format off
+constexpr std::uint32_t cachedCalculation4BitTo4ByteTable[16] = {
+ Calculate4BitTo4Byte(0x00), Calculate4BitTo4Byte(0x01), Calculate4BitTo4Byte(0x02), Calculate4BitTo4Byte(0x03),
+ Calculate4BitTo4Byte(0x04), Calculate4BitTo4Byte(0x05), Calculate4BitTo4Byte(0x06), Calculate4BitTo4Byte(0x07),
+ Calculate4BitTo4Byte(0x08), Calculate4BitTo4Byte(0x09), Calculate4BitTo4Byte(0x0a), Calculate4BitTo4Byte(0x0b),
+ Calculate4BitTo4Byte(0x0c), Calculate4BitTo4Byte(0x0d), Calculate4BitTo4Byte(0x0e), Calculate4BitTo4Byte(0x0f)};
+// clang-format on
} // end unnamed namespace
bool LoadBitmapFromWbmp(const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap)
return false;
}
Dali::Vector<unsigned char> map;
- Dali::Vector<unsigned char> surface; //unsigned int
size_t position = 0;
- unsigned int w, h;
- unsigned int type;
- unsigned int line_length;
- unsigned char* line = NULL;
- unsigned int cur = 0, x, y;
+ std::uint32_t w, h;
+ std::uint32_t type;
+ std::uint32_t lineByteLength;
if(fseek(fp, 0, SEEK_END))
{
return false;
}
- surface.ResizeUninitialized(w * h); //(w * h * 4);
- memset(&surface[0], 0, w * h); // w * h * 4
+ lineByteLength = (w + 7) >> 3;
+ // fsize was wrong! Load failed.
+ if(DALI_UNLIKELY(position + h * lineByteLength > fsize))
+ {
+ DALI_LOG_ERROR("Pixel infomation is bigger than file size! (%u + %u * %u > %u)\n", static_cast<std::uint32_t>(position), h, lineByteLength, fsize);
+ return false;
+ }
- line_length = (w + 7) >> 3;
- for(y = 0; y < h; y++)
+ // w >= 1 and h >= 1. So we can assume that outputPixels is not null.
+ auto outputPixels = (bitmap = Dali::Devel::PixelBuffer::New(w, h, Pixel::L8)).GetBuffer();
+ /**
+ * @code
+ * std::uint8_t* line = NULL;
+ * std::uint32_t cur = 0, x, y;
+ * for(y = 0; y < h; y++)
+ * {
+ * line = &map[0] + position;
+ * position += lineByteLength;
+ * for(x = 0; x < w; x++)
+ * {
+ * int idx = x >> 3;
+ * int offset = 1 << (0x07 - (x & 0x07));
+ * if(line[idx] & offset)
+ * {
+ * outputPixels[cur] = 0xff; //0xffffffff;
+ * }
+ * else
+ * {
+ * outputPixels[cur] = 0x00; //0xff000000;
+ * }
+ * cur++;
+ * }
+ * }
+ * @endcode
+ */
+
+ const std::uint8_t* inputPixels = &map[0] + position;
+ const std::uint32_t lineByteLengthWithoutPadding = w >> 3;
+ const std::uint8_t linePadding = w & 0x07;
+
+ for(std::uint32_t y = 0; y < h; y++)
{
- if(position + line_length > fsize)
+ for(std::uint32_t x = 0; x < lineByteLengthWithoutPadding; x++)
{
- return false;
+ // memset whole 8 bits
+ // outputPixels filled 4 bytes in one operation.
+ // cachedCalculation4BitTo4ByteTable calculated in compile-time.
+ *(reinterpret_cast<std::uint32_t*>(outputPixels + 0)) = cachedCalculation4BitTo4ByteTable[((*inputPixels) >> 4) & 0x0f];
+ *(reinterpret_cast<std::uint32_t*>(outputPixels + 4)) = cachedCalculation4BitTo4ByteTable[(*inputPixels) & 0x0f];
+ outputPixels += 8;
+ ++inputPixels;
}
- line = &map[0] + position;
- position += line_length;
- for(x = 0; x < w; x++)
+ if(linePadding > 0)
{
- int idx = x >> 3;
- int offset = 1 << (0x07 - (x & 0x07));
- if(line[idx] & offset)
+ // memset linePadding bits naive.
+ for(std::uint8_t x = 0; x < linePadding; ++x)
{
- surface[cur] = 0xff; //0xffffffff;
+ const std::uint8_t offset = (0x07 - (x & 0x07));
+ *outputPixels = ((*inputPixels) >> offset) & 1 ? 0xff : 0x00;
+ ++outputPixels;
}
- else
- {
- surface[cur] = 0x00; //0xff000000;
- }
- cur++;
+ ++inputPixels;
}
}
- auto pixels = (bitmap = Dali::Devel::PixelBuffer::New(w, h, Pixel::L8)).GetBuffer();
-
- memcpy(pixels, &surface[0], w * h); //w * h * 4
return true;
}
{
const unsigned int ADAPTOR_MAJOR_VERSION = 2;
const unsigned int ADAPTOR_MINOR_VERSION = 1;
-const unsigned int ADAPTOR_MICRO_VERSION = 13;
+const unsigned int ADAPTOR_MICRO_VERSION = 14;
const char* const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-adaptor
Summary: The DALi Tizen Adaptor
-Version: 2.1.13
+Version: 2.1.14
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT