Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-20026

Access violation reading when drawing QImage

    XMLWordPrintable

Details

    • Bug
    • Resolution: Cannot Reproduce
    • P2: Important
    • None
    • 4.7.3
    • GUI: Painting
    • None
    • Qt 4.7.3 for MS VC 2010, Win32, Microsoft Visual Studio 2010, SSE enabled

    Description

      The following code causes an access violation reading or an assert:

      #include <Qt>
      #include <QImage>
      #include <QPainter>
      #include <QString>
      
      
      const quint32 GUARD1 = 1;
      const quint32 GUARD2 = 2;
      
      const int IMG_WIDTH  = 4;
      const int IMG_HEIGHT = 2;
      
      const uint SRC_COLOR = 0xAAAAAAAA;
      const uint DST_COLOR = 0;
      
      
      int main( int /*agrc*/, char ** /*argv*/ )
      {
          // The image format should be QImage::Format_ARGB32_Premultiplied, because
          // the issue is in src/gui/painting/qpaintengine_raster.cpp, method
          // void QRasterPaintEngine::drawImage(const QRectF &r,
          //                                    const QImage &img,
          //                                    const QRectF &sr,
          //                                    Qt::ImageConversionFlags),
          // line 2777
          QImage src( IMG_WIDTH, IMG_HEIGHT, QImage::Format_ARGB32_Premultiplied );
          src.fill( SRC_COLOR );
      
          QImage dst( IMG_WIDTH, IMG_HEIGHT, QImage::Format_ARGB32_Premultiplied );
          dst.fill( DST_COLOR );
      
          QPainter painter( &dst );
          // The issue is here!
          painter.drawImage( QPointF( 0, 0 ), src, QRectF( 0.0, 0.5, IMG_WIDTH, 1.5 ) );
      
          const uint * dstData = reinterpret_cast<const uint *>( dst.bits() );
          for ( int y = 0; y < IMG_HEIGHT; ++y )
          {
              for ( int x = 0; x < IMG_WIDTH; ++x )
              {
                  uint pixel = *( dstData + y * IMG_WIDTH + x );
                  Q_ASSERT_X(
                      pixel == SRC_COLOR || pixel == DST_COLOR,
                      "",
                      QString( "x = %1, y = %2, pixel = 0x%3, expected 0x%4 or 0x%5" ).
                          arg( x ).arg( y ).arg( pixel, 0, 16 ).
                          arg( SRC_COLOR, 0, 16 ).arg( DST_COLOR, 0, 16 ).
                          toAscii()
                  );
              }
          }
      
          return 0;
      }
      

      What happens:
      painter.drawImage gets QRectF with the top = 0.5 and the height = 1.5. The height of the source image is 2, so the QRectF is correct.
      But QRasterPaintEngine::drawImage converts QRectF( 0.0, 0.5, 4.0, 1.5 ) to QRect( 0, 1, 4, 2 ) (see qpaintengine_raster.cpp, line 2777), which has the height = 2 and the top = 1.
      This QRect exceeds the source image rectangle, and later this causes an access violation reading.

      Workaround:
      Temporarily do not use overloaded QPainter::drawImage methods that get QRectF.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            rodal Samuel Rødal
            york Yuriy Pishchalnikov
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes