Reputation: 1174
I am trying to compile Qt with Intel icpc on Ubuntu 14.04 and I get a compilation error on this file - qpnghandler.cpp
From the qpnghandler.cpp file that I have this is the relevant code -
static
void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, float screen_gamma=0.0)
{
if (screen_gamma != 0.0 && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
double file_gamma;
png_get_gAMA(png_ptr, info_ptr, &file_gamma);
png_set_gamma(png_ptr, screen_gamma, file_gamma);
}
png_uint_32 width;
png_uint_32 height;
int bit_depth;
int color_type;
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
if (color_type == PNG_COLOR_TYPE_GRAY) {
// Black & White or 8-bit grayscale
if (bit_depth == 1 && info_ptr->channels == 1) {
png_set_invert_mono(png_ptr);
png_read_update_info(png_ptr, info_ptr);
if (image.size() != QSize(width, height) || image.format() != QImage::Format_Mono) {
image = QImage(width, height, QImage::Format_Mono);
if (image.isNull())
return;
}
image.setColorCount(2);
image.setColor(1, qRgb(0,0,0));
image.setColor(0, qRgb(255,255,255));
} else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_set_expand(png_ptr);
png_set_strip_16(png_ptr);
png_set_gray_to_rgb(png_ptr);
if (image.size() != QSize(width, height) || image.format() != QImage::Format_ARGB32) {
image = QImage(width, height, QImage::Format_ARGB32);
if (image.isNull())
return;
}
if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
png_set_swap_alpha(png_ptr);
png_read_update_info(png_ptr, info_ptr);
} else {
if (bit_depth == 16)
png_set_strip_16(png_ptr);
else if (bit_depth < 8)
png_set_packing(png_ptr);
int ncols = bit_depth < 8 ? 1 << bit_depth : 256;
png_read_update_info(png_ptr, info_ptr);
if (image.size() != QSize(width, height) || image.format() != QImage::Format_Indexed8) {
image = QImage(width, height, QImage::Format_Indexed8);
if (image.isNull())
return;
}
image.setColorCount(ncols);
for (int i=0; i<ncols; i++) {
int c = i*255/(ncols-1);
image.setColor(i, qRgba(c,c,c,0xff));
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
#if PNG_LIBPNG_VER_MAJOR < 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR < 4)
const int g = info_ptr->trans_values.gray;
#else
const int g = info_ptr->trans_color.gray;
#endif
if (g < ncols) {
image.setColor(g, 0);
}
}
}
} else if (color_type == PNG_COLOR_TYPE_PALETTE
&& png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)
&& info_ptr->num_palette <= 256)
{
// 1-bit and 8-bit color
if (bit_depth != 1)
png_set_packing(png_ptr);
png_read_update_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
QImage::Format format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8;
if (image.size() != QSize(width, height) || image.format() != format) {
image = QImage(width, height, format);
if (image.isNull())
return;
}
image.setColorCount(info_ptr->num_palette);
int i = 0;
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
while (i < info_ptr->num_trans) {
image.setColor(i, qRgba(
info_ptr->palette[i].red,
info_ptr->palette[i].green,
info_ptr->palette[i].blue,
#if PNG_LIBPNG_VER_MAJOR < 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR < 4)
info_ptr->trans[i]
#else
info_ptr->trans_alpha[i]
#endif
)
);
i++;
}
}
while (i < info_ptr->num_palette) {
image.setColor(i, qRgba(
info_ptr->palette[i].red,
info_ptr->palette[i].green,
info_ptr->palette[i].blue,
0xff
)
);
i++;
}
} else {
// 32-bit
if (bit_depth == 16)
png_set_strip_16(png_ptr);
png_set_expand(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
QImage::Format format = QImage::Format_ARGB32;
// Only add filler if no alpha, or we can get 5 channel data.
if (!(color_type & PNG_COLOR_MASK_ALPHA)
&& !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_set_filler(png_ptr, 0xff, QSysInfo::ByteOrder == QSysInfo::BigEndian ?
PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
// We want 4 bytes, but it isn't an alpha channel
format = QImage::Format_RGB32;
}
if (image.size() != QSize(width, height) || image.format() != format) {
image = QImage(width, height, format);
if (image.isNull())
return;
}
if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
png_set_swap_alpha(png_ptr);
png_read_update_info(png_ptr, info_ptr);
}
// Qt==ARGB==Big(ARGB)==Little(BGRA)
if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
png_set_bgr(png_ptr);
}
}
Can somebody guide me on what modifications I can bring to that file so that I can compile qpnghandler.cpp ?
icpc -c -wd654,1572 -g -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -O2 -fvisibility=hidden -fvisibility-inlines-hidden -D_REENTRANT -I/usr/include/freetype2 -fPIC -DQT_SHARED -DQT_BUILD_GUI_LIB -DQT_NO_USING_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT3_SUPPORT -DQT_MOC_COMPAT -DQT_HAVE_MMX -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_NO_OPENTYPE -DQT_NO_STYLE_MAC -DQT_NO_STYLE_WINDOWSVISTA -DQT_NO_STYLE_WINDOWSXP -DQT_NO_STYLE_WINDOWSCE -DQT_NO_STYLE_WINDOWSMOBILE -DQT_NO_STYLE_S60 -DQ_INTERNAL_QAPP_SRC -DQT_NO_DEBUG -DQT_CORE_LIB -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -I../../mkspecs/linux-icc -I. -I../../include/QtCore -I../../include -I../../include/QtGui -I.rcc/release-shared -I../3rdparty/xorg -I/usr/include/freetype2 -I../3rdparty/harfbuzz/src -Idialogs -I.moc/release-shared -I/usr/X11R6/include -I.uic/release-shared -o .obj/release-shared/qpnghandler.o image/qpnghandler.cpp
image/qpnghandler.cpp(169): error: pointer to incomplete class type is not allowed
if (bit_depth == 1 && info_ptr->channels == 1) {
^
image/qpnghandler.cpp(214): error: pointer to incomplete class type is not allowed
const int g = info_ptr->trans_color.gray;
^
image/qpnghandler.cpp(223): error: pointer to incomplete class type is not allowed
&& info_ptr->num_palette <= 256)
^
image/qpnghandler.cpp(236): error: pointer to incomplete class type is not allowed
image.setColorCount(info_ptr->num_palette);
^
image/qpnghandler.cpp(239): error: pointer to incomplete class type is not allowed
while (i < info_ptr->num_trans) {
^
image/qpnghandler.cpp(241): error: pointer to incomplete class type is not allowed
info_ptr->palette[i].red,
^
image/qpnghandler.cpp(242): error: pointer to incomplete class type is not allowed
info_ptr->palette[i].green,
^
Upvotes: 0
Views: 276
Reputation: 3816
TL;DR: you're compiling an ancient Qt against a new libpng. This new libpng has changed its API in an incompatible way. Newer Qt supports this newer libpng just fine.
Qt 4.6 was released in 2009. If you're for some reason stuck with Qt 4.x, you should definitely use the 4.8 branch -- because it contains security and portability fixes like the one which solves the problem that you're hitting. However, upstream support for the 4.x branch of Qt has ended, so you should probably look into porting your code to Qt 5.x if you're actively working on this project (and if you expect to continue working on it in future).
If you desperately want to create a Frankenstein build of Qt 4.6 for some reason (maybe you're bisecting a tricky error in Qt 4 and want to reach back seven years into the history to see if that version was buggy, too), you should look into using the 1.4 branch of libpng
. If that is not possible for you for some reason, then you can carefully port the Qt's PNG code to the API of libpng-1.5
or libpng-1.6
. Details on how to do this are available at libpng 1.5.10 error: dereferencing pointer to incomplete type.
Upvotes: 2