Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QImage::scaled description and c++ code inconsistency
Forum Updated to NodeBB v4.3 + New Features

QImage::scaled description and c++ code inconsistency

Scheduled Pinned Locked Moved General and Desktop
14 Posts 5 Posters 3.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    hpaulh
    wrote on last edited by
    #1

    In the QImage::scaled function there is the following code:

    @QSize newSize = size();
    newSize.scale(s, aspectMode);
    if (newSize == size())
    return *this;@

    But the description of the scaled functions says:

    bq. Returns a copy of the image...

    "link to the description of scaled function":http://doc-snapshot.qt-project.org/qt5-5.4/qimage.html#scaled

    In my opinion this causes a confusion, because if the scaled image desired size is the size of the original image, the original image itself gets returned and not a copy of it. This can lead to program malfunctions as deleting the original image results in deleting the scaled image too.

    As I am a beginner with Qt and Qt forums, please don't get mad if this is not the place for such problems. I am just trying to improve the great thing that Qt represents.

    Thanks,
    Paul H

    1 Reply Last reply
    0
    • F Offline
      F Offline
      Francknos
      wrote on last edited by
      #2

      It's normal because if you make return *this;
      You return a pointer of object deleted ! Because "return" delete "this".

      You have to return QImage or something like that.

      1 Reply Last reply
      0
      • H Offline
        H Offline
        hpaulh
        wrote on last edited by
        #3

        That is the code found in the qt source code. I believe I cannot or should not try to modify it.

        1 Reply Last reply
        0
        • F Offline
          F Offline
          Francknos
          wrote on last edited by
          #4

          Where you find it ?

          Do you have more code ?

          1 Reply Last reply
          0
          • R Offline
            R Offline
            Rondog
            wrote on last edited by
            #5

            I don't see a problem with this.

            'this' is a pointer to the item and '*this' is the value that the pointer is pointing to (QImage in this case). There is no pointer to the original image involved. From the users point of view there is no difference.

            This check is probably there for performance reasons. If the new size is the same as the original no scaling is required so just return a copy of the original. Further in the source code there is probably something that is more complex returning an updated QImage(new_size).

            1 Reply Last reply
            0
            • H Offline
              H Offline
              hpaulh
              wrote on last edited by
              #6

              the code can be found here
              "scaled function":https://qt.gitorious.org/qt/qt/source/57756e72adf2081137b97f0e689dd16c770d10b1:src/gui/image/qimage.cpp#L4373

              1 Reply Last reply
              0
              • H Offline
                H Offline
                hpaulh
                wrote on last edited by
                #7

                To farther clear what I wanted to say:

                running the following code:

                @unsigned char * data = new unsigned char[64 * 64]{};
                QImage testImg(data, 64, 64, QImage::Format_RGB888);
                QImage scaledImg1 = testImg.scaled(64, 64);
                QImage scaledImg2 = testImg.scaled(63, 63);

                std::cout << "testImg:" << testImg.data_ptr() << "\nscaledImg1:" << scaledImg1.data_ptr() << "\nscaledImg2:" << scaledImg2.data_ptr();@

                outputs:

                testImg:00000000061E00D0
                scaledImg1:00000000061E00D0
                scaledImg2:00000000061E0190D

                In my opinion the first two pointers should not be pointing to the same address or according to the function description it should not.

                Hope this is more clear now.

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  Rondog
                  wrote on last edited by
                  #8

                  There might be more going on in the background. QString, for example, uses something called 'copy on write'. With this you can have many QString variables all pointing to one item. I don't know if this applies to QImage but it might.

                  If the two copies are the same then you should find that changing one of them (drawing an extra line or something) would update both. You will need to add some extra code to modify one of them and display both side by side.

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Hi,

                    Like Rondog wrote, QImage is one of the "implicitly shared class":http://doc.qt.io/qt-5/implicit-sharing.html#implicit-data-sharing from Qt. So as long as you're not modifying the image, there's no use to create a copy from it.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • JKSHJ Offline
                      JKSHJ Offline
                      JKSH
                      Moderators
                      wrote on last edited by
                      #10

                      [quote author="hpaulh" date="1423665080"]To farther clear what I wanted to say:

                      running the following code:

                      @unsigned char * data = new unsigned char[64 * 64]{};
                      QImage testImg(data, 64, 64, QImage::Format_RGB888);
                      QImage scaledImg1 = testImg.scaled(64, 64);
                      QImage scaledImg2 = testImg.scaled(63, 63);

                      std::cout << "testImg:" << testImg.data_ptr() << "\nscaledImg1:" << scaledImg1.data_ptr() << "\nscaledImg2:" << scaledImg2.data_ptr();@

                      outputs:

                      testImg:00000000061E00D0
                      scaledImg1:00000000061E00D0
                      scaledImg2:00000000061E0190D

                      In my opinion the first two pointers should not be pointing to the same address or according to the function description it should not. [/quote]After you print the pointer values, modify scaledImg1 using setPixel() and print the pointer values again. You'll see what Rondog and SGaist meant.

                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                      1 Reply Last reply
                      0
                      • H Offline
                        H Offline
                        hpaulh
                        wrote on last edited by
                        #11

                        [quote author="SGaist" date="1423694493"]Hi,

                        Like Rondog wrote, QImage is one of the "implicitly shared class":http://doc.qt.io/qt-5/implicit-sharing.html#implicit-data-sharing from Qt. So as long as you're not modifying the image, there's no use to create a copy from it.[/quote]

                        Thanks for your reply.

                        The problem is when you have a code like this:

                        @QImage image(...);
                        QImage scaledImage = image.scaled(QSize(same as the image));
                        someVector.push_back(scaledImage);@

                        When image goes out of scope, the scaledImage on the vector gets deleted too because it's the same (or at least the data pointer).

                        And this brings the initial stated problem: maybe if it's not too much of a trouble, state in the description of the scaled function that this situation might occur. I only posted this in the idea that other users can avoid having the same problem.

                        Thanks!

                        1 Reply Last reply
                        0
                        • H Offline
                          H Offline
                          hpaulh
                          wrote on last edited by
                          #12

                          [quote author="JKSH" date="1423699718"][quote author="hpaulh" date="1423665080"]To farther clear what I wanted to say:

                          running the following code:

                          @unsigned char * data = new unsigned char[64 * 64]{};
                          QImage testImg(data, 64, 64, QImage::Format_RGB888);
                          QImage scaledImg1 = testImg.scaled(64, 64);
                          QImage scaledImg2 = testImg.scaled(63, 63);

                          std::cout << "testImg:" << testImg.data_ptr() << "\nscaledImg1:" << scaledImg1.data_ptr() << "\nscaledImg2:" << scaledImg2.data_ptr();@

                          outputs:

                          testImg:00000000061E00D0
                          scaledImg1:00000000061E00D0
                          scaledImg2:00000000061E0190D

                          In my opinion the first two pointers should not be pointing to the same address or according to the function description it should not. [/quote]After you print the pointer values, modify scaledImg1 using setPixel() and print the pointer values again. You'll see what Rondog and SGaist meant.[/quote]

                          Thanks for your reply. Indeed, after using setPixel on the scaledImg1 the data pointer is changed.

                          Anyway, the initial stated problem was that the description of the scaled function is somehow misleading by the fact that I was expecting "a copy" of the image and not the same image. I just wanted to argue that maybe in the future the description gets updated so other people wont face the same problem.

                          1 Reply Last reply
                          0
                          • JKSHJ Offline
                            JKSHJ Offline
                            JKSH
                            Moderators
                            wrote on last edited by
                            #13

                            You're welcome.

                            [quote author="hpaulh" date="1423729910"]The problem is when you have a code like this:

                            @QImage image(...);
                            QImage scaledImage = image.scaled(QSize(same as the image));
                            someVector.push_back(scaledImage);@

                            When image goes out of scope, the scaledImage on the vector gets deleted too because it's the same (or at least the data pointer).[/quote]No it won't.

                            Qt value classes use reference counting. When image goes out of scope, the destructor checks the reference counter. It sees that another copy (scaledImage) is using that same vector, so it won't delete the vector.

                            [quote author="hpaulh" date="1423730259"]Anyway, the initial stated problem was that the description of the scaled function is somehow misleading by the fact that I was expecting "a copy" of the image and not the same image. I just wanted to argue that maybe in the future the description gets updated so other people wont face the same problem.[/quote]But there IS a copy!

                            @
                            // Like you said...
                            testImg.data_ptr() == scaledImg1.data_ptr();

                            // But...
                            &testImg != &scaledImg1;
                            @

                            scaledImg1 is a copy of testImg, even though it shares the same data as testImg.

                            This type of copying is called shallow copying: Multiple copies share the same block of data memory. The opposite is deep copying, where each copy is allocated its own unique data memory.

                            This is documented at http://doc.qt.io/qt-5/implicit-sharing.html.

                            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                            1 Reply Last reply
                            0
                            • H Offline
                              H Offline
                              hpaulh
                              wrote on last edited by
                              #14

                              Thank you all for making lots of things more clear now!

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved