summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README3
-rw-r--r--configure.ac5
-rw-r--r--lib-x86-32/include/pnglibconf.h174
-rw-r--r--plugins/artwork/Makefile.am2
-rw-r--r--plugins/artwork/artwork.c265
5 files changed, 446 insertions, 3 deletions
diff --git a/README b/README
index bedc3517..ce85c322 100644
--- a/README
+++ b/README
@@ -31,7 +31,8 @@ full list of dependencies:
alsa-lib: ALSA support
libvorbis and libogg: for ogg vorbis plugin
libcurl >= 7.10: for last.fm, vfs_curl (shoutcast/icecast), artwork plugins
- libjpeg: for artwork plugin
+ imlib2: for artwork plugin; see libjpeg and libpng below
+ libjpeg and libpng: for artwork plugin (when imlib2 is not installed, or --disable-artwork-imlib2 is used)
libmad: for mp3 plugin (mpeg1,2 layers1,2,3)
libFLAC: for flac plugin
wavpack: for wavpack plugin
diff --git a/configure.ac b/configure.ac
index f1e47909..575d795c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -412,6 +412,9 @@ if test "x$enable_artwork" != "xno" ; then
HAVE_JPEG=yes
JPEG_DEPS_LIBS="../../$LIB/libjpeg.a"
AC_SUBST(JPEG_DEPS_LIBS)
+ HAVE_PNG=yes
+ PNG_DEPS_LIBS="../../$LIB/libpng15.a ../../$LIB/libz.a"
+ AC_SUBST(PNG_DEPS_LIBS)
HAVE_IMLIB2=no
else
if test "x$enable_artwork_imlib2" != "xno" ; then
@@ -420,6 +423,7 @@ if test "x$enable_artwork" != "xno" ; then
if test "x$enable_artwork_imlib2" == "xno" || test "x$HAVE_IMLIB2" == "xno" ; then
AC_CHECK_LIB([jpeg], [main], [HAVE_JPEG=yes;JPEG_DEPS_LIBS="-ljpeg";AC_SUBST(JPEG_DEPS_LIBS)])
+ AC_CHECK_LIB([png], [main], [HAVE_PNG=yes;PNG_DEPS_LIBS="-lpng -lz";AC_SUBST(PNG_DEPS_LIBS)])
fi
fi
@@ -571,6 +575,7 @@ AM_CONDITIONAL(HAVE_VFS_ZIP, test "x$HAVE_VFS_ZIP" = "xyes")
AM_CONDITIONAL(HAVE_CONVERTER, test "x$HAVE_CONVERTER" = "xyes")
AM_CONDITIONAL(HAVE_IMLIB2, test "x$HAVE_IMLIB2" = "xyes")
AM_CONDITIONAL(HAVE_JPEG, test "x$HAVE_JPEG" = "xyes")
+AM_CONDITIONAL(HAVE_PNG, test "x$HAVE_PNG" = "xyes")
AC_SUBST(PLUGINS_DIRS)
diff --git a/lib-x86-32/include/pnglibconf.h b/lib-x86-32/include/pnglibconf.h
new file mode 100644
index 00000000..cd203f88
--- /dev/null
+++ b/lib-x86-32/include/pnglibconf.h
@@ -0,0 +1,174 @@
+/* pnglibconf.h - library build configuration */
+
+/* libpng version 1.5.0 - January 6, 2011 */
+
+/* Copyright (c) 1998-2011 Glenn Randers-Pehrson */
+
+/* This code is released under the libpng license. */
+/* For conditions of distribution and use, see the disclaimer */
+/* and license in png.h */
+
+/* pnglibconf.h */
+/* Machine generated file: DO NOT EDIT */
+/* Derived from: scripts/pnglibconf.dfa */
+#ifndef PNGLCONF_H
+#define PNGLCONF_H
+/* settings */
+#define PNG_MAX_GAMMA_8 11
+#define PNG_CALLOC_SUPPORTED
+#define PNG_QUANTIZE_RED_BITS 5
+#define PNG_USER_WIDTH_MAX 1000000L
+#define PNG_QUANTIZE_GREEN_BITS 5
+#define PNG_API_RULE 0
+#define PNG_QUANTIZE_BLUE_BITS 5
+#define PNG_USER_CHUNK_CACHE_MAX 0
+#define PNG_USER_HEIGHT_MAX 1000000L
+#define PNG_sCAL_PRECISION 5
+#define PNG_COST_SHIFT 3
+#define PNG_WEIGHT_SHIFT 8
+#define PNG_USER_CHUNK_MALLOC_MAX 0
+#define PNG_DEFAULT_READ_MACROS 1
+#define PNG_ZBUF_SIZE 8192
+#define PNG_GAMMA_THRESHOLD_FIXED 5000
+/* end of settings */
+/* options */
+#define PNG_INFO_IMAGE_SUPPORTED
+#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#define PNG_POINTER_INDEXING_SUPPORTED
+#define PNG_WARNINGS_SUPPORTED
+#define PNG_FLOATING_ARITHMETIC_SUPPORTED
+#define PNG_WRITE_SUPPORTED
+#define PNG_WRITE_INTERLACING_SUPPORTED
+#define PNG_WRITE_16BIT_SUPPORTED
+#define PNG_EASY_ACCESS_SUPPORTED
+#define PNG_ALIGN_MEMORY_SUPPORTED
+#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_USER_LIMITS_SUPPORTED
+#define PNG_FIXED_POINT_SUPPORTED
+/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
+#define PNG_ERROR_TEXT_SUPPORTED
+#define PNG_READ_SUPPORTED
+/*#undef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED*/
+#define PNG_BENIGN_ERRORS_SUPPORTED
+#define PNG_SETJMP_SUPPORTED
+#define PNG_WRITE_FLUSH_SUPPORTED
+#define PNG_MNG_FEATURES_SUPPORTED
+#define PNG_FLOATING_POINT_SUPPORTED
+#define PNG_INCH_CONVERSIONS_SUPPORTED
+#define PNG_STDIO_SUPPORTED
+#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_USER_MEM_SUPPORTED
+#define PNG_IO_STATE_SUPPORTED
+#define PNG_SET_USER_LIMITS_SUPPORTED
+#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#define PNG_WRITE_FILTER_SUPPORTED
+#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED
+#define PNG_WRITE_iCCP_SUPPORTED
+#define PNG_READ_TRANSFORMS_SUPPORTED
+#define PNG_READ_GAMMA_SUPPORTED
+#define PNG_READ_bKGD_SUPPORTED
+#define PNG_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_READ_sCAL_SUPPORTED
+#define PNG_WRITE_hIST_SUPPORTED
+#define PNG_READ_OPT_PLTE_SUPPORTED
+#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+#define PNG_WRITE_gAMA_SUPPORTED
+#define PNG_READ_GRAY_TO_RGB_SUPPORTED
+#define PNG_WRITE_pCAL_SUPPORTED
+#define PNG_READ_INVERT_ALPHA_SUPPORTED
+#define PNG_WRITE_TRANSFORMS_SUPPORTED
+#define PNG_READ_sBIT_SUPPORTED
+#define PNG_READ_PACK_SUPPORTED
+#define PNG_WRITE_SWAP_SUPPORTED
+#define PNG_READ_cHRM_SUPPORTED
+#define PNG_WRITE_tIME_SUPPORTED
+#define PNG_READ_INTERLACING_SUPPORTED
+#define PNG_READ_tRNS_SUPPORTED
+#define PNG_WRITE_pHYs_SUPPORTED
+#define PNG_WRITE_INVERT_SUPPORTED
+#define PNG_READ_RGB_TO_GRAY_SUPPORTED
+#define PNG_WRITE_sRGB_SUPPORTED
+#define PNG_READ_oFFs_SUPPORTED
+#define PNG_WRITE_FILLER_SUPPORTED
+#define PNG_WRITE_TEXT_SUPPORTED
+#define PNG_WRITE_SHIFT_SUPPORTED
+#define PNG_PROGRESSIVE_READ_SUPPORTED
+#define PNG_READ_SHIFT_SUPPORTED
+#define PNG_CONVERT_tIME_SUPPORTED
+#define PNG_READ_USER_TRANSFORM_SUPPORTED
+#define PNG_READ_INT_FUNCTIONS_SUPPORTED
+#define PNG_READ_USER_CHUNKS_SUPPORTED
+#define PNG_READ_hIST_SUPPORTED
+#define PNG_READ_16BIT_SUPPORTED
+#define PNG_READ_SWAP_ALPHA_SUPPORTED
+#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
+#define PNG_SEQUENTIAL_READ_SUPPORTED
+#define PNG_READ_BACKGROUND_SUPPORTED
+#define PNG_READ_QUANTIZE_SUPPORTED
+#define PNG_READ_iCCP_SUPPORTED
+#define PNG_READ_STRIP_ALPHA_SUPPORTED
+#define PNG_READ_PACKSWAP_SUPPORTED
+#define PNG_READ_sRGB_SUPPORTED
+#define PNG_WRITE_tEXt_SUPPORTED
+#define PNG_READ_gAMA_SUPPORTED
+#define PNG_READ_pCAL_SUPPORTED
+#define PNG_WRITE_sPLT_SUPPORTED
+#define PNG_READ_SWAP_SUPPORTED
+#define PNG_READ_tIME_SUPPORTED
+#define PNG_READ_pHYs_SUPPORTED
+#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+#define PNG_TIME_RFC1123_SUPPORTED
+#define PNG_READ_TEXT_SUPPORTED
+#define PNG_WRITE_BGR_SUPPORTED
+#define PNG_USER_CHUNKS_SUPPORTED
+#define PNG_CONSOLE_IO_SUPPORTED
+#define PNG_WRITE_PACK_SUPPORTED
+#define PNG_READ_FILLER_SUPPORTED
+#define PNG_WRITE_bKGD_SUPPORTED
+#define PNG_WRITE_tRNS_SUPPORTED
+#define PNG_READ_sPLT_SUPPORTED
+#define PNG_WRITE_sCAL_SUPPORTED
+#define PNG_WRITE_oFFs_SUPPORTED
+#define PNG_READ_tEXt_SUPPORTED
+#define PNG_WRITE_sBIT_SUPPORTED
+#define PNG_READ_INVERT_SUPPORTED
+#define PNG_READ_16_TO_8_SUPPORTED
+#define PNG_WRITE_cHRM_SUPPORTED
+#define PNG_16BIT_SUPPORTED
+#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+#define PNG_READ_BGR_SUPPORTED
+#define PNG_WRITE_PACKSWAP_SUPPORTED
+#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+#define PNG_sCAL_SUPPORTED
+#define PNG_WRITE_zTXt_SUPPORTED
+#define PNG_USER_TRANSFORM_INFO_SUPPORTED
+#define PNG_sBIT_SUPPORTED
+#define PNG_cHRM_SUPPORTED
+#define PNG_bKGD_SUPPORTED
+#define PNG_tRNS_SUPPORTED
+#define PNG_WRITE_iTXt_SUPPORTED
+#define PNG_oFFs_SUPPORTED
+#define PNG_READ_EXPAND_16_SUPPORTED
+#define PNG_USER_TRANSFORM_PTR_SUPPORTED
+#define PNG_hIST_SUPPORTED
+#define PNG_iCCP_SUPPORTED
+#define PNG_sRGB_SUPPORTED
+#define PNG_READ_zTXt_SUPPORTED
+#define PNG_gAMA_SUPPORTED
+#define PNG_pCAL_SUPPORTED
+#define PNG_CHECK_cHRM_SUPPORTED
+#define PNG_tIME_SUPPORTED
+#define PNG_READ_EXPAND_SUPPORTED
+#define PNG_pHYs_SUPPORTED
+#define PNG_READ_iTXt_SUPPORTED
+#define PNG_TEXT_SUPPORTED
+#define PNG_SAVE_INT_32_SUPPORTED
+#define PNG_sPLT_SUPPORTED
+#define PNG_tEXt_SUPPORTED
+#define PNG_zTXt_SUPPORTED
+#define PNG_iTXt_SUPPORTED
+/* end of options */
+#endif /* PNGLCONF_H */
diff --git a/plugins/artwork/Makefile.am b/plugins/artwork/Makefile.am
index 01f5e87c..53cda944 100644
--- a/plugins/artwork/Makefile.am
+++ b/plugins/artwork/Makefile.am
@@ -9,7 +9,7 @@ if HAVE_IMLIB2
ARTWORK_DEPS=$(IMLIB2_DEPS_LIBS)
ARTWORK_CFLAGS=-DUSE_IMLIB2
else
-ARTWORK_DEPS=$(JPEG_DEPS_LIBS)
+ARTWORK_DEPS=$(JPEG_DEPS_LIBS) $(PNG_DEPS_LIBS)
endif
AM_CFLAGS = $(CFLAGS) $(ARTWORK_CFLAGS) -std=c99
diff --git a/plugins/artwork/artwork.c b/plugins/artwork/artwork.c
index a65ed413..997e96c6 100644
--- a/plugins/artwork/artwork.c
+++ b/plugins/artwork/artwork.c
@@ -18,7 +18,8 @@ static uintptr_t imlib_mutex;
#else
#include <jpeglib.h>
#include <jerror.h>
-#include <setjmp.h>
+//#include <setjmp.h>
+#include <png.h>
#endif
#define min(x,y) ((x)<(y)?(x):(y))
@@ -332,6 +333,263 @@ jpeg_resize (const char *fname, const char *outname, int scaled_size) {
return 0;
}
+
+int
+png_resize (const char *fname, const char *outname, int scaled_size) {
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ unsigned int sig_read = 0;
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type;
+ int number_passes;
+ png_uint_32 row;
+ int bpp;
+ int err = -1;
+ FILE *fp = NULL;
+ FILE *out = NULL;
+ struct my_error_mgr jerr;
+ struct jpeg_compress_struct cinfo_out;
+
+ fp = fopen(fname, "rb");
+ if (!fp) {
+ goto error;
+ }
+
+ png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr) {
+ goto error;
+ }
+
+ if (setjmp(png_jmpbuf((png_ptr))))
+ {
+ fprintf (stderr, "failed to read png: %s\n", fname);
+ goto error;
+ }
+ png_init_io(png_ptr, fp);
+
+ info_ptr = png_create_info_struct (png_ptr);
+ if (!info_ptr) {
+ goto error;
+ }
+ // if (setjmp (png_ptr->jmpbuf)) {
+ // goto err;
+ // }
+
+ png_set_sig_bytes (png_ptr, sig_read);
+
+ png_read_info(png_ptr, info_ptr);
+
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+ &interlace_type, NULL, NULL);
+
+ /* Strip alpha bytes from the input data without combining with the
+ * background (not recommended).
+ */
+ png_set_strip_alpha(png_ptr);
+
+ /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
+ * byte into separate bytes (useful for paletted and grayscale images).
+ */
+ png_set_packing(png_ptr);
+
+ /* Expand paletted colors into true RGB triplets */
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_palette_to_rgb(png_ptr);
+
+ /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
+ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
+ png_set_expand_gray_1_2_4_to_8(png_ptr);
+
+ // /* Expand paletted or RGB images with transparency to full alpha channels
+ // * so the data will be available as RGBA quartets.
+ // */
+ // if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ // png_set_tRNS_to_alpha(png_ptr);
+
+ // /* Set the background color to draw transparent and alpha images over.
+ // * It is possible to set the red, green, and blue components directly
+ // * for paletted images instead of supplying a palette index. Note that
+ // * even if the PNG file supplies a background, you are not required to
+ // * use it - you should use the (solid) application background if it has one.
+ // */
+ //
+ // png_color_16 my_background, *image_background;
+ //
+ // if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+ // png_set_background(png_ptr, image_background,
+ // PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ // else
+ // png_set_background(png_ptr, &my_background,
+ // PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+ // screen_gamma = 2.2; /* A good guess for a PC monitor in a dimly
+ // lit room */
+
+ /* Tell libpng to handle the gamma conversion for you. The final call
+ * is a good guess for PC generated images, but it should be configurable
+ * by the user at run time by the user. It is strongly suggested that
+ * your application support gamma correction.
+ */
+
+ // int intent;
+ //
+ // if (png_get_sRGB(png_ptr, info_ptr, &intent))
+ // png_set_gamma(png_ptr, screen_gamma, 0.45455);
+ // else
+ // {
+ // double image_gamma;
+ // if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
+ // png_set_gamma(png_ptr, screen_gamma, image_gamma);
+ // else
+ // png_set_gamma(png_ptr, screen_gamma, 0.45455);
+ // }
+
+ // /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
+ // if (color_type & PNG_COLOR_MASK_COLOR)
+ // png_set_bgr(png_ptr);
+ //
+ // /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+ // png_set_swap_alpha(png_ptr);
+ //
+ // /* Swap bytes of 16 bit files to least significant byte first */
+ // png_set_swap(png_ptr);
+ //
+ // /* Add filler (or alpha) byte (before/after each RGB triplet) */
+ // png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+
+ /* Turn on interlace handling. REQUIRED if you are not using
+ * png_read_image(). To see how to handle interlacing passes,
+ * see the png_read_row() method below:
+ */
+ number_passes = png_set_interlace_handling(png_ptr);
+
+ // /* Optional call to gamma correct and add the background to the palette
+ // * and update info structure. REQUIRED if you are expecting libpng to
+ // * update the palette for you (ie you selected such a transform above).
+ // */
+ // png_read_update_info(png_ptr, info_ptr);
+
+ /* Allocate the memory to hold the image using the fields of info_ptr. */
+
+ /* The easiest way to read the image: */
+
+ png_bytep *row_pointers = png_malloc(png_ptr, height*sizeof (png_bytep));
+
+ /* Clear the pointer array */
+ for (row = 0; row < height; row++)
+ row_pointers[row] = NULL;
+
+ for (row = 0; row < height; row++)
+ row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
+ info_ptr));
+
+ /* Now it's time to read the image. One of these methods is REQUIRED */
+ /* The other way to read images - deal with interlacing: */
+
+ png_read_image(png_ptr, row_pointers);
+
+
+ out = fopen (outname, "w+b");
+ if (!out) {
+ fclose (fp);
+ return -1;
+ }
+
+
+ int i;
+
+ cinfo_out.err = jpeg_std_error (&jerr.pub);
+ jerr.pub.error_exit = my_error_exit;
+ /* Establish the setjmp return context for my_error_exit to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ goto error;
+ }
+
+ jpeg_create_compress(&cinfo_out);
+
+ jpeg_stdio_dest(&cinfo_out, out);
+
+ int sw, sh;
+ if (deadbeef->conf_get_int ("artwork.scale_towards_longer", 1)) {
+ if (width > height) {
+ sh = scaled_size;
+ sw = scaled_size * width / height;
+ }
+ else {
+ sw = scaled_size;
+ sh = scaled_size * height / width;
+ }
+ }
+ else {
+ if (width < height) {
+ sh = scaled_size;
+ sw = scaled_size * width / height;
+ }
+ else {
+ sw = scaled_size;
+ sh = scaled_size * height / width;
+ }
+ }
+
+ cinfo_out.image_width = sw;
+ cinfo_out.image_height = sh;
+ cinfo_out.input_components = 3;
+ cinfo_out.in_color_space = JCS_RGB;
+
+ jpeg_set_defaults(&cinfo_out);
+
+ jpeg_set_quality(&cinfo_out, 100, TRUE);
+ jpeg_start_compress(&cinfo_out, TRUE);
+
+ float sy = 0;
+ float dy = (float)height / (float)sh;
+
+ int input_y = 1;
+ while (input_y <= height)
+ {
+ uint8_t *buf = row_pointers[input_y-1];
+
+ // scale row
+ uint8_t out_buf[sw * cinfo_out.input_components];
+ float sx = 0;
+ float dx = (float)width/(float)sw;
+ for (int i = 0; i < sw; i++) {
+ memcpy (&out_buf[i * cinfo_out.input_components], &buf[(int)sx * cinfo_out.input_components], cinfo_out.input_components);
+ sx += dx;
+ }
+
+ while ((int)sy == input_y-1) {
+ uint8_t *ptr = out_buf;
+ jpeg_write_scanlines(&cinfo_out, &ptr, 1);
+ sy += dy;
+ }
+ input_y++;
+ }
+
+ jpeg_finish_compress(&cinfo_out); //Always finish
+ jpeg_destroy_compress(&cinfo_out); //Free resources
+
+ /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
+ png_read_end(png_ptr, info_ptr);
+
+ err = 0;
+error:
+ if (out) {
+ fclose (out);
+ }
+ if (fp) {
+ fclose (fp);
+ }
+ if (png_ptr) {
+ png_destroy_read_struct (&png_ptr, info_ptr ? &info_ptr : NULL, (png_infopp)NULL);
+ }
+
+ return err;
+}
+
#endif
#define BUFFER_SIZE 4096
@@ -396,6 +654,11 @@ copy_file (const char *in, const char *out, int img_size) {
int res = jpeg_resize (in, out, img_size);
if (res != 0) {
unlink (out);
+ res = png_resize (in, out, img_size);
+ if (res != 0) {
+ unlink (out);
+ return -1;
+ }
}
#endif
return 0;