Skip to content

Commit c9590ff

Browse files
committed
Added CM_AUTO, which automatically selects CM_STORE or CM_DEFLATE based on file extension. Used to avoid double-compression of already compressed file formats such as images.
1 parent 761c2ec commit c9590ff

3 files changed

Lines changed: 53 additions & 1 deletion

File tree

Zip/include/Poco/Zip/Compress.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "Poco/FIFOEvent.h"
2626
#include <istream>
2727
#include <ostream>
28+
#include <set>
2829

2930

3031
namespace Poco {
@@ -69,6 +70,25 @@ class Zip_API Compress
6970
ZipArchive close();
7071
/// Finalizes the ZipArchive, closes it.
7172

73+
void setStoreExtensions(const std::set<std::string>& extensions);
74+
/// Sets the file extensions for which the CM_STORE compression method
75+
/// is used if CM_AUTO is specified in addFile() or addRecursive().
76+
/// For all other extensions, CM_DEFLATE is used. This is used to avoid
77+
/// double compression of already compressed file formats, which usually
78+
/// leads to worse results. Extensions will be converted to lower case.
79+
///
80+
/// The default extensions are:
81+
/// - gif
82+
/// - jpg
83+
/// - jpeg
84+
/// - png
85+
86+
const std::set<std::string>& getStoreExtensions() const;
87+
/// Returns the file extensions for which the CM_STORE compression method
88+
/// is used if CM_AUTO is specified in addFile() or addRecursive().
89+
///
90+
/// See setStoreExtensions() for more information.
91+
7292
private:
7393
enum
7494
{
@@ -86,6 +106,7 @@ class Zip_API Compress
86106
/// copys an already compressed ZipEntry from in
87107

88108
private:
109+
std::set<std::string> _storeExtensions;
89110
std::ostream& _out;
90111
bool _seekableOut;
91112
ZipArchive::FileHeaders _files;
@@ -114,6 +135,12 @@ inline const std::string& Compress::getZipComment() const
114135
}
115136

116137

138+
inline const std::set<std::string>& Compress::getStoreExtensions() const
139+
{
140+
return _storeExtensions;
141+
}
142+
143+
117144
} } // namespace Poco::Zip
118145

119146

Zip/include/Poco/Zip/ZipCommon.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class Zip_API ZipCommon
4949
CM_DEFLATE = 8,
5050
CM_ENHANCEDDEFLATE = 9,
5151
CM_DATECOMPRIMPLODING = 10,
52-
CM_UNUSED = 11
52+
CM_UNUSED = 11,
53+
CM_AUTO = 255 /// automatically select DM_DEFLATE or CM_STORE based on file type (extension)
5354
};
5455

5556
enum CompressionLevel

Zip/src/Compress.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "Poco/StreamCopier.h"
2424
#include "Poco/File.h"
2525
#include "Poco/FileStream.h"
26+
#include "Poco/String.h"
2627

2728

2829
namespace Poco {
@@ -37,6 +38,10 @@ Compress::Compress(std::ostream& out, bool seekableOut):
3738
_dirs(),
3839
_offset(0)
3940
{
41+
_storeExtensions.insert("gif");
42+
_storeExtensions.insert("png");
43+
_storeExtensions.insert("jpg");
44+
_storeExtensions.insert("jpeg");
4045
}
4146

4247

@@ -47,6 +52,15 @@ Compress::~Compress()
4752

4853
void Compress::addEntry(std::istream& in, const Poco::DateTime& lastModifiedAt, const Poco::Path& fileName, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl)
4954
{
55+
if (cm == ZipCommon::CM_AUTO)
56+
{
57+
std::string ext = Poco::toLower(fileName.getExtension());
58+
if (_storeExtensions.find(ext) != _storeExtensions.end())
59+
cm = ZipCommon::CM_STORE;
60+
else
61+
cm = ZipCommon::CM_DEFLATE;
62+
}
63+
5064
std::string fn = ZipUtil::validZipEntryFileName(fileName);
5165

5266
if (_files.size() >= 65535)
@@ -300,4 +314,14 @@ ZipArchive Compress::close()
300314
}
301315

302316

317+
void Compress::setStoreExtensions(const std::set<std::string>& extensions)
318+
{
319+
_storeExtensions.clear();
320+
for (std::set<std::string>::const_iterator it = extensions.begin(); it != extensions.end(); ++it)
321+
{
322+
_storeExtensions.insert(Poco::toLower(*it));
323+
}
324+
}
325+
326+
303327
} } // namespace Poco::Zip

0 commit comments

Comments
 (0)