diff --git a/Makefile.vc b/Makefile.vc
index a3f59ddb..f19305a6 100644
--- a/Makefile.vc
+++ b/Makefile.vc
@@ -171,6 +171,9 @@ DSP_OBJS = \
     $(DIROBJ)\dsp\upsampling_sse2.obj \
     $(DIROBJ)\dsp\yuv.obj \
 
+EX_FORMAT_DEC_OBJS = \
+    $(DIROBJ)\examples/pngdec.obj \
+
 EX_UTIL_OBJS = \
     $(DIROBJ)\examples\example_util.obj \
 
@@ -218,7 +221,7 @@ OUT_LIBS = $(LIBWEBP)
 OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe
 
 all: $(OUT_LIBS) $(OUT_EXAMPLES)
-$(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj
+$(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(EX_FORMAT_DEC_OBJS)
 $(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj
 $(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX)
 $(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(LIBWEBP)
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 6fd7fc06..1c00640c 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -20,7 +20,8 @@ dwebp_CPPFLAGS  = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
 dwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES)
 dwebp_LDADD = libexampleutil.la ../src/libwebp.la $(PNG_LIBS) $(JPEG_LIBS)
 
-cwebp_SOURCES = cwebp.c metadata.h stopwatch.h
+cwebp_SOURCES  = cwebp.c metadata.h stopwatch.h
+cwebp_SOURCES += pngdec.c pngdec.h
 cwebp_CPPFLAGS  = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
 cwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
 cwebp_LDADD = ../src/libwebp.la $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS)
diff --git a/examples/cwebp.c b/examples/cwebp.c
index c99e9395..fc5da760 100644
--- a/examples/cwebp.c
+++ b/examples/cwebp.c
@@ -18,12 +18,8 @@
 #include "config.h"
 #endif
 
-#ifdef WEBP_HAVE_PNG
-#include <png.h>
-#endif
-
 #ifdef WEBP_HAVE_JPEG
-#include <setjmp.h>   // note: this must be included *after* png.h
+#include <setjmp.h>
 #include <jpeglib.h>
 #endif
 
@@ -47,6 +43,7 @@
 
 #include "webp/encode.h"
 #include "./metadata.h"
+#include "./pngdec.h"
 #include "./stopwatch.h"
 #ifndef WEBP_DLL
 #if defined(__cplusplus) || defined(c_plusplus)
@@ -388,106 +385,6 @@ static int ReadJPEG(FILE* in_file, WebPPicture* const pic) {
 }
 #endif
 
-#ifdef WEBP_HAVE_PNG
-static void PNGAPI error_function(png_structp png, png_const_charp dummy) {
-  (void)dummy;  // remove variable-unused warning
-  longjmp(png_jmpbuf(png), 1);
-}
-
-static int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha) {
-  png_structp png;
-  png_infop info;
-  int color_type, bit_depth, interlaced;
-  int has_alpha;
-  int num_passes;
-  int p;
-  int ok = 0;
-  png_uint_32 width, height, y;
-  int stride;
-  uint8_t* rgb = NULL;
-
-  png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
-  if (png == NULL) {
-    goto End;
-  }
-
-  png_set_error_fn(png, 0, error_function, NULL);
-  if (setjmp(png_jmpbuf(png))) {
- Error:
-    png_destroy_read_struct(&png, NULL, NULL);
-    free(rgb);
-    goto End;
-  }
-
-  info = png_create_info_struct(png);
-  if (info == NULL) goto Error;
-
-  png_init_io(png, in_file);
-  png_read_info(png, info);
-  if (!png_get_IHDR(png, info,
-                    &width, &height, &bit_depth, &color_type, &interlaced,
-                    NULL, NULL)) goto Error;
-
-  png_set_strip_16(png);
-  png_set_packing(png);
-  if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
-  if (color_type == PNG_COLOR_TYPE_GRAY ||
-      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
-    if (bit_depth < 8) {
-      png_set_expand_gray_1_2_4_to_8(png);
-    }
-    png_set_gray_to_rgb(png);
-  }
-  if (png_get_valid(png, info, PNG_INFO_tRNS)) {
-    png_set_tRNS_to_alpha(png);
-    has_alpha = 1;
-  } else {
-    has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
-  }
-
-  if (!keep_alpha) {
-    png_set_strip_alpha(png);
-    has_alpha = 0;
-  }
-
-  num_passes = png_set_interlace_handling(png);
-  png_read_update_info(png, info);
-  stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb);
-  rgb = (uint8_t*)malloc(stride * height);
-  if (rgb == NULL) goto Error;
-  for (p = 0; p < num_passes; ++p) {
-    for (y = 0; y < height; ++y) {
-      png_bytep row = rgb + y * stride;
-      png_read_rows(png, &row, NULL, 1);
-    }
-  }
-  png_read_end(png, info);
-  png_destroy_read_struct(&png, &info, NULL);
-
-  pic->width = width;
-  pic->height = height;
-  ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride)
-                 : WebPPictureImportRGB(pic, rgb, stride);
-  free(rgb);
-
-  if (ok && has_alpha && keep_alpha == 2) {
-    WebPCleanupTransparentArea(pic);
-  }
-
- End:
-  return ok;
-}
-#else
-static int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha) {
-  (void)in_file;
-  (void)pic;
-  (void)keep_alpha;
-  fprintf(stderr, "PNG support not compiled. Please install the libpng "
-          "development package before building.\n");
-  return 0;
-}
-#endif
-
 #ifdef WEBP_HAVE_TIFF
 static int ReadTIFF(const char* const filename,
                     WebPPicture* const pic, int keep_alpha) {
diff --git a/examples/pngdec.c b/examples/pngdec.c
new file mode 100644
index 00000000..ff984734
--- /dev/null
+++ b/examples/pngdec.c
@@ -0,0 +1,124 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// This code is licensed under the same terms as WebM:
+//  Software License Agreement:  http://www.webmproject.org/license/software/
+//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
+// -----------------------------------------------------------------------------
+//
+// PNG decode.
+
+#include "./pngdec.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#ifdef WEBP_HAVE_PNG
+#include <png.h>
+#include <setjmp.h>   // note: this must be included *after* png.h
+#include <stdlib.h>
+
+#include "webp/encode.h"
+
+static void PNGAPI error_function(png_structp png, png_const_charp dummy) {
+  (void)dummy;  // remove variable-unused warning
+  longjmp(png_jmpbuf(png), 1);
+}
+
+int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha) {
+  png_structp png;
+  png_infop info;
+  int color_type, bit_depth, interlaced;
+  int has_alpha;
+  int num_passes;
+  int p;
+  int ok = 0;
+  png_uint_32 width, height, y;
+  int stride;
+  uint8_t* rgb = NULL;
+
+  png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+  if (png == NULL) {
+    goto End;
+  }
+
+  png_set_error_fn(png, 0, error_function, NULL);
+  if (setjmp(png_jmpbuf(png))) {
+ Error:
+    png_destroy_read_struct(&png, NULL, NULL);
+    free(rgb);
+    goto End;
+  }
+
+  info = png_create_info_struct(png);
+  if (info == NULL) goto Error;
+
+  png_init_io(png, in_file);
+  png_read_info(png, info);
+  if (!png_get_IHDR(png, info,
+                    &width, &height, &bit_depth, &color_type, &interlaced,
+                    NULL, NULL)) goto Error;
+
+  png_set_strip_16(png);
+  png_set_packing(png);
+  if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
+  if (color_type == PNG_COLOR_TYPE_GRAY ||
+      color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+    if (bit_depth < 8) {
+      png_set_expand_gray_1_2_4_to_8(png);
+    }
+    png_set_gray_to_rgb(png);
+  }
+  if (png_get_valid(png, info, PNG_INFO_tRNS)) {
+    png_set_tRNS_to_alpha(png);
+    has_alpha = 1;
+  } else {
+    has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
+  }
+
+  if (!keep_alpha) {
+    png_set_strip_alpha(png);
+    has_alpha = 0;
+  }
+
+  num_passes = png_set_interlace_handling(png);
+  png_read_update_info(png, info);
+  stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb);
+  rgb = (uint8_t*)malloc(stride * height);
+  if (rgb == NULL) goto Error;
+  for (p = 0; p < num_passes; ++p) {
+    for (y = 0; y < height; ++y) {
+      png_bytep row = rgb + y * stride;
+      png_read_rows(png, &row, NULL, 1);
+    }
+  }
+  png_read_end(png, info);
+  png_destroy_read_struct(&png, &info, NULL);
+
+  pic->width = width;
+  pic->height = height;
+  ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride)
+                 : WebPPictureImportRGB(pic, rgb, stride);
+  free(rgb);
+
+  if (ok && has_alpha && keep_alpha == 2) {
+    WebPCleanupTransparentArea(pic);
+  }
+
+ End:
+  return ok;
+}
+#else  // !WEBP_HAVE_PNG
+int ReadPNG(FILE* in_file, struct WebPPicture* const pic, int keep_alpha) {
+  (void)in_file;
+  (void)pic;
+  (void)keep_alpha;
+  fprintf(stderr, "PNG support not compiled. Please install the libpng "
+          "development package before building.\n");
+  return 0;
+}
+#endif  // WEBP_HAVE_PNG
+
+// -----------------------------------------------------------------------------
diff --git a/examples/pngdec.h b/examples/pngdec.h
new file mode 100644
index 00000000..5cee3ad2
--- /dev/null
+++ b/examples/pngdec.h
@@ -0,0 +1,31 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// This code is licensed under the same terms as WebM:
+//  Software License Agreement:  http://www.webmproject.org/license/software/
+//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
+// -----------------------------------------------------------------------------
+//
+// PNG decode.
+
+#ifndef WEBP_EXAMPLES_PNGDEC_H_
+#define WEBP_EXAMPLES_PNGDEC_H_
+
+#include <stdio.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+struct WebPPicture;
+
+// Reads a PNG from 'in_file', returning the decoded output in 'pic'.
+// If 'keep_alpha' is true and the PNG has an alpha channel, the output is RGBA
+// otherwise it will be RGB.
+// Returns true on success.
+int ReadPNG(FILE* in_file, struct WebPPicture* const pic, int keep_alpha);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}    // extern "C"
+#endif
+
+#endif  // WEBP_EXAMPLES_PNGDEC_H_
diff --git a/makefile.unix b/makefile.unix
index 4e532010..3a93c319 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -124,6 +124,9 @@ ENC_OBJS = \
     src/enc/vp8l.o \
     src/enc/webpenc.o \
 
+EX_FORMAT_DEC_OBJS = \
+    examples/pngdec.o \
+
 EX_UTIL_OBJS = \
     examples/example_util.o \
 
@@ -189,6 +192,8 @@ endif
 
 all: ex
 
+$(EX_FORMAT_DEC_OBJS): %.o: %.h
+
 %.o: %.c $(HDRS)
 	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
 
@@ -202,7 +207,7 @@ src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS)
 
 ex: $(OUT_EXAMPLES)
 
-examples/cwebp: examples/cwebp.o
+examples/cwebp: examples/cwebp.o $(EX_FORMAT_DEC_OBJS)
 examples/dwebp: examples/dwebp.o
 examples/gif2webp: examples/gif2webp.o
 examples/vwebp: examples/vwebp.o