Repository: trafficserver
Updated Branches:
  refs/heads/master 9c707a89d -> 39b2eb4b9


TS-4095: New cppapi plugin for converting images formats to webp. This closes 
#393


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/39b2eb4b
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/39b2eb4b
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/39b2eb4b

Branch: refs/heads/master
Commit: 39b2eb4b98cf4973a64407bcb47c9d93ee5c30fa
Parents: 9c707a8
Author: Sandeep Davu <[email protected]>
Authored: Sat Feb 20 23:36:20 2016 -0800
Committer: Kit Chan <[email protected]>
Committed: Sat Feb 20 23:36:20 2016 -0800

----------------------------------------------------------------------
 configure.ac                                    |  11 ++
 doc/admin-guide/plugins/index.en.rst            |   4 +
 doc/admin-guide/plugins/webp_transform.en.rst   |  39 +++++++
 plugins/experimental/Makefile.am                |   5 +-
 .../webp_transform/ImageTransform.cc            | 109 +++++++++++++++++++
 plugins/experimental/webp_transform/Makefile.am |  28 +++++
 plugins/experimental/webp_transform/README      |   4 +
 7 files changed, 199 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/39b2eb4b/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index a3aa6ca..7d70788 100644
--- a/configure.ac
+++ b/configure.ac
@@ -409,6 +409,12 @@ PKG_CHECK_MODULES([LIBMEMCACHED], [libmemcached >= 1.0], 
[have_libmemcached=yes]
 AM_CONDITIONAL([BUILD_MEMCACHED_REMAP_PLUGIN], [test "x${have_libmemcached}" = 
"xyes"])
 
 #
+# Check Magick++ is available. Enable experimental/webp_transform plugin
+#
+PKG_CHECK_MODULES([LIBMAGICKCPP],[Magick++], [have_libmagickcpp=yes], 
[have_libmagickcpp=no])
+AM_CONDITIONAL([BUILD_HAS_IMAGEMAGICKCPP], [test "x${have_libmagickcpp}" = 
"xyes"])
+
+#
 # Example plugins. The example plugins are always built, but not always 
installed. Installing
 # them is useful for QA, but not useful for most users, so we default this to 
disabled.
 #
@@ -1932,6 +1938,11 @@ AS_IF([test "x$enable_experimental_plugins" = "xyes"], [
     plugins/experimental/stream_editor/Makefile
 ])])
 
+AS_IF([test "x$enable_experimental_plugins" = "xyes"], [
+  AS_IF([test "x$enable_cppapi" = "xyes"], [
+    AC_CONFIG_FILES([plugins/experimental/webp_transform/Makefile])
+  ])])
+
 AS_IF([test "x$enable_cppapi" = "xyes"], [
   AC_CONFIG_FILES([
   lib/atscppapi/Makefile

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/39b2eb4b/doc/admin-guide/plugins/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/admin-guide/plugins/index.en.rst 
b/doc/admin-guide/plugins/index.en.rst
index 5745a4d..f237749 100644
--- a/doc/admin-guide/plugins/index.en.rst
+++ b/doc/admin-guide/plugins/index.en.rst
@@ -116,6 +116,7 @@ directory of the |TS| source tree. Experimental plugins can 
be compiled by passi
    SSL Headers <sslheaders.en>
    Stale While Revalidate <stale_while_revalidate.en>
    TS Lua <ts_lua.en>
+   WebP Transform <webp_transform.en>
    X-Debug <xdebug.en>
 
 :doc:`AuthProxy <authproxy.en>`
@@ -181,6 +182,9 @@ directory of the |TS| source tree. Experimental plugins can 
be compiled by passi
 :doc:`TS Lua <ts_lua.en>`
    Allows plugins to be written in Lua instead of C code.
 
+:doc:`WebP Transform <webp_transform.en>`
+   Converts jpeg and png images to webp format.
+
 :doc:`X-Debug <xdebug.en>`
    Allows HTTP clients to debug the operation of the Traffic Server cache 
using the X-Debug header.
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/39b2eb4b/doc/admin-guide/plugins/webp_transform.en.rst
----------------------------------------------------------------------
diff --git a/doc/admin-guide/plugins/webp_transform.en.rst 
b/doc/admin-guide/plugins/webp_transform.en.rst
new file mode 100644
index 0000000..280aca6
--- /dev/null
+++ b/doc/admin-guide/plugins/webp_transform.en.rst
@@ -0,0 +1,39 @@
+.. _webp_transform:
+
+WebpTransform Plugin
+****************
+
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+This plugin converts jpeg and png images and transforms them into webp format.
+All response with content-type 'image/jpeg' or 'image/png' will go through the 
transform. 
+Content-type is changed to 'image/webp' on successful transformation. 
+
+Installation
+============
+
+Add the following line to :file:`plugin.config`::
+
+    webp_transform.so
+
+
+Note
+===================
+
+This plugin only supports jpeg and png and requires Magick++ from ImageMagick.
+Other image formats can easily be supported.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/39b2eb4b/plugins/experimental/Makefile.am
----------------------------------------------------------------------
diff --git a/plugins/experimental/Makefile.am b/plugins/experimental/Makefile.am
index c5055ae..6aa03fc 100644
--- a/plugins/experimental/Makefile.am
+++ b/plugins/experimental/Makefile.am
@@ -45,7 +45,8 @@ SUBDIRS = \
  url_sig \
  xdebug \
  mp4 \
- stream_editor
+ stream_editor \
+ webp_transform
 
 if HAS_MYSQL
   SUBDIRS += mysql_remap
@@ -54,3 +55,5 @@ endif
 if BUILD_LUAJIT
   SUBDIRS += ts_lua
 endif
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/39b2eb4b/plugins/experimental/webp_transform/ImageTransform.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/webp_transform/ImageTransform.cc 
b/plugins/experimental/webp_transform/ImageTransform.cc
new file mode 100644
index 0000000..b5d22bb
--- /dev/null
+++ b/plugins/experimental/webp_transform/ImageTransform.cc
@@ -0,0 +1,109 @@
+/**
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include <sstream>
+#include <iostream>
+#include <atscppapi/PluginInit.h>
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/TransformationPlugin.h>
+#include <atscppapi/Logger.h>
+
+#include <Magick++.h>
+
+using std::string;
+using namespace Magick;
+using namespace atscppapi;
+
+namespace
+{
+#define TAG "webp_transform"
+}
+
+class ImageTransform : public TransformationPlugin
+{
+public:
+  ImageTransform(Transaction &transaction) : TransformationPlugin(transaction, 
TransformationPlugin::RESPONSE_TRANSFORMATION)
+  {
+    TransformationPlugin::registerHook(HOOK_READ_RESPONSE_HEADERS);
+  }
+
+  void
+  handleReadResponseHeaders(Transaction &transaction)
+  {
+    transaction.getServerResponse().getHeaders()["Content-Type"] = 
"image/webp";
+    transaction.getServerResponse().getHeaders()["Vary"] = "Content-Type"; // 
to have a separate cache entry.
+
+    TS_DEBUG(TAG, "url %s", 
transaction.getServerRequest().getUrl().getUrlString().c_str());
+    transaction.resume();
+  }
+
+  void
+  consume(const string &data)
+  {
+    _img.write(data.data(), data.size());
+  }
+
+  void
+  handleInputComplete()
+  {
+    string input_data = _img.str();
+    Blob input_blob(input_data.data(), input_data.length());
+    Image image;
+    image.read(input_blob);
+
+    Blob output_blob;
+    image.magick("WEBP");
+    image.write(&output_blob);
+    string output_data(reinterpret_cast<const char *>(output_blob.data()), 
output_blob.length());
+    produce(output_data);
+
+    setOutputComplete();
+  }
+
+  virtual ~ImageTransform() {}
+
+private:
+  std::stringstream _img;
+};
+
+
+class GlobalHookPlugin : public GlobalPlugin
+{
+public:
+  GlobalHookPlugin() { registerHook(HOOK_READ_RESPONSE_HEADERS); }
+  virtual void
+  handleReadResponseHeaders(Transaction &transaction)
+  {
+    string ctype = 
transaction.getServerResponse().getHeaders().values("Content-Type");
+    string user_agent = 
transaction.getServerRequest().getHeaders().values("User-Agent");
+    if (user_agent.find("Chrome") != string::npos && (ctype.find("jpeg") != 
string::npos || ctype.find("png") != string::npos)) {
+      TS_DEBUG(TAG, "Content type is either jpeg or png. Converting to webp");
+      transaction.addPlugin(new ImageTransform(transaction));
+    }
+
+    transaction.resume();
+  }
+};
+
+void
+TSPluginInit(int argc ATSCPPAPI_UNUSED, const char *argv[] ATSCPPAPI_UNUSED)
+{
+  RegisterGlobalPlugin("CPP_Webp_Transform", "apache", 
"[email protected]");
+  InitializeMagick("");
+  new GlobalHookPlugin();
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/39b2eb4b/plugins/experimental/webp_transform/Makefile.am
----------------------------------------------------------------------
diff --git a/plugins/experimental/webp_transform/Makefile.am 
b/plugins/experimental/webp_transform/Makefile.am
new file mode 100644
index 0000000..64ef1ab
--- /dev/null
+++ b/plugins/experimental/webp_transform/Makefile.am
@@ -0,0 +1,28 @@
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+include $(top_srcdir)/build/plugins.mk
+
+if BUILD_HAS_IMAGEMAGICKCPP
+
+AM_CPPFLAGS += -I$(top_srcdir)/lib/atscppapi/src/include -Wno-unused-variable 
$(LIBMAGICKCPP_CFLAGS)
+target=WebpTransform.so
+pkglib_LTLIBRARIES = WebpTransform.la
+WebpTransform_la_SOURCES = ImageTransform.cc 
+WebpTransform_la_LDFLAGS = -module -avoid-version -shared 
-L$(top_srcdir)/lib/atscppapi/src/ -latscppapi $(TS_PLUGIN_LDFLAGS) 
$(LIBMAGICKCPP_LIBS)
+
+endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/39b2eb4b/plugins/experimental/webp_transform/README
----------------------------------------------------------------------
diff --git a/plugins/experimental/webp_transform/README 
b/plugins/experimental/webp_transform/README
new file mode 100644
index 0000000..595d0e6
--- /dev/null
+++ b/plugins/experimental/webp_transform/README
@@ -0,0 +1,4 @@
+Converting jpeg and png to webp using ImageMagick Magick++ lib
+Pre-requisites
+
+1. Magick++ api for ImageMagick 

Reply via email to