summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@sun.com>2008-08-21 19:58:06 -0700
committerAlan Coopersmith <alan.coopersmith@sun.com>2008-08-21 19:58:06 -0700
commit5d5587a36453d731e9a7353a98fa391dbb51b57d (patch)
tree6466f3105d798f3775114e80361b82800a49bf79
parent624b7a507cdea25cec0728b4679610df3fb3097c (diff)
Add support for bzip2 bitmap font compression
Code originally written for Solaris Xsun in 2003, ported now to current Xorg <http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4819077>
-rw-r--r--configure.ac16
-rw-r--r--include/X11/fonts/bufio.h3
-rw-r--r--src/bitmap/bitmapfunc.c51
-rw-r--r--src/bitmap/bitscale.c21
-rw-r--r--src/fontfile/Makefile.am4
-rw-r--r--src/fontfile/bunzip2.c179
-rw-r--r--src/fontfile/fileio.c9
7 files changed, 261 insertions, 22 deletions
diff --git a/configure.ac b/configure.ac
index fe55e41..b4a9505 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,6 +128,19 @@ fi
AC_DEFINE(X_GZIP_FONT_COMPRESSION,1,[Support gzip for bitmap fonts])
X_GZIP_FONT_COMPRESSION=1
AC_SUBST(X_GZIP_FONT_COMPRESSION)
+AC_CHECK_LIB(z, gzopen, [Z_LIBS=-lz], AC_MSG_ERROR([*** zlib is required]))
+
+AC_ARG_WITH(bzip2,
+ AS_HELP_STRING([--with-bzip2],
+ [Support bzip2 compressed bitmap fonts]),
+ [], [with_bzip2=no])
+if test "x$with_bzip2" = xyes; then
+ AC_CHECK_LIB(bz2, BZ2_bzopen, [Z_LIBS="$Z_LIBS -lbz2"],
+ AC_MSG_ERROR([*** libbz2 is required for bzip2 support]))
+ AC_DEFINE(X_BZIP2_FONT_COMPRESSION,1,[Support bzip2 for bitmap fonts])
+fi
+AM_CONDITIONAL(X_BZIP2_FONT_COMPRESSION, [test "x$with_bzip2" = xyes ])
+AC_SUBST(Z_LIBS)
AC_ARG_ENABLE(builtins, [ --disable-builtins ], [XFONT_BUILTINS=$enableval], [XFONT_BUILTINS=yes])
AM_CONDITIONAL(XFONT_BUILTINS, [test "x$XFONT_BUILTINS" = xyes ])
@@ -200,9 +213,6 @@ if test "x$XFONT_FC" = xyes; then
AC_DEFINE(XFONT_FC,1,[Support the X Font Services Protocol])
fi
-AC_CHECK_LIB(z, gzopen, [Z_LIBS=-lz
-AC_SUBST(Z_LIBS)], AC_MSG_ERROR([*** zlib is required]))
-
AC_CHECK_LIB(m, hypot, [MATH_LIBS=-lm
AC_SUBST(MATH_LIBS)], AC_MSG_ERROR([*** libm is required]))
diff --git a/include/X11/fonts/bufio.h b/include/X11/fonts/bufio.h
index b31b813..b5977b1 100644
--- a/include/X11/fonts/bufio.h
+++ b/include/X11/fonts/bufio.h
@@ -71,6 +71,9 @@ extern BufFilePtr BufFilePushCompressed ( BufFilePtr );
#ifdef X_GZIP_FONT_COMPRESSION
extern BufFilePtr BufFilePushZIP ( BufFilePtr );
#endif
+#ifdef X_BZIP2_FONT_COMPRESSION
+extern BufFilePtr BufFilePushBZIP2 ( BufFilePtr );
+#endif
extern int BufFileClose ( BufFilePtr, int );
extern int BufFileRead ( BufFilePtr, char*, int );
extern int BufFileWrite ( BufFilePtr, char*, int );
diff --git a/src/bitmap/bitmapfunc.c b/src/bitmap/bitmapfunc.c
index 81fc5c0..e980dfb 100644
--- a/src/bitmap/bitmapfunc.c
+++ b/src/bitmap/bitmapfunc.c
@@ -77,23 +77,32 @@ static BitmapFileFunctionsRec readers[] = {
#if XFONT_PCFFORMAT
{ pcfReadFont, pcfReadFontInfo} ,
{ pcfReadFont, pcfReadFontInfo} ,
-#ifdef X_GZIP_FONT_COMPRESSION
+# ifdef X_GZIP_FONT_COMPRESSION
{ pcfReadFont, pcfReadFontInfo} ,
-#endif
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { pcfReadFont, pcfReadFontInfo} ,
+# endif
#endif
#if XFONT_SNFFORMAT
{ snfReadFont, snfReadFontInfo},
{ snfReadFont, snfReadFontInfo},
-#ifdef X_GZIP_FONT_COMPRESSION
+# ifdef X_GZIP_FONT_COMPRESSION
{ snfReadFont, snfReadFontInfo} ,
-#endif
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { snfReadFont, snfReadFontInfo} ,
+# endif
#endif
#if XFONT_BDFFORMAT
{ bdfReadFont, bdfReadFontInfo} ,
{ bdfReadFont, bdfReadFontInfo} ,
-#ifdef X_GZIP_FONT_COMPRESSION
+# ifdef X_GZIP_FONT_COMPRESSION
{ bdfReadFont, bdfReadFontInfo} ,
-#endif
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { bdfReadFont, bdfReadFontInfo} ,
+# endif
#endif
#if XFONT_PCFFORMAT
{ pmfReadFont, pcfReadFontInfo} ,
@@ -177,12 +186,18 @@ static FontRendererRec renderers[] = {
{ ".pcf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
CAPABILITIES },
-#ifdef X_GZIP_FONT_COMPRESSION
+# ifdef X_GZIP_FONT_COMPRESSION
{ ".pcf.gz", 7,
- BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapOpenBitmap, BitmapOpenScalable,
BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
CAPABILITIES },
-#endif
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { ".pcf.bz2", 8,
+ BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
#endif
#if XFONT_SNFFORMAT
{ ".snf", 4, BitmapOpenBitmap, BitmapOpenScalable,
@@ -191,11 +206,16 @@ static FontRendererRec renderers[] = {
{ ".snf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
CAPABILITIES },
-#ifdef X_GZIP_FONT_COMPRESSION
+# ifdef X_GZIP_FONT_COMPRESSION
{ ".snf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable,
BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
CAPABILITIES },
-#endif
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { ".snf.bz2", 8, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
#endif
#if XFONT_BDFFORMAT
{ ".bdf", 4, BitmapOpenBitmap, BitmapOpenScalable,
@@ -204,11 +224,16 @@ static FontRendererRec renderers[] = {
{ ".bdf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
CAPABILITIES },
-#ifdef X_GZIP_FONT_COMPRESSION
+# ifdef X_GZIP_FONT_COMPRESSION
{ ".bdf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable,
BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
CAPABILITIES },
-#endif
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { ".bdf.bz2", 8, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
#endif
#if XFONT_PCFFORMAT
{ ".pmf", 4, BitmapOpenBitmap, BitmapOpenScalable,
diff --git a/src/bitmap/bitscale.c b/src/bitmap/bitscale.c
index 958dc2d..ffdbe1d 100644
--- a/src/bitmap/bitscale.c
+++ b/src/bitmap/bitscale.c
@@ -108,23 +108,32 @@ static const ScaleFunc scale[] =
#if XFONT_PCFFORMAT
BitmapScaleBitmaps,
BitmapScaleBitmaps,
-#ifdef X_GZIP_FONT_COMPRESSION
+# ifdef X_GZIP_FONT_COMPRESSION
BitmapScaleBitmaps,
-#endif
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ BitmapScaleBitmaps,
+# endif
#endif
#if XFONT_SNFFORMAT
BitmapScaleBitmaps,
BitmapScaleBitmaps,
-#ifdef X_GZIP_FONT_COMPRESSION
+# ifdef X_GZIP_FONT_COMPRESSION
BitmapScaleBitmaps,
-#endif
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ BitmapScaleBitmaps,
+# endif
#endif
#if XFONT_BDFFORMAT
BitmapScaleBitmaps,
BitmapScaleBitmaps,
-#ifdef X_GZIP_FONT_COMPRESSION
+# ifdef X_GZIP_FONT_COMPRESSION
BitmapScaleBitmaps,
-#endif
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ BitmapScaleBitmaps,
+# endif
#endif
#if XFONT_PCFFORMAT
PrinterScaleBitmaps,
diff --git a/src/fontfile/Makefile.am b/src/fontfile/Makefile.am
index 8c361bd..8418269 100644
--- a/src/fontfile/Makefile.am
+++ b/src/fontfile/Makefile.am
@@ -28,3 +28,7 @@ libfontfile_la_SOURCES = \
register.c \
renderers.c \
catalogue.c
+
+if X_BZIP2_FONT_COMPRESSION
+libfontfile_la_SOURCES += bunzip2.c
+endif
diff --git a/src/fontfile/bunzip2.c b/src/fontfile/bunzip2.c
new file mode 100644
index 0000000..9964de6
--- /dev/null
+++ b/src/fontfile/bunzip2.c
@@ -0,0 +1,179 @@
+/* Based on src/fontfile/gunzip.c
+ written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996.
+ intended for inclusion in X11 public releases. */
+
+/* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ */
+
+
+#include "config.h"
+
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/bufio.h>
+#include <bzlib.h>
+
+typedef struct _xzip_buf {
+ bz_stream z;
+ int zstat;
+ BufChar b[BUFFILESIZE];
+ BufChar b_in[BUFFILESIZE];
+ BufFilePtr f;
+} xzip_buf;
+
+static int BufBzip2FileClose ( BufFilePtr f, int flag );
+static int BufBzip2FileFill ( BufFilePtr f );
+static int BufBzip2FileSkip ( BufFilePtr f, int c );
+
+_X_HIDDEN BufFilePtr
+BufFilePushBZIP2 (BufFilePtr f)
+{
+ xzip_buf *x;
+
+ x = (xzip_buf *) xalloc (sizeof (xzip_buf));
+ if (!x) return NULL;
+
+ bzero(&(x->z), sizeof(bz_stream));
+ x->f = f;
+
+ x->zstat = BZ2_bzDecompressInit(&(x->z),
+ 0, /* verbosity: 0 silent, 4 max */
+ 0); /* 0: go faster, 1: use less memory */
+ if (x->zstat != BZ_OK) {
+ xfree(x);
+ return NULL;
+ }
+
+ /* now that the history buffer is allocated, we provide the data buffer */
+ x->z.next_out = (char *) x->b;
+ x->z.avail_out = BUFFILESIZE;
+ x->z.next_in = (char *) x->b_in;
+ x->z.avail_in = 0;
+
+ return BufFileCreate((char *)x,
+ BufBzip2FileFill,
+ NULL,
+ BufBzip2FileSkip,
+ BufBzip2FileClose);
+}
+
+static int
+BufBzip2FileClose(BufFilePtr f, int flag)
+{
+ xzip_buf *x = (xzip_buf *)f->private;
+ BZ2_bzDecompressEnd (&(x->z));
+ BufFileClose (x->f, flag);
+ xfree (x);
+ return 1;
+}
+
+/* here's the real work.
+ -- we need to put stuff in f.buffer, update f.left and f.bufp,
+ then return the first byte (or BUFFILEEOF).
+ -- to do this, we need to get stuff into avail_in, and next_in,
+ and call BZ2_bzDecompress appropriately.
+ -- we may also need to add CRC maintenance - if BZ2_bzDecompress tells us
+ BZ_STREAM_END, we then have 4bytes CRC and 4bytes length...
+*/
+static int
+BufBzip2FileFill (BufFilePtr f)
+{
+ xzip_buf *x = (xzip_buf *)f->private;
+
+ /* we only get called when left == 0... */
+ /* but just in case, deal */
+ if (f->left >= 0) {
+ f->left--;
+ return *(f->bufp++);
+ }
+ /* did we run out last time? */
+ switch (x->zstat) {
+ case BZ_OK:
+ break;
+ case BZ_STREAM_END:
+ case BZ_DATA_ERROR:
+ case BZ_DATA_ERROR_MAGIC:
+ f->left = 0;
+ return BUFFILEEOF;
+ default:
+ return BUFFILEEOF;
+ }
+ /* now we work to consume what we can */
+ /* let libbz2 know what we can handle */
+ x->z.next_out = (char *) x->b;
+ x->z.avail_out = BUFFILESIZE;
+
+ /* and try to consume all of it */
+ while (x->z.avail_out > 0) {
+ /* if we don't have anything to work from... */
+ if (x->z.avail_in == 0) {
+ /* ... fill the z buf from underlying file */
+ int i, c;
+ for (i = 0; i < sizeof(x->b_in); i++) {
+ c = BufFileGet(x->f);
+ if (c == BUFFILEEOF) break;
+ x->b_in[i] = c;
+ }
+ x->z.avail_in += i;
+ x->z.next_in = (char *) x->b_in;
+ }
+ /* so now we have some output space and some input data */
+ x->zstat = BZ2_bzDecompress(&(x->z));
+ /* the inflation output happens in the f buffer directly... */
+ if (x->zstat == BZ_STREAM_END) {
+ /* deal with EOF, crc */
+ break;
+ }
+ if (x->zstat != BZ_OK) {
+ break;
+ }
+ }
+ f->bufp = x->b;
+ f->left = BUFFILESIZE - x->z.avail_out;
+
+ if (f->left >= 0) {
+ f->left--;
+ return *(f->bufp++);
+ } else {
+ return BUFFILEEOF;
+ }
+}
+
+/* there should be a BufCommonSkip... */
+static int
+BufBzip2FileSkip (BufFilePtr f, int c)
+{
+ /* BufFileRawSkip returns the count unchanged.
+ BufCompressedSkip returns 0.
+ That means it probably never gets called... */
+ int retval = c;
+ while(c--) {
+ int get = BufFileGet(f);
+ if (get == BUFFILEEOF) return get;
+ }
+ return retval;
+}
diff --git a/src/fontfile/fileio.c b/src/fontfile/fileio.c
index a3f9464..3733148 100644
--- a/src/fontfile/fileio.c
+++ b/src/fontfile/fileio.c
@@ -78,6 +78,15 @@ FontFileOpen (const char *name)
}
raw = cooked;
#endif
+#ifdef X_BZIP2_FONT_COMPRESSION
+ } else if (len > 4 && !strcmp (name + len - 4, ".bz2")) {
+ cooked = BufFilePushBZIP2 (raw);
+ if (!cooked) {
+ BufFileClose (raw, TRUE);
+ return 0;
+ }
+ raw = cooked;
+#endif
}
return (FontFilePtr) raw;
}