summaryrefslogtreecommitdiff
path: root/src/cos_parse.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2018-01-23 22:57:18 +0000
committerVincent Sanders <vince@kyllikki.org>2018-01-23 22:57:18 +0000
commit06b733c6296bb7bf8724a599c48d42655a190f74 (patch)
tree23e15f9faf752dfa79f30a569d10140d235f4b22 /src/cos_parse.c
parent04517ee5560353cab1ecf5d24a1cb6301d3a8b05 (diff)
downloadlibnspdf-06b733c6296bb7bf8724a599c48d42655a190f74.tar.gz
libnspdf-06b733c6296bb7bf8724a599c48d42655a190f74.tar.bz2
add parameter parsing for content objects
Diffstat (limited to 'src/cos_parse.c')
-rw-r--r--src/cos_parse.c518
1 files changed, 513 insertions, 5 deletions
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) {