Problem with included pnglib


#1

Hi,

I have a problem where each time a PNG is loaded, even the included stock images for folder icons, the app compiled with Juce crashes. The problem goes away when undefining JUCE_INCLUDE_PNGLIB_CODE in juce_Config.h. Looking at the stack trace from the crash, I find this:

#0 ( crc32(buf=0x0, len=-1250873772) (/home/johannes/code/juced/juce/src/juce_extended/audio/formats/../../dependancies/mpc/common/crc32.c:55) #1 0x81b924d png_calculate_crc(png_ptr=0xb5712d78, ptr=0xb5712e54 "IHDR", length=4) (/home/johannes/code/juced/juce/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/png.c:229) #2 0x81b940a png_crc_read(png_ptr=0xb5712d78, buf=0xb5712e54 "IHDR", length=4) (/home/johannes/code/juced/juce/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/pngrutil.c:101) #3 0x81c3118 png_read_info(png_ptr=0xb5712d78, info_ptr=0xb57174e8) (/home/johannes/code/juced/juce/src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/pngread.c:410) #4 0x81c381c juce::juce_loadPNGImageFromStream(in=@0xbfdecb1c) (/home/johannes/code/juced/juce/src/juce_appframework/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp:164) #5 0x8121a8f juce::PNGImageFormat::decodeImage(this=0x822f8dc, in=@0xbfdecb1c) (/home/johannes/code/juced/juce/src/juce_appframework/gui/graphics/imaging/juce_ImageFileFormat.cpp:67) #6 0x8121759 juce::ImageFileFormat::loadFrom(input=@0xbfdecb1c) (/home/johannes/code/juced/juce/src/juce_appframework/gui/graphics/imaging/juce_ImageFileFormat.cpp:197) #7 0x81217a9 juce::ImageFileFormat::loadFrom(rawData=0x81df920, numBytes=2462) (/home/johannes/code/juced/juce/src/juce_appframework/gui/graphics/imaging/juce_ImageFileFormat.cpp:220) #8 0x8120387 juce::ImageCache::getFromMemory(imageData=0x81df920, dataSize=2462) (/home/johannes/code/juced/juce/src/juce_appframework/gui/graphics/imaging/juce_ImageCache.cpp:233) #9 0x80c2666 juce::LookAndFeel::getDefaultFolderImage(this=0x82386c8) (/home/johannes/code/juced/juce/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp:2728)

Now, the code in png.c calling crc32() does this:

if (need_crc) png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);

So it should call the function defined in juce_core/io/streams/zlib/crc32.c,
'unsigned long ZEXPORT crc32 (unsigned long crc, const unsigned char FAR *buf, unsigned len)'
But it ends up calling a crc32 function with different signature, defined in the ‘mpc’ lib.

The pnglib and zlib code gets #included surrounded by an extern “C” block in juce_PNGLoader.cpp, so I reckon what happens is this:
The compiler resolves the crc32 function correctly, but because it is extern “C”, no name mangling is done, so the linker resolves the ‘crc32’ symbol to the wrong function.
I am using ‘gcc version 4.2.4 (Ubuntu 4.2.4-1ubuntu4)’ .

I see 2 possible workarounds:

  • rename one of the crc32 functions
  • use a newer zlib and #define Z_PREFIX. This redefines all zlib functions with a z_ prefix (see zconf.h) which might remove the problem.

#2

How about this tweak to juce_GZIPDecompressorInputStream.cpp:

extern "C" { #undef OS_CODE #undef fdopen #define ZLIB_INTERNAL #define crc32 juce_crc32

(I’ve not tried it, it’s just a suggestion…)


#3

Sorry - ignore that last post.

But I just checked and it does already use Z_PREFIX…


#4

Apparently… Anyway, there is a simple fix: make mpc’s crc32 function static.

/* Return the CRC of the bytes buf[0..len-1]. */ static unsigned long crc32(unsigned char *buf, int len) { return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL; }


#5

Where’s that? Can’t find that code anywhere…


#6

Sorry, that code actually is present only in jucetice, not in Juce… Disregard the topic altogether… I’ll report it to kraken. :oops: