gansub
gansub

Reputation: 1174

Compilation error compiling Qt with icpc on Ubuntu 14.04

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

Answers (1)

Jan Kundr&#225;t
Jan Kundr&#225;t

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

Related Questions