Commit dc240524ff31891a442225430b28e9620c1fa89f

Werner Lemberg 2013-08-29T17:53:24

[gzip] New function `FT_Gzip_Uncompress'. This is modeled after zlib's `uncompress' function. We need this for WOFF support. * include/freetype/ftgzip.h, src/gzip/ftgzip.c (FT_Gzip_Uncompress): New function. * src/gzip/rules.mk: Rewrite to better reflect dependencies.

diff --git a/ChangeLog b/ChangeLog
index ec43cca..8508ff6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2013-08-28  Werner Lemberg  <wl@gnu.org>
 
+	[gzip] New function `FT_Gzip_Uncompress'.
+
+	This is modeled after zlib's `uncompress' function.  We need this
+	for WOFF support.
+
+	* include/freetype/ftgzip.h, src/gzip/ftgzip.c (FT_Gzip_Uncompress):
+	New function.
+
+	* src/gzip/rules.mk: Rewrite to better reflect dependencies.
+
+2013-08-28  Werner Lemberg  <wl@gnu.org>
+
 	[autofit] Fix `make multi' compilation.
 
 	* src/autofit/afblue.cin, src/autofit/afblue.c: Don't include
diff --git a/include/freetype/ftgzip.h b/include/freetype/ftgzip.h
index acbc4f0..78e7269 100644
--- a/include/freetype/ftgzip.h
+++ b/include/freetype/ftgzip.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Gzip-compressed stream support.                                      */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2004, 2006 by                                    */
+/*  Copyright 2002-2004, 2006, 2013 by                                     */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -91,6 +91,53 @@ FT_BEGIN_HEADER
   FT_Stream_OpenGzip( FT_Stream  stream,
                       FT_Stream  source );
 
+
+ /************************************************************************
+  *
+  * @function:
+  *   FT_Gzip_Uncompress
+  *
+  * @description:
+  *   Decompress a zipped input buffer into an output buffer.  This function
+  *   is modeled after zlib's `uncompress' function.
+  *
+  * @input:
+  *   memory ::
+  *     A FreeType memory handle.
+  *
+  *   input ::
+  *     The input buffer.
+  *
+  *   input_len ::
+  *     The length of the input buffer.
+  *
+  * @output:
+  *   output::
+  *     The output buffer.
+  *
+  * @inout:
+  *   output_len ::
+  *     Before calling the function, this is the the total size of the
+  *     output buffer, which must be large enough to hold the entire
+  *     uncompressed data (so the size of the uncompressed data must be
+  *     known in advance).  After calling the function, `output_len' is the
+  *     size of the used data in `output'.
+  *
+  * @return:
+  *   FreeType error code.  0~means success.
+  *
+  * @note:
+  *   This function may return `FT_Err_Unimplemented_Feature' if your build
+  *   of FreeType was not compiled with zlib support.
+  */
+  FT_EXPORT( FT_Error )
+  FT_Gzip_Uncompress( FT_Memory       memory,
+                      FT_Byte*        output,
+                      FT_ULong*       output_len,
+                      const FT_Byte*  input,
+                      FT_ULong        input_len );
+
+
  /* */
 
 
diff --git a/src/gzip/ftgzip.c b/src/gzip/ftgzip.c
index f267558..2c60b6c 100644
--- a/src/gzip/ftgzip.c
+++ b/src/gzip/ftgzip.c
@@ -596,6 +596,8 @@
   }
 
 
+  /* documentation is in ftgzip.h */
+
   FT_EXPORT_DEF( FT_Error )
   FT_Stream_OpenGzip( FT_Stream  stream,
                       FT_Stream  source )
@@ -684,7 +686,64 @@
     return error;
   }
 
-#else  /* !FT_CONFIG_OPTION_USE_ZLIB */
+
+  /* documentation is in ftgzip.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Gzip_Uncompress( FT_Memory       memory,
+                      FT_Byte*        output,
+                      FT_ULong*       output_len,
+                      const FT_Byte*  input,
+                      FT_ULong        input_len )
+  {
+    z_stream  stream;
+    int       err;
+
+
+    /* this function is modeled after zlib's `uncompress' function */
+
+    stream.next_in  = (Bytef*)input;
+    stream.avail_in = (uInt)input_len;
+
+    stream.next_out  = output;
+    stream.avail_out = (uInt)*output_len;
+
+    stream.zalloc = (alloc_func)ft_gzip_alloc;
+    stream.zfree  = (free_func) ft_gzip_free;
+    stream.opaque = memory;
+
+    err = inflateInit2( &stream, MAX_WBITS );
+    if ( err != Z_OK )
+      return FT_THROW( Invalid_Argument );
+
+    err = inflate( &stream, Z_FINISH );
+    if ( err != Z_STREAM_END )
+    {
+      inflateEnd( &stream );
+      if ( err == Z_OK )
+        err = Z_BUF_ERROR;
+    }
+    else
+    {
+      *output_len = stream.total_out;
+
+      err = inflateEnd( &stream );
+    }
+
+    if ( err == Z_MEM_ERROR )
+      return FT_THROW( Out_Of_Memory );
+
+    if ( err == Z_BUF_ERROR )
+      return FT_THROW( Array_Too_Large );
+
+    if ( err == Z_DATA_ERROR )
+      return FT_THROW( Invalid_Table );
+
+    return FT_Err_Ok;
+  }
+
+
+#else /* !FT_CONFIG_OPTION_USE_ZLIB */
 
   FT_EXPORT_DEF( FT_Error )
   FT_Stream_OpenGzip( FT_Stream  stream,
@@ -696,6 +755,23 @@
     return FT_THROW( Unimplemented_Feature );
   }
 
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Gzip_Uncompress( FT_Memory       memory,
+                      FT_Byte*        output,
+                      FT_ULong*       output_len,
+                      const FT_Byte*  input,
+                      FT_ULong        input_len )
+  {
+    FT_UNUSED( memory );
+    FT_UNUSED( output );
+    FT_UNUSED( output_len );
+    FT_UNUSED( input );
+    FT_UNUSED( input_len );
+
+    return FT_THROW( Unimplemented_Feature );
+  }
+
 #endif /* !FT_CONFIG_OPTION_USE_ZLIB */
 
 
diff --git a/src/gzip/rules.mk b/src/gzip/rules.mk
index d2a43a6..37cd991 100644
--- a/src/gzip/rules.mk
+++ b/src/gzip/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2002, 2003 by
+# Copyright 2002, 2003, 2013 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -27,49 +27,52 @@ else
 endif
 
 
-# gzip support sources (i.e., C files)
+# gzip support sources
 #
-GZIP_DRV_SRC := $(GZIP_DIR)/ftgzip.c
-
-# gzip support headers
+# All source and header files get loaded by `ftgzip.c' only if SYTEM_ZLIB is
+# not defined (regardless whether we have a `single' or a `multi' build).
+# However, it doesn't harm if we add everything as a dependency
+# unconditionally.
 #
-GZIP_DRV_H :=
+GZIP_DRV_SRCS := $(GZIP_DIR)/adler32.c  \
+                 $(GZIP_DIR)/infblock.c \
+                 $(GZIP_DIR)/infblock.h \
+                 $(GZIP_DIR)/infcodes.c \
+                 $(GZIP_DIR)/infcodes.h \
+                 $(GZIP_DIR)/inffixed.h \
+                 $(GZIP_DIR)/inflate.c  \
+                 $(GZIP_DIR)/inftrees.c \
+                 $(GZIP_DIR)/inftrees.h \
+                 $(GZIP_DIR)/infutil.c  \
+                 $(GZIP_DIR)/infutil.h  \
+                 $(GZIP_DIR)/zconf.h    \
+                 $(GZIP_DIR)/zlib.h     \
+                 $(GZIP_DIR)/zutil.c    \
+                 $(GZIP_DIR)/zutil.h
 
 
 # gzip driver object(s)
 #
-#   GZIP_DRV_OBJ_M is used during `multi' builds
-#   GZIP_DRV_OBJ_S is used during `single' builds
-#
-ifeq ($(SYSTEM_ZLIB),)
-  GZIP_DRV_OBJ_M := $(GZIP_DRV_SRC:$(GZIP_DIR)/%.c=$(OBJ_DIR)/%.$O)
-else
-  GZIP_DRV_OBJ_M := $(OBJ_DIR)/ftgzip.$O
-endif
-GZIP_DRV_OBJ_S := $(OBJ_DIR)/ftgzip.$O
-
-# gzip support source file for single build
+#   GZIP_DRV_OBJ is used during both `single' and `multi' builds
 #
-GZIP_DRV_SRC_S := $(GZIP_DIR)/ftgzip.c
+GZIP_DRV_OBJ := $(OBJ_DIR)/ftgzip.$O
 
 
-# gzip support - single object
+# gzip main source file
 #
-$(GZIP_DRV_OBJ_S): $(GZIP_DRV_SRC_S) $(GZIP_DRV_SRC) $(FREETYPE_H) \
-                   $(GZIP_DRV_H)
-	$(GZIP_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(GZIP_DRV_SRC_S))
+GZIP_DRV_SRC := $(GZIP_DIR)/ftgzip.c
 
 
-# gzip support - multiple objects
+# gzip support - object
 #
-$(OBJ_DIR)/%.$O: $(GZIP_DIR)/%.c $(FREETYPE_H) $(GZIP_DRV_H)
-	$(GZIP_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
+$(GZIP_DRV_OBJ): $(GZIP_DRV_SRC) $(GZIP_DRV_SRCS) $(FREETYPE_H)
+	$(GZIP_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(GZIP_DRV_SRC))
 
 
 # update main driver object lists
 #
-DRV_OBJS_S += $(GZIP_DRV_OBJ_S)
-DRV_OBJS_M += $(GZIP_DRV_OBJ_M)
+DRV_OBJS_S += $(GZIP_DRV_OBJ)
+DRV_OBJS_M += $(GZIP_DRV_OBJ)
 
 
 # EOF