summaryrefslogtreecommitdiff
path: root/util/cairo-script
diff options
context:
space:
mode:
Diffstat (limited to 'util/cairo-script')
-rw-r--r--util/cairo-script/cairo-script-file.c39
-rw-r--r--util/cairo-script/cairo-script-objects.c22
-rw-r--r--util/cairo-script/cairo-script-private.h9
-rw-r--r--util/cairo-script/cairo-script-scanner.c52
4 files changed, 92 insertions, 30 deletions
diff --git a/util/cairo-script/cairo-script-file.c b/util/cairo-script/cairo-script-file.c
index 18b5b862..2a7296d2 100644
--- a/util/cairo-script/cairo-script-file.c
+++ b/util/cairo-script/cairo-script-file.c
@@ -37,6 +37,7 @@
#include <stdio.h>
#include <limits.h> /* INT_MAX */
#include <string.h>
+#include <zlib.h>
#define CHUNK_SIZE 32768
@@ -148,17 +149,43 @@ csi_file_new_from_string (csi_t *ctx,
csi_file_t *file;
file = _csi_slab_alloc (ctx, sizeof (csi_file_t));
- if (file == NULL)
+ if (_csi_unlikely (file == NULL))
return _csi_error (CAIRO_STATUS_NO_MEMORY);
file->base.type = CSI_OBJECT_TYPE_FILE;
file->base.ref = 1;
- file->type = BYTES;
- file->src = src; src->base.ref++;
- file->data = src->string;
- file->bp = file->data;
- file->rem = src->len;
+ if (src->deflate) {
+ uLongf len = src->deflate;
+ csi_object_t tmp_obj;
+ csi_string_t *tmp_str;
+ csi_status_t status;
+
+ status = csi_string_new (ctx, &tmp_obj, NULL, src->deflate);
+ if (_csi_unlikely (status))
+ return status;
+
+ tmp_str = tmp_obj.datum.string;
+ if (uncompress ((Bytef *) tmp_str->string, &len,
+ (Bytef *) src->string, src->len) != Z_OK)
+ {
+ csi_string_free (ctx, tmp_str);
+ _csi_slab_free (ctx, file, sizeof (csi_file_t));
+ return _csi_error (CAIRO_STATUS_NO_MEMORY);
+ }
+
+ file->type = BYTES;
+ file->src = tmp_str;
+ file->data = tmp_str->string;
+ file->bp = file->data;
+ file->rem = tmp_str->len;
+ } else {
+ file->type = BYTES;
+ file->src = src; src->base.ref++;
+ file->data = src->string;
+ file->bp = file->data;
+ file->rem = src->len;
+ }
obj->type = CSI_OBJECT_TYPE_FILE;
obj->datum.file = file;
diff --git a/util/cairo-script/cairo-script-objects.c b/util/cairo-script/cairo-script-objects.c
index 784376b2..9cc59c90 100644
--- a/util/cairo-script/cairo-script-objects.c
+++ b/util/cairo-script/cairo-script-objects.c
@@ -507,6 +507,7 @@ csi_string_new (csi_t *ctx,
string->string[len] = '\0';
}
string->len = len;
+ string->deflate = 0;
string->base.type = CSI_OBJECT_TYPE_STRING;
string->base.ref = 1;
@@ -518,6 +519,26 @@ csi_string_new (csi_t *ctx,
}
csi_status_t
+csi_string_deflate_new (csi_t *ctx,
+ csi_object_t *obj,
+ void *bytes,
+ int in_len,
+ int out_len)
+{
+ csi_status_t status;
+ csi_string_t *string;
+
+ status = csi_string_new (ctx, obj, bytes, in_len);
+ if (_csi_unlikely (status))
+ return status;
+
+ string = obj->datum.string;
+ string->deflate = out_len;
+
+ return CSI_STATUS_SUCCESS;
+}
+
+csi_status_t
csi_string_new_from_bytes (csi_t *ctx,
csi_object_t *obj,
char *bytes,
@@ -534,6 +555,7 @@ csi_string_new_from_bytes (csi_t *ctx,
string->string = bytes;
string->len = len;
+ string->deflate = 0;
string->base.type = CSI_OBJECT_TYPE_STRING;
string->base.ref = 1;
diff --git a/util/cairo-script/cairo-script-private.h b/util/cairo-script/cairo-script-private.h
index 996b40d7..54a840f2 100644
--- a/util/cairo-script/cairo-script-private.h
+++ b/util/cairo-script/cairo-script-private.h
@@ -386,6 +386,7 @@ struct _csi_matrix {
struct _csi_string {
csi_compound_object_t base;
csi_integer_t len;
+ csi_integer_t deflate;
char *string;
};
@@ -435,7 +436,6 @@ struct _csi_scanner {
csi_stack_t procedure_stack;
csi_object_t build_procedure;
- int string_p;
unsigned int accumulator;
unsigned int accumulator_count;
@@ -757,6 +757,13 @@ csi_string_new (csi_t *ctx,
int len);
csi_private csi_status_t
+csi_string_deflate_new (csi_t *ctx,
+ csi_object_t *obj,
+ void *bytes,
+ int in_len,
+ int out_len);
+
+csi_private csi_status_t
csi_string_new_from_bytes (csi_t *ctx,
csi_object_t *obj,
char *bytes,
diff --git a/util/cairo-script/cairo-script-scanner.c b/util/cairo-script/cairo-script-scanner.c
index b3217cd7..3cc39575 100644
--- a/util/cairo-script/cairo-script-scanner.c
+++ b/util/cairo-script/cairo-script-scanner.c
@@ -39,6 +39,7 @@
#include <stdio.h> /* EOF */
#include <string.h> /* memset */
#include <assert.h>
+#include <zlib.h>
#define DEBUG_SCAN 0
@@ -488,18 +489,6 @@ token_end (csi_t *ctx, csi_scanner_t *scan, csi_file_t *src)
}
static void
-string_inc_p (csi_scanner_t *scan)
-{
- scan->string_p++;
-}
-
-static int
-string_dec_p (csi_scanner_t *scan)
-{
- return --scan->string_p == 0;
-}
-
-static void
string_add (csi_t *ctx, csi_scanner_t *scan, int c)
{
buffer_check (ctx, scan, 1);
@@ -616,7 +605,7 @@ base85_add (csi_t *ctx, csi_scanner_t *scan, int c)
}
static void
-base85_end (csi_t *ctx, csi_scanner_t *scan)
+base85_end (csi_t *ctx, csi_scanner_t *scan, cairo_bool_t deflate)
{
csi_object_t obj;
cairo_status_t status;
@@ -647,12 +636,24 @@ base85_end (csi_t *ctx, csi_scanner_t *scan)
break;
}
- status = csi_string_new (ctx,
- &obj,
- scan->buffer.base,
- scan->buffer.ptr - scan->buffer.base);
- if (_csi_unlikely (status))
- longjmp (scan->jmpbuf, status);
+ if (deflate) {
+ uLongf len = *(uint32_t *) scan->buffer.base;
+ Bytef *source = (Bytef *) (scan->buffer.base + sizeof (uint32_t));
+
+ status = csi_string_deflate_new (ctx, &obj,
+ source,
+ (Bytef *) scan->buffer.ptr - source,
+ len);
+ if (_csi_unlikely (status))
+ longjmp (scan->jmpbuf, status);
+ } else {
+ status = csi_string_new (ctx,
+ &obj,
+ scan->buffer.base,
+ scan->buffer.ptr - scan->buffer.base);
+ if (_csi_unlikely (status))
+ longjmp (scan->jmpbuf, status);
+ }
if (scan->build_procedure.type != CSI_OBJECT_TYPE_NULL)
status = csi_array_append (ctx,
@@ -714,6 +715,8 @@ _scan_file (csi_t *ctx, csi_file_t *src)
uint32_t u32;
float f;
} u;
+ int deflate = 0;
+ int string_p;
scan_none:
while ((c = csi_file_getc (src)) != EOF) {
@@ -757,6 +760,8 @@ scan_none:
token_add_unchecked (scan, '<');
token_end (ctx, scan, src);
goto scan_none;
+ case '|':
+ deflate = 1;
case '~':
goto scan_base85;
default:
@@ -1000,7 +1005,7 @@ scan_comment:
scan_string:
buffer_reset (&scan->buffer);
- scan->string_p = 1;
+ string_p = 1;
while ((c = csi_file_getc (src)) != EOF) {
switch (c) {
case '\\': /* escape */
@@ -1086,12 +1091,12 @@ scan_string:
break;
case '(':
- string_inc_p (scan);
+ string_p++;
string_add (ctx, scan, c);
break;
case ')':
- if (string_dec_p (scan)) {
+ if (--string_p == 0) {
string_end (ctx, scan);
goto scan_none;
}
@@ -1166,7 +1171,8 @@ scan_base85:
return;
case '>':
- base85_end (ctx, scan);
+ base85_end (ctx, scan, deflate);
+ deflate = 0;
goto scan_none;
}
csi_file_putc (src, next);