1--  ________  ___   ______       ______      ___
2-- /___..._/  |.|   |.___.\     /. __ .\   __|.|   ____
3--    /../    |.|   |.____/     |.|__|.|  /....|  __\..\
4--  _/../___  |.|   |.|    ===  |..__..| |. = .| | = ..|
5-- /_______/  |_|  /__|        /__|  |_|  \__\_|  \__\_|
6
7--  Zip.Compress
8----------------
9--
10--  Created 9-Dec-2007
11--
12--  This package facilitates the storage or compression of data.
13--
14--  Note that unlike decompression where the decoding is unique,
15--  there is a quasi indefinite number of ways of compressing data into
16--  most Zip-supported formats, including LZW (Shrink), Reduce, Deflate, or LZMA.
17--  As a result, you may want to use your own way for compressing data.
18--  This package is a portable one and doesn't claim to be the "best".
19--  The term "best" is relative to the needs, since there are at least
20--  two criteria that usually go in opposite directions: speed and
21--  compression ratio, a bit like risk and return in finance.
22
23-- Legal licensing note:
24
25--  Copyright (c) 2007 .. 2018 Gautier de Montmollin (Maintainer of the Ada version)
26--  SWITZERLAND
27
28--  Permission is hereby granted, free of charge, to any person obtaining a copy
29--  of this software and associated documentation files (the "Software"), to deal
30--  in the Software without restriction, including without limitation the rights
31--  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32--  copies of the Software, and to permit persons to whom the Software is
33--  furnished to do so, subject to the following conditions:
34
35--  The above copyright notice and this permission notice shall be included in
36--  all copies or substantial portions of the Software.
37
38--  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39--  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40--  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41--  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42--  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43--  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44--  THE SOFTWARE.
45
46-- NB: this is the MIT License, as found on the site
47-- http://www.opensource.org/licenses/mit-license.php
48
49---------------------------------------------------------------------------------
50
51with Zip_Streams;
52
53package Zip.Compress is
54
55  --  Compression_Method is actually reflecting the way of compressing
56  --  data, not only the final compression format called "method" in
57  --  Zip specifications.
58
59  type Compression_Method is
60    (--  No compression:
61     Store,
62     --  Shrink = LZW algorithm, as in GIF pictures:
63     Shrink,
64     --  Reduce combines LZ and a Markov predictor; 4 strengths available:
65     Reduce_1,
66     Reduce_2,
67     Reduce_3,
68     Reduce_4,
69     --  Deflate combines LZ and Huffman encoding; 4 strengths available:
70     Deflate_Fixed,
71     Deflate_1,
72     Deflate_2,
73     Deflate_3,
74     --  LZMA:
75     LZMA_1,
76     LZMA_2,
77     LZMA_3,           --  NB: LZMA_3 can be very slow on large data
78     --  LZMA with non-default parameters, targeted for specific data types:
79     LZMA_2_for_Zip_in_Zip,
80     LZMA_3_for_Zip_in_Zip,
81     LZMA_2_for_Source,
82     LZMA_3_for_Source,
83     LZMA_for_JPEG,
84     LZMA_for_ARW,   --  Raw camera picture
85     LZMA_for_ORF,   --  Raw camera picture
86     LZMA_for_MP3,
87     LZMA_for_MP4,
88     LZMA_for_PGM,  --  TBD: photo vs drawing (expect much LZ redundancy in the latter)
89     LZMA_for_PPM,  --  TBD: photo vs drawing (expect much LZ redundancy in the latter)
90     LZMA_for_PNG,
91     LZMA_for_GIF,
92     LZMA_for_WAV,
93     --  Multi-method:
94     --    Preselection: select a method depending on hints, like the uncompressed size
95     Preselection_1,  --  Not too slow; selects Deflate_3 or LZMA_2*
96     Preselection_2   --  Can be very slow on large data; selects Deflate_3, LZMA_2* or LZMA_3*
97    );
98
99  type Method_to_Format_type is array(Compression_Method) of PKZip_method;
100  Method_to_Format: constant Method_to_Format_type;
101
102  subtype Reduction_Method is Compression_Method range Reduce_1 .. Reduce_4;
103
104  --  Deflate_Fixed compresses the data into a single block and with predefined
105  --  ("fixed") compression structures. The data are basically LZ-compressed
106  --  only, since the Huffman code sets are flat and not tailored for the data.
107  subtype Deflation_Method is Compression_Method range Deflate_Fixed .. Deflate_3;
108
109  --  The multi-block Deflate methods use refined techniques to decide when to
110  --  start a new block and what sort of block to put next.
111  subtype Taillaule_Deflation_Method is Compression_Method range Deflate_1 .. Deflate_3;
112
113  subtype LZMA_Method is Compression_Method range LZMA_1 .. LZMA_for_WAV;
114
115  subtype Multi_Method is Compression_Method range Preselection_1 .. Preselection_2;
116
117  subtype Preselection_Method is Compression_Method range Preselection_1 .. Preselection_2;
118
119  subtype Single_Method is Compression_Method
120    range Compression_Method'First .. Compression_Method'Pred(Multi_Method'First);
121
122  User_abort: exception;
123
124  type Data_content_type is (
125    Neutral,
126    Source_code,
127    JPEG,
128    ARW_RW2,     --  Raw digital camera image
129    ORF_CR2,     --  Raw digital camera image
130    Zip_in_Zip,
131    GIF, PNG, PGM, PPM,
132    WAV,
133    MP3, MP4
134  );
135
136  --  Compress data from an input stream to an output stream until
137  --  End_Of_File(input) = True, or number of input bytes = input_size .
138  --  If password /= "", an encryption header is written.
139
140  procedure Compress_data(
141    input,
142    output          : in out Zip_Streams.Root_Zipstream_Type'Class;
143    input_size_known: Boolean;
144    input_size      : File_size_type; -- ignored if input_size_known = False
145    method          : Compression_Method;
146    feedback        : Feedback_proc;
147    password        : String;
148    content_hint    : Data_content_type;
149    CRC             : out Interfaces.Unsigned_32;
150    output_size     : out File_size_type;
151    zip_type        : out Interfaces.Unsigned_16
152    -- ^ code corresponding to the compression method actually used
153  );
154
155  function Guess_type_from_name(name: String) return Data_content_type;
156
157private
158
159  buffer_size: constant:= 1024 * 1024; -- 1 MB
160
161  Method_to_Format: constant Method_to_Format_type :=
162    (Store               => store,
163     Shrink              => shrink,
164     Reduce_1            => reduce_1,
165     Reduce_2            => reduce_2,
166     Reduce_3            => reduce_3,
167     Reduce_4            => reduce_4,
168     Deflation_Method    => deflate,
169     LZMA_Method         => lzma_meth,
170     Multi_Method        => unknown
171    );
172
173end Zip.Compress;
174