PDA

View Full Version : Errors when reading a QImage sent through a socket



volatile_ah
28th July 2009, 11:55
Hey guys,

First up I'm new to this whole Qt-programming, but it's been a fun challenge thus far.

What I'm trying to do is send a QImage across the network using a QTcpSocket. Let's for a second pretend I don't care about bandwidth, I just want to try and get this working.

Below is my server code (snippet):



QBuffer image_buffer;
QImageWriter writer(&image_buffer, "PNG");
if(!writer.write(captured_image.getImage()))
qWarning()<<"ERROR: Unable to write image to buffer: "<<writer.errorString();

QByteArray data;
QDataStream out(&data, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out<<(quint32)image_buffer.data().size();

qDebug()<<"Image size = "<<image_buffer.data().size();

out<<image_buffer.data();

video_socket.write(data);
if(!video_socket.waitForBytesWritten())
qWarning()<<"ERROR: Unable to send image: "<<video_socket.errorString();


My client code (snippet) is as follows:



QDataStream in(&video_socket);
in.setVersion(QDataStream::Qt_4_0);

while(video_socket.bytesAvailable() < sizeof(quint32))
{
qDebug()<<"Waiting for image size...";
if(!video_socket.waitForReadyRead())
{
qWarning()<<"ERROR: Failed to read image size: "<<video_socket.errorString();
return;
}
}

quint32 image_size;
in>>image_size;

qDebug()<<"Image Size = "<<image_size;

while(video_socket.bytesAvailable() < image_size)
{
qDebug()<<"Waiting for image...";
if(!video_socket.waitForReadyRead())
{
qWarning()<<"ERROR: Failed to read image: "<<video_socket.errorString();
return;
}
}

QByteArray data;
in>>data;

qDebug()<<"Data size = "<<data.size();

QBuffer image_buffer(&data);
QImageReader reader(&image_buffer, "PNG");
QImage received_image;

if(!reader.read(&received_image))
{
qWarning()<<"ERROR: Unable to read received image from buffer: "<<reader.errorString();
return;
}


However, the client only seems to be able to read the size of the image, then dies.

Below is the output from the qDebug() statements in the server:

Image size = 384387
Data written = 384395

And below is my output from qDebug() statements in the client program:

Waiting for image size...
Image Size = 384387
Waiting for image...
Waiting for image...
Waiting for image...
ERROR: Failed to read image: "The remote host closed the connection"

So I guess my question is, can anyone see why it is doing this? I'm at a loss...

Any help would be terrific!!!

Regards,
Adrian

wysota
28th July 2009, 12:29
You're overcomplicating things. If you are using QDataStream then just stream the image directly into it.


QImage img;
QDataStream str(&socket);
str << img;


QImage img;
QDataStream str(&socket);
str >> img;

Currently you are misusing the data stream, it is not a general purpose binary stream but a serialization mechanism - it adds additional information to data it is being passed to, so you can't write a byte array directly to a socket and on the other end stream it out using QDataStream as the data lacks that additional information QDataStream requires.

volatile_ah
30th July 2009, 10:04
Thanks very much wysota.

I changed my client code to the following:



// Block until data is available for reading
if(!video_socket.waitForReadyRead())
{
qWarning()<<"ERROR: could not read image: "<<video_socket.errorString();
return;
}

// Read the image from the socket via the data stream
in>>received_image;

qDebug()<<"Image received";


And server to:



// Write the image to the socket via the data stream
out<<captured_image.getImage();

// Block until the data stream has been written to the socket
if(!video_socket.waitForBytesWritten())
qWarning()<<"ERROR: Unable to send image: "<<video_socket.errorString();

qDebug()<<"Image sent";


And for some images it works perfectly.

However, for other images (seems to be the larger the image the more likely it is to happen), I get the following message:

libpng error: Read Error

A bit of googling shows this may be a Linux problem rather than a problem with what I am doing in Qt. However, I havent managed to find a reason for it yet. I've tried different QDataStream versions (Qt_4_0 to Qt_4_5) but the error stil occurs. My libpng (Ubuntu distro) seems to be all up to date (at least from the repository anyway). Hmmm....

joergwl
1st September 2009, 11:42
Hi,

I got the same problem also on Ubuntu (januty) :crying:

If anyone has an idea about how to overcome this issue, it would be most appreciated.

Ciao
joergwl

joergwl
1st September 2009, 13:00
SOLVED

I used the fortune samples for a start and the block length is defined as quint16, which is a bit to small to send bigger images.

After changing the block length to qint64 all works fine:)

joergwl

wysota
1st September 2009, 13:01
The same problem meaning what?