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. Returning QByteArray as Qvariant
Forum Updated to NodeBB v4.3 + New Features

Returning QByteArray as Qvariant

Scheduled Pinned Locked Moved Solved General and Desktop
qvariantqbytearrayqpixmapreturn
8 Posts 4 Posters 4.2k 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.
  • E Offline
    E Offline
    Euclide
    wrote on 8 Apr 2018, 21:59 last edited by Euclide 4 Aug 2018, 22:01
    #1

    Hello I am experiencing some problems with my code. I am implementing a function that returns tag value from a music:

    QVariant getTagValue (TagKey key)
    

    For the cover the return value is a QByteArray. The problem shows up when I try to convert the returned value to a QPixmap.

    ...
    QPixmap image;
    QByteArray data = music.getTagValue (Music::TagKey::Cover).toByteArray();
    bool ok = image.loadFromData(data);    //Returns false
                                           //Error: Corrupt JPEG data: premature end of data segment
                                           //Unsupported marker type 0x0b
    

    But when I do the same thing inside the function just before the return statement it just works fine.
    How do you explain that?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 8 Apr 2018, 22:01 last edited by
      #2

      Hi,

      How is getTagValue implemented ?

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

      E 2 Replies Last reply 9 Apr 2018, 00:40
      0
      • S SGaist
        8 Apr 2018, 22:01

        Hi,

        How is getTagValue implemented ?

        E Offline
        E Offline
        Euclide
        wrote on 9 Apr 2018, 00:40 last edited by
        #3

        @SGaist The implementation:

        QVariant Music::getTagValue(Music::TagKey key)
        {
           TagParser::TagValue value;
           value = getRawValue ((TagParser::KnownField) key);
        
           if (key == ... )
           ....
        
           else if (key == TagKey::Cover)
              {
                 if (value.isEmpty ())
                    return QByteArray  ();
        
                 QByteArray data = QByteArray::fromRawData (value.dataPointer (), value.dataSize ());
        
                 return data;
              }
           ...
        }
        
        J 1 Reply Last reply 9 Apr 2018, 04:53
        0
        • S SGaist
          8 Apr 2018, 22:01

          Hi,

          How is getTagValue implemented ?

          E Offline
          E Offline
          Euclide
          wrote on 9 Apr 2018, 00:55 last edited by Euclide 4 Sept 2018, 01:04
          #4

          @SGaist

          TagParser::TagValue Music::getRawValue(TagParser::KnownField field)
          {
             if (fileInfo.isOpen ())
                {
                   auto tags = fileInfo.tags ();
          
                   for (uint i=0; i < tags.size (); i++)
                      {
                         TagParser::TagValue value = tags.at (i)->value (field);
                         if (!value.isEmpty ())
                            return value;
                      }
               }
          
             return TagParser::TagValue();
          }
          

          TagParser is library from GitHub.
          I already made the following implementation with the library and it worked perfectly:

          QPixmap cover()
          {
             TagParser::TagValue value;
             value = getRawValue (TagParser::KnownField::Cover);
          
             if (value.isEmpty ())
                return QByteArray  ();
          
             QByteArray data = QByteArray::fromRawData (value.dataPointer (), value.dataSize ());
             QPixmap pixmap;
             pixmap.loadFromData (data);
          
             return pixmap;
          }
          
          1 Reply Last reply
          0
          • E Euclide
            9 Apr 2018, 00:40

            @SGaist The implementation:

            QVariant Music::getTagValue(Music::TagKey key)
            {
               TagParser::TagValue value;
               value = getRawValue ((TagParser::KnownField) key);
            
               if (key == ... )
               ....
            
               else if (key == TagKey::Cover)
                  {
                     if (value.isEmpty ())
                        return QByteArray  ();
            
                     QByteArray data = QByteArray::fromRawData (value.dataPointer (), value.dataSize ());
            
                     return data;
                  }
               ...
            }
            
            J Offline
            J Offline
            J.Hilk
            Moderators
            wrote on 9 Apr 2018, 04:53 last edited by
            #5

            @Euclide said in Returning QByteArray as Qvariant:

            QVariant Music::getTagValue(Music::TagKey key)
            {....
            
                     QByteArray data = QByteArray::fromRawData (value.dataPointer (), value.dataSize ());
            
                     return data;
                  }
               ...
            }
            

            I'm not sure if that implicit conversion will work. You should try:

            return QVariant(data);


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            1
            • C Offline
              C Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on 9 Apr 2018, 17:55 last edited by
              #6

              @Euclide said in Returning QByteArray as Qvariant:

              QByteArray data = QByteArray::fromRawData (value.dataPointer (), value.dataSize ());

              This is very very dangerous in the current use case. When value goes out of scope before data (which is likely the case here since data is moved into the QVariant) the next access to this data will likely point to uninitialized memory.
              Don't use QByteArray::fromRawData() when you don't know what you're doing!

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              E 1 Reply Last reply 10 Apr 2018, 02:06
              4
              • C Christian Ehrlicher
                9 Apr 2018, 17:55

                @Euclide said in Returning QByteArray as Qvariant:

                QByteArray data = QByteArray::fromRawData (value.dataPointer (), value.dataSize ());

                This is very very dangerous in the current use case. When value goes out of scope before data (which is likely the case here since data is moved into the QVariant) the next access to this data will likely point to uninitialized memory.
                Don't use QByteArray::fromRawData() when you don't know what you're doing!

                E Offline
                E Offline
                Euclide
                wrote on 10 Apr 2018, 02:06 last edited by
                #7

                @Christian-Ehrlicher Yes I agree.

                1 Reply Last reply
                0
                • E Offline
                  E Offline
                  Euclide
                  wrote on 10 Apr 2018, 02:17 last edited by Euclide 4 Oct 2018, 02:21
                  #8

                  I found where the problem was!

                  As Christian Ehrlicher said according to the Documentation QByteArray::fromRawData() only store the pointer to the data. That explain why it doensn't work outside the function since the data goes out of scope. Instead of using this method I used one the constructors that make deep copy of the data. And it just works fine!

                       QByteArray data (value.dataPointer (), value.dataSize ());
                       return data;
                  

                  Thanks all!

                  1 Reply Last reply
                  1

                  7/8

                  10 Apr 2018, 02:06

                  • Login

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