diff options
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | lib-x86-32/include/pnglibconf.h | 174 | ||||
-rw-r--r-- | plugins/artwork/Makefile.am | 2 | ||||
-rw-r--r-- | plugins/artwork/artwork.c | 265 |
5 files changed, 446 insertions, 3 deletions
@@ -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; |