diff --git a/pdf.c b/pdf.c index 5c8dc7f6589060062ef1cb4c878790c455c1328c..de83c95928aea9a2cbbb82650e5cbc6b5fed1f3c 100644 --- a/pdf.c +++ b/pdf.c @@ -240,18 +240,42 @@ act_ahextruncated(const HParseResult *p, void *u) HParsedToken * act_a85zero(const HParseResult *p, void *u) { - uint8_t nybble = 0; - /* Remember, this only represents 4 bytes. */ - return H_MAKE_UINT(nybble); + uint8_t b = 0; + return H_MAKE_UINT(b); } HParsedToken * -act_a85digit(const HParseResult *p void *u) +act_a85digit(const HParseResult *p, void *u) { - uint8_t nybble = H_CAST_UINT(p->ast); - nybble -= '!'; + uint8_t b = H_CAST_UINT(p->ast); + b -= '!'; - return H_MAKE_UINT(nybble); + /* At this point we have the base85 value of one byte out of 5 */ + return H_MAKE_UINT(b); +} + +HParsedToken * +act_a85group(const HParseResult *p, void *u) +{ + uint64_t b = 0; + HCountedArray *seq = H_CAST_SEQ(p->ast); + HParsedToken **digits = h_seq_elements(p->ast); + + /* 2^32-1, the max value the group can hold as per spec */ + #define A85GRPMAX 4294967296 + + /* Only for groups that do not need to padded to 5 */ + assert(seq->used == 5); + b += H_CAST_UINT(digits[0]) * ((uint64_t) pow(85,4)); + b += H_CAST_UINT(digits[1]) * ((uint64_t) pow(85,3)); + b += H_CAST_UINT(digits[2]) * ((uint64_t) pow(85,2)); + b += H_CAST_UINT(digits[3]) * ((uint64_t) pow(85,1)); + b += H_CAST_UINT(digits[4]); + + assert(b <= A85GRPMAX); + // TODO: make it generic with H_ACT_APPLY + + return H_MAKE_UINT(b); } HParsedToken *