1d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne/*
2d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneCopyright 2013 Google Inc. All Rights Reserved.
3d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
4d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneLicensed under the Apache License, Version 2.0 (the "License");
5d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenneyou may not use this file except in compliance with the License.
6d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneYou may obtain a copy of the License at
7d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
8d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    http://www.apache.org/licenses/LICENSE-2.0
9d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
10d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneUnless required by applicable law or agreed to in writing, software
11d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennedistributed under the License is distributed on an "AS IS" BASIS,
12d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneSee the License for the specific language governing permissions and
14d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennelimitations under the License.
15d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
16d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneAuthor: lode.vandevenne@gmail.com (Lode Vandevenne)
17d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneAuthor: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
18d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne*/
19d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
20d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne#include "zlib_container.h"
218c218eff39749e738c92bf34155099ad280c16f7Lode Vandevenne#include "util.h"
22d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
23d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne#include <stdio.h>
24d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
25d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne#include "deflate.h"
26d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
27d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
28d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne/* Calculates the adler32 checksum of the data */
29d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennestatic unsigned adler32(const unsigned char* data, size_t size)
30d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne{
31d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  static const unsigned sums_overflow = 5550;
32d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned s1 = 1;
33d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned s2 = 1 >> 16;
34d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
35d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  while (size > 0) {
36d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    size_t amount = size > sums_overflow ? sums_overflow : size;
37d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    size -= amount;
38d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    while (amount > 0) {
39d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      s1 += (*data++);
40d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      s2 += s1;
41d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      amount--;
42d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    }
43d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    s1 %= 65521;
44d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    s2 %= 65521;
45d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  }
46d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
47d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  return (s2 << 16) | s1;
48d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne}
49d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
50981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevennevoid ZopfliZlibCompress(const ZopfliOptions* options,
51981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevenne                        const unsigned char* in, size_t insize,
52981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevenne                        unsigned char** out, size_t* outsize) {
53d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned char bitpointer = 0;
54d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned checksum = adler32(in, (unsigned)insize);
55d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned cmf = 120;  /* CM 8, CINFO 7. See zlib spec.*/
56d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned flevel = 0;
57d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned fdict = 0;
58d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned cmfflg = 256 * cmf + fdict * 32 + flevel * 64;
59d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned fcheck = 31 - cmfflg % 31;
60d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  cmfflg += fcheck;
61d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
62981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevenne  ZOPFLI_APPEND_DATA(cmfflg / 256, out, outsize);
63981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevenne  ZOPFLI_APPEND_DATA(cmfflg % 256, out, outsize);
64d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
65981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevenne  ZopfliDeflate(options, 2 /* dynamic block */, 1 /* final */,
66981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevenne                in, insize, &bitpointer, out, outsize);
67d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
68981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevenne  ZOPFLI_APPEND_DATA((checksum >> 24) % 256, out, outsize);
69981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevenne  ZOPFLI_APPEND_DATA((checksum >> 16) % 256, out, outsize);
70981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevenne  ZOPFLI_APPEND_DATA((checksum >> 8) % 256, out, outsize);
71981df0fe897c94382b9b963eb72bc36cbc2e729cLode Vandevenne  ZOPFLI_APPEND_DATA(checksum % 256, out, outsize);
72d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
73d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  if (options->verbose) {
74d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    fprintf(stderr,
75806be49c750347eb78f4d94bb21ad37aa9121f93Lode Vandevenne            "Original Size: %d, Zlib: %d, Compression: %f%% Removed\n",
76d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne            (int)insize, (int)*outsize,
77806be49c750347eb78f4d94bb21ad37aa9121f93Lode Vandevenne            100.0 * (double)(insize - *outsize) / (double)insize);
78d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  }
79d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne}
80