summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile2
-rw-r--r--src/cos_content.c517
-rw-r--r--src/cos_content.h (renamed from src/content.h)10
-rw-r--r--src/cos_parse.c510
4 files changed, 546 insertions, 493 deletions
diff --git a/src/Makefile b/src/Makefile
index 35576c2..23c20fd 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,3 +1,3 @@
-DIR_SOURCES := document.c byte_class.c cos_parse.c cos_object.c pdf_doc.c meta.c page.c xref.c cos_stream_filter.c
+DIR_SOURCES := document.c byte_class.c cos_parse.c cos_object.c pdf_doc.c meta.c page.c xref.c cos_stream_filter.c cos_content.c
include $(NSBUILD)/Makefile.subdir
diff --git a/src/cos_content.c b/src/cos_content.c
new file mode 100644
index 0000000..6978606
--- /dev/null
+++ b/src/cos_content.c
@@ -0,0 +1,517 @@
+/*
+ * Copyright 2018 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of libnspdf.
+ *
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <nspdf/errors.h>
+
+#include "cos_object.h"
+#include "cos_content.h"
+#include "pdf_doc.h"
+
+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;
+}
+
+/* exported interface documented in cos_content.h */
+nspdferror
+nspdf__cos_content_convert(enum content_operator operator,
+ struct cos_object **operands,
+ unsigned int *operand_idx,
+ struct content_operation *operation_out)
+{
+ nspdferror res;
+
+ operation_out->operator = operator;
+
+ 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;
+
+ 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;
+ }
+
+ return res;
+}
diff --git a/src/content.h b/src/cos_content.h
index af91b13..9921e2b 100644
--- a/src/content.h
+++ b/src/cos_content.h
@@ -12,8 +12,8 @@
* NetSurf PDF library parsed content stream
*/
-#ifndef NSPDF__CONTENT_H_
-#define NSPDF__CONTENT_H_
+#ifndef NSPDF__COS_CONTENT_H_
+#define NSPDF__COS_CONTENT_H_
/**
* content operator
@@ -223,4 +223,10 @@ struct content_operation
} u;
};
+/**
+ * convert an operator and operand list into an operation
+ */
+nspdferror nspdf__cos_content_convert(enum content_operator operator, struct cos_object **operands, unsigned int *operand_idx, struct content_operation *operation_out);
+
+
#endif
diff --git a/src/cos_parse.c b/src/cos_parse.c
index a1587d5..dea67f9 100644
--- a/src/cos_parse.c
+++ b/src/cos_parse.c
@@ -19,7 +19,7 @@
#include "cos_parse.h"
#include "byte_class.h"
#include "cos_object.h"
-#include "content.h"
+#include "cos_content.h"
#include "pdf_doc.h"
/** increments in which cos string allocations are extended */
@@ -1246,367 +1246,9 @@ parse_operator(struct cos_stream *stream,
}
-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
+ * largest number of operands any operator requires
*
* This would be 6 except scn in Nchannel colourspace may have 32
*/
@@ -1707,7 +1349,6 @@ parse_content_operation(struct nspdf_doc *doc,
res = parse_operator(stream, &offset, &operator);
}
-
/*
printf("returning operator %d with %d operands %d to %d of %d\n>>>%.*s<<<\n",
operator,
@@ -1719,130 +1360,10 @@ parse_content_operation(struct nspdf_doc *doc,
stream->data + (*offset_out));
*/
- operation_out->operator = operator;
-
- 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;
-
- 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;
- }
-
+ res = nspdf__cos_content_convert(operator,
+ operands,
+ operand_idx,
+ operation_out);
if (res == NSPDFERROR_OK) {
*operand_idx = 0;
@@ -1870,15 +1391,24 @@ cos_parse_content_streams(struct nspdf_doc *doc,
//#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),
+ printf("float:%lu unsigned int:%lu\n"
+ "struct content_operation:%lu\n"
+ " operator:%lu\n"
+ " union:%lu\n"
+ " number:%lu\n"
+ " string:%lu\n"
+ " string.length:%lu\n"
+ " string.u:%lu\n"
+ " string.u.cdata:%lu\n"
+ " array:%lu\n",
sizeof(float),
sizeof(unsigned int),
+ sizeof(struct content_operation),
+ sizeof(foo.operator),
sizeof(foo.u),
- sizeof(foo.u.n),
+ sizeof(foo.u.number),
sizeof(foo.u.string),
+ sizeof(foo.u.string.length),
sizeof(foo.u.string.u),
sizeof(foo.u.string.u.cdata),
sizeof(foo.u.array));