diff options
Diffstat (limited to 'util/cairo-script')
-rw-r--r-- | util/cairo-script/cairo-script-file.c | 39 | ||||
-rw-r--r-- | util/cairo-script/cairo-script-objects.c | 22 | ||||
-rw-r--r-- | util/cairo-script/cairo-script-private.h | 9 | ||||
-rw-r--r-- | util/cairo-script/cairo-script-scanner.c | 52 |
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); |