From 06b733c6296bb7bf8724a599c48d42655a190f74 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 23 Jan 2018 22:57:18 +0000 Subject: add parameter parsing for content objects --- src/content.h | 276 +++++++++++++++++++++--------- src/cos_parse.c | 518 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 713 insertions(+), 81 deletions(-) (limited to 'src') diff --git a/src/content.h b/src/content.h index 11f4c3d..af91b13 100644 --- a/src/content.h +++ b/src/content.h @@ -15,88 +15,212 @@ #ifndef NSPDF__CONTENT_H_ #define NSPDF__CONTENT_H_ +/** + * content operator + * + * parameters types are listed as: + * tag - + * prp - properties + * num - floating point value + */ enum content_operator { - CONTENT_OP_b, /* b - close, fill and stroke path with nonzero winding - * rule. */ - CONTENT_OP_B, /* B - fill and stroke path using nonzero winding rule */ - CONTENT_OP_b_, /* b* - close, fill and stroke path with even/odd rule */ - CONTENT_OP_B_, /* B* - fill and stroke path with even/odd rule */ - CONTENT_OP_BDC, /* BDC - begin marked content sequence with property list */ - CONTENT_OP_BI, /* BI - begin inline image*/ - CONTENT_OP_BMC, /* BMC - begin marked content sequence */ - CONTENT_OP_BT, /* BT - begin text */ - CONTENT_OP_BX, /* BX - begin compatability */ - CONTENT_OP_c, /* c - append curved segment to path */ - CONTENT_OP_cm, /* cm - concatinate matrix to current trasnsform matrix */ - CONTENT_OP_CS, /* CS - set colour space for stroking operations */ - CONTENT_OP_cs, /* cs - set colourspace for non stroke operations */ - CONTENT_OP_d, /* d - set line dash pattern */ - CONTENT_OP_d0, /* d0 - set glyph width in type 3 font */ - CONTENT_OP_d1, /* d1 - set glyph width and bounding box in type 3 font */ - CONTENT_OP_Do, /* Do - invoke named xobject */ - CONTENT_OP_DP, /* DP - define marked content point with property list */ - CONTENT_OP_EI, /* EI - end of inline image */ - CONTENT_OP_EMC, /* EMC - end marked content sequence */ - CONTENT_OP_ET, /* ET - end text object */ - CONTENT_OP_EX, /* EX - end compatability section */ - CONTENT_OP_f, /* f - fill path using nonzero winding rule */ - CONTENT_OP_F, /* F - fill path using nonzero winding rule */ - CONTENT_OP_f_, /* f* - fill path with even/odd rule */ - CONTENT_OP_G, /* G - set gray level for stroking operations */ - CONTENT_OP_g, /* g - set gray level for nonstroking operations */ - CONTENT_OP_gs, /* gs - set parameters from graphics state directory */ - CONTENT_OP_h, /* h - close subpath */ - CONTENT_OP_i, /* i - set flatness tolerance */ - CONTENT_OP_ID, /* ID - begin inline image data */ - CONTENT_OP_j, /* j - set join style */ - CONTENT_OP_J, /* J - */ - CONTENT_OP_K, /* K - */ - CONTENT_OP_k, /* k - */ - CONTENT_OP_l, /* l - */ - CONTENT_OP_m, /* m - */ - CONTENT_OP_M, /* M - */ - CONTENT_OP_MP, /* MP - */ - CONTENT_OP_n, /* n - */ - CONTENT_OP_q, /* q - */ - CONTENT_OP_Q, /* Q - */ - CONTENT_OP_re, /* re - */ - CONTENT_OP_RG, /* RG - */ - CONTENT_OP_rg, /* rg - */ - CONTENT_OP_ri, /* ri - */ - CONTENT_OP_s, /* s - */ - CONTENT_OP_S, /* S - */ - CONTENT_OP_SC, /* SC - */ - CONTENT_OP_sc, /* sc - */ - CONTENT_OP_SCN, /* SCN - */ - CONTENT_OP_scn, /* scn - */ - CONTENT_OP_sh, /* sh - */ - CONTENT_OP_T_, /* T* - */ - CONTENT_OP_Tc, /* Tc - */ - CONTENT_OP_Td, /* Td - */ - CONTENT_OP_TD, /* TD - */ - CONTENT_OP_Tf, /* Tf - */ - CONTENT_OP_Tj, /* Tj - */ - CONTENT_OP_TJ, /* TJ - */ - CONTENT_OP_TL, /* TL - */ - CONTENT_OP_Tm, /* Tm - */ - CONTENT_OP_Tr, /* Tr - */ - CONTENT_OP_Ts, /* Ts - */ - CONTENT_OP_Tw, /* Tw - */ - CONTENT_OP_Tz, /* Tz - */ - CONTENT_OP_v, /* v - */ - CONTENT_OP_w, /* w - */ - CONTENT_OP_W, /* W - */ - CONTENT_OP_W_, /* W* - */ - CONTENT_OP_y, /* y - append curved segment to path */ - CONTENT_OP__, /* ' - move to next line and show text */ - CONTENT_OP___, /* " - set word and char spacing, move to next line and - * show text */ + /** + * close, fill and stroke path with nonzero winding rule. + * b() + */ + CONTENT_OP_b, + + /** + * fill and stroke path using nonzero winding rule. + * B() + */ + CONTENT_OP_B, + + /** + * close, fill and stroke path with even/odd rule + * b*() + */ + CONTENT_OP_b_, + + /** + * fill and stroke path with even/odd rule + * B*() + */ + CONTENT_OP_B_, + + /** + * tag prp BDC + * begin marked content sequence with property list + */ + CONTENT_OP_BDC, + + /** + * BI() + * begin inline image + */ + CONTENT_OP_BI, + + /** + * tag BMC + * begin marked content sequence + */ + CONTENT_OP_BMC, + + /** + * begin text + * BT() + */ + CONTENT_OP_BT, + + /** + * begin compatability + * BX() + */ + CONTENT_OP_BX, + + /** + * append curved segment to path + * c(num x1, num y1, num x2, num y2, num x3, num y3) + */ + CONTENT_OP_c, + CONTENT_OP_cm, /* a b c d e f cm - concatinate matrix to current trasnsform matrix */ + CONTENT_OP_CS, /* name CS - set colour space for stroking operations */ + CONTENT_OP_cs, /* name cs - set colourspace for non stroke operations */ + CONTENT_OP_d, /* array phase d - set line dash pattern */ + CONTENT_OP_d0, /* wx wy d0 - set glyph width in type 3 font */ + CONTENT_OP_d1, /* wx wy llx lly urx ury d1 - set glyph width and bounding box in type 3 font */ + CONTENT_OP_Do, /* name Do - invoke named xobject */ + CONTENT_OP_DP, /* tag prp DP - define marked content point with property list */ + CONTENT_OP_EI, /* EI - end of inline image */ + CONTENT_OP_EMC, /* EMC - end marked content sequence */ + CONTENT_OP_ET, /* ET - end text object */ + CONTENT_OP_EX, /* EX - end compatability section */ + CONTENT_OP_f, /* f - fill path using nonzero winding rule */ + CONTENT_OP_F, /* F - fill path using nonzero winding rule */ + CONTENT_OP_f_, /* f* - fill path with even/odd rule */ + + /** + * set gray level for stroking operations + * G(num gray) + */ + CONTENT_OP_G, + + /** + * set gray level for nonstroking operations + * g(num gray) + */ + CONTENT_OP_g, + CONTENT_OP_gs, /* dictName gs - set parameters from graphics state directory */ + + /** + * close subpath + * h() + */ + CONTENT_OP_h, + + /** + * set flatness tolerance + * i(num flatness) + */ + CONTENT_OP_i, + CONTENT_OP_ID, /* ID - begin inline image data */ + + /** + * set line join style (0, 1 or 2) + * j(int linejoin) + */ + CONTENT_OP_j, + CONTENT_OP_J, /* linecap J - sel line cap style (int 0, 1 or 2) */ + CONTENT_OP_K, /* c m y k K - set cmyk colour for stroking operations */ + CONTENT_OP_k, /* c m y k k - set cmyk colour for nonstroking operations */ + CONTENT_OP_l, /* x y l - append straight line segment to path */ + CONTENT_OP_m, /* x y m - begin new subpath */ + + /** + * set mitre limit + * M(num mitrelimit) + */ + CONTENT_OP_M, + CONTENT_OP_MP, /* tag MP - define marked content point */ + CONTENT_OP_n, /* n - end path without filling or stroking*/ + CONTENT_OP_q, /* q - save graphics state */ + CONTENT_OP_Q, /* Q - restore graphics state */ + CONTENT_OP_re, /* x y w h re - append rectangle to path */ + CONTENT_OP_RG, /* r g b RG - stroke colour in DeviceRGB colourspace */ + CONTENT_OP_rg, /* r g b rg - nonstroke colour in DeviceRGB colourspace */ + CONTENT_OP_ri, /* intent ri - set color rendering intent */ + CONTENT_OP_s, /* s - close and stroke path */ + CONTENT_OP_S, /* S - stroke path */ + CONTENT_OP_SC, /* c1 c... SC - set colour for stroking operation. 1 3 or 4 params */ + CONTENT_OP_sc, /* c1 c... sc - same as SC for nonstroking operations */ + CONTENT_OP_SCN, /* c1 c... name SCN - same as SC but extra colour spaces. max 32 params */ + CONTENT_OP_scn, /* c1 c... name scn - same as SCN for nonstroking operations */ + CONTENT_OP_sh, /* name sh - paint area defined by shading pattern */ + CONTENT_OP_T_, /* T* - move to start of next text line */ + CONTENT_OP_Tc, /* charspace Tc - set character spacing */ + CONTENT_OP_Td, /* tx ty Td - move text position */ + CONTENT_OP_TD, /* tx ty TD - move text position and set leading */ + CONTENT_OP_Tf, /* font size Tf - select text font and size */ + CONTENT_OP_Tj, /* string Tj - show text */ + CONTENT_OP_TJ, /* array TJ - show text strings allowing individual positioning */ + CONTENT_OP_TL, /* leading TL - set text leading for T* ' " operators */ + CONTENT_OP_Tm, /* a b c d e f Tm - set the text matrix */ + CONTENT_OP_Tr, /* render Tr - set rendering mode (int) */ + CONTENT_OP_Ts, /* rise Ts - set text rise */ + CONTENT_OP_Tw, /* wordspace Tw - set word spacing */ + CONTENT_OP_Tz, /* scale Tz - set horizontal scaling */ + CONTENT_OP_v, /* x2 y2 x3 y3 v - append curved segment path */ + + /** + * set line width + * w(num linewidth) + */ + CONTENT_OP_w, + CONTENT_OP_W, /* W - set clipping path using nonzero winding rule */ + CONTENT_OP_W_, /* W* - set clipping path using odd even rule */ + CONTENT_OP_y, /* x1 y1 x3 y3 y - append curved segment to path */ + CONTENT_OP__, /* string ' - move to next line and show text */ + CONTENT_OP___, /* aw ac string " - set word and char spacing, move to next line and show text */ }; +/* six numbers is adequate for almost all operations */ +#define content_number_size (6) + +/* compute how long the embedded string can be without inflating the + * structure. size of the pointer is used instead of unsigned int as that is + * what will control the structure padding. + */ +#define content_string_intrnl_lngth ((sizeof(float) * content_number_size) - sizeof(uint8_t *)) + + struct content_operation { enum content_operator operator; - + union { + float number[content_number_size]; + + char *name; + + int64_t i[3]; + + struct { + unsigned int length; + union { + char cdata[content_string_intrnl_lngth]; + uint8_t *pdata; + } u; + } string; + + struct { + unsigned int length; + struct cos_object **values; + } array; + + struct { + char *name; + float number; + } namenumber; + } u; }; #endif diff --git a/src/cos_parse.c b/src/cos_parse.c index 1881e6a..a1587d5 100644 --- a/src/cos_parse.c +++ b/src/cos_parse.c @@ -1245,6 +1245,371 @@ parse_operator(struct cos_stream *stream, return NSPDFERROR_OK; } + +static const char*operator_name(enum content_operator operator) +{ + switch(operator) { + case CONTENT_OP_b: return "b"; + case CONTENT_OP_B: return "B"; + case CONTENT_OP_b_: return "b*"; + case CONTENT_OP_B_: return "B*"; + case CONTENT_OP_BDC: return "BDC"; + case CONTENT_OP_BI: return "BI"; + case CONTENT_OP_BMC: return "BMC"; + case CONTENT_OP_BT: return "BT"; + case CONTENT_OP_BX: return "BX"; + case CONTENT_OP_c: return "c"; + case CONTENT_OP_cm: return "cm"; + case CONTENT_OP_CS: return "CS"; + case CONTENT_OP_cs: return "cs"; + case CONTENT_OP_d: return "d"; + case CONTENT_OP_d0: return "d0"; + case CONTENT_OP_d1: return "d1"; + case CONTENT_OP_Do: return "Do"; + case CONTENT_OP_DP: return "DP"; + case CONTENT_OP_EI: return "EI"; + case CONTENT_OP_EMC: return "EMC"; + case CONTENT_OP_ET: return "ET"; + case CONTENT_OP_EX: return "EX"; + case CONTENT_OP_f: return "f"; + case CONTENT_OP_F: return "F"; + case CONTENT_OP_f_: return "f*"; + case CONTENT_OP_G: return "G"; + case CONTENT_OP_g: return "g"; + case CONTENT_OP_gs: return "gs"; + case CONTENT_OP_h: return "h"; + case CONTENT_OP_i: return "i"; + case CONTENT_OP_ID: return "ID"; + case CONTENT_OP_j: return "j"; + case CONTENT_OP_J: return "J"; + case CONTENT_OP_K: return "K"; + case CONTENT_OP_k: return "k"; + case CONTENT_OP_l: return "l"; + case CONTENT_OP_m: return "m"; + case CONTENT_OP_M: return "M"; + case CONTENT_OP_MP: return "MP"; + case CONTENT_OP_n: return "n"; + case CONTENT_OP_q: return "q"; + case CONTENT_OP_Q: return "Q"; + case CONTENT_OP_re: return "re"; + case CONTENT_OP_RG: return "RG"; + case CONTENT_OP_rg: return "rg"; + case CONTENT_OP_ri: return "ri"; + case CONTENT_OP_s: return "s"; + case CONTENT_OP_S: return "S"; + case CONTENT_OP_SC: return "SC"; + case CONTENT_OP_sc: return "sc"; + case CONTENT_OP_SCN: return "SCN"; + case CONTENT_OP_scn: return "scn"; + case CONTENT_OP_sh: return "sh"; + case CONTENT_OP_T_: return "T*"; + case CONTENT_OP_Tc: return "Tc"; + case CONTENT_OP_Td: return "Td"; + case CONTENT_OP_TD: return "TD"; + case CONTENT_OP_Tf: return "Tf"; + case CONTENT_OP_Tj: return "Tj"; + case CONTENT_OP_TJ: return "TJ"; + case CONTENT_OP_TL: return "TL"; + case CONTENT_OP_Tm: return "Tm"; + case CONTENT_OP_Tr: return "Tr"; + case CONTENT_OP_Ts: return "Ts"; + case CONTENT_OP_Tw: return "Tw"; + case CONTENT_OP_Tz: return "Tz"; + case CONTENT_OP_v: return "v"; + case CONTENT_OP_w: return "w"; + case CONTENT_OP_W: return "W"; + case CONTENT_OP_W_: return "W_"; + case CONTENT_OP_y: return "y"; + case CONTENT_OP__: return "\'"; + case CONTENT_OP___: return "\""; + } + return "????"; +} + + +/** + * move number operands from list into operation + * + * This ensures all operands are correctly handled not just the wanted ones + * + * \param wanted The number of wanted operands to place in the operation + * \param operands The array of operands from the parse + * \param operand_idx The number of operands from the parse + * \param operation_out The operation to place numbers in + */ +static nspdferror +copy_numbers(unsigned int wanted, + struct cos_object **operands, + unsigned int *operand_idx, + struct content_operation *operation_out) +{ + nspdferror res; + unsigned int index = 0; + + while ((index < (*operand_idx)) && + (index < wanted)) { + /* process wanted operands */ + res = cos_get_number(NULL, + *(operands + index), + &operation_out->u.number[index]); + if (res != NSPDFERROR_OK) { + printf("operand %d could not be set in operation (code %d)\n", + index, res); + } + cos_free_object(*(operands + index)); + index++; + } + if ((*operand_idx) > index) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), wanted, *operand_idx); + while (index < (*operand_idx)) { + cos_free_object(*(operands + index)); + index++; + } + } else if ((*operand_idx) < index) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), wanted, *operand_idx); + } + + *operand_idx = 0; /* all operands freed */ + + return NSPDFERROR_OK; +} + +static nspdferror +copy_integers(unsigned int wanted, + struct cos_object **operands, + unsigned int *operand_idx, + struct content_operation *operation_out) +{ + nspdferror res; + unsigned int index = 0; + + while ((index < (*operand_idx)) && + (index < wanted)) { + /* process wanted operands */ + res = cos_get_int(NULL, + *(operands + index), + &operation_out->u.i[index]); + if (res != NSPDFERROR_OK) { + printf("operand %d could not be set in operation (code %d)\n", + index, res); + } + cos_free_object(*(operands + index)); + index++; + } + if ((*operand_idx) > index) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), wanted, *operand_idx); + while (index < (*operand_idx)) { + cos_free_object(*(operands + index)); + index++; + } + } else if ((*operand_idx) < index) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), wanted, *operand_idx); + } + + *operand_idx = 0; /* all operands freed */ + + return NSPDFERROR_OK; +} + +static nspdferror +copy_string(struct cos_object **operands, + unsigned int *operand_idx, + struct content_operation *operation_out) +{ + nspdferror res; + unsigned int index = 0; + struct cos_string *string; + + if ((*operand_idx) == 0) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), 1, *operand_idx); + operation_out->u.string.length = 0; + return NSPDFERROR_OK; + } + + /* process wanted operands */ + res = cos_get_string(NULL, *operands, &string); + if (res != NSPDFERROR_OK) { + printf("string could not be set in operation (code %d)\n", res); + operation_out->u.string.length = 0; + } else { + operation_out->u.string.length = string->length; + if (string->length > content_string_intrnl_lngth) { + /* steal the string from the object */ + operation_out->u.string.u.pdata = string->data; + string->alloc = 0; + string->length = 0; + /*printf("external string \"%.*s\"\n", + operation_out->u.string.length, + operation_out->u.string.u.pdata);*/ + } else { + memcpy(operation_out->u.string.u.cdata, + string->data, + string->length); + /*printf("internal string \"%.*s\"\n", + operation_out->u.string.length, + operation_out->u.string.u.cdata);*/ + } + } + + if ((*operand_idx) > 1) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), 1, *operand_idx); + } + + /* free all operands */ + while (index < (*operand_idx)) { + cos_free_object(*(operands + index)); + index++; + } + *operand_idx = 0; + + return NSPDFERROR_OK; +} + +static nspdferror +copy_array(struct cos_object **operands, + unsigned int *operand_idx, + struct content_operation *operation_out) +{ + unsigned int index = 0; + + if ((*operand_idx) == 0) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), 1, *operand_idx); + operation_out->u.array.length = 0; + return NSPDFERROR_OK; + } + + /* process wanted operands */ + if ((*operands)->type != COS_TYPE_ARRAY) { + printf("operand was not an array\n"); + operation_out->u.array.length = 0; + } else { + operation_out->u.array.length = (*operands)->u.array->length; + /* steal the values from the array object */ + operation_out->u.array.values = (*operands)->u.array->values; + (*operands)->u.array->alloc = 0; + (*operands)->u.array->length = 0; + } + + if ((*operand_idx) > 1) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), 1, *operand_idx); + } + + /* free all operands */ + while (index < (*operand_idx)) { + cos_free_object(*(operands + index)); + index++; + } + *operand_idx = 0; + + return NSPDFERROR_OK; +} + + +static nspdferror +copy_name(struct cos_object **operands, + unsigned int *operand_idx, + struct content_operation *operation_out) +{ + unsigned int index = 0; + + if ((*operand_idx) == 0) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), 1, *operand_idx); + operation_out->u.name = NULL; + return NSPDFERROR_OK; + } + + /* process wanted operands */ + if ((*operands)->type != COS_TYPE_NAME) { + printf("operand was not a name\n"); + operation_out->u.name = NULL; + } else { + /* steal the name from the name object */ + operation_out->u.name = (*operands)->u.name; + (*operands)->u.name = NULL; + } + + if ((*operand_idx) > 1) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), 1, *operand_idx); + } + + /* free all operands */ + while (index < (*operand_idx)) { + cos_free_object(*(operands + index)); + index++; + } + *operand_idx = 0; + + return NSPDFERROR_OK; +} + +static nspdferror +copy_name_number(struct cos_object **operands, + unsigned int *operand_idx, + struct content_operation *operation_out) +{ + unsigned int index = 0; + + if ((*operand_idx) == 0) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), 2, *operand_idx); + operation_out->u.namenumber.name = NULL; + return NSPDFERROR_OK; + } + + /* process wanted operands */ + if ((*operands)->type != COS_TYPE_NAME) { + printf("operand was not a name\n"); + operation_out->u.namenumber.name = NULL; + } else { + /* steal the name from the name object */ + operation_out->u.namenumber.name = (*operands)->u.name; + (*operands)->u.name = NULL; + + operation_out->u.namenumber.number = 0; + /* get the number */ + if ((*operand_idx) > 1) { + nspdferror res; + res = cos_get_number(NULL, + *(operands + 1), + &operation_out->u.namenumber.number); + if (res != NSPDFERROR_OK) { + printf("operand 1 could not be set in operation (code %d)\n", res); + } + } else { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), 2, *operand_idx); + } + } + + if ((*operand_idx) > 2) { + printf("operator %s that takes %d operands passed %d\n", + operator_name(operation_out->operator), 2, *operand_idx); + } + + /* free all operands */ + while (index < (*operand_idx)) { + cos_free_object(*(operands + index)); + index++; + } + *operand_idx = 0; + + return NSPDFERROR_OK; +} + +/** largest number of operands any operator requires + * + * This would be 6 except scn in Nchannel colourspace may have 32 + */ #define MAX_OPERAND_COUNT 32 static inline nspdferror @@ -1342,7 +1707,6 @@ parse_content_operation(struct nspdf_doc *doc, res = parse_operator(stream, &offset, &operator); } - operation_out->operator = operator; /* printf("returning operator %d with %d operands %d to %d of %d\n>>>%.*s<<<\n", @@ -1355,11 +1719,138 @@ parse_content_operation(struct nspdf_doc *doc, stream->data + (*offset_out)); */ - *operand_idx = 0; + operation_out->operator = operator; - *offset_out = offset; + switch (operator) { + case CONTENT_OP_b: + case CONTENT_OP_B: + case CONTENT_OP_b_: + case CONTENT_OP_B_: + case CONTENT_OP_BI: + case CONTENT_OP_BT: + case CONTENT_OP_BX: + case CONTENT_OP_EI: + case CONTENT_OP_EMC: + case CONTENT_OP_ET: + case CONTENT_OP_EX: + case CONTENT_OP_f: + case CONTENT_OP_F: + case CONTENT_OP_f_: + case CONTENT_OP_h: + case CONTENT_OP_ID: + case CONTENT_OP_n: + case CONTENT_OP_q: + case CONTENT_OP_Q: + case CONTENT_OP_s: + case CONTENT_OP_S: + case CONTENT_OP_T_: + case CONTENT_OP_W: + case CONTENT_OP_W_: + /* no operands */ + res = copy_numbers(0, operands, operand_idx, operation_out); + break; - return NSPDFERROR_OK; + case CONTENT_OP_G: + case CONTENT_OP_g: + case CONTENT_OP_i: + case CONTENT_OP_M: + case CONTENT_OP_Tc: + case CONTENT_OP_TL: + case CONTENT_OP_Ts: + case CONTENT_OP_Tw: + case CONTENT_OP_Tz: + case CONTENT_OP_w: + /* one number */ + res = copy_numbers(1, operands, operand_idx, operation_out); + break; + + case CONTENT_OP_d0: + case CONTENT_OP_l: + case CONTENT_OP_m: + case CONTENT_OP_Td: + case CONTENT_OP_TD: + /* two numbers */ + res = copy_numbers(2, operands, operand_idx, operation_out); + break; + + case CONTENT_OP_RG: + case CONTENT_OP_rg: + /* three numbers */ + res = copy_numbers(3, operands, operand_idx, operation_out); + break; + + case CONTENT_OP_K: + case CONTENT_OP_k: + case CONTENT_OP_re: + case CONTENT_OP_v: + case CONTENT_OP_y: + /* four numbers */ + res = copy_numbers(4, operands, operand_idx, operation_out); + break; + + case CONTENT_OP_c: + case CONTENT_OP_cm: + case CONTENT_OP_d1: + case CONTENT_OP_Tm: + /* six numbers */ + res = copy_numbers(6, operands, operand_idx, operation_out); + break; + + case CONTENT_OP_Tj: + case CONTENT_OP__: + /* single string */ + res = copy_string(operands, operand_idx, operation_out); + break; + + case CONTENT_OP_TJ: + /* single array */ + res = copy_array(operands, operand_idx, operation_out); + break; + + case CONTENT_OP_Tf: + /* name and number */ + res = copy_name_number(operands, operand_idx, operation_out); + break; + + case CONTENT_OP_gs: + /* name */ + res = copy_name(operands, operand_idx, operation_out); + break; + + case CONTENT_OP_j: + case CONTENT_OP_J: + /* one integer */ + res = copy_integers(1, operands, operand_idx, operation_out); + break; + + case CONTENT_OP_BDC: + case CONTENT_OP_BMC: + case CONTENT_OP_CS: + case CONTENT_OP_cs: + case CONTENT_OP_d: + case CONTENT_OP_Do: + case CONTENT_OP_DP: + case CONTENT_OP_MP: + case CONTENT_OP_ri: + case CONTENT_OP_SC: + case CONTENT_OP_sc: + case CONTENT_OP_SCN: + case CONTENT_OP_scn: + case CONTENT_OP_sh: + case CONTENT_OP_Tr: + case CONTENT_OP___: + res = copy_numbers(0, operands, operand_idx, operation_out); + break; + } + + if (res == NSPDFERROR_OK) { + + *operand_idx = 0; + + *offset_out = offset; + } + + return res; } nspdferror @@ -1376,7 +1867,22 @@ cos_parse_content_streams(struct nspdf_doc *doc, struct cos_object *operands[MAX_OPERAND_COUNT]; unsigned int operand_idx = 0; - //printf("%.*s", (int)stream->length, stream->data); + //#define SHOW_STRUCT_SIZE + #ifdef SHOW_STRUCT_SIZE + struct content_operation foo; + printf("content_operation length:%d\nfloat:%d\nunsigned int:%d\n" + "union %d\n" + " n:%d string:%d string.u:%d string.u.cdata:%d array:%d\n", + sizeof(struct content_operation), + sizeof(float), + sizeof(unsigned int), + sizeof(foo.u), + sizeof(foo.u.n), + sizeof(foo.u.string), + sizeof(foo.u.string.u), + sizeof(foo.u.string.u.cdata), + sizeof(foo.u.array)); + #endif cosobj = calloc(1, sizeof(struct cos_object)); if (cosobj == NULL) { @@ -1394,6 +1900,8 @@ cos_parse_content_streams(struct nspdf_doc *doc, stream = *(streams + stream_index); offset = 0; + //printf("%.*s", (int)stream->length, stream->data); + /* skip any leading whitespace */ res = nspdf__stream_skip_ws(stream, &offset); if (res != NSPDFERROR_OK) { -- cgit v1.2.3