{"action":"created","issue":{"url":"https://api.github.com/repos/google/zopfli/issues/79","repository_url":"https://api.github.com/repos/google/zopfli","labels_url":"https://api.github.com/repos/google/zopfli/issues/79/labels{/name}","comments_url":"https://api.github.com/repos/google/zopfli/issues/79/comments","events_url":"https://api.github.com/repos/google/zopfli/issues/79/events","html_url":"https://github.com/google/zopfli/issues/79","id":119380510,"number":79,"title":"patch: libzopfli distributed compression","user":{"login":"pdknsk","id":1097609,"avatar_url":"https://avatars.githubusercontent.com/u/1097609?v=3","gravatar_id":"","url":"https://api.github.com/users/pdknsk","html_url":"https://github.com/pdknsk","followers_url":"https://api.github.com/users/pdknsk/followers","following_url":"https://api.github.com/users/pdknsk/following{/other_user}","gists_url":"https://api.github.com/users/pdknsk/gists{/gist_id}","starred_url":"https://api.github.com/users/pdknsk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pdknsk/subscriptions","organizations_url":"https://api.github.com/users/pdknsk/orgs","repos_url":"https://api.github.com/users/pdknsk/repos","events_url":"https://api.github.com/users/pdknsk/events{/privacy}","received_events_url":"https://api.github.com/users/pdknsk/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":8,"created_at":"2015-11-29T19:22:16Z","updated_at":"2016-05-24T16:38:51Z","closed_at":null,"body":"I have a custom PNG optimiser for large files, which uses ```libzopfli``` for deflate compression. To improve speed, image data is split into chunks, and compression run on multiple cores. This works very well, scales perfectly, and causes only a negligible size increase.\r\n\r\nI'm attaching a patch here for anyone interested, or perhaps to be included into ```libzopfli``` itself. I think it's the least intrusive way to add this, but perhaps not the most elegant, so I'm not submitting a PR.\r\n\r\n```diff\r\ndiff --git a/src/zopfli/deflate.c b/src/zopfli/deflate.c\r\nindex 4d124f4..7628658 100644\r\n--- a/src/zopfli/deflate.c\r\n+++ b/src/zopfli/deflate.c\r\n@@ -834,18 +834,28 @@ void ZopfliDeflate(const ZopfliOptions* options, int btype, int final,\r\n                    unsigned char* bp, unsigned char** out, size_t* outsize) {\r\n  size_t offset = *outsize;\r\n #if ZOPFLI_MASTER_BLOCK_SIZE == 0\r\n-  ZopfliDeflatePart(options, btype, final, in, 0, insize, bp, out, outsize);\r\n+  ZopfliDeflatePart(options, btype, final == 1, in, 0, insize, bp, out, outsize);\r\n #else\r\n   size_t i = 0;\r\n   do {\r\n     int masterfinal = (i + ZOPFLI_MASTER_BLOCK_SIZE >= insize);\r\n-    int final2 = final && masterfinal;\r\n+    int final2 = final == 1 && masterfinal;\r\n     size_t size = masterfinal ? insize - i : ZOPFLI_MASTER_BLOCK_SIZE;\r\n     ZopfliDeflatePart(options, btype, final2,\r\n                       in, i, i + size, bp, out, outsize);\r\n     i += size;\r\n   } while (i < insize);\r\n #endif\r\n+\r\n+  /* Z_SYNC_FLUSH */\r\n+  if (final == 2) {\r\n+    AddBits(0, 3, bp, out, outsize);\r\n+    ZOPFLI_APPEND_DATA(0, out, outsize);\r\n+    ZOPFLI_APPEND_DATA(0, out, outsize);\r\n+    ZOPFLI_APPEND_DATA(0xFF, out, outsize);\r\n+    ZOPFLI_APPEND_DATA(0xFF, out, outsize);\r\n+  }\r\n+\r\n   if (options->verbose) {\r\n     fprintf(stderr,\r\n             \"Original Size: %lu, Deflate: %lu, Compression: %f%% Removed\\n\",\r\n```\r\n\r\nTo use this, call ```ZopfliDeflate``` with ```1``` passed for ```final``` on the last chunk, and ```2``` on all other chunks.\r\n\r\nPS. The documentation from the zlib manual.\r\n> If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. [...] This completes the current deflate block and follows it with an empty stored block that is three bits plus filler bits to the next byte, followed by four bytes (00 00 ff ff)."},"comment":{"url":"https://api.github.com/repos/google/zopfli/issues/comments/221330627","html_url":"https://github.com/google/zopfli/issues/79#issuecomment-221330627","issue_url":"https://api.github.com/repos/google/zopfli/issues/79","id":221330627,"user":{"login":"Jesin","id":722506,"avatar_url":"https://avatars.githubusercontent.com/u/722506?v=3","gravatar_id":"","url":"https://api.github.com/users/Jesin","html_url":"https://github.com/Jesin","followers_url":"https://api.github.com/users/Jesin/followers","following_url":"https://api.github.com/users/Jesin/following{/other_user}","gists_url":"https://api.github.com/users/Jesin/gists{/gist_id}","starred_url":"https://api.github.com/users/Jesin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jesin/subscriptions","organizations_url":"https://api.github.com/users/Jesin/orgs","repos_url":"https://api.github.com/users/Jesin/repos","events_url":"https://api.github.com/users/Jesin/events{/privacy}","received_events_url":"https://api.github.com/users/Jesin/received_events","type":"User","site_admin":false},"created_at":"2016-05-24T16:38:51Z","updated_at":"2016-05-24T16:38:51Z","body":"Zopfli already does \"block splitting\". Does that provide a natural way to parallelize the rest of the processing, or is that something else?"}}
{"actor":{"display_login":"Jesin"}}