Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Returning QByteArray as Qvariant

    General and Desktop
    qvariant qbytearray qpixmap return
    4
    8
    3031
    Loading More Posts
    • 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
      Euclide last edited by Euclide

      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 Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        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 Reply Quote 0
        • E
          Euclide @SGaist last edited by

          @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.Hilk 1 Reply Last reply Reply Quote 0
          • E
            Euclide @SGaist last edited by Euclide

            @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 Reply Quote 0
            • J.Hilk
              J.Hilk Moderators @Euclide last edited by

              @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

              Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


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

              1 Reply Last reply Reply Quote 1
              • Christian Ehrlicher
                Christian Ehrlicher Lifetime Qt Champion last edited by

                @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 has to stay free or it will die.

                E 1 Reply Last reply Reply Quote 4
                • E
                  Euclide @Christian Ehrlicher last edited by

                  @Christian-Ehrlicher Yes I agree.

                  1 Reply Last reply Reply Quote 0
                  • E
                    Euclide last edited by Euclide

                    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 Reply Quote 1
                    • First post
                      Last post