mirror of
https://github.com/taglib/taglib.git
synced 2025-06-03 00:58:12 -04:00
Read the compressed data as a stream
This avoids allocating the complete buffer at first based solely on the value read from the frame header. This then does a sanity check at the end of reading to make sure that the two values match. At present, it just prints a debugging message if the values do not match. Fixes #466
This commit is contained in:
parent
31982660c8
commit
caa53e8de5
@ -254,12 +254,44 @@ ByteVector Frame::fieldData(const ByteVector &frameData) const
|
||||
if(d->header->compression() &&
|
||||
!d->header->encryption())
|
||||
{
|
||||
ByteVector data(frameDataLength);
|
||||
uLongf uLongTmp = frameDataLength;
|
||||
::uncompress((Bytef *) data.data(),
|
||||
(uLongf *) &uLongTmp,
|
||||
(Bytef *) frameData.data() + frameDataOffset,
|
||||
size());
|
||||
z_stream stream;
|
||||
memset(&stream, 0, sizeof(z_stream));
|
||||
|
||||
if(inflateInit(&stream) != Z_OK)
|
||||
return ByteVector();
|
||||
|
||||
stream.avail_in = (uLongf) frameDataLength;
|
||||
stream.next_in = (Bytef *) frameData.data() + frameDataOffset;
|
||||
|
||||
static const uint chunkSize = 1024;
|
||||
|
||||
ByteVector data;
|
||||
ByteVector chunk(chunkSize);
|
||||
|
||||
do {
|
||||
stream.avail_out = (uLongf) chunk.size();
|
||||
stream.next_out = (Bytef *) chunk.data();
|
||||
|
||||
int result = inflate(&stream, Z_NO_FLUSH);
|
||||
|
||||
if(result == Z_STREAM_ERROR)
|
||||
return ByteVector();
|
||||
else if(result == Z_NEED_DICT ||
|
||||
result == Z_DATA_ERROR ||
|
||||
result == Z_MEM_ERROR)
|
||||
{
|
||||
inflateEnd(&stream);
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
data.append(stream.avail_out == 0 ? chunk : chunk.mid(0, chunk.size() - stream.avail_out));
|
||||
} while(stream.avail_out == 0);
|
||||
|
||||
inflateEnd(&stream);
|
||||
|
||||
if(frameDataLength != data.size())
|
||||
debug("frameDataLength does not match the data length returned by zlib");
|
||||
|
||||
return data;
|
||||
}
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user