summaryrefslogtreecommitdiff
path: root/filter/ahxd.c
diff options
context:
space:
mode:
Diffstat (limited to 'filter/ahxd.c')
-rw-r--r--filter/ahxd.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/filter/ahxd.c b/filter/ahxd.c
new file mode 100644
index 00000000..b557399c
--- /dev/null
+++ b/filter/ahxd.c
@@ -0,0 +1,113 @@
+#include <fitz.h>
+
+typedef struct fz_ahxd_s fz_ahxd;
+
+struct fz_ahxd_s
+{
+ fz_filter super;
+ int odd;
+ int a;
+};
+
+static inline int iswhite(int a)
+{
+ switch (a) {
+ case '\n': case '\r': case '\t': case ' ':
+ case '\0': case '\f': case '\b': case 0177:
+ return 1;
+ }
+ return 0;
+}
+
+static inline int ishex(int a)
+{
+ return (a >= 'A' && a <= 'F') ||
+ (a >= 'a' && a <= 'f') ||
+ (a >= '0' && a <= '9');
+}
+
+static inline int fromhex(int a)
+{
+ if (a >= 'A' && a <= 'F')
+ return a - 'A' + 0xA;
+ if (a >= 'a' && a <= 'f')
+ return a - 'a' + 0xA;
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ return 0;
+}
+
+fz_error *
+fz_newahxd(fz_filter **fp, fz_obj *params)
+{
+ FZ_NEWFILTER(fz_ahxd, f, ahxd);
+ f->odd = 0;
+ f->a = 0;
+ return nil;
+}
+
+void
+fz_freeahxd(fz_filter *f)
+{
+ fz_free(f);
+}
+
+fz_error *
+fz_processahxd(fz_filter *filter, fz_buffer *in, fz_buffer *out)
+{
+ fz_ahxd *f = (fz_ahxd*)filter;
+ int b, c;
+
+ while (1)
+ {
+ if (in->rp == in->wp)
+ return fz_ioneedin;
+
+ if (out->wp == out->ep)
+ return fz_ioneedout;
+
+ c = *in->rp++;
+
+ if (ishex(c)) {
+ if (!f->odd) {
+ f->a = fromhex(c);
+ f->odd = 1;
+ }
+ else {
+ b = fromhex(c);
+ *out->wp++ = (f->a << 4) | b;
+ f->odd = 0;
+ }
+ }
+
+ else if (c == '>') {
+ if (f->odd)
+ *out->wp++ = (f->a << 4);
+ out->eof = 1;
+ return fz_iodone;
+ }
+
+ else if (!iswhite(c)) {
+ return fz_throw("ioerror: bad data in ahxd: '%c'", c);
+ }
+ }
+}
+
+void
+fz_pushbackahxd(fz_filter *filter, fz_buffer *in, fz_buffer *out, int n)
+{
+ int k;
+
+ assert(filter->process == fz_processahxd);
+ assert(out->wp - n >= out->rp);
+
+ k = 0;
+ while (k < n * 2) {
+ in->rp --;
+ if (ishex(*in->rp))
+ k ++;
+ }
+
+ out->wp -= n;
+}
+