summaryrefslogtreecommitdiff
path: root/util/cairo-script/cairo-script-scanner.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/cairo-script/cairo-script-scanner.c')
-rw-r--r--util/cairo-script/cairo-script-scanner.c184
1 files changed, 142 insertions, 42 deletions
diff --git a/util/cairo-script/cairo-script-scanner.c b/util/cairo-script/cairo-script-scanner.c
index eeec6861f..4254aa01e 100644
--- a/util/cairo-script/cairo-script-scanner.c
+++ b/util/cairo-script/cairo-script-scanner.c
@@ -38,10 +38,15 @@
#include <math.h> /* pow */
#include <stdio.h> /* EOF */
#include <stdint.h> /* for {INT,UINT}*_{MIN,MAX} */
+#include <stdlib.h> /* malloc/free */
#include <string.h> /* memset */
#include <assert.h>
#include <zlib.h>
+#if HAVE_LZO
+#include <lzo/lzo2a.h>
+#endif
+
#define DEBUG_SCAN 0
#if WORDS_BIGENDIAN
@@ -124,7 +129,8 @@ fprintf_obj (FILE *stream, csi_t *ctx, const csi_object_t *obj)
obj->datum.matrix->matrix.y0);
break;
case CSI_OBJECT_TYPE_STRING:
- fprintf (stream, "string: len=%ld\n", obj->datum.string->len);
+ fprintf (stream, "string: len=%ld, defate=%ld, method=%d\n",
+ obj->datum.string->len, obj->datum.string->deflate, obj->datum.string->method);
break;
/* cairo */
@@ -799,6 +805,7 @@ string_read (csi_t *ctx,
uint32_t u32;
scan_read (scan, src, &u32, 4);
obj->datum.string->deflate = be32 (u32);
+ obj->datum.string->method = compressed;
}
if (_csi_likely (len))
@@ -994,8 +1001,13 @@ scan_none:
obj.type &= ~CSI_OBJECT_ATTR_EXECUTABLE;
break;
+#define STRING_LZO 154
+ case STRING_LZO:
+ scan_read (scan, src, &u.u32, 4);
+ string_read (ctx, scan, src, be32 (u.u32), LZO, &obj);
+ break;
+
/* unassigned */
- case 154:
case 155:
case 156:
case 157:
@@ -1569,51 +1581,139 @@ _translate_string (csi_t *ctx,
uint16_t u16;
uint32_t u32;
} u;
- int len;
+ void *buf;
+ unsigned long hdr_len, buf_len, deflate;
+ int method;
+
+ buf = string->string;
+ buf_len = string->len;
+ deflate = string->deflate;
+ method = string->method;
+
+#if HAVE_LZO
+ if (method == NONE && buf_len > 16) {
+ unsigned long mem_len = 2*string->len > LZO2A_999_MEM_COMPRESS ? 2*string->len : LZO2A_999_MEM_COMPRESS;
+ void *mem = malloc (mem_len);
+ void *work = malloc(LZO2A_999_MEM_COMPRESS);
+
+ if (lzo2a_999_compress ((lzo_bytep) buf, buf_len,
+ (lzo_bytep) mem, &mem_len,
+ work) == 0 &&
+ 8+2*mem_len < buf_len)
+ {
+ method = LZO;
+ deflate = buf_len;
+ buf_len = mem_len;
+ buf = mem;
+ }
+ else
+ {
+ free (mem);
+ }
-#if WORDS_BIGENDIAN
- if (string->len <= UINT8_MAX) {
- hdr = STRING_1;
- u.u8 = string->len;
- len = 1;
- } else if (string->len <= UINT16_MAX) {
- hdr = STRING_2_MSB;
- u.u16 = string->len;
- len = 2;
- } else {
- hdr = STRING_4_MSB;
- u.u32 = string->len;
- len = 4;
+ free (work);
}
-#else
- if (string->len <= UINT8_MAX) {
- hdr = STRING_1;
- u.u8 = string->len;
- len = 1;
- } else if (string->len <= UINT16_MAX) {
- hdr = STRING_2_LSB;
- u.u16 = string->len;
- len = 2;
- } else {
- hdr = STRING_4_LSB;
- u.u32 = string->len;
- len = 4;
+#if HAVE_ZLIB
+ if (method == ZLIB) {
+ buf_len = string->deflate;
+ buf = malloc (string->deflate);
+ if (uncompress ((Bytef *) buf, &buf_len,
+ (Bytef *) string->string, string->len) == Z_OK)
+ {
+ if (buf_len <= 8 + 2*string->len) {
+ method = NONE;
+ deflate = 0;
+ } else {
+ unsigned long mem_len = 2*string->deflate;
+ void *mem = malloc (mem_len);
+ void *work = malloc(LZO2A_999_MEM_COMPRESS);
+
+ if (lzo2a_999_compress ((lzo_bytep) buf, buf_len,
+ (lzo_bytep) mem, &mem_len,
+ work) == 0)
+ {
+ if (8 + mem_len > buf_len) {
+ method = NONE;
+ deflate = 0;
+ } else {
+ free (buf);
+ method = LZO;
+ deflate = buf_len;
+ buf_len = mem_len;
+ buf = mem;
+ assert(deflate);
+ }
+ }
+ else
+ {
+ free (buf);
+ buf = string->string;
+ buf_len = string->len;
+ }
+
+ free (work);
+ }
+ }
+ else
+ {
+ free (buf);
+ buf = string->string;
+ buf_len = string->len;
+ }
}
#endif
- if (string->deflate)
- hdr |= STRING_DEFLATE;
-
- closure->write_func (closure->closure,
- (unsigned char *) &hdr, 1);
- closure->write_func (closure->closure,
- (unsigned char *) &u, len);
- if (string->deflate) {
- uint32_t u32 = to_be32 (string->deflate);
- closure->write_func (closure->closure,
- (unsigned char *) &u32, 4);
+#endif
+
+ if (method == LZO) {
+ hdr = STRING_LZO;
+ u.u32 = to_be32 (buf_len);
+ hdr_len = 4;
+ } else {
+#if WORDS_BIGENDIAN
+ if (buf_len <= UINT8_MAX) {
+ hdr = STRING_1;
+ u.u8 = buf_len;
+ hdr_len = 1;
+ } else if (buf_len <= UINT16_MAX) {
+ hdr = STRING_2_MSB;
+ u.u16 = buf_len;
+ hdr_len = 2;
+ } else {
+ hdr = STRING_4_MSB;
+ u.u32 = buf_len;
+ hdr_len = 4;
+ }
+#else
+ if (buf_len <= UINT8_MAX) {
+ hdr = STRING_1;
+ u.u8 = buf_len;
+ hdr_len = 1;
+ } else if (buf_len <= UINT16_MAX) {
+ hdr = STRING_2_LSB;
+ u.u16 = buf_len;
+ hdr_len = 2;
+ } else {
+ hdr = STRING_4_LSB;
+ u.u32 = buf_len;
+ hdr_len = 4;
+ }
+#endif
+ if (deflate) {
+ assert (method == ZLIB);
+ hdr |= STRING_DEFLATE;
+ }
}
- closure->write_func (closure->closure,
- (unsigned char *) string->string, string->len);
+
+ closure->write_func (closure->closure, (unsigned char *) &hdr, 1);
+ closure->write_func (closure->closure, (unsigned char *) &u, hdr_len);
+ if (deflate) {
+ uint32_t u32 = to_be32 (deflate);
+ closure->write_func (closure->closure, (unsigned char *) &u32, 4);
+ }
+ closure->write_func (closure->closure, (unsigned char *) buf, buf_len);
+
+ if (buf != string->string)
+ free (buf);
return CSI_STATUS_SUCCESS;
}