winemenubuilder: Use png file format for icons with 24 & 32-bit color.

Vitaliy Margolen wine-patch at kievinfo.com
Mon Jan 16 15:54:04 CST 2006


ChangeLog:
winemenubuilder: Use png file format for icons with 24 & 32-bit color.
This implementation doesn't account for AND mask and doesn't set few other properties.
However it worked for me on number of different icons and it's still better then not creating
icon at all.

 configure                                  |   82 ++++++++++++++++++++++++
 configure.ac                               |   10 +++
 include/config.h.in                        |    3 +
 programs/winemenubuilder/Makefile.in       |    2 -
 programs/winemenubuilder/winemenubuilder.c |   95 +++++++++++++++++++++++++++-
 5 files changed, 186 insertions(+), 6 deletions(-)
-------------- next part --------------
39080605f51d1ea844b8ce828ca92fc7c083be26
diff --git a/configure b/configure
index 1880b82..2e4a869 100755
--- a/configure
+++ b/configure
@@ -311,7 +311,7 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS DLLDEFS build build_cpu build_vendor build_os host host_cpu host_vendor host_os WIN16_FILES WIN16_INSTALL SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPPBIN ac_ct_CPPBIN TOOLSDIR CPP X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LEX LEXLIB LEX_OUTPUT_ROOT XLEX BISON AS ac_ct_AS LD ac_ct_LD AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP WINDRES ac_ct_WINDRES LN_S LN EGREP LDCONFIG INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LINT LINTFLAGS FONTFORGE PKG_CONFIG PRELINK LIBPTHREAD XLIB XFILES OPENGLFILES GLU32FILES OPENGL_LIBS GLUT_LIBS GLUT32FILES NASLIBS XML2LIBS XML2INCL XSLTLIBS XSLTINCL CURSESLIBS sane_devel SANELIBS SANEINCL ICULIBS LCMSLIBS LDAPLIBS FREETYPELIBS FREETYPEINCL ft_devel ft_devel2 FONTSSUBDIRS ARTSCCONFIG ARTSLIBS ARTSINCL ESDCONFIG ESDLIBS ESDINCL ALSALIBS AUDIOIOLIBS EXTRACFLAGS BUILTINFLAG DLLEXT DLLFLAGS DLLIBS LDSHARED LDDLLFLAGS LIBEXT IMPLIBEXT DLLTOOL ac_ct_DLLTOOL DLLWRAP ac_ct_DLLWRAP LDEXECFLAGS COREFOUNDATIONLIB IOKITLIB LDLIBWINEFLAGS CROSSTEST CROSSCC CROSSWINDRES LDPATH CRTLIBS SOCKETLIBS WINE_BINARIES MAIN_BINARY LDD LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS DLLDEFS build build_cpu build_vendor build_os host host_cpu host_vendor host_os WIN16_FILES WIN16_INSTALL SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPPBIN ac_ct_CPPBIN TOOLSDIR CPP X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LEX LEXLIB LEX_OUTPUT_ROOT XLEX BISON AS ac_ct_AS LD ac_ct_LD AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP WINDRES ac_ct_WINDRES LN_S LN EGREP LDCONFIG INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LINT LINTFLAGS FONTFORGE PKG_CONFIG PRELINK LIBPTHREAD XLIB XFILES OPENGLFILES GLU32FILES OPENGL_LIBS GLUT_LIBS GLUT32FILES NASLIBS XML2LIBS XML2INCL XSLTLIBS XSLTINCL CURSESLIBS sane_devel SANELIBS SANEINCL ICULIBS LCMSLIBS PNGLIBS LDAPLIBS FREETYPELIBS FREETYPEINCL ft_devel ft_devel2 FONTSSUBDIRS ARTSCCONFIG ARTSLIBS ARTSINCL ESDCONFIG ESDLIBS ESDINCL ALSALIBS AUDIOIOLIBS EXTRACFLAGS BUILTINFLAG DLLEXT DLLFLAGS DLLIBS LDSHARED LDDLLFLAGS LIBEXT IMPLIBEXT DLLTOOL ac_ct_DLLTOOL DLLWRAP ac_ct_DLLWRAP LDEXECFLAGS COREFOUNDATIONLIB IOKITLIB LDLIBWINEFLAGS CROSSTEST CROSSCC CROSSWINDRES LDPATH CRTLIBS SOCKETLIBS WINE_BINARIES MAIN_BINARY LDD LIBOBJS LTLIBOBJS'
 ac_subst_files='MAKE_RULES MAKE_DLL_RULES MAKE_IMPLIB_RULES MAKE_TEST_RULES MAKE_LIB_RULES MAKE_PROG_RULES'
 
 # Initialize some variables set by options.
@@ -7091,6 +7091,7 @@ for ac_header in \
 	poll.h \
 	process.h \
 	pthread.h \
+	png.h \
 	pwd.h \
 	regex.h \
 	sched.h \
@@ -9613,6 +9614,84 @@ fi
 
 fi
 
+PNGLIBS=""
+
+if test "$ac_cv_header_png_h" = "yes"
+then
+    echo "$as_me:$LINENO: checking for png_set_IHDR in -lpng" >&5
+echo $ECHO_N "checking for png_set_IHDR in -lpng... $ECHO_C" >&6
+if test "${ac_cv_lib_png_png_set_IHDR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char png_set_IHDR ();
+int
+main ()
+{
+png_set_IHDR ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_png_png_set_IHDR=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_png_png_set_IHDR=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_png_png_set_IHDR" >&5
+echo "${ECHO_T}$ac_cv_lib_png_png_set_IHDR" >&6
+if test $ac_cv_lib_png_png_set_IHDR = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PNG 1
+_ACEOF
+
+         PNGLIBS="-lpng"
+fi
+
+fi
+
 LDAPLIBS=""
 
 if test "$ac_cv_header_ldap_h" = "yes" -a "$ac_cv_header_lber_h" = "yes"
@@ -19689,6 +19768,7 @@ s, at SANELIBS@,$SANELIBS,;t t
 s, at SANEINCL@,$SANEINCL,;t t
 s, at ICULIBS@,$ICULIBS,;t t
 s, at LCMSLIBS@,$LCMSLIBS,;t t
+s, at PNGLIBS@,$PNGLIBS,;t t
 s, at LDAPLIBS@,$LDAPLIBS,;t t
 s, at FREETYPELIBS@,$FREETYPELIBS,;t t
 s, at FREETYPEINCL@,$FREETYPEINCL,;t t
diff --git a/configure.ac b/configure.ac
index b458d7d..c1b78b3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -224,6 +224,7 @@ AC_CHECK_HEADERS(\
 	poll.h \
 	process.h \
 	pthread.h \
+	png.h \
 	pwd.h \
 	regex.h \
 	sched.h \
@@ -542,6 +543,15 @@ then
          LCMSLIBS="-llcms"])
 fi
 
+dnl **** Check for libpng ***
+AC_SUBST(PNGLIBS,"")
+if test "$ac_cv_header_png_h" = "yes"
+then
+    AC_CHECK_LIB(png, png_set_IHDR,
+        [AC_DEFINE(HAVE_PNG, 1, [Define if you have the libpng development environment])
+         PNGLIBS="-lpng"])
+fi
+
 dnl **** Check for OpenLDAP ***
 AC_SUBST(LDAPLIBS,"")
 if test "$ac_cv_header_ldap_h" = "yes" -a "$ac_cv_header_lber_h" = "yes"
diff --git a/include/config.h.in b/include/config.h.in
index 51ecdc5..95c7149 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -458,6 +458,9 @@
 /* Define to 1 if the system has the type `pid_t'. */
 #undef HAVE_PID_T
 
+/* Define to 1 if you have the <png.h> header file. */
+#undef HAVE_PNG_H
+
 /* Define to 1 if you have the <poll.h> header file. */
 #undef HAVE_POLL_H
 
diff --git a/programs/winemenubuilder/Makefile.in b/programs/winemenubuilder/Makefile.in
index 48ac38d..adb79a1 100644
--- a/programs/winemenubuilder/Makefile.in
+++ b/programs/winemenubuilder/Makefile.in
@@ -5,7 +5,7 @@ VPATH     = @srcdir@
 MODULE    = winemenubuilder.exe
 APPMODE   = -mwindows
 IMPORTS   = shell32 ole32 user32 advapi32 kernel32
-EXTRALIBS = -luuid
+EXTRALIBS = -luuid @PNGLIBS@
 
 C_SRCS = \
 	winemenubuilder.c
diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index 08c0760..93d883f 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -62,6 +62,9 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#ifdef HAVE_PNG_H
+#include <png.h>
+#endif
 #include <errno.h>
 #include <stdarg.h>
 
@@ -143,7 +146,87 @@ typedef struct
  * FIXME: should not use stdio
  */
 
-static BOOL SaveIconResAsXPM(const BITMAPINFO *pIcon, const char *szXPMFileName, LPCWSTR commentW)
+#ifdef HAVE_PNG_H
+static BOOL SaveIconResAsPNG(const BITMAPINFO *pIcon, char *szPNGFileName, LPCWSTR commentW)
+{
+    FILE *fPNGFile;
+    png_structp png_ptr;
+    png_infop info_ptr;
+    int i;
+    int nXORWidthBytes, bpp, color_type = 0;
+    const BYTE *pXOR;
+    int width  = pIcon->bmiHeader.biWidth;
+    int height = pIcon->bmiHeader.biHeight / 2;
+
+    if (pIcon->bmiHeader.biClrUsed)
+    {
+        WINE_FIXME("Indexed colors are not supported\n");
+        return FALSE;
+    }
+
+    switch (pIcon->bmiHeader.biBitCount)
+    {
+    case 32:
+        color_type |= PNG_COLOR_MASK_ALPHA;
+        /* fall through */
+    case 24:
+        bpp = 8;
+        color_type |= PNG_COLOR_MASK_COLOR;
+        break;
+    default:
+        return FALSE;
+    }
+
+    memcpy(szPNGFileName + strlen(szPNGFileName) - 3, "png", 3);
+    if (!(fPNGFile = fopen(szPNGFileName, "w")))
+    {
+        WINE_ERR("unable to open '%s' for writing: %s\n", szPNGFileName, strerror(errno));
+        return FALSE;
+    }
+
+    nXORWidthBytes = 4 * ((width * pIcon->bmiHeader.biBitCount / 32) +
+                         ((width * pIcon->bmiHeader.biBitCount % 32) > 0));
+    pXOR = (const BYTE*) pIcon + sizeof (BITMAPINFOHEADER) +
+            (pIcon->bmiHeader.biClrUsed * sizeof (RGBQUAD));
+
+    if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) ||
+        !(info_ptr = png_create_info_struct(png_ptr)))
+        goto error;
+
+    if (setjmp(png_jmpbuf(png_ptr)))
+    {
+        /* All future errors jump here */
+        WINE_ERR("png error\n");
+        goto error;
+    }
+
+    png_init_io(png_ptr, fPNGFile);
+    png_set_IHDR(png_ptr, info_ptr, width, height, bpp,
+                 color_type,
+                 PNG_INTERLACE_NONE,
+                 PNG_COMPRESSION_TYPE_DEFAULT,
+                 PNG_FILTER_TYPE_DEFAULT);
+
+    png_write_info(png_ptr, info_ptr);
+    png_set_bgr(png_ptr);
+    for (i = height - 1; i >= 0 ; i--)
+        png_write_row(png_ptr, (png_bytep)pXOR + nXORWidthBytes * i);
+    png_write_end(png_ptr, info_ptr);
+
+    png_destroy_write_struct(&png_ptr, &info_ptr);
+    if (png_ptr) png_destroy_write_struct(&png_ptr, NULL);
+    fclose(fPNGFile);
+    return TRUE;
+
+ error:
+    if (png_ptr) png_destroy_write_struct(&png_ptr, NULL);
+    fclose(fPNGFile);
+    unlink(szPNGFileName);
+    return FALSE;
+}
+#endif
+
+static BOOL SaveIconResAsXPM(const BITMAPINFO *pIcon, char *szXPMFileName, LPCWSTR commentW)
 {
     FILE *fXPMFile;
     int nHeight;
@@ -158,6 +241,10 @@ static BOOL SaveIconResAsXPM(const BITMA
     int i,j;
     char *comment;
 
+#ifdef HAVE_PNG_H
+    if (pIcon->bmiHeader.biBitCount >= 24) return SaveIconResAsPNG(pIcon, szXPMFileName, commentW);
+#endif
+
     if (!((pIcon->bmiHeader.biBitCount == 4) || (pIcon->bmiHeader.biBitCount == 8)))
     {
         WINE_FIXME("Unsupported color depth %d-bit\n", pIcon->bmiHeader.biBitCount);
@@ -261,7 +348,7 @@ static BOOL CALLBACK EnumResNameProc(HMO
         return TRUE;
 }
 
-static BOOL extract_icon32(LPCWSTR szFileName, int nIndex, const char *szXPMFileName)
+static BOOL extract_icon32(LPCWSTR szFileName, int nIndex, char *szXPMFileName)
 {
     HMODULE hModule;
     HRSRC hResInfo;
@@ -350,7 +437,7 @@ static BOOL extract_icon32(LPCWSTR szFil
     return ret;
 }
 
-static BOOL ExtractFromEXEDLL(LPCWSTR szFileName, int nIndex, const char *szXPMFileName)
+static BOOL ExtractFromEXEDLL(LPCWSTR szFileName, int nIndex, char *szXPMFileName)
 {
     if (!extract_icon32(szFileName, nIndex, szXPMFileName) /*&&
         !extract_icon16(szFileName, szXPMFileName)*/)
@@ -358,7 +445,7 @@ static BOOL ExtractFromEXEDLL(LPCWSTR sz
     return TRUE;
 }
 
-static int ExtractFromICO(LPCWSTR szFileName, const char *szXPMFileName)
+static int ExtractFromICO(LPCWSTR szFileName, char *szXPMFileName)
 {
     FILE *fICOFile;
     ICONDIR iconDir;


More information about the wine-patches mailing list