aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/Pl_ASCII85Decoder.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2008-04-29 14:55:25 +0200
committerJay Berkenbilt <ejb@ql.org>2008-04-29 14:55:25 +0200
commit9a0b88bf7777c153dc46ace22db74ef24d51583a (patch)
treef567ac1cf2bf5071a611eb49323a935b6ac938ff /libqpdf/Pl_ASCII85Decoder.cc
downloadqpdf-9a0b88bf7777c153dc46ace22db74ef24d51583a.tar.zst
update release date to actual daterelease-qpdf-2.0
git-svn-id: svn+q:///qpdf/trunk@599 71b93d88-0707-0410-a8cf-f5a4172ac649
Diffstat (limited to 'libqpdf/Pl_ASCII85Decoder.cc')
-rw-r--r--libqpdf/Pl_ASCII85Decoder.cc131
1 files changed, 131 insertions, 0 deletions
diff --git a/libqpdf/Pl_ASCII85Decoder.cc b/libqpdf/Pl_ASCII85Decoder.cc
new file mode 100644
index 00000000..4ecdaf41
--- /dev/null
+++ b/libqpdf/Pl_ASCII85Decoder.cc
@@ -0,0 +1,131 @@
+#include <qpdf/Pl_ASCII85Decoder.hh>
+#include <qpdf/QEXC.hh>
+#include <qpdf/QTC.hh>
+#include <string.h>
+
+Pl_ASCII85Decoder::Pl_ASCII85Decoder(char const* identifier, Pipeline* next) :
+ Pipeline(identifier, next),
+ pos(0),
+ eod(0)
+{
+ memset(this->inbuf, 117, 5);
+}
+
+Pl_ASCII85Decoder::~Pl_ASCII85Decoder()
+{
+}
+
+void
+Pl_ASCII85Decoder::write(unsigned char* buf, int len)
+{
+ if (eod > 1)
+ {
+ return;
+ }
+ for (int i = 0; i < len; ++i)
+ {
+ if (eod > 1)
+ {
+ break;
+ }
+ else if (eod == 1)
+ {
+ if (buf[i] == '>')
+ {
+ flush();
+ eod = 2;
+ }
+ else
+ {
+ throw QEXC::General(
+ "broken end-of-data sequence in base 85 data");
+ }
+ }
+ else
+ {
+ switch (buf[i])
+ {
+ case ' ':
+ case '\f':
+ case '\v':
+ case '\t':
+ case '\r':
+ case '\n':
+ QTC::TC("libtests", "Pl_ASCII85Decoder ignore space");
+ // ignore whitespace
+ break;
+
+ case '~':
+ eod = 1;
+ break;
+
+ case 'z':
+ if (pos != 0)
+ {
+ throw QEXC::General(
+ "unexpected z during base 85 decode");
+ }
+ else
+ {
+ QTC::TC("libtests", "Pl_ASCII85Decoder read z");
+ getNext()->write((unsigned char*)"\000\000\000\000", 4);
+ }
+ break;
+
+ default:
+ if ((buf[i] < 33) || (buf[i] > 117))
+ {
+ throw QEXC::General
+ ("character out of range during base 85 decode");
+ }
+ else
+ {
+ this->inbuf[this->pos++] = buf[i];
+ if (pos == 5)
+ {
+ flush();
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+void
+Pl_ASCII85Decoder::flush()
+{
+ if (this->pos == 0)
+ {
+ QTC::TC("libtests", "Pl_ASCII85Decoder no-op flush");
+ return;
+ }
+ unsigned long lval = 0;
+ for (int i = 0; i < 5; ++i)
+ {
+ lval *= 85;
+ lval += (this->inbuf[i] - 33);
+ }
+
+ unsigned char outbuf[4];
+ memset(outbuf, 0, 4);
+ for (int i = 3; i >= 0; --i)
+ {
+ outbuf[i] = lval & 0xff;
+ lval >>= 8;
+ }
+
+ QTC::TC("libtests", "Pl_ASCII85Decoder partial flush",
+ (this->pos == 5) ? 0 : 1);
+ getNext()->write(outbuf, this->pos - 1);
+
+ this->pos = 0;
+ memset(this->inbuf, 117, 5);
+}
+
+void
+Pl_ASCII85Decoder::finish()
+{
+ flush();
+ getNext()->finish();
+}