/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
void ThreadedDeflater::Task::doWork()
{
stream.zalloc = nullptr;
stream.zfree = nullptr;
stream.opaque = nullptr; // -MAX_WBITS means 32k window size and raw stream if (deflateInit2(&stream, deflater->zlibLevel, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL,
Z_DEFAULT_STRATEGY)
!= Z_OK)
{
SAL_WARN("package.threadeddeflate", "deflateInit2() failed");
abort();
} // Find out size for our output buffer to be large enough for deflate() needing to be called just once.
sal_Int64 outputMaxSize = deflateBound(&stream, blockSize); // add extra size for Z_SYNC_FLUSH
outputMaxSize += 20;
deflater->outBuffers[sequence].resize(outputMaxSize);
sal_Int64 myInBufferStart = sequence * MaxBlockSize; // zlib doesn't handle const properly unsignedchar* inBufferPtr = reinterpret_cast<unsignedchar*>( const_cast<signedchar*>(deflater->inBuffer.getConstArray())); if (!firstTask)
{ // the window size is 32k, so set last 32k of previous data as the dictionary
assert(MAX_WBITS == 15);
assert(MaxBlockSize >= 32768); if (sequence > 0)
{
deflateSetDictionary(&stream, inBufferPtr + myInBufferStart - 32768, 32768);
} else
{ unsignedchar* prevBufferPtr = reinterpret_cast<unsignedchar*>( const_cast<signedchar*>(deflater->prevDataBlock.getConstArray()));
deflateSetDictionary(&stream, prevBufferPtr + MaxBlockSize - 32768, 32768);
}
}
stream.next_in = inBufferPtr + myInBufferStart;
stream.avail_in = blockSize;
stream.next_out = reinterpret_cast<unsignedchar*>(deflater->outBuffers[sequence].data());
stream.avail_out = outputMaxSize;
// The trick is in using Z_SYNC_FLUSH instead of Z_NO_FLUSH. It will align the data at a byte boundary, // and since we use a raw stream, the data blocks then can be simply concatenated. int res = deflate(&stream, lastTask ? Z_FINISH : Z_SYNC_FLUSH);
assert(stream.avail_in == 0); // Check that everything has been deflated. if (lastTask ? res == Z_STREAM_END : res == Z_OK)
{ // ok
sal_Int64 outSize = outputMaxSize - stream.avail_out;
deflater->outBuffers[sequence].resize(outSize);
} else
{
SAL_WARN("package.threadeddeflate", "deflate() failed");
abort();
}
deflateEnd(&stream);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.