Skip to content

Commit

Permalink
Add an option to set the DEFLATE level
Browse files Browse the repository at this point in the history
  • Loading branch information
dduponchel committed Aug 22, 2014
1 parent bf7ec8c commit 8b92719
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 8 deletions.
1 change: 1 addition & 0 deletions documentation/api_jszip/file_data.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ binary | boolean | `false` | set to `true` if the data should be treated as
date | date | the current date | the last modification date.
compression | string | null | If set, specifies compression method to use for this specific file. If not, the default file compression will be used, see [generate(options)]({{site.baseurl}}/documentation/api_jszip/generate.html).
comment | string | null | The comment for this file.
compressionOptions | object | `null` | the options to use when compressing the file, see [generate(options)]({{site.baseurl}}/documentation/api_jszip/generate.html).
optimizedBinaryString | boolean | `false` | Set to true if (and only if) the input is a "binary string" and has already been prepared with a 0xFF mask.
createFolders | boolean | `false` | Set to true if folders in the file path should be automatically created, otherwise there will only be virtual folders that represent the path to the file.

Expand Down
11 changes: 11 additions & 0 deletions documentation/api_jszip/generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ name | type | default | description
options | object | | the options to generate the zip file :
options.base64 | boolean | false | **deprecated**, use `type` instead. If `type` is not used, set to `false` to get the result as a raw byte string, `true` to encode it as base64.
options.compression | string | `STORE` (no compression) | the default file compression method to use. Available methods are `STORE` and `DEFLATE`. You can also provide your own compression method.
options.compressionOptions | object | `null` | the options to use when compressing the file, see below.
options.type | string | `base64` | The type of zip to return, see below for the other types.
options.comment | string | | The comment to use for the zip file.

Expand All @@ -35,6 +36,16 @@ comment.

If not set, JSZip will use the field `comment` on its `options`.

The `compressionOptions` parameter depends of the compression type. With
`STORE` (no compression), this parameter is ignored. With `DEFLATE`, you can
give the compression level with `compressionOptions : {level:6}` (or any level
between 1 (best speed) and 9 (best compression)).

Note : if the entry is *already* compressed (coming from a compressed zip file),
calling `generate()` with a different compression level won't update the entry.
The reason is simple : JSZip doesn't know how was compressed the content and
how to match the compression level with the implementation we use.

__Returns__ : The generated zip file.

__Throws__ : An exception if the asked `type` is not available in the browser,
Expand Down
2 changes: 1 addition & 1 deletion lib/compressions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
exports.STORE = {
magic: "\x00\x00",
compress: function(content) {
compress: function(content, compressionOptions) {
return content; // no compression
},
uncompress: function(content) {
Expand Down
1 change: 1 addition & 0 deletions lib/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ exports.createFolders = false;
exports.date = null;
exports.compression = null;
exports.comment = null;
exports.compressionOptions = null;
6 changes: 4 additions & 2 deletions lib/flate.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ exports.uncompressInputType = USE_TYPEDARRAY ? "uint8array" : "array";
exports.compressInputType = USE_TYPEDARRAY ? "uint8array" : "array";

exports.magic = "\x08\x00";
exports.compress = function(input) {
return pako.deflateRaw(input);
exports.compress = function(input, compressionOptions) {
return pako.deflateRaw(input, {
level : compressionOptions.level || -1 // default compression
});
};
exports.uncompress = function(input) {
return pako.inflateRaw(input);
Expand Down
13 changes: 8 additions & 5 deletions lib/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,10 @@ var folderAdd = function(name, createFolders) {
* Generate a JSZip.CompressedObject for a given zipOject.
* @param {ZipObject} file the object to read.
* @param {JSZip.compression} compression the compression to use.
* @param {Object} compressionOptions the options to use when compressing.
* @return {JSZip.CompressedObject} the compressed result.
*/
var generateCompressedObjectFrom = function(file, compression) {
var generateCompressedObjectFrom = function(file, compression, compressionOptions) {
var result = new CompressedObject(),
content;

Expand All @@ -327,7 +328,7 @@ var generateCompressedObjectFrom = function(file, compression) {
else {
content = file._data.getContent();
// need to decompress / recompress
result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content));
result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions);
}
}
else {
Expand All @@ -339,7 +340,7 @@ var generateCompressedObjectFrom = function(file, compression) {
}
result.uncompressedSize = content.length;
result.crc32 = crc32(content);
result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content));
result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions);
}

result.compressedSize = result.compressedContent.length;
Expand Down Expand Up @@ -647,7 +648,8 @@ var out = {
base64: true,
compression: "STORE",
type: "base64",
comment: null
comment: null,
compressionOptions : null
});

utils.checkSupport(options.type);
Expand All @@ -670,8 +672,9 @@ var out = {
if (!compression) {
throw new Error(compressionName + " is not a valid compression method !");
}
var compressionOptions = file.options.compressionOptions || options.compressionOptions || {};

var compressedObject = generateCompressedObjectFrom.call(this, file, compression);
var compressedObject = generateCompressedObjectFrom.call(this, file, compression, compressionOptions);

var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength);
localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize;
Expand Down
28 changes: 28 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,34 @@ test("Empty files / folders are not compressed", function() {
JSZip.compressions.DEFLATE.compress = oldDeflateCompress;
});

test("DEFLATE level on generate()", function() {
var zip = new JSZip();
zip.file("Hello.txt", "world");

var oldDeflateCompress = JSZip.compressions.DEFLATE.compress;
JSZip.compressions.DEFLATE.compress = function (str, options) {
equal(options.level, 5);
return str;
};
zip.generate({compression:'DEFLATE', compressionOptions : {level:5}});

JSZip.compressions.DEFLATE.compress = oldDeflateCompress;
});

test("DEFLATE level on file() takes precedence", function() {
var zip = new JSZip();
zip.file("Hello.txt", "world", {compressionOptions:{level:9}});

var oldDeflateCompress = JSZip.compressions.DEFLATE.compress;
JSZip.compressions.DEFLATE.compress = function (str, options) {
equal(options.level, 9);
return str;
};
zip.generate({compression:'DEFLATE', compressionOptions : {level:5}});

JSZip.compressions.DEFLATE.compress = oldDeflateCompress;
});

test("unknown compression throws an exception", function () {
var zip = new JSZip().file("file.txt", "test");
try {
Expand Down

0 comments on commit 8b92719

Please sign in to comment.