From 6a871d66a45e3b8adbc70146e68d2448193e6d06 Mon Sep 17 00:00:00 2001
From: James Zern <jzern@google.com>
Date: Thu, 6 Dec 2012 13:48:21 -0800
Subject: [PATCH] cwebp: extract jpeg decoding to its own module

Change-Id: I45e1f0fa7b34286dd98926e0485e5a8ab1964570
---
 Makefile.vc          |   1 +
 examples/Makefile.am |   1 +
 examples/cwebp.c     |  99 +-----------------------------------
 examples/jpegdec.c   | 117 +++++++++++++++++++++++++++++++++++++++++++
 examples/jpegdec.h   |  31 ++++++++++++
 makefile.unix        |   1 +
 6 files changed, 152 insertions(+), 98 deletions(-)
 create mode 100644 examples/jpegdec.c
 create mode 100644 examples/jpegdec.h

diff --git a/Makefile.vc b/Makefile.vc
index f19305a6..b23c4c82 100644
--- a/Makefile.vc
+++ b/Makefile.vc
@@ -172,6 +172,7 @@ DSP_OBJS = \
     $(DIROBJ)\dsp\yuv.obj \
 
 EX_FORMAT_DEC_OBJS = \
+    $(DIROBJ)\examples/jpegdec.obj \
     $(DIROBJ)\examples/pngdec.obj \
 
 EX_UTIL_OBJS = \
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 1c00640c..0a52e4e4 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -21,6 +21,7 @@ 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 += jpegdec.c jpegdec.h
 cwebp_SOURCES += pngdec.c pngdec.h
 cwebp_CPPFLAGS  = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
 cwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
diff --git a/examples/cwebp.c b/examples/cwebp.c
index fc5da760..1358b1e3 100644
--- a/examples/cwebp.c
+++ b/examples/cwebp.c
@@ -18,11 +18,6 @@
 #include "config.h"
 #endif
 
-#ifdef WEBP_HAVE_JPEG
-#include <setjmp.h>
-#include <jpeglib.h>
-#endif
-
 #ifdef WEBP_HAVE_TIFF
 #include <tiffio.h>
 #endif
@@ -42,6 +37,7 @@
 
 
 #include "webp/encode.h"
+#include "./jpegdec.h"
 #include "./metadata.h"
 #include "./pngdec.h"
 #include "./stopwatch.h"
@@ -292,99 +288,6 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
 
 #else  // !HAVE_WINCODEC_H
 
-#ifdef WEBP_HAVE_JPEG
-struct my_error_mgr {
-  struct jpeg_error_mgr pub;
-  jmp_buf setjmp_buffer;
-};
-
-static void my_error_exit(j_common_ptr dinfo) {
-  struct my_error_mgr* myerr = (struct my_error_mgr*) dinfo->err;
-  (*dinfo->err->output_message) (dinfo);
-  longjmp(myerr->setjmp_buffer, 1);
-}
-
-static int ReadJPEG(FILE* in_file, WebPPicture* const pic) {
-  int ok = 0;
-  int stride, width, height;
-  uint8_t* rgb = NULL;
-  uint8_t* row_ptr = NULL;
-  struct jpeg_decompress_struct dinfo;
-  struct my_error_mgr jerr;
-  JSAMPARRAY buffer;
-
-  dinfo.err = jpeg_std_error(&jerr.pub);
-  jerr.pub.error_exit = my_error_exit;
-
-  if (setjmp(jerr.setjmp_buffer)) {
- Error:
-    jpeg_destroy_decompress(&dinfo);
-    goto End;
-  }
-
-  jpeg_create_decompress(&dinfo);
-  jpeg_stdio_src(&dinfo, in_file);
-  jpeg_read_header(&dinfo, TRUE);
-
-  dinfo.out_color_space = JCS_RGB;
-  dinfo.dct_method = JDCT_IFAST;
-  dinfo.do_fancy_upsampling = TRUE;
-
-  jpeg_start_decompress(&dinfo);
-
-  if (dinfo.output_components != 3) {
-    goto Error;
-  }
-
-  width = dinfo.output_width;
-  height = dinfo.output_height;
-  stride = dinfo.output_width * dinfo.output_components * sizeof(*rgb);
-
-  rgb = (uint8_t*)malloc(stride * height);
-  if (rgb == NULL) {
-    goto End;
-  }
-  row_ptr = rgb;
-
-  buffer = (*dinfo.mem->alloc_sarray) ((j_common_ptr) &dinfo,
-                                       JPOOL_IMAGE, stride, 1);
-  if (buffer == NULL) {
-    goto End;
-  }
-
-  while (dinfo.output_scanline < dinfo.output_height) {
-    if (jpeg_read_scanlines(&dinfo, buffer, 1) != 1) {
-      goto End;
-    }
-    memcpy(row_ptr, buffer[0], stride);
-    row_ptr += stride;
-  }
-
-  jpeg_finish_decompress(&dinfo);
-  jpeg_destroy_decompress(&dinfo);
-
-  // WebP conversion.
-  pic->width = width;
-  pic->height = height;
-  ok = WebPPictureImportRGB(pic, rgb, stride);
-
- End:
-  if (rgb) {
-    free(rgb);
-  }
-  return ok;
-}
-
-#else
-static int ReadJPEG(FILE* in_file, WebPPicture* const pic) {
-  (void)in_file;
-  (void)pic;
-  fprintf(stderr, "JPEG support not compiled. Please install the libjpeg "
-          "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/jpegdec.c b/examples/jpegdec.c
new file mode 100644
index 00000000..a17adb5a
--- /dev/null
+++ b/examples/jpegdec.c
@@ -0,0 +1,117 @@
+// 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/
+// -----------------------------------------------------------------------------
+//
+// JPEG decode.
+
+#include "./jpegdec.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#ifdef WEBP_HAVE_JPEG
+#include <jpeglib.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "webp/encode.h"
+
+struct my_error_mgr {
+  struct jpeg_error_mgr pub;
+  jmp_buf setjmp_buffer;
+};
+
+static void my_error_exit(j_common_ptr dinfo) {
+  struct my_error_mgr* myerr = (struct my_error_mgr*) dinfo->err;
+  (*dinfo->err->output_message) (dinfo);
+  longjmp(myerr->setjmp_buffer, 1);
+}
+
+int ReadJPEG(FILE* in_file, WebPPicture* const pic) {
+  int ok = 0;
+  int stride, width, height;
+  uint8_t* rgb = NULL;
+  uint8_t* row_ptr = NULL;
+  struct jpeg_decompress_struct dinfo;
+  struct my_error_mgr jerr;
+  JSAMPARRAY buffer;
+
+  dinfo.err = jpeg_std_error(&jerr.pub);
+  jerr.pub.error_exit = my_error_exit;
+
+  if (setjmp(jerr.setjmp_buffer)) {
+ Error:
+    jpeg_destroy_decompress(&dinfo);
+    goto End;
+  }
+
+  jpeg_create_decompress(&dinfo);
+  jpeg_stdio_src(&dinfo, in_file);
+  jpeg_read_header(&dinfo, TRUE);
+
+  dinfo.out_color_space = JCS_RGB;
+  dinfo.dct_method = JDCT_IFAST;
+  dinfo.do_fancy_upsampling = TRUE;
+
+  jpeg_start_decompress(&dinfo);
+
+  if (dinfo.output_components != 3) {
+    goto Error;
+  }
+
+  width = dinfo.output_width;
+  height = dinfo.output_height;
+  stride = dinfo.output_width * dinfo.output_components * sizeof(*rgb);
+
+  rgb = (uint8_t*)malloc(stride * height);
+  if (rgb == NULL) {
+    goto End;
+  }
+  row_ptr = rgb;
+
+  buffer = (*dinfo.mem->alloc_sarray) ((j_common_ptr) &dinfo,
+                                       JPOOL_IMAGE, stride, 1);
+  if (buffer == NULL) {
+    goto End;
+  }
+
+  while (dinfo.output_scanline < dinfo.output_height) {
+    if (jpeg_read_scanlines(&dinfo, buffer, 1) != 1) {
+      goto End;
+    }
+    memcpy(row_ptr, buffer[0], stride);
+    row_ptr += stride;
+  }
+
+  jpeg_finish_decompress(&dinfo);
+  jpeg_destroy_decompress(&dinfo);
+
+  // WebP conversion.
+  pic->width = width;
+  pic->height = height;
+  ok = WebPPictureImportRGB(pic, rgb, stride);
+
+ End:
+  if (rgb) {
+    free(rgb);
+  }
+  return ok;
+}
+#else  // !WEBP_HAVE_JPEG
+int ReadJPEG(FILE* in_file, struct WebPPicture* const pic) {
+  (void)in_file;
+  (void)pic;
+  fprintf(stderr, "JPEG support not compiled. Please install the libjpeg "
+          "development package before building.\n");
+  return 0;
+}
+#endif  // WEBP_HAVE_JPEG
+
+// -----------------------------------------------------------------------------
diff --git a/examples/jpegdec.h b/examples/jpegdec.h
new file mode 100644
index 00000000..22396200
--- /dev/null
+++ b/examples/jpegdec.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/
+// -----------------------------------------------------------------------------
+//
+// JPEG decode.
+
+#ifndef WEBP_EXAMPLES_JPEGDEC_H_
+#define WEBP_EXAMPLES_JPEGDEC_H_
+
+#include <stdio.h>
+#include "webp/types.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+struct WebPPicture;
+
+// Reads a JPEG from 'in_file', returning the decoded output in 'pic'.
+// The output is RGB.
+// Returns true on success.
+int ReadJPEG(FILE* in_file, struct WebPPicture* const pic);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}    // extern "C"
+#endif
+
+#endif  // WEBP_EXAMPLES_JPEGDEC_H_
diff --git a/makefile.unix b/makefile.unix
index 3a93c319..5cd2dec8 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -125,6 +125,7 @@ ENC_OBJS = \
     src/enc/webpenc.o \
 
 EX_FORMAT_DEC_OBJS = \
+    examples/jpegdec.o \
     examples/pngdec.o \
 
 EX_UTIL_OBJS = \