summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2011-02-02 12:03:06 +0000
committerRobin Watts <robin.watts@artifex.com>2011-02-02 12:03:06 +0000
commit57d53977c81bc64fdfda8db3d2f098376a1f0bf1 (patch)
tree8ecdc148a298e37bcfd948a6cacbc57d226e757f
parentc2da983137c7b0d9eadfab5705e7cc1bc90f7ca1 (diff)
downloadmupdf-57d53977c81bc64fdfda8db3d2f098376a1f0bf1.tar.xz
Squeeze the flags and the lengths of CMap ranges into one unsigned short, thus saving 512K or so.
-rw-r--r--mupdf/cmapdump.c8
-rw-r--r--mupdf/mupdf.h6
-rw-r--r--mupdf/pdf_cmap.c65
3 files changed, 46 insertions, 33 deletions
diff --git a/mupdf/cmapdump.c b/mupdf/cmapdump.c
index b08b5628..411d1d11 100644
--- a/mupdf/cmapdump.c
+++ b/mupdf/cmapdump.c
@@ -111,14 +111,12 @@ main(int argc, char **argv)
if (cmap->rlen == 0)
{
fprintf(fo, "\t/* dummy entry for non-c99 compilers */\n");
- fprintf(fo, "\t{ 0x0, 0x0, PDF_CMAP_RANGE, 0 }\n");
+ fprintf(fo, "\t{ 0x0, %d, 0 }\n", PDF_CMAP_RANGE);
}
for (k = 0; k < cmap->rlen; k++)
{
- fprintf(fo, "\t{ 0x%04x, 0x%04x, %s %d },\n",
- cmap->ranges[k].low, cmap->ranges[k].high,
- flagtoname(cmap->ranges[k].flag),
- cmap->ranges[k].offset);
+ fprintf(fo, "\t{ 0x%04x, 0x%04x, %d },\n",
+ cmap->ranges[k].low, cmap->ranges[k].extentflags, cmap->ranges[k].offset);
}
fprintf(fo, "};\n\n");
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h
index 9b8c6111..7b782071 100644
--- a/mupdf/mupdf.h
+++ b/mupdf/mupdf.h
@@ -276,8 +276,10 @@ enum { PDF_CMAP_SINGLE, PDF_CMAP_RANGE, PDF_CMAP_TABLE, PDF_CMAP_MULTI };
struct pdf_range_s
{
unsigned short low;
- unsigned short high;
- unsigned short flag; /* single, range, table, multi */
+ /* Next, we pack 2 fields into the same unsigned short. Top 14 bits
+ * are the extent, bottom 2 bits are flags: single, range, table,
+ * multi */
+ unsigned short extentflags;
unsigned short offset; /* range-delta or table-index */
};
diff --git a/mupdf/pdf_cmap.c b/mupdf/pdf_cmap.c
index 3b9b9d80..aab6bd60 100644
--- a/mupdf/pdf_cmap.c
+++ b/mupdf/pdf_cmap.c
@@ -18,6 +18,12 @@
#include "fitz.h"
#include "mupdf.h"
+/* Macros for accessing the combined extentflags field */
+#define pdf_range_high(r) ((r)->low + ((r)->extentflags >> 2))
+#define pdf_range_flags(r) ((r)->extentflags & 3)
+#define pdf_range_set_high(r, h) ((r)->extentflags = (((r)->extentflags & 3) | ((h - (r)->low) << 2)))
+#define pdf_range_set_flags(r, f) ((r)->extentflags = (((r)->extentflags & ~3) | f))
+
/*
* Allocate, destroy and simple parameters.
*/
@@ -125,15 +131,15 @@ pdf_debugcmap(pdf_cmap *cmap)
for (i = 0; i < cmap->rlen; i++)
{
pdf_range *r = &cmap->ranges[i];
- printf("\t\t<%04x> <%04x> ", r->low, r->high);
- if (r->flag == PDF_CMAP_TABLE)
+ printf("\t\t<%04x> <%04x> ", r->low, pdf_range_high(r));
+ if (pdf_range_flags(r) == PDF_CMAP_TABLE)
{
printf("[ ");
- for (k = 0; k < r->high - r->low + 1; k++)
+ for (k = 0; k < pdf_range_high(r) - r->low + 1; k++)
printf("%d ", cmap->table[r->offset + k]);
printf("]\n");
}
- else if (r->flag == PDF_CMAP_MULTI)
+ else if (pdf_range_flags(r) == PDF_CMAP_MULTI)
{
printf("< ");
n = cmap->table[r->offset];
@@ -187,14 +193,21 @@ addtable(pdf_cmap *cmap, int value)
static void
addrange(pdf_cmap *cmap, int low, int high, int flag, int offset)
{
+ /* If the range is too large to be represented, split it */
+ if (high - low > 0x3fff)
+ {
+ addrange(cmap, low, low+0x3fff, flag, offset);
+ addrange(cmap, low+0x3fff, high, flag, offset+0x3fff);
+ return;
+ }
if (cmap->rlen + 1 > cmap->rcap)
{
cmap->rcap = cmap->rcap > 1 ? (cmap->rcap * 3) / 2 : 256;
cmap->ranges = fz_realloc(cmap->ranges, cmap->rcap, sizeof(pdf_range));
}
cmap->ranges[cmap->rlen].low = low;
- cmap->ranges[cmap->rlen].high = high;
- cmap->ranges[cmap->rlen].flag = flag;
+ pdf_range_set_high(&cmap->ranges[cmap->rlen], high);
+ pdf_range_set_flags(&cmap->ranges[cmap->rlen], flag);
cmap->ranges[cmap->rlen].offset = offset;
cmap->rlen ++;
}
@@ -277,33 +290,33 @@ pdf_sortcmap(pdf_cmap *cmap)
while (b < cmap->ranges + cmap->rlen)
{
/* ignore one-to-many mappings */
- if (b->flag == PDF_CMAP_MULTI)
+ if (pdf_range_flags(b) == PDF_CMAP_MULTI)
{
*(++a) = *b;
}
/* input contiguous */
- else if (a->high + 1 == b->low)
+ else if (pdf_range_high(a) + 1 == b->low)
{
/* output contiguous */
- if (a->high - a->low + a->offset + 1 == b->offset)
+ if (pdf_range_high(a) - a->low + a->offset + 1 == b->offset)
{
/* SR -> R and SS -> R and RR -> R and RS -> R */
- if (a->flag == PDF_CMAP_SINGLE || a->flag == PDF_CMAP_RANGE)
+ if (pdf_range_flags(a) == PDF_CMAP_SINGLE || pdf_range_flags(a) == PDF_CMAP_RANGE)
{
- a->flag = PDF_CMAP_RANGE;
- a->high = b->high;
+ pdf_range_set_flags(a, PDF_CMAP_RANGE);
+ pdf_range_set_high(a, pdf_range_high(b));
}
/* LS -> L */
- else if (a->flag == PDF_CMAP_TABLE && b->flag == PDF_CMAP_SINGLE)
+ else if (pdf_range_flags(a) == PDF_CMAP_TABLE && pdf_range_flags(b) == PDF_CMAP_SINGLE)
{
- a->high = b->high;
+ pdf_range_set_high(a, pdf_range_high(b));
addtable(cmap, b->offset);
}
/* LR -> LR */
- else if (a->flag == PDF_CMAP_TABLE && b->flag == PDF_CMAP_RANGE)
+ else if (pdf_range_flags(a) == PDF_CMAP_TABLE && pdf_range_flags(b) == PDF_CMAP_RANGE)
{
*(++a) = *b;
}
@@ -319,19 +332,19 @@ pdf_sortcmap(pdf_cmap *cmap)
else
{
/* SS -> L */
- if (a->flag == PDF_CMAP_SINGLE && b->flag == PDF_CMAP_SINGLE)
+ if (pdf_range_flags(a) == PDF_CMAP_SINGLE && pdf_range_flags(b) == PDF_CMAP_SINGLE)
{
- a->flag = PDF_CMAP_TABLE;
- a->high = b->high;
+ pdf_range_set_flags(a, PDF_CMAP_TABLE);
+ pdf_range_set_high(a, pdf_range_high(b));
addtable(cmap, a->offset);
addtable(cmap, b->offset);
a->offset = cmap->tlen - 2;
}
/* LS -> L */
- else if (a->flag == PDF_CMAP_TABLE && b->flag == PDF_CMAP_SINGLE)
+ else if (pdf_range_flags(a) == PDF_CMAP_TABLE && pdf_range_flags(b) == PDF_CMAP_SINGLE)
{
- a->high = b->high;
+ pdf_range_set_high(a, pdf_range_high(b));
addtable(cmap, b->offset);
}
@@ -368,14 +381,14 @@ pdf_lookupcmap(pdf_cmap *cmap, int cpt)
m = (l + r) >> 1;
if (cpt < cmap->ranges[m].low)
r = m - 1;
- else if (cpt > cmap->ranges[m].high)
+ else if (cpt > pdf_range_high(&cmap->ranges[m]))
l = m + 1;
else
{
int i = cpt - cmap->ranges[m].low + cmap->ranges[m].offset;
- if (cmap->ranges[m].flag == PDF_CMAP_TABLE)
+ if (pdf_range_flags(&cmap->ranges[m]) == PDF_CMAP_TABLE)
return cmap->table[i];
- if (cmap->ranges[m].flag == PDF_CMAP_MULTI)
+ if (pdf_range_flags(&cmap->ranges[m]) == PDF_CMAP_MULTI)
return cmap->table[cmap->ranges[m].offset + 1]; /* first char */
return i;
}
@@ -400,17 +413,17 @@ pdf_lookupcmapfull(pdf_cmap *cmap, int cpt, int *out)
m = (l + r) >> 1;
if (cpt < cmap->ranges[m].low)
r = m - 1;
- else if (cpt > cmap->ranges[m].high)
+ else if (cpt > pdf_range_high(&cmap->ranges[m]))
l = m + 1;
else
{
k = cpt - cmap->ranges[m].low + cmap->ranges[m].offset;
- if (cmap->ranges[m].flag == PDF_CMAP_TABLE)
+ if (pdf_range_flags(&cmap->ranges[m]) == PDF_CMAP_TABLE)
{
out[0] = cmap->table[k];
return 1;
}
- else if (cmap->ranges[m].flag == PDF_CMAP_MULTI)
+ else if (pdf_range_flags(&cmap->ranges[m]) == PDF_CMAP_MULTI)
{
n = cmap->ranges[m].offset;
for (i = 0; i < cmap->table[n]; i++)