├── .gitignore
├── LICENSE
├── Readme.txt
├── docs
├── contents.txt
├── developer.txt
├── howtocompile.txt
├── lgpl-3.0.txt
├── sample_images.zip
└── versionnumbering.txt
└── source
├── Makefile
├── Makefile_osx
├── app_icon.ico
├── aricoder.cpp
├── aricoder.h
├── bitops.cpp
├── bitops.h
├── dct8x8.h
├── file_icon.ico
├── icons.rc
├── icons.res
├── packjpg.cpp
├── packjpg.spec
├── packjpgdll.h
├── packjpglib.h
└── pjpgtbl.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 | *.obj
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Compiled Dynamic libraries
12 | *.so
13 | *.dylib
14 | *.dll
15 |
16 | # Fortran module files
17 | *.mod
18 |
19 | # Compiled Static libraries
20 | *.lai
21 | *.la
22 | *.a
23 | *.lib
24 |
25 | # Executables
26 | *.exe
27 | *.out
28 | *.app
29 |
30 | # Folders to ignore
31 | /zzz_backup/
32 |
33 | # Test / output files
34 | *.jpg
35 | *.jpeg
36 | *.pjg
37 | *.pgm
38 | *.nfo
39 | *.hdr
40 | *.huf
41 | *.coll?
42 | *.zdst?
43 | *.dist
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
167 |
--------------------------------------------------------------------------------
/Readme.txt:
--------------------------------------------------------------------------------
1 | packJPG v2.5k (01/22/2016)
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~
3 |
4 | packJPG is a compression program specially designed for further
5 | compression of JPEG images without causing any further loss. Typically
6 | it reduces the file size of a JPEG file by 20%.
7 |
8 |
9 | LGPL v3 license and special permissions
10 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 |
12 | All programs in this package are free software; you can redistribute
13 | them and/or modify them under the terms of the GNU Lesser General Public
14 | License as published by the Free Software Foundation; either version 3
15 | of the License, or (at your option) any later version.
16 |
17 | The package is distributed in the hope that it will be useful, but
18 | WITHOUT ANY WARRANTY; without even the implied warranty of
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
20 | General Public License for more details at
21 | http://www.gnu.org/copyleft/lgpl.html.
22 |
23 | If the LGPL v3 license is not compatible with your software project you
24 | might contact us and ask for a special permission to use the packJPG
25 | library under different conditions. In any case, usage of the packJPG
26 | algorithm under the LGPL v3 or above is highly advised and special
27 | permissions will only be given where necessary on a case by case basis.
28 | This offer is aimed mainly at closed source freeware developers seeking
29 | to add PJG support to their software projects.
30 |
31 | Copyright 2006...2014 by HTW Aalen University and Matthias Stirner.
32 |
33 |
34 | Usage of packJPG
35 | ~~~~~~~~~~~~~~~~
36 |
37 | JPEG files are compressed and PJG files are decompressed using this
38 | command:
39 |
40 | "packJPG [file(s)]"
41 |
42 | packJPG recognizes file types on its own and decides whether to compress
43 | (JPG) or decompress (PJG). For unrecognized file types no action is
44 | taken. Files are recognized by content, not by extension.
45 |
46 | packJPG supports wildcards like "*.*" and drag and drop of multiple
47 | files. Filenames for output files are created automatically. In default
48 | mode, files are never overwritten. If a filename is already in use,
49 | packJPG creates a new filename by adding underscores.
50 |
51 | If "-" is used as a filename input from stdin is assumed and output is
52 | written to stdout. This can be useful for example if jpegtran is to be
53 | used as a preprocessor.
54 |
55 | Usage examples:
56 |
57 | "packJPG *.pjg"
58 | "packJPG lena.jpg"
59 | "packJPG kodim??.jpg"
60 | "packJPG - < sail.pjg > sail.jpg"
61 |
62 |
63 | Command line switches
64 | ~~~~~~~~~~~~~~~~~~~~~
65 |
66 | -ver verify files after processing
67 | -v? level of verbosity; 0,1 or 2 is allowed (default 0)
68 | -np no pause after processing files
69 | -o overwrite existing files
70 | -p proceed on warnings
71 | -d discard meta-info
72 |
73 | By default, compression is cancelled on warnings. If warnings are
74 | skipped by using "-p", most files with warnings can also be compressed,
75 | but JPEG files reconstructed from PJG files might not be bitwise
76 | identical with the original JPEG files. There won't be any loss to
77 | image data or quality however.
78 |
79 | Unnecessary meta information can be discarded using "-d". This reduces
80 | compressed files' sizes. Be warned though, reconstructed files won't be
81 | bitwise identical with the original files and meta information will be
82 | lost forever. As with "-p" there won't be any loss to image data or
83 | quality.
84 |
85 | There is no known case in which a file compressed by packJPG (without
86 | the "-p" option, see above) couldn't be reconstructed to exactly the
87 | state it was before. If you want an additional layer of safety you can
88 | also use the verify option "-ver". In this mode, files are compressed,
89 | then decompressed and the decompressed file compared to the original
90 | file. If this test doesn't pass there will be an error message and the
91 | compressed file won't be written to the drive.
92 |
93 | Please note that the "-ver" option should never be used in conjunction
94 | with the "-d" and/or "-p" options. As stated above, the "-p" and "-d"
95 | options will most likely lead to reconstructed JPG files not being
96 | bitwise identical to the original JPG files. In turn, the verification
97 | process may fail on various files although nothing actually went wrong.
98 |
99 | Usage examples:
100 |
101 | "packJPG -v1 -o baboon.pjg"
102 | "packJPG -ver lena.jpg"
103 | "packJPG -d tiffany.jpg"
104 | "packJPG -p *.jpg"
105 |
106 |
107 | Known Limitations
108 | ~~~~~~~~~~~~~~~~~
109 |
110 | packJPG is a compression program specially for JPEG files, so it doesn't
111 | compress other file types.
112 |
113 | packJPG has low error tolerance. JPEG files might not work with packJPG
114 | even if they work perfectly with other image processing software. The
115 | command line switch "-p" can be used to increase error tolerance and
116 | compatibility.
117 |
118 | If you try to drag and drop to many files at once, there might be a
119 | windowed error message about missing privileges. In that case you can
120 | try it again with less files or consider using the command prompt.
121 | packJPG has been tested to work perfectly with thousands of files from
122 | the command line. This issue also happens with drag and drop in other
123 | applications, so it might not be a limitation of packJPG but a
124 | limitation of Windows.
125 |
126 | Compressed PJG files are not compatible between different packJPG
127 | versions. You will get an error message if you try to decompress PJG
128 | files with a different version than the one used for compression. You
129 | may download older versions of packJPG from:
130 | http://www.elektronik.htw-aalen.de/packJPG/binaries/old/
131 |
132 |
133 | Open source release / developer info
134 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135 |
136 | The packJPG source codes is found inside the "source" subdirectory.
137 | Additional documents aimed to developers, containing detailed
138 | instructions on compiling the source code and using special
139 | functionality, are included in the "packJPG" subdirectory.
140 |
141 |
142 | History
143 | ~~~~~~~
144 |
145 | v1.9a (04/20/2007) (non public)
146 | - first released version
147 | - only for testing purposes
148 |
149 | v2.0 (05/28/2007) (public)
150 | - first public version of packJPG
151 | - minor improvements to overall compression
152 | - minor bugfixes
153 |
154 | v2.2 (08/05/2007) (public)
155 | - around 40% faster compression & decompression
156 | - major improvements to overall compression (around 2% on average)
157 | - reading from stdin, writing to stdout
158 | - smaller executable
159 | - minor bugfixes
160 | - various minor improvements
161 |
162 | v2.3 (09/18/2007) (public)
163 | - compatibility with JPEG progressive mode
164 | - compatibility with JPEG extended sequential mode
165 | - compatibility with the CMYK color space
166 | - compatibility with older CPUs
167 | - around 15% faster compression & decompression
168 | - new switch: [-d] (discard meta-info)
169 | - various bugfixes
170 |
171 | v2.3a (11/21/2007) (public)
172 | - crash issue with certain images fixed
173 | - compatibility with packJPG v2.3 maintained
174 |
175 | v2.3b (12/20/2007) (public)
176 | - some minor errors in the packJPG library fixed
177 | - compatibility with packJPG v2.3 maintained
178 |
179 | v2.4 (03/24/2010) (public)
180 | - major improvements (1%...2%) to overall compression
181 | - around 10% faster compression & decompression
182 | - major improvements to JPG compatibility
183 | - size of executable reduced to ~33%
184 | - new switch: [-ver] (verify file after processing)
185 | - new switch: [-np] (no pause after processing)
186 | - new progress bar output mode
187 | - arithmetic coding routines rewritten from scratch
188 | - various smaller improvements to numerous to list here
189 | - new SFX (self extracting) archive format
190 |
191 | v2.5 (11/11/2011) (public)
192 | - improvements (~0.5%) to overall compression
193 | - several minor bugfixes
194 | - major code cleanup
195 | - removed packJPX from the package
196 | - added packARC to the package
197 | - packJPG is now open source!
198 |
199 | v2.5a (11/21/11) (public)
200 | - source code compatibility improvements (Gerhard Seelmann)
201 | - avoid some compiler warnings (Gerhard Seelmann)
202 | - source code clean up (Gerhard Seelmann)
203 |
204 | v2.5b (01/27/12) (public)
205 | - further removal of redundant code
206 | - some fixes for the packJPG static library
207 | - compiler fix for Mac OS (thanks to Sergio Lopez)
208 | - improved compression ratio calculation
209 | - eliminated the need for temp files
210 |
211 | v2.5c (04/13/12) (public)
212 | - various source code optimizations
213 |
214 | v2.5d (07/03/12) (public)
215 | - fixed a rare bug with progressive JPEG
216 |
217 | v2.5e (07/03/12) (public)
218 | - some minor source code optimizations
219 | - changed packJPG licensing to LGPL
220 | - moved packARC to a separate package
221 |
222 | v2.5f (02/24/13) (public)
223 | - fixed a minor bug in the JPG parser (thanks to Stephan Busch)
224 |
225 | v2.5g (09/14/13) (public)
226 | - fixed a rare crash bug with manipulated JPEG files
227 |
228 | v2.5h (12/07/13) (public)
229 | - added a warning for inefficient huffman coding (thanks to Moinak Ghosh)
230 |
231 | v2.5i (12/26/13) (public)
232 | - fixed possible crash with malformed JPEG (thanks to Moinak Ghosh)
233 |
234 | v2.5j (01/15/14) (public)
235 | - various source code optimizations (using cppcheck)
236 |
237 | v2.5k (01/22/16) (public)
238 | - Updated contact info
239 | - fixed a minor bug
240 |
241 |
242 | Acknowledgements
243 | ~~~~~~~~~~~~~~~~
244 |
245 | packJPG is the result of countless hours of research and development. It
246 | is part of my final year project for Hochschule Aalen.
247 |
248 | Prof. Dr. Gerhard Seelmann from Hochschule Aalen supported my
249 | development of packJPG with his extensive knowledge in the field of data
250 | compression. Without his advice, packJPG would not be possible.
251 |
252 | The official developer blog for packJPG is hosted by encode.ru.
253 |
254 | packJPG logo and icon are designed by Michael Kaufmann.
255 |
256 |
257 | Contact
258 | ~~~~~~~
259 |
260 | The official developer blog for packJPG:
261 | http://packjpg.encode.ru/
262 |
263 | For questions and bug reports:
264 | packjpg (at) matthiasstirner.com
265 |
266 |
267 | ____________________________________
268 | packJPG by Matthias Stirner, 01/2016
269 |
--------------------------------------------------------------------------------
/docs/contents.txt:
--------------------------------------------------------------------------------
1 | packJPG package - table of contents
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 |
4 |
5 | Source files
6 | ~~~~~~~~~~~~
7 |
8 | All files needed to compile packJPG as an executable or as a library are
9 | included in the 'source' subdirectory':
10 |
11 | - 'Makefile' (universal makefile)
12 | - 'aricoder.cpp' (arithmetic coder source file)
13 | - 'aricoder.h' (arithmetic coder header file)
14 | - 'bitops.cpp' (bitwise file I/O routines source file)
15 | - 'bitops.h' (bitwise file I/O routines header file)
16 | - 'dct8x8.h' (discrete cosine transform header file)
17 | - 'packjpg.cpp' (packJPG main source file)
18 | - 'packjpglib.h' (packJPG static library header file)
19 | - 'pjpgtbl.h' (helper tables header file)
20 |
21 | These files are included as well, but are not necessarily needed for
22 | compiling packJPG:
23 |
24 | - 'packjpg.spec' (RPM spec file, provided by Bryan Stillwell)
25 | - 'Makefile_osx' (special OS X Makefile, provided by Ryan Flynn)
26 | - 'packjpgdll.h' (packJPG DLL header file)
27 | - 'file_icon.ico' (suggested .pjg icon in .ico format)
28 | - 'app_icon.ico' (application icon in .ico format)
29 | - 'icon.res' (application icon in Windows .res format)
30 |
31 |
32 | Documentation
33 | ~~~~~~~~~~~~~
34 |
35 | The packJPG source code is well commented. Additionally, these files are
36 | included in the 'doc' subdirectory.
37 |
38 | - 'developer.txt' (information about developer functions)
39 | - 'sample_images.zip' (sample images, referenced in 'developer.txt')
40 | - 'AalenUniv.jpg' (sample image, showing Aalen University)
41 | - 'dsci0692.jpg' (sample image, showing a flower)
42 | - 'usage.txt' (generic usage information)
43 | - 'howtocompile.txt' (compile instructions)
44 | - 'versionnumbering.txt' (version numbering guideline)
45 | - 'contents.txt' (the file you are currently reading)
46 |
47 |
48 | *NOT* included
49 | ~~~~~~~~~~~~~~
50 |
51 | There's no further documentation on the packJPG algorithms - all
52 | documentation is included within the source code.
53 |
54 |
55 | ____________________________________
56 | packJPG by Matthias Stirner, 10/2012
--------------------------------------------------------------------------------
/docs/developer.txt:
--------------------------------------------------------------------------------
1 | -Developer functions detailed descriptions
2 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 | -
4 | -packJPG contains functionality especially designed for developers. This
5 | -document details how to use the developer functions.
6 | -
7 | -
8 | -Developer switches
9 | -~~~~~~~~~~~~~~~~~~
10 | -
11 | - -dev needed to enable any of the switches bewlow
12 | -
13 | - -test test algorithms, alert if error
14 | - -split split jpeg (to header & image data)
15 | - -coll? write coefficients (0=std,1=dhf,2=squ,3=unc)
16 | - -fcol? write filtered coefficients (see above)
17 | - -zdst write zero distribution lists to files
18 | - -info write debug info to .nfo file
19 | - -dist write distribution data to file
20 | - -pgm convert and write to pgm files
21 | -
22 | - -s? set global number of segments (1<=s<=49)
23 | - -t? set global noise threshold (0<=t<=10)
24 | - -s?,? set number of segments for component
25 | - -t?,? set noise threshold for component
26 | -
27 | -
28 | -Developer switches usage
29 | -~~~~~~~~~~~~~~~~~~~~~~~~
30 | -
31 | -The developer switch "-ver" is needed the enable any developer function.
32 | -Other developer functions won't work without it.
33 | -
34 | -"-test" is a special case of the "-ver" option. Files are also verified,
35 | -but if any error happens, all the output will be kept for the developer
36 | -to have a look at it.
37 | -
38 | -"-split" splits a JPEG file to huffman coded image data and header data.
39 | -This mode is useful if a closer look at the header of a given file is
40 | -needed.
41 | -
42 | -"-coll?" and "-fcol?" write decompressed DCT coefficients to separate
43 | -files (one for each color component). DCT coefficients are stored in two
44 | -byte signed short integers. In the "-fcol?" option, DC coefficents are
45 | -replaced by the corresponding DC prediction errors, while using the
46 | -"-coll?" option will dump DC coeffcients without any prediction applied.
47 | -The "?" has to be replaced by a number 0, 1, 2 or 3, which will
48 | -determine the order the coefficients will be stored inside the files.
49 | -Have a look at the included sample images or the source code to get an
50 | -idea on which each number stands for.
51 | -
52 | -"-zdst" writes zero distribution lists to files (one for each color
53 | -component). For each 8x8 image data block in a given color component, a
54 | -zero distribution list contains the number of coefficients unequal zero.
55 | -These numbers are stored as unsigned one byte chars. In packJPG, zero
56 | -distribution lists are used as a replacement for JPEGs EOB symbol and
57 | -for segmentation of data.
58 | -
59 | -"-info" dumps a ".nfo" text file with data about the JPEG file.
60 | -Structure of header, type of coding and quantization tables for each
61 | -component are included in this file.
62 | -
63 | -"-dump" dumps distribution for a given file to ".dist" files (again, one
64 | -file per color component). For each band seperately this files contain
65 | -the number of coefficients = 0; 1; 2; 3; 4; .... (absolute values). Have
66 | -a look at the source code to get an idea about the structure of these
67 | -files.
68 | -
69 | -"-pgm" mainly serves as a test function for the integrated DCT routines.
70 | -Each color component is transformed back to it's image representation
71 | -using the IDCT and dumped seperately as a ".PGM" (Portable GrayMap)
72 | -file.
73 | -
74 | -"-t?" and "-s?" control specific compression settings. By manipulating
75 | -these parameters, you might achieve higher compression. By default,
76 | -these values are set automatically. The default for segmentation ("-s?")
77 | -is 10. The default for the noise threshold ("-t?") is dependant on the
78 | -size of the input file. Higher sizes mean higher t - theres more data
79 | -for the statistical model to learn in bigger files, so less has to be
80 | -considered noise.
81 | -
82 | -
83 | -____________________________________
84 | -packJPG by Matthias Stirner, 11/2011
85 |
--------------------------------------------------------------------------------
/docs/howtocompile.txt:
--------------------------------------------------------------------------------
1 | How to compile packJPG (01/30/2012)
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 |
4 | This document gives detailed instructions on compiling packJPG either as
5 | an executable or a static/shared libary.
6 |
7 |
8 | Compiling packJPG as an executable
9 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 |
11 | Makefiles or provided for Microsoft Windows NT ('Makefile') and Unix
12 | ('Makefile.unix'). Both have been tested and verified to work in GCC
13 | v3.4.5, but they should work with other compilers and newer/older
14 | versions of the GCC as well. If you want to compile packJPG in Microsoft
15 | Visual Studio for Microsoft Windows, just create a new project and add
16 | all source files to it.
17 |
18 |
19 | Compiling packJPG as a static or shared library
20 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21 |
22 | If you want to compile packJPG as a static or shared library, add all
23 | the source files to a new static/shared library project. 'BUILD_LIB'
24 | (without the ') has to be defined either at the beginning of
25 | 'packJPG.cpp' or from the compilers options. 'BUILD_DLL' has to be
26 | defined in addition only if a shared library is to be compiled (don't
27 | define this for a static library!).
28 |
29 | The source file 'packJPGdll.h' contains all public function declarations
30 | of the library and can be included in external projects which use the
31 | packJPG shared library.
32 |
33 |
34 | Compiling developer functions
35 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
36 |
37 | If you want to include developer functions in the packJPG executable,
38 | 'DEV_BUILD' has to be defined. Developer functions are not available in
39 | the packJPG library. They are not needed in any way for basic packJPG
40 | functionality (i.e. compression and decompression) and can be left out
41 | to compile a smaller executable. Read 'developer.txt' for more
42 | information.
43 |
44 |
45 | Defines overview / summary
46 | ~~~~~~~~~~~~~~~~~~~~~~~~~~
47 |
48 | This paragraph gives a short overview over preprocessor defines
49 | mentioned in the above paragraphs.
50 |
51 | BUILD_LIB
52 | Has to be defined when compiling a static or shared library.
53 |
54 | BUILD_DLL
55 | Has to defined when compiling a shared library only.
56 |
57 | BUILD_DEV
58 | If this is defined, developer functions are included in the executable.
59 | In library builds developer functions are not available.
60 |
61 |
62 | ____________________________________
63 | packJPG by Matthias Stirner, 01/2012
--------------------------------------------------------------------------------
/docs/lgpl-3.0.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/docs/sample_images.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/packjpg/packJPG/93a7dfbe1fb9aa2aee763cc5b8a16c14b2f66c8c/docs/sample_images.zip
--------------------------------------------------------------------------------
/docs/versionnumbering.txt:
--------------------------------------------------------------------------------
1 | Version numbering guideline
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 |
4 |
5 | The packJPG version consists of two parts the main version number and
6 | the sub version string. An example: 'packJPG v2.4a', an older version of
7 | packJPG, has the main version number '2.4' and the sub version string
8 | 'a'.
9 |
10 | Compressed .pjg files are required to be compatible between subversions:
11 | packJPG v2.4a compressed .pjg files can be extracted by packJPG v2.4,
12 | packJPG v2.4b, packJPG v2.4c, ... and vice versa. Only if there is a
13 | change in the main version number, encoded files can be incompatible
14 | between each other: packJPG v2.4 won't extract packJPG v2.3 compressed
15 | .pjg files and vice versa.
16 |
17 | The subversion string is used to indicate smaller changes that won't
18 | break compatibility, like, f.e., bug fixes or speed improvements. It can
19 | also be empty (for the first new main version in a series) and should be
20 | enumerated as 'a', 'b', 'c', ... , 'z', 'aa', 'ab', 'ac', ..., 'zz'. For
21 | any highly specific improvements it might also be used differently, to
22 | indicate these changes, f.e. 'packJPG v2.5fast'.
23 |
24 | The main version number is changed directly in the source code via the
25 | 'pjgversion' (main version number) and the 'subversion' (subversion
26 | string) constant variables.
27 |
28 |
--------------------------------------------------------------------------------
/source/Makefile:
--------------------------------------------------------------------------------
1 | # packXXX Makefile, based on UniMake: Universal Makefile
2 | # Created by Matthias Stirner, 01/2016
3 |
4 | TARGET = packJPG
5 | CC = gcc
6 | CPP = g++
7 | RC = windres -O coff
8 | CPPFLAGS = -I. -O3 -Wall -pedantic -funroll-loops -ffast-math -fsched-spec-load -fomit-frame-pointer -std=c++14
9 | LDFLAGS = -static -static-libgcc -static-libstdc++ -lstdc++fs
10 | CSRC = $(wildcard *.c)
11 | CPPSRC = $(wildcard *.cpp)
12 | DEPS = $(wildcard *.h) Makefile
13 | OBJ = $(patsubst %.c,%.o,$(CSRC)) $(patsubst %.cpp,%.o,$(CPPSRC))
14 |
15 | # conditional stuff
16 | ifeq ($(OS),Windows_NT)
17 | LDFLAGS += -lpthread -L libwinpthread-1.dll
18 | RES = icons.res
19 | UPX := -upx --best --lzma $(TARGET).exe
20 | else
21 | CPPFLAGS += -DUNIX
22 | RC =
23 | RES =
24 | UPX =
25 | endif
26 |
27 | %.o: %.cpp $(DEPS)
28 | $(CPP) -c -o $@ $< $(CPPFLAGS)
29 |
30 | %.res: %.rc
31 | @-$(RC) $< $@
32 |
33 | $(TARGET): $(OBJ) $(RES)
34 | $(CPP) -o $@ $^ -s $(LDFLAGS)
35 | $(UPX)
36 |
37 | .PHONY: all dev lib dll
38 |
39 | all: $(TARGET)
40 |
41 | dev: CPPFLAGS += -DDEV_BUILD
42 | dev: $(TARGET)
43 |
44 | lib: CPPFLAGS += -DBUILD_LIB
45 | lib: $(OBJ)
46 | ar r $(TARGET)lib.a $(OBJ)
47 | ranlib $(TARGET)lib.a
48 |
49 | dll: CPPFLAGS += -DBUILD_DLL
50 | dll: LDFLAGS += -Wl,--out-implib,libpackJPG.a -fvisibility=hidden
51 | dll: $(OBJ)
52 | $(CPP) -shared -o $(TARGET).dll $^ $(LDFLAGS)
53 |
54 | clean:
55 | @echo clean...
56 | @-rm *.o *.a $(TARGET) $(TARGET).exe $(TARGET).dll
57 |
--------------------------------------------------------------------------------
/source/Makefile_osx:
--------------------------------------------------------------------------------
1 | # Project: packJPG
2 | # Makefile created by Ryan Flynn 2014.02.06
3 | # Working with Clang 5.1
4 |
5 | CC = cc
6 | CPP = c++
7 | RC = windres
8 | CFLAGS = -I. -DUNIX -DDEV_BUILD -O3 -Wall -pedantic -funroll-loops -ffast-math -fomit-frame-pointer -std=c++14
9 | LDFLAGS = -lstdc++fs
10 | DEPS = bitops.h aricoder.h pjpgtbl.h dct8x8.h Makefile
11 | OBJ = bitops.o aricoder.o packjpg.o
12 | RES = icon.res
13 | BIN = packjpg
14 |
15 | %.o: %.cpp $(DEPS)
16 | $(CPP) -c -o $@ $< $(CFLAGS)
17 |
18 | $(BIN): $(OBJ)
19 | $(CPP) -o $@ $^ $(LDFLAGS)
20 |
21 | clean:
22 | $(RM) $(OBJ) $(BIN)
23 |
--------------------------------------------------------------------------------
/source/app_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/packjpg/packJPG/93a7dfbe1fb9aa2aee763cc5b8a16c14b2f66c8c/source/app_icon.ico
--------------------------------------------------------------------------------
/source/aricoder.cpp:
--------------------------------------------------------------------------------
1 | #include "aricoder.h"
2 |
3 | #include "bitops.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | template
11 | void ArithmeticBitWriter::write_bit() {
12 | // add bit at last position
13 | curr_byte_ = (curr_byte_ << 1) | bit;
14 | // increment bit position
15 | curr_bit_++;
16 |
17 | // write bit if done
18 | if (curr_bit_ == 8) {
19 | data_.emplace_back(curr_byte_);
20 | curr_bit_ = 0;
21 | }
22 | }
23 |
24 | void ArithmeticBitWriter::write_n_zero_bits(std::size_t n) {
25 | if (n + curr_bit_ >= 8) {
26 | auto remainingBits = 8 - curr_bit_;
27 | n -= remainingBits;
28 | curr_byte_ <<= remainingBits;
29 | data_.emplace_back(curr_byte_);
30 | curr_bit_ = 0;
31 | }
32 |
33 | while (n >= 8) {
34 | data_.emplace_back(0);
35 | n -= 8;
36 | }
37 |
38 | curr_byte_ <<= n;
39 | curr_bit_ += n;
40 | }
41 |
42 | void ArithmeticBitWriter::write_n_one_bits(std::size_t n) {
43 | constexpr std::uint8_t all_ones = std::numeric_limits::max();
44 | if (n + curr_bit_ >= 8) {
45 | auto remainingBits = 8 - curr_bit_;
46 | n -= remainingBits;
47 | curr_byte_ <<= remainingBits;
48 | curr_byte_ |= all_ones >> (8 - remainingBits);
49 | data_.emplace_back(curr_byte_);
50 | curr_bit_ = 0;
51 | }
52 |
53 | while (n >= 8) {
54 | data_.emplace_back(all_ones);
55 | n -= 8;
56 | }
57 |
58 | curr_byte_ = (curr_byte_ << n) | (all_ones >> (8 - n));
59 | curr_bit_ += n;
60 | }
61 |
62 | void ArithmeticBitWriter::pad() {
63 | while (curr_bit_ > 0) {
64 | write_bit<0>();
65 | }
66 | }
67 |
68 | std::vector ArithmeticBitWriter::get_data() const {
69 | return data_;
70 | }
71 |
72 | ArithmeticDecoder::ArithmeticDecoder(Reader& reader) : reader_(reader) {
73 | // code buffer has to be filled before starting decoding
74 | for (std::uint32_t i = 0; i < CODER_USE_BITS; i++ ) {
75 | ccode = ( ccode << 1 ) | read_bit();
76 | }
77 | }
78 |
79 | ArithmeticEncoder::ArithmeticEncoder(Writer& writer) : writer_(writer) {}
80 |
81 | ArithmeticEncoder::~ArithmeticEncoder() {
82 | if (!finalized) {
83 | this->finalize();
84 | }
85 | }
86 |
87 | void ArithmeticEncoder::finalize() {
88 | if (finalized) {
89 | return;
90 | }
91 |
92 | // due to clow < CODER_LIMIT050, and chigh >= CODER_LIMIT050
93 | // there are only two possible cases
94 | if (clow < CODER_LIMIT025) {
95 | bitwriter_->write_bit<0>();
96 | bitwriter_->write_bit<1>();
97 | bitwriter_->write_n_one_bits(nrbits);
98 | nrbits = 0;
99 | } else {
100 | // case b.), clow >= CODER_LIMIT025
101 | bitwriter_->write_bit<1>();
102 | }
103 | // done, zeroes are auto-read by the decoder
104 |
105 | bitwriter_->pad(); // Pad code with zeroes.
106 | writer_.write(bitwriter_->get_data());
107 |
108 | finalized = true;
109 | }
110 |
111 | /* -----------------------------------------------
112 | arithmetic encoder function
113 | ----------------------------------------------- */
114 |
115 | void ArithmeticEncoder::encode( symbol* s )
116 | {
117 | // Make local copies of clow_ and chigh_ for cache performance:
118 | uint32_t clow_local = clow;
119 | uint32_t chigh_local = chigh;
120 | // update steps, low count, high count
121 | cstep = (chigh_local - clow_local + 1) / s->scale;
122 | chigh_local = clow_local + (cstep * s->high_count) - 1;
123 | clow_local = clow_local + (cstep * s->low_count);
124 |
125 | // e3 scaling is performed for speed and to avoid underflows
126 | // if both, low and high are either in the lower half or in the higher half
127 | // one bit can be safely shifted out
128 | while ( clow_local >= CODER_LIMIT050 || chigh_local < CODER_LIMIT050 ) {
129 | if (chigh_local < CODER_LIMIT050 ) { // this means both, high and low are below, and 0 can be safely shifted out
130 | // write 0 bit
131 | bitwriter_->write_bit<0>();
132 | // shift out remaing e3 bits
133 | bitwriter_->write_n_one_bits(nrbits);
134 | nrbits = 0;
135 | }
136 | else { // if the first wasn't the case, it's clow >= CODER_LIMIT050
137 | // write 1 bit
138 | bitwriter_->write_bit<1>();
139 | clow_local &= CODER_LIMIT050 - 1;
140 | chigh_local &= CODER_LIMIT050 - 1;
141 | // shift out remaing e3 bits
142 | bitwriter_->write_n_zero_bits(nrbits);
143 | nrbits = 0;
144 | }
145 | clow_local <<= 1;
146 | chigh_local <<= 1;
147 | chigh_local++;
148 | }
149 |
150 | // e3 scaling, to make sure that theres enough space between low and high
151 | while ( (clow_local >= CODER_LIMIT025 ) && (chigh_local < CODER_LIMIT075 ) ) {
152 | nrbits++;
153 | clow_local &= CODER_LIMIT025 - 1;
154 | chigh_local ^= CODER_LIMIT025 + CODER_LIMIT050;
155 | // clow -= CODER_LIMIT025;
156 | // chigh -= CODER_LIMIT025;
157 | clow_local <<= 1;
158 | chigh_local <<= 1;
159 | chigh_local++;
160 | }
161 |
162 | clow = clow_local;
163 | chigh = chigh_local;
164 | }
165 |
166 |
167 | /* -----------------------------------------------
168 | arithmetic decoder get count function
169 | ----------------------------------------------- */
170 |
171 | unsigned int ArithmeticDecoder::decode_count( symbol* s )
172 | {
173 | // update cstep, which is needed to remove the symbol from the stream later
174 | cstep = ( ( chigh - clow ) + 1 ) / s->scale;
175 |
176 | // return counts, needed to decode the symbol from the statistical model
177 | return ( ccode - clow ) / cstep;
178 | }
179 |
180 | /* -----------------------------------------------
181 | arithmetic decoder function
182 | ----------------------------------------------- */
183 |
184 | void ArithmeticDecoder::decode( symbol* s )
185 | {
186 | // no actual decoding takes place, as this has to happen in the statistical model
187 | // the symbol has to be removed from the stream, though
188 |
189 | // alread have steps updated from decoder_count
190 | // update low count and high count
191 | uint32_t ccode_local = ccode;
192 | uint32_t clow_local = clow;
193 | uint32_t chigh_local = clow_local + (cstep * s->high_count) - 1;
194 | clow_local = clow_local + (cstep * s->low_count);
195 |
196 | // e3 scaling is performed for speed and to avoid underflows
197 | // if both, low and high are either in the lower half or in the higher half
198 | // one bit can be safely shifted out
199 | while ( (clow_local >= CODER_LIMIT050 ) || (chigh_local < CODER_LIMIT050 ) ) {
200 | if (clow_local >= CODER_LIMIT050 ) {
201 | clow_local &= CODER_LIMIT050 - 1;
202 | chigh_local &= CODER_LIMIT050 - 1;
203 | ccode_local &= CODER_LIMIT050 - 1;
204 | } // if the first wasn't the case, it's chigh < CODER_LIMIT050
205 | clow_local <<= 1;
206 | chigh_local <<= 1;
207 | chigh_local++;
208 | ccode_local <<= 1;
209 | ccode_local |= read_bit();
210 | }
211 |
212 | // e3 scaling, to make sure that theres enough space between low and high
213 | while ( (clow_local >= CODER_LIMIT025 ) && (chigh_local < CODER_LIMIT075 ) ) {
214 | clow_local &= CODER_LIMIT025 - 1;
215 | chigh_local ^= CODER_LIMIT025 + CODER_LIMIT050;
216 | // clow -= CODER_LIMIT025;
217 | // chigh -= CODER_LIMIT025;
218 | ccode_local -= CODER_LIMIT025;
219 | clow_local <<= 1;
220 | chigh_local <<= 1;
221 | chigh_local++;
222 | ccode_local <<= 1;
223 | ccode_local |= read_bit();
224 | }
225 | chigh = chigh_local;
226 | clow = clow_local;
227 | ccode = ccode_local;
228 | }
229 |
230 | /* -----------------------------------------------
231 | bit reader function
232 | ----------------------------------------------- */
233 |
234 | unsigned char ArithmeticDecoder::read_bit()
235 | {
236 | // read in new byte if needed
237 | if ( cbit == 0 ) {
238 | if ( !reader_.read_byte(&bbyte)) // read next byte if available
239 | bbyte = 0; // if no more data is left in the stream
240 | cbit = 8;
241 | }
242 |
243 | // decrement current bit position
244 | cbit--;
245 | // return bit at cbit position
246 | return BITN( bbyte, cbit );
247 | }
248 |
249 |
250 | /* -----------------------------------------------
251 | universal statistical model for arithmetic coding
252 |
253 | boundaries of this model:
254 | max_s (maximum symbol) -> 1 <= max_s <= 1024 (???)
255 | max_c (maximum context) -> 1 <= max_c <= 1024 (???)
256 | max_o (maximum order) -> -1 <= max_o <= 4
257 | c_lim (maximum count) -> 2 <= c_lim <= 4096 (???)
258 | WARNING: this can be memory intensive, so don't overdo it
259 | max_s == 256; max_c == 256; max_o == 4 would be way too much
260 | ----------------------------------------------- */
261 |
262 | model_s::model_s( int max_s, int max_c, int max_o, int c_lim ) :
263 | // Copy settings into the model:
264 | max_symbol(max_s),
265 | max_context(max_c),
266 | max_order(max_o + 1),
267 | max_count(c_lim),
268 |
269 | current_order(max_o + 1),
270 | sb0_count(max_s),
271 |
272 | totals(max_s + 2),
273 | scoreboard(new bool[max_s]),
274 | contexts(max_o + 3)
275 | {
276 | std::fill(scoreboard, scoreboard + max_symbol, false);
277 |
278 | // set up null table
279 | table_s* null_table = new table_s;
280 | null_table->counts = std::vector(max_symbol, uint16_t(1)); // Set all probabilities to 1.
281 |
282 | // set up internal counts
283 | null_table->max_count = 1;
284 | null_table->max_symbol = max_symbol;
285 |
286 | // set up start table
287 | table_s* start_table = new table_s;
288 | start_table->links = std::vector(max_context);
289 |
290 | // integrate tables into contexts
291 | contexts[ 0 ] = null_table;
292 | contexts[ 1 ] = start_table;
293 |
294 | // build initial 'normal' tables
295 | for (int i = 2; i <= max_order; i++ ) {
296 | // set up current order table
297 | contexts[i] = new table_s;
298 | // build forward links
299 | if ( i < max_order ) {
300 | contexts[i]->links = std::vector(max_context);
301 | }
302 | contexts[ i - 1 ]->links[ 0 ] = contexts[ i ];
303 | }
304 | }
305 |
306 |
307 | /* -----------------------------------------------
308 | model class destructor - recursive cleanup of memory is done here
309 | ----------------------------------------------- */
310 |
311 | model_s::~model_s()
312 | {
313 | // clean up each 'normal' table
314 | delete contexts[1];
315 |
316 | // clean up null table
317 | delete contexts[0];
318 |
319 | // free everything else
320 | delete[] scoreboard;
321 | }
322 |
323 |
324 | /* -----------------------------------------------
325 | Updates statistics for a specific symbol / resets to highest order.
326 | Use -1 if you just want to reset without updating statistics.
327 | ----------------------------------------------- */
328 | void model_s::update_model( int symbol )
329 | {
330 | // only contexts, that were actually used to encode
331 | // the symbol get its count updated
332 | if ( symbol >= 0 ) {
333 | for (int local_order = ( current_order < 1 ) ? 1 : current_order;
334 | local_order <= max_order; local_order++ ) {
335 | table_s* context = contexts[ local_order ];
336 | auto& count = context->counts[symbol];
337 | // update count for specific symbol & scale
338 | count++;
339 | // store side information for totalize_table
340 | context->max_count = std::max(count, context->max_count);
341 | context->max_symbol = std::max(uint16_t(symbol + 1), context->max_symbol);
342 | // if count for that symbol have gone above the maximum count
343 | // the table has to be resized (scale factor 2)
344 | if (count == max_count) {
345 | context->rescale_table();
346 | }
347 | }
348 | }
349 |
350 | // reset scoreboard and current order
351 | current_order = max_order;
352 | std::fill(scoreboard, scoreboard + max_symbol, false);
353 | sb0_count = max_symbol;
354 | }
355 |
356 |
357 | /* -----------------------------------------------
358 | shift in one context (max no of contexts is max_c)
359 | ----------------------------------------------- */
360 |
361 | void model_s::shift_context( int c )
362 | {
363 | // shifting is not possible if max_order is below 1
364 | // or context index is negative
365 | if ( ( max_order < 2 ) || ( c < 0 ) ) return;
366 |
367 | // shift each orders' context
368 | for (int i = max_order; i > 1; i-- ) {
369 | // this is the new current order context
370 | table_s* context = contexts[ i - 1 ]->links[ c ];
371 |
372 | // check if context exists, build if needed
373 | if ( context == nullptr ) {
374 | // reserve memory for next table_s
375 | context = new table_s;
376 | // finished here if this is a max order context
377 | if ( i < max_order ) {
378 | // build links to higher order tables otherwise
379 | context->links.resize(max_context);
380 | }
381 | // put context to its right place
382 | contexts[ i - 1 ]->links[ c ] = context;
383 | }
384 |
385 | // switch context
386 | contexts[ i ] = context;
387 | }
388 | }
389 |
390 |
391 | /* -----------------------------------------------
392 | Flushes the entire model by calling rescale_table on all contexts.
393 | ----------------------------------------------- */
394 |
395 | void model_s::flush_model()
396 | {
397 | contexts[1]->recursive_flush();
398 | }
399 |
400 |
401 | /* -----------------------------------------------
402 | Excludes every symbol above c.
403 | ----------------------------------------------- */
404 |
405 | void model_s::exclude_symbols(int c)
406 | {
407 | // exclusions are back to normal after update_model is used
408 |
409 | for ( c = c + 1; c < max_symbol; c++ ) {
410 | if ( !scoreboard[ c ] ) {
411 | scoreboard[ c ] = true;
412 | sb0_count--;
413 | }
414 | }
415 | }
416 |
417 |
418 | /* -----------------------------------------------
419 | converts an int to a symbol, needed only when encoding
420 | ----------------------------------------------- */
421 |
422 | int model_s::convert_int_to_symbol( int c, symbol *s )
423 | {
424 | // search the symbol c in the current context table_s,
425 | // return scale, low- and high counts
426 |
427 | // totalize table for the current context
428 | table_s* context = contexts[ current_order ];
429 | totalize_table( context );
430 |
431 | // finding the scale is easy
432 | s->scale = totals[ 0 ];
433 |
434 | // check if that symbol exists in the current table. send escape otherwise
435 | if ( context->counts[ c ] > 0 ) {
436 | // return high and low count for the current symbol
437 | s->low_count = totals[ c + 2 ];
438 | s->high_count = totals[ c + 1 ];
439 | return 0;
440 | }
441 |
442 | // return high and low count for the escape symbol
443 | s->low_count = totals[ 1 ];
444 | s->high_count = totals[ 0 ];
445 | current_order--;
446 | return 1;
447 | }
448 |
449 |
450 | /* -----------------------------------------------
451 | returns the current context scale needed only when decoding
452 | ----------------------------------------------- */
453 |
454 | void model_s::get_symbol_scale( symbol *s )
455 | {
456 | // getting the scale is easy: totalize the table_s, use accumulated count -> done
457 | totalize_table( contexts[ current_order ] );
458 | s->scale = totals[ 0 ];
459 | }
460 |
461 |
462 | /* -----------------------------------------------
463 | converts a count to an int, called after get_symbol_scale
464 | ----------------------------------------------- */
465 |
466 | int model_s::convert_symbol_to_int(uint32_t count, symbol *s)
467 | {
468 | // seek the symbol that matches the count,
469 | // also, set low- and high count for the symbol - it has to be removed from the stream
470 |
471 |
472 | // go through the totals table, search the symbol that matches the count
473 | int c;
474 | for (c = 1; c < int(totals.size()); c++) {
475 | if (count >= totals[c]) {
476 | break;
477 | }
478 | }
479 | // set up the current symbol
480 | s->low_count = totals[c]; // It is guaranteed that there exists such a symbol.
481 | s->high_count = totals[c - 1]; // This is guaranteed to not go out of bounds since the search started at index 1 of totals.
482 | // send escape if escape symbol encountered
483 | if (c == 1) {
484 | current_order--;
485 | return ESCAPE_SYMBOL;
486 | }
487 |
488 | // return symbol value
489 | return c - 2 ; // Since c is not one and is a positive number, this will be nonnegative.
490 | }
491 |
492 |
493 | /* -----------------------------------------------
494 | totals are calculated by accumulating counts in the current table_s
495 | ----------------------------------------------- */
496 |
497 | void model_s::totalize_table( table_s* context )
498 | {
499 | // update exclusion is used, so this has to be done each time
500 | // escape probability calculation also takes place here
501 |
502 | // accumulated counts must never exceed CODER_MAXSCALE
503 | // as CODER_MAXSCALE is big enough, though, (2^29), this shouldn't happen and is not checked
504 |
505 | const auto& counts = context->counts;
506 |
507 | // check counts
508 | if (!counts.empty()) { // if counts are already set
509 | // locally store current fill/symbol count
510 | int local_symb = sb0_count;
511 |
512 | // set the last symbol of the totals to zero
513 | int i = context->max_symbol - 1;
514 | totals[i + 2] = 0;
515 |
516 | // (re)set current total
517 | uint32_t curr_total = 0;
518 |
519 | // go reverse though the whole counts table and accumulate counts
520 | // leave space at the beginning of the table for the escape symbol
521 | for (; i >= 0; i--) {
522 | // only count probability if the current symbol is not 'scoreboard - excluded'
523 | if (!scoreboard[i]) {
524 | uint16_t curr_count = counts[i];
525 | if (curr_count > 0) {
526 | // add counts for the current symbol
527 | curr_total += curr_count;
528 | // exclude symbol from scoreboard
529 | scoreboard[i] = true;
530 | sb0_count--;
531 | }
532 | }
533 | totals[i + 1] = curr_total;
534 | }
535 | // here the escape calculation needs to take place
536 | uint32_t esc_prob;
537 | if (local_symb == sb0_count) {
538 | esc_prob = 1;
539 | } else if (sb0_count == 0) {
540 | esc_prob = 0;
541 | } else {
542 | // esc_prob = 1;
543 | esc_prob = sb0_count * ( local_symb - sb0_count );
544 | esc_prob /= ( local_symb * context->max_count );
545 | esc_prob++;
546 | }
547 | // include escape probability in totals table
548 | totals[ 0 ] = totals[ 1 ] + esc_prob;
549 | } else { // if counts are not already set
550 | // setup counts for current table
551 | context->counts.resize(max_symbol);
552 | // set totals table -> only escape probability included
553 | totals[ 0 ] = 1;
554 | totals[ 1 ] = 0;
555 | }
556 | }
557 |
558 | /* -----------------------------------------------
559 | special version of model_s for binary coding
560 |
561 | boundaries of this model:
562 | ... (maximum symbol) -> 2 (0 or 1 )
563 | max_c (maximum context) -> 1 <= max_c <= 1024 (???)
564 | max_o (maximum order) -> -1 <= max_o <= 4
565 | ----------------------------------------------- */
566 |
567 | model_b::model_b( int max_c, int max_o, int c_lim ) :
568 | // Copy settings into the model:
569 | max_context(max_c),
570 | max_order(max_o + 1),
571 | max_count(c_lim),
572 |
573 | contexts(max_o + 3)
574 | {
575 | // set up null table
576 | table* null_table = new table;
577 | null_table->counts = std::vector(2, uint16_t(1));
578 | null_table->scale = uint32_t(2);
579 |
580 | // set up start table
581 | table* start_table = new table;
582 | start_table->links = std::vector(max_context);
583 |
584 | // integrate tables into contexts
585 | contexts[ 0 ] = null_table;
586 | contexts[ 1 ] = start_table;
587 |
588 | // build initial 'normal' tables
589 | for (int i = 2; i <= max_order; i++ ) {
590 | // set up current order table
591 | contexts[i] = new table;
592 | // build forward links
593 | if ( i < max_order ) {
594 | contexts[i]->links = std::vector(max_context);
595 | }
596 | contexts[ i - 1 ]->links[ 0 ] = contexts[ i ];
597 | }
598 | }
599 |
600 |
601 | /* -----------------------------------------------
602 | model class destructor - recursive cleanup of memory is done here
603 | ----------------------------------------------- */
604 |
605 | model_b::~model_b()
606 | {
607 | // clean up each 'normal' table
608 | delete contexts[1];
609 |
610 | // clean up null table
611 | delete contexts[0];
612 | }
613 |
614 |
615 | /* -----------------------------------------------
616 | updates statistics for a specific symbol / resets to highest order
617 | ----------------------------------------------- */
618 |
619 | void model_b::update_model( int symbol )
620 | {
621 | // use -1 if you just want to reset without updating statistics
622 |
623 | table* context = contexts[ max_order ];
624 |
625 | // only contexts, that were actually used to encode
626 | // the symbol get their counts updated
627 | if ( ( symbol >= 0 ) && ( max_order >= 0 ) ) {
628 | // update count for specific symbol & scale
629 | context->counts[ symbol ]++;
630 | context->scale++;
631 | // if counts for that symbol have gone above the maximum count
632 | // the table has to be resized (scale factor 2)
633 | if ( context->counts[ symbol ] >= max_count )
634 | context->rescale_table();
635 | }
636 | }
637 |
638 |
639 | /* -----------------------------------------------
640 | shift in one context (max no of contexts is max_c)
641 | ----------------------------------------------- */
642 |
643 | void model_b::shift_context( int c )
644 | {
645 | // shifting is not possible if max_order is below 1
646 | // or context index is negative
647 | if ( (max_order < 2 ) || ( c < 0 ) ) return;
648 |
649 | // shift each orders' context
650 | for (int i = max_order; i > 1; i-- ) {
651 | // this is the new current order context
652 | table* context = contexts[ i - 1 ]->links[ c ];
653 |
654 | // check if context exists, build if needed
655 | if ( context == nullptr ) {
656 | // reserve memory for next table
657 | context = new table;
658 | // finished here if this is a max order context
659 | if ( i < max_order) {
660 | // build links to higher order tables otherwise
661 | context->links.resize(max_context);
662 | }
663 | // put context to its right place
664 | contexts[ i - 1 ]->links[ c ] = context;
665 | }
666 |
667 | // switch context
668 | contexts[ i ] = context;
669 | }
670 | }
671 |
672 |
673 | /* -----------------------------------------------
674 | Flushes the entire model by calling rescale_table on all contexts.
675 | ----------------------------------------------- */
676 |
677 | void model_b::flush_model()
678 | {
679 | contexts[1]->recursive_flush();
680 | }
681 |
682 |
683 | /* -----------------------------------------------
684 | converts an int to a symbol, needed only when encoding
685 | ----------------------------------------------- */
686 |
687 | int model_b::convert_int_to_symbol( int c, symbol *s )
688 | {
689 | table* context = contexts[ max_order ];
690 |
691 | // check if counts are available
692 | context->check_counts();
693 |
694 | // finding the scale is easy
695 | s->scale = context->scale;
696 |
697 | // return high and low count for current symbol
698 | if ( c == 0 ) { // if 0 is to be encoded
699 | s->low_count = uint32_t(0);
700 | s->high_count = context->counts[ 0 ];
701 | }
702 | else { // if 1 is to be encoded
703 | s->low_count = context->counts[ 0 ];
704 | s->high_count = context->scale;
705 | }
706 |
707 | return 1;
708 | }
709 |
710 |
711 | /* -----------------------------------------------
712 | returns the current context scale needed only when decoding
713 | ----------------------------------------------- */
714 |
715 | void model_b::get_symbol_scale( symbol *s )
716 | {
717 | table* context = contexts[ max_order ];
718 |
719 | // check if counts are available
720 | context->check_counts();
721 |
722 | // getting the scale is easy
723 | s->scale = context->scale;
724 | }
725 |
726 |
727 | /* -----------------------------------------------
728 | converts a count to an int, called after get_symbol_scale
729 | ----------------------------------------------- */
730 |
731 | int model_b::convert_symbol_to_int(uint32_t count, symbol *s)
732 | {
733 | table* context = contexts[ max_order ];
734 | auto counts0 = context->counts[ 0 ];
735 |
736 | // set up the current symbol
737 | if ( count < counts0 ) {
738 | s->low_count = uint32_t(0);
739 | s->high_count = counts0;
740 | return 0;
741 | }
742 | else {
743 | s->low_count = counts0;
744 | s->high_count = s->scale;
745 | return 1;
746 | }
747 | }
748 |
--------------------------------------------------------------------------------
/source/aricoder.h:
--------------------------------------------------------------------------------
1 | #ifndef ARICODER_H
2 | #define ARICODER_H
3 |
4 | #include "bitops.h"
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | // defines for coder
12 | constexpr uint32_t CODER_USE_BITS = 31; // Must never be above 31.
13 | constexpr uint32_t CODER_LIMIT100 = uint32_t(1 << CODER_USE_BITS);
14 | constexpr uint32_t CODER_LIMIT025 = CODER_LIMIT100 / 4;
15 | constexpr uint32_t CODER_LIMIT050 = (CODER_LIMIT100 / 4) * 2;
16 | constexpr uint32_t CODER_LIMIT075 = (CODER_LIMIT100 / 4) * 3;
17 | constexpr uint32_t CODER_MAXSCALE = CODER_LIMIT025 - 1;
18 | constexpr uint32_t ESCAPE_SYMBOL = CODER_LIMIT025;
19 |
20 | // symbol struct, used in arithmetic coding
21 | struct symbol {
22 | uint32_t low_count;
23 | uint32_t high_count;
24 | uint32_t scale;
25 | };
26 |
27 | // table struct, used in in statistical models,
28 | // holding all info needed for one context
29 | struct table {
30 | // counts for each symbol contained in the table
31 | std::vector counts;
32 | // links to higher order contexts
33 | std::vector links;
34 | // accumulated counts
35 | uint32_t scale = uint32_t(0);
36 |
37 | /* -----------------------------------------------
38 | Recursively deletes all the tables pointed to in links.
39 | ----------------------------------------------- */
40 | ~table() {
41 | for (auto& link : links) {
42 | if (link != nullptr) {
43 | delete link;
44 | }
45 | }
46 | }
47 |
48 | /* -----------------------------------------------
49 | Checks if counts exist, creating it if it does not.
50 | ----------------------------------------------- */
51 | inline void check_counts() {
52 | // check if counts are available
53 | if (counts.empty()) {
54 | // setup counts for current table
55 | counts.resize(2, uint16_t(1));
56 | // set scale
57 | scale = uint32_t(2);
58 | }
59 | }
60 |
61 | /* -----------------------------------------------
62 | Resizes the table by rightshifting each count by 1.
63 | ----------------------------------------------- */
64 | inline void rescale_table() {
65 | // Do nothing if counts is not set:
66 | if (!counts.empty()) {
67 | // Scale the table by bitshifting each count, be careful not to set any count zero:
68 | counts[0] = std::max(uint16_t(1), uint16_t(counts[0] >> 1));
69 | counts[1] = std::max(uint16_t(1), uint16_t(counts[1] >> 1));
70 | scale = counts[0] + counts[1];
71 | }
72 | }
73 |
74 | /* -----------------------------------------------
75 | Recursively runs rescale_table on this and all linked contexts.
76 | ----------------------------------------------- */
77 | inline void recursive_flush() {
78 | for (auto& link : links) {
79 | if (link != nullptr) {
80 | link->recursive_flush();
81 | }
82 | }
83 | // rescale specific table
84 | rescale_table();
85 | }
86 | };
87 |
88 | // special table struct, used in in model_s,
89 | // holding additional info for a speedier 'totalize_table'
90 | struct table_s {
91 | // counts for each symbol contained in the table
92 | std::vector counts;
93 | // links to higher order contexts
94 | std::vector links;
95 | // speedup info
96 | uint16_t max_count = uint16_t(0);
97 | uint16_t max_symbol = uint16_t(0);
98 |
99 | /* -----------------------------------------------
100 | Recursively deletes all the tables pointed to in links.
101 | ----------------------------------------------- */
102 | ~table_s() {
103 | for (auto& link : links) {
104 | if (link != nullptr) {
105 | delete link;
106 | }
107 | }
108 | }
109 |
110 | /* -----------------------------------------------
111 | Resizes the table by rightshifting each count by 1.
112 | ----------------------------------------------- */
113 | inline void rescale_table() {
114 | // Nothing to do if counts has not been set.
115 | if (counts.empty()) return;
116 |
117 | // now scale the table by bitshifting each count
118 | int lst_symbol = max_symbol;
119 | int i;
120 | for (i = 0; i < lst_symbol; i++) {
121 | counts[i] >>= 1; // Counts will not become negative since it is an unsigned type.
122 | }
123 |
124 | // also rescale tables max count
125 | max_count >>= 1;
126 |
127 | // seek for new last symbol
128 | for (i = lst_symbol - 1; i >= 0; i--) {
129 | if (counts[i] > 0) {
130 | break;
131 | }
132 | }
133 | max_symbol = i + 1;
134 | }
135 |
136 | /* -----------------------------------------------
137 | Recursively runs rescale_table on this and all linked contexts.
138 | ----------------------------------------------- */
139 | inline void recursive_flush() {
140 | for (auto& link : links) {
141 | if (link != nullptr) {
142 | link->recursive_flush();
143 | }
144 | }
145 |
146 | // rescale specific table
147 | rescale_table();
148 | }
149 | };
150 |
151 | class ArithmeticBitWriter {
152 | public:
153 | template
154 | void write_bit();
155 |
156 | void write_n_zero_bits(std::size_t n);
157 |
158 | void write_n_one_bits(std::size_t n);
159 |
160 | void pad();
161 |
162 | std::vector get_data() const;
163 |
164 |
165 | private:
166 | std::vector data_;
167 | std::uint8_t curr_byte_ = 0;
168 | std::size_t curr_bit_ = 0;
169 | };
170 |
171 |
172 | /* -----------------------------------------------
173 | class for arithmetic coding of data to/from iostream
174 | ----------------------------------------------- */
175 |
176 | class ArithmeticEncoder
177 | {
178 | public:
179 | ArithmeticEncoder(Writer& writer);
180 | ~ArithmeticEncoder();
181 | void encode( symbol* s );
182 |
183 | void finalize();
184 |
185 | private:
186 |
187 | // i/o variables
188 |
189 | bool finalized = false;
190 | Writer& writer_;
191 | std::unique_ptr bitwriter_ = std::make_unique();
192 |
193 | // arithmetic coding variables
194 | unsigned int ccode = 0;
195 | unsigned int clow = 0;
196 | unsigned int chigh = CODER_LIMIT100 - 1;
197 | unsigned int cstep = 0;
198 | unsigned int nrbits = 0;
199 | };
200 |
201 | class ArithmeticDecoder {
202 | public:
203 | ArithmeticDecoder(Reader& reader);
204 | ~ArithmeticDecoder() {}
205 | unsigned int decode_count( symbol* s );
206 | void decode( symbol* s );
207 |
208 | private:
209 | unsigned char read_bit();
210 |
211 | // i/o variables
212 | Reader& reader_;
213 | unsigned char bbyte = 0;
214 | unsigned char cbit = 0;
215 |
216 | // arithmetic coding variables
217 | unsigned int ccode = 0;
218 | unsigned int clow = 0;
219 | unsigned int chigh = CODER_LIMIT100 - 1;
220 | unsigned int cstep = 0;
221 | };
222 |
223 |
224 | /* -----------------------------------------------
225 | universal statistical model for arithmetic coding
226 | ----------------------------------------------- */
227 |
228 | class model_s
229 | {
230 | public:
231 |
232 | model_s( int max_s, int max_c, int max_o, int c_lim );
233 | ~model_s();
234 |
235 | void update_model( int symbol );
236 | void shift_context( int c );
237 | void flush_model();
238 | void exclude_symbols(int c);
239 |
240 | int convert_int_to_symbol( int c, symbol *s );
241 | void get_symbol_scale( symbol *s );
242 | int convert_symbol_to_int(uint32_t count, symbol *s);
243 |
244 | private:
245 |
246 | inline void totalize_table(table_s* context);
247 |
248 | const int max_symbol;
249 | const int max_context;
250 | const int max_order;
251 | const int max_count;
252 |
253 | int current_order;
254 | int sb0_count;
255 |
256 | std::vector totals;
257 | bool* scoreboard;
258 | std::vector contexts;
259 | };
260 |
261 |
262 | /* -----------------------------------------------
263 | binary statistical model for arithmetic coding
264 | ----------------------------------------------- */
265 |
266 | class model_b
267 | {
268 | public:
269 |
270 | model_b( int max_c, int max_o, int c_lim );
271 | ~model_b();
272 |
273 | void update_model( int symbol );
274 | void shift_context( int c );
275 | void flush_model();
276 |
277 | int convert_int_to_symbol( int c, symbol *s );
278 | void get_symbol_scale( symbol *s );
279 | int convert_symbol_to_int(uint32_t count, symbol *s);
280 |
281 | private:
282 |
283 | const int max_context;
284 | const int max_order;
285 | const int max_count;
286 |
287 | std::vector contexts;
288 | };
289 |
290 | // Base case for shifting an arbitrary number of contexts into the model.
291 | template
292 | static void shift_model(M) {}
293 |
294 | // Shift an arbitrary number of contexts into the model (at most max_c contexts).
295 | template
296 | static void shift_model(M model, C context, Cargs ... contextList) {
297 | model->shift_context(context);
298 | shift_model(model, contextList...);
299 | }
300 |
301 | /* -----------------------------------------------
302 | generic model_s encoder function
303 | ----------------------------------------------- */
304 | static inline void encode_ari( ArithmeticEncoder* encoder, model_s* model, int c )
305 | {
306 | symbol s;
307 | int esc;
308 |
309 | do {
310 | esc = model->convert_int_to_symbol( c, &s );
311 | encoder->encode( &s );
312 | } while ( esc );
313 | model->update_model( c );
314 | }
315 |
316 | /* -----------------------------------------------
317 | generic model_s decoder function
318 | ----------------------------------------------- */
319 | static inline int decode_ari( ArithmeticDecoder* decoder, model_s* model )
320 | {
321 | symbol s;
322 | uint32_t count;
323 | int c;
324 |
325 | do{
326 | model->get_symbol_scale( &s );
327 | count = decoder->decode_count( &s );
328 | c = model->convert_symbol_to_int( count, &s );
329 | decoder->decode( &s );
330 | } while ( c == ESCAPE_SYMBOL );
331 | model->update_model( c );
332 |
333 | return c;
334 | }
335 |
336 | /* -----------------------------------------------
337 | generic model_b encoder function
338 | ----------------------------------------------- */
339 | static inline void encode_ari( ArithmeticEncoder* encoder, model_b* model, int c )
340 | {
341 | symbol s;
342 |
343 | model->convert_int_to_symbol( c, &s );
344 | encoder->encode( &s );
345 | model->update_model( c );
346 | }
347 |
348 | /* -----------------------------------------------
349 | generic model_b decoder function
350 | ----------------------------------------------- */
351 | static inline int decode_ari( ArithmeticDecoder* decoder, model_b* model )
352 | {
353 | symbol s;
354 |
355 | model->get_symbol_scale( &s );
356 | uint32_t count = decoder->decode_count( &s );
357 | int c = model->convert_symbol_to_int( count, &s );
358 | decoder->decode( &s );
359 | model->update_model( c );
360 |
361 | return c;
362 | }
363 |
364 | #endif
365 |
--------------------------------------------------------------------------------
/source/bitops.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | This file contains special classes for bitwise
3 | reading and writing of arrays
4 | */
5 |
6 | #include "bitops.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #if defined(_WIN32) || defined(WIN32)
17 | #include
18 | #include
19 | #endif
20 |
21 |
22 | /* -----------------------------------------------
23 | constructor for BitReader class
24 | ----------------------------------------------- */
25 |
26 | BitReader::BitReader( unsigned char* array, int size ) {
27 | data = array;
28 | lbyte = size;
29 | }
30 |
31 | /* -----------------------------------------------
32 | destructor for BitReader class
33 | ----------------------------------------------- */
34 |
35 | BitReader::~BitReader() {}
36 |
37 | /* -----------------------------------------------
38 | reads n bits from BitReader
39 | ----------------------------------------------- */
40 |
41 | unsigned int BitReader::read( int nbits ) {
42 | unsigned int retval = 0;
43 |
44 | if ( eof()) {
45 | peof_ += nbits;
46 | return 0;
47 | }
48 |
49 | while ( nbits >= cbit ) {
50 | nbits -= cbit;
51 | retval |= ( RBITS( data[cbyte], cbit ) << nbits );
52 | update_curr_byte();
53 | if (eof()) {
54 | peof_ = nbits;
55 | return retval;
56 | }
57 | }
58 |
59 | if ( nbits > 0 ) {
60 | retval |= ( MBITS( data[cbyte], cbit, (cbit-nbits) ) );
61 | cbit -= nbits;
62 | }
63 |
64 | return retval;
65 | }
66 |
67 | /* -----------------------------------------------
68 | reads one bit from BitReader
69 | ----------------------------------------------- */
70 |
71 | unsigned char BitReader::read_bit() {
72 | if (eof()) {
73 | peof_++;
74 | return 0;
75 | }
76 |
77 | // read one bit
78 | unsigned char bit = BITN( data[cbyte], --cbit );
79 | if ( cbit == 0 ) {
80 | update_curr_byte();
81 | }
82 |
83 | return bit;
84 | }
85 |
86 | void BitReader::update_curr_byte() {
87 | cbyte++;
88 | eof_ = cbyte == lbyte;
89 | cbit = 8;
90 | }
91 |
92 | /* -----------------------------------------------
93 | to skip padding from current byte
94 | ----------------------------------------------- */
95 |
96 | unsigned char BitReader::unpad( unsigned char fillbit ) {
97 | if ( ( cbit == 8 ) || eof()) {
98 | return fillbit;
99 | } else {
100 | fillbit = read( 1 );
101 | while ( cbit != 8 ) {
102 | read( 1 );
103 | }
104 | }
105 |
106 | return fillbit;
107 | }
108 |
109 | /* -----------------------------------------------
110 | get current position in array
111 | ----------------------------------------------- */
112 |
113 | int BitReader::getpos() {
114 | return cbyte;
115 | }
116 |
117 | /* -----------------------------------------------
118 | get current bit position
119 | ----------------------------------------------- */
120 |
121 | int BitReader::getbitp() {
122 | return cbit;
123 | }
124 |
125 | /* -----------------------------------------------
126 | set byte and bit position
127 | ----------------------------------------------- */
128 |
129 | void BitReader::setpos( int pbyte, int pbit ) {
130 | if ( pbyte < lbyte ) {
131 | // reset eof
132 | eof_ = false;
133 | // set positions
134 | cbyte = pbyte;
135 | cbit = pbit;
136 | } else {
137 | // set eof
138 | eof_ = true;
139 | // set positions
140 | cbyte = lbyte;
141 | cbit = 8;
142 | peof_ = ( ( pbyte - lbyte ) * 8 ) + 8 - pbit;
143 | }
144 | }
145 |
146 | /* -----------------------------------------------
147 | rewind n bits
148 | ----------------------------------------------- */
149 |
150 | void BitReader::rewind_bits( int nbits ) {
151 | if (eof()) {
152 | if (nbits > peof_) {
153 | nbits -= peof_;
154 | peof_ = 0;
155 | } else {
156 | peof_ -= nbits;
157 | return;
158 | }
159 | eof_ = false;
160 | }
161 |
162 | cbit += nbits;
163 | cbyte -= cbit / 8;
164 | cbit = cbit % 8;
165 | if ( cbyte < 0 ) {
166 | cbyte = 0;
167 | cbit = 8;
168 | }
169 | }
170 |
171 | bool BitReader::eof() {
172 | return eof_;
173 | }
174 |
175 | int BitReader::peof() {
176 | return peof_;
177 | }
178 |
179 | BitWriter::BitWriter(std::uint8_t padbit) : padbit_(padbit) {}
180 |
181 | BitWriter::~BitWriter() {}
182 |
183 | std::uint32_t rbits32(std::uint32_t val, std::size_t n) {
184 | return val & (0xFFFFFFFF >> (32 - n));
185 | }
186 |
187 | std::uint32_t mbits32(std::uint32_t val, std::size_t l, std::size_t r) {
188 | return rbits32(val, l) >> r;
189 | }
190 |
191 | void BitWriter::write_u16(std::uint16_t val, std::size_t num_bits) {
192 | while (num_bits >= curr_bit_) {
193 | curr_byte_ |= mbits32(val, num_bits, num_bits - curr_bit_);
194 | num_bits -= curr_bit_;
195 | write_curr_byte();
196 | }
197 |
198 | if (num_bits > 0) {
199 | curr_byte_ |= rbits32(val, num_bits) << (curr_bit_ - num_bits);
200 | curr_bit_ -= num_bits;
201 | }
202 | }
203 |
204 | void BitWriter::write_bit(std::uint8_t bit) {
205 | curr_bit_--;
206 | curr_byte_ |= bit << curr_bit_;
207 | if (curr_bit_ == 0) {
208 | write_curr_byte();
209 | }
210 | }
211 |
212 | void BitWriter::write_curr_byte() {
213 | bytes_.emplace_back(curr_byte_);
214 | curr_byte_ = 0;
215 | curr_bit_ = 8;
216 | }
217 |
218 | void BitWriter::pad() {
219 | while (curr_bit_ < 8) {
220 | write_bit(padbit_);
221 | }
222 | }
223 |
224 | std::vector BitWriter::get_bytes() {
225 | pad(); // Pad the last bits of the current byte before returning the written bytes.
226 | return bytes_;
227 | }
228 |
229 | unsigned char* BitWriter::get_c_bytes() {
230 | pad(); // Pad the last bits of the current byte before returning the written bytes.
231 | unsigned char* c_bytes = new unsigned char[bytes_.size()];
232 | std::copy(std::begin(bytes_), std::end(bytes_), c_bytes);
233 | return c_bytes;
234 | }
235 |
236 | std::size_t BitWriter::num_bytes_written() const {
237 | return bytes_.size();
238 | }
239 |
240 | unsigned char* Reader::get_c_data() {
241 | const auto data = this->get_data();
242 | auto c_data_copy = (unsigned char*)std::malloc(data.size() * sizeof data[0]);
243 | if (c_data_copy == nullptr) {
244 | return nullptr;
245 | }
246 |
247 | std::copy(std::begin(data), std::end(data), c_data_copy);
248 | return c_data_copy;
249 | }
250 |
251 | MemoryReader::MemoryReader(const std::vector& bytes) :
252 | data_(bytes),
253 | cbyte_(std::begin(data_)) {
254 | }
255 |
256 | MemoryReader::MemoryReader(const std::uint8_t* bytes, std::size_t size) :
257 | data_(bytes, bytes + size),
258 | cbyte_(std::begin(data_)) {
259 | }
260 |
261 | std::size_t MemoryReader::read(std::uint8_t* to, std::size_t num_to_read) {
262 | if (num_to_read == 0 || to == nullptr) {
263 | return 0;
264 | }
265 | auto numAvailable = std::distance(cbyte_, std::end(data_));
266 | auto numRead = std::min(static_cast(numAvailable), num_to_read);
267 | auto end = std::next(cbyte_, numRead);
268 | std::copy(cbyte_, end, to);
269 | cbyte_ = end;
270 | return numRead;
271 | }
272 |
273 | std::size_t MemoryReader::read(std::vector& into, std::size_t n, std::size_t offset) {
274 | const std::size_t num_available = get_size() - num_bytes_read(); // The number of bytes in the reader not yet read.
275 | const std::size_t num_to_read = std::min(n, num_available); // How many bytes will be read.
276 | if (into.size() < num_to_read + offset) {
277 | into.resize(num_to_read + offset);
278 | }
279 |
280 | const auto end = std::next(cbyte_, num_to_read);
281 | const auto write_start = std::next(std::begin(into), offset);
282 | std::copy(cbyte_, end, write_start);
283 | cbyte_ = end;
284 | return num_to_read;
285 | }
286 |
287 | std::uint8_t MemoryReader::read_byte() {
288 | if (end_of_reader()) {
289 | throw std::runtime_error("No bytes left to read");
290 | } else {
291 | std::uint8_t the_byte = *cbyte_;
292 | ++cbyte_;
293 | return the_byte;
294 | }
295 | }
296 |
297 | bool MemoryReader::read_byte(std::uint8_t* byte) {
298 | if (end_of_reader()) {
299 | return false;
300 | } else {
301 | *byte = *cbyte_;
302 | ++cbyte_;
303 | return true;
304 | }
305 | }
306 |
307 | void MemoryReader::skip(std::size_t n) {
308 | auto num_to_skip = std::min(n, std::size_t(std::distance(cbyte_, std::end(data_))));
309 | cbyte_ += num_to_skip;
310 | }
311 |
312 | void MemoryReader::rewind_bytes(std::size_t n) {
313 | auto num_to_rewind = std::min(n, std::size_t(std::distance(std::begin(data_), cbyte_)));
314 | auto new_pos = std::distance(std::begin(data_), cbyte_) - num_to_rewind;
315 | cbyte_ = std::next(std::begin(data_), new_pos);
316 | }
317 |
318 | void MemoryReader::rewind() {
319 | cbyte_ = std::begin(data_);
320 | }
321 |
322 | std::size_t MemoryReader::num_bytes_read() {
323 | return std::distance(std::begin(data_), cbyte_);
324 | }
325 |
326 | std::size_t MemoryReader::get_size() {
327 | return data_.size();
328 | }
329 |
330 | std::vector MemoryReader::get_data() {
331 | return data_;
332 | }
333 |
334 | bool MemoryReader::error() {
335 | return false;
336 | }
337 |
338 | bool MemoryReader::end_of_reader() {
339 | return cbyte_ == std::end(data_);
340 | }
341 |
342 | unsigned char* Writer::get_c_data() {
343 | try {
344 | const auto data = this->get_data();
345 | auto c_data_copy = (unsigned char*)std::malloc(data.size() * sizeof data[0]);
346 | if (c_data_copy == nullptr) {
347 | return nullptr;
348 | }
349 |
350 | std::copy(std::begin(data), std::end(data), c_data_copy);
351 | return c_data_copy;
352 | } catch (const std::exception&) {
353 | return nullptr;
354 | }
355 | }
356 |
357 | MemoryWriter::MemoryWriter() {}
358 |
359 | std::size_t MemoryWriter::write(const std::uint8_t* from, std::size_t n) {
360 | data_.insert(std::end(data_), from, from + n);
361 | return n;
362 | }
363 |
364 | std::size_t MemoryWriter::write(const std::vector& bytes) {
365 | data_.insert(std::end(data_), std::begin(bytes), std::end(bytes));
366 | return bytes.size();
367 | }
368 |
369 | std::size_t MemoryWriter::write(const std::array& bytes) {
370 | data_.insert(std::end(data_), std::begin(bytes), std::end(bytes));
371 | return bytes.size();
372 | }
373 |
374 | bool MemoryWriter::write_byte(std::uint8_t byte) {
375 | data_.emplace_back(byte);
376 | return true;
377 | }
378 |
379 | std::vector MemoryWriter::get_data() {
380 | return data_;
381 | }
382 |
383 | void MemoryWriter::reset() {
384 | data_.resize(0);
385 | }
386 |
387 | std::size_t MemoryWriter::num_bytes_written() {
388 | return data_.size();
389 | }
390 |
391 | bool MemoryWriter::error() {
392 | return false;
393 | }
394 |
395 | FileWriter::FileWriter(const std::string& file_path) : file_path_(file_path) {
396 | fptr_ = std::fopen(file_path.c_str(), "wb");
397 | if (fptr_ != nullptr) {
398 | file_buffer_.reserve(32768);
399 | std::setvbuf(fptr_, file_buffer_.data(), _IOFBF, file_buffer_.capacity());
400 | } else {
401 | throw std::runtime_error("Unable to open " + file_path_ + " for writing.");
402 | }
403 |
404 | }
405 |
406 | FileWriter::~FileWriter() {
407 | if (fptr_ != nullptr) {
408 | std::fflush(fptr_);
409 | std::fclose(fptr_);
410 | }
411 | }
412 |
413 | std::size_t FileWriter::write(const std::uint8_t* from, std::size_t n) {
414 | return std::fwrite(from, sizeof from[0], n, fptr_);
415 | }
416 |
417 | std::size_t FileWriter::write(const std::vector& bytes) {
418 | return write(bytes.data(), bytes.size());
419 | }
420 |
421 | std::size_t FileWriter::write(const std::array& bytes) {
422 | return write(bytes.data(), 2);
423 | }
424 |
425 | bool FileWriter::write_byte(std::uint8_t byte) {
426 | return std::fputc(byte, fptr_) == byte;
427 | }
428 |
429 | std::vector FileWriter::get_data() {
430 | std::fflush(fptr_);
431 | if (std::ifstream is{ file_path_, std::ios::binary | std::ios::ate }) {
432 | const auto size = is.tellg();
433 | std::vector data_copy(size);
434 | is.seekg(0);
435 | if (is.read(reinterpret_cast(data_copy.data()), size)) {
436 | return data_copy;
437 | } else {
438 | throw std::runtime_error("FileWriter::get_data: unable to read bytes from file.");
439 | }
440 | } else {
441 | throw std::runtime_error("FileWriter::get_data: unable to open read stream for file.");
442 | }
443 | }
444 |
445 | void FileWriter::reset() {
446 | std::fseek(fptr_, 0, SEEK_SET);
447 | }
448 |
449 | std::size_t FileWriter::num_bytes_written() {
450 | std::fflush(fptr_);
451 | return std::experimental::filesystem::file_size(file_path_);
452 | }
453 |
454 | bool FileWriter::error() {
455 | return fptr_ == nullptr || std::ferror(fptr_);
456 | }
457 |
458 | StreamWriter::StreamWriter() {
459 | writer_ = std::make_unique();
460 | }
461 |
462 | StreamWriter::~StreamWriter() {
463 | #if defined(_WIN32) || defined(WIN32)
464 | const int result = _setmode(_fileno(stdout), _O_BINARY);
465 | if (result == -1) {
466 | return;
467 | }
468 | #endif
469 | const auto& data = writer_->get_data();
470 | fwrite(data.data(), sizeof data[0], data.size(), stdout);
471 | }
472 |
473 | std::size_t StreamWriter::write(const std::uint8_t* from, std::size_t n) {
474 | return writer_->write(from, n);
475 | }
476 |
477 | std::size_t StreamWriter::write(const std::vector& bytes) {
478 | return writer_->write(bytes);
479 | }
480 |
481 | std::size_t StreamWriter::write(const std::array& bytes) {
482 | return writer_->write(bytes);
483 | }
484 |
485 | bool StreamWriter::write_byte(std::uint8_t byte) {
486 | return writer_->write_byte(byte);
487 | }
488 |
489 | std::vector StreamWriter::get_data() {
490 | return writer_->get_data();
491 | }
492 |
493 | void StreamWriter::reset() {
494 | writer_->reset();
495 | }
496 |
497 | std::size_t StreamWriter::num_bytes_written() {
498 | return writer_->num_bytes_written();
499 | }
500 |
501 | bool StreamWriter::error() {
502 | return writer_->error();
503 | }
504 |
505 |
506 |
507 | FileReader::FileReader(const std::string& file_path) {
508 | if (std::ifstream is{ file_path, std::ios::binary | std::ios::ate }) {
509 | const auto size = is.tellg();
510 | std::vector data(size);
511 | is.seekg(0);
512 | if (is.read(reinterpret_cast(data.data()), size)) {
513 | reader_ = std::make_unique(data);
514 | } else {
515 | throw std::runtime_error("FileReader: unable to read bytes from " + file_path);
516 | }
517 | } else {
518 | throw std::runtime_error("FileReader: unable to open read stream for " + file_path);
519 | }
520 | }
521 |
522 | FileReader::~FileReader() {}
523 |
524 | std::size_t FileReader::read(std::uint8_t* to, std::size_t num_to_read) {
525 | return reader_->read(to, num_to_read);
526 | }
527 |
528 | std::size_t FileReader::read(std::vector& into, std::size_t num_to_read, std::size_t offset) {
529 | return reader_->read(into, num_to_read, offset);
530 | }
531 |
532 | std::uint8_t FileReader::read_byte() {
533 | return reader_->read_byte();
534 | }
535 |
536 | bool FileReader::read_byte(std::uint8_t* to) {
537 | return reader_->read_byte(to);
538 | }
539 |
540 | void FileReader::skip(std::size_t n) {
541 | return reader_->skip(n);
542 | }
543 |
544 | void FileReader::rewind_bytes(std::size_t n) {
545 | return reader_->rewind_bytes(n);
546 | }
547 |
548 | void FileReader::rewind() {
549 | reader_->rewind();
550 | }
551 |
552 | std::size_t FileReader::num_bytes_read() {
553 | return reader_->num_bytes_read();
554 | }
555 |
556 | std::size_t FileReader::get_size() {
557 | return reader_->get_size();
558 | }
559 |
560 | std::vector FileReader::get_data() {
561 | return reader_->get_data();
562 | }
563 |
564 | bool FileReader::error() {
565 | return reader_->error();
566 | }
567 |
568 | bool FileReader::end_of_reader() {
569 | return reader_->end_of_reader();
570 | }
571 |
572 | StreamReader::StreamReader() {
573 | #if defined(_WIN32) || defined(WIN32)
574 | const int result = _setmode(_fileno(stdin), _O_BINARY);
575 | if (result == -1) {
576 | throw std::runtime_error("Unable to set mode for stdin");
577 | }
578 | #endif
579 | // read whole stream into memory buffer
580 | std::vector stream_data;
581 | constexpr auto buffer_capacity = 1024 * 1024;
582 | std::vector buffer(buffer_capacity);
583 |
584 | auto bytes_read = std::fread(buffer.data(), sizeof buffer[0], buffer_capacity, stdin);
585 | while (bytes_read > 0) {
586 | stream_data.insert(std::end(stream_data), std::begin(buffer), std::begin(buffer) + bytes_read);
587 | bytes_read = std::fread(buffer.data(), sizeof buffer[0], buffer_capacity, stdin);
588 | }
589 |
590 | reader_ = std::make_unique(stream_data);
591 | }
592 |
593 | std::size_t StreamReader::read(std::uint8_t* to, std::size_t num_to_read) {
594 | return reader_->read(to, num_to_read);
595 | }
596 |
597 | std::size_t StreamReader::read(std::vector& into, std::size_t num_to_read, std::size_t offset) {
598 | return reader_->read(into, num_to_read, offset);
599 | }
600 |
601 | std::uint8_t StreamReader::read_byte() {
602 | return reader_->read_byte();
603 | }
604 |
605 | bool StreamReader::read_byte(std::uint8_t* to) {
606 | return reader_->read_byte(to);
607 | }
608 |
609 | void StreamReader::skip(std::size_t n) {
610 | reader_->skip(n);
611 | }
612 |
613 | void StreamReader::rewind_bytes(std::size_t n) {
614 | reader_->rewind_bytes(n);
615 | }
616 |
617 | void StreamReader::rewind() {
618 | reader_->rewind();
619 | }
620 |
621 | std::size_t StreamReader::num_bytes_read() {
622 | return reader_->num_bytes_read();
623 | }
624 |
625 | std::size_t StreamReader::get_size() {
626 | return reader_->get_size();
627 | }
628 |
629 | std::vector StreamReader::get_data() {
630 | return reader_->get_data();
631 | }
632 |
633 | bool StreamReader::error() {
634 | return reader_->error();
635 | }
636 |
637 | bool StreamReader::end_of_reader() {
638 | return reader_->end_of_reader();
639 | }
640 |
--------------------------------------------------------------------------------
/source/bitops.h:
--------------------------------------------------------------------------------
1 | #ifndef BITOPS_H
2 | #define BITOPS_H
3 |
4 | #define RBITS( c, n ) ( c & ( 0xFF >> (8 - n) ) )
5 | #define LBITS( c, n ) ( c >> (8 - n) )
6 | #define MBITS( c, l, r ) ( RBITS( c,l ) >> r )
7 | #define BITN( c, n ) ( (c >> n) & 0x1 )
8 | #define BITLEN( l, v ) for ( l = 0; ( v >> l ) > 0; l++ )
9 | #define FDIV2( v, p ) ( ( v < 0 ) ? -( (-v) >> p ) : ( v >> p ) )
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 |
17 | /* -----------------------------------------------
18 | class to read arrays bitwise
19 | ----------------------------------------------- */
20 | class BitReader {
21 | public:
22 | BitReader( unsigned char* array, int size );
23 | ~BitReader();
24 | unsigned int read( int nbits );
25 | unsigned char read_bit();
26 | unsigned char unpad( unsigned char fillbit );
27 | int getpos();
28 | int getbitp();
29 | void setpos( int pbyte, int pbit );
30 | void rewind_bits( int nbits );
31 | bool eof();
32 | int peof();
33 |
34 | private:
35 | void update_curr_byte();
36 |
37 | unsigned char* data = nullptr;
38 | int lbyte = 0;
39 | int cbyte = 0;
40 | int cbit = 8;
41 | int peof_ = 0;
42 | bool eof_ = false;
43 | };
44 |
45 |
46 | class BitWriter {
47 | public:
48 | BitWriter(std::uint8_t padbit);
49 | ~BitWriter();
50 | /*
51 | * Writes the first (lowest) n bits from val (n is assumed to be less than or equal to 16).
52 | */
53 | void write_u16(std::uint16_t val, std::size_t num_bits);
54 |
55 | /*
56 | * Writes the bit (assumed to be 0 or 1).
57 | */
58 | void write_bit(std::uint8_t bit);
59 | /**
60 | * Fills in the remainder of the current byte using the padbit.
61 | */
62 | void pad();
63 | /**
64 | * Returns a copy of the bytes written to the writer, padding the current byte if necessary.
65 | */
66 | std::vector get_bytes();
67 | /**
68 | * Allocates and returns a copy of the bytes written to the writer, padding the current byte if necessary.
69 | */
70 | unsigned char* get_c_bytes();
71 | /*
72 | * Returns the number of bytes written. If a byte has not been fully written (e.g., only 5 bits have been written),
73 | * then it is not counted in the number of bytes written.
74 | */
75 | std::size_t num_bytes_written() const;
76 | private:
77 | void write_curr_byte();
78 |
79 | std::vector bytes_;
80 | const std::uint8_t padbit_; // A bit, either 0 or 1, to fill the unwritten bits of the current byte with.
81 | std::uint8_t curr_byte_ = 0; // The current byte being written.
82 | std::size_t curr_bit_ = 8; // The position of the next bit in the current byte.
83 | };
84 |
85 | class Reader {
86 | public:
87 | Reader() {}
88 |
89 | virtual ~Reader() {}
90 |
91 | /*
92 | * Reads the minimum of n and the number of unread bytes to the pointer.
93 | */
94 | virtual std::size_t read(std::uint8_t* to, std::size_t n) = 0;
95 |
96 | /*
97 | * Reads the minimum of n and the number of unread bytes to the vector, starting at the given offset in the
98 | * vector. If the destination vector is too small, it is resized. Returns the number of bytes read.
99 | */
100 | virtual std::size_t read(std::vector& into, std::size_t n, std::size_t offset = 0) = 0;
101 |
102 | /*
103 | * Returns one byte from the reader, throwing a std::runtime_error exception if there are none left to read.
104 | */
105 | virtual std::uint8_t read_byte() = 0;
106 |
107 | /*
108 | * Reads one byte to the pointer, returning whether there was a byte available to writer.
109 | */
110 | virtual bool read_byte(std::uint8_t* to) = 0;
111 |
112 | /*
113 | * Skips the minimum of the n and the number of unread bytes left in the reader.
114 | */
115 | virtual void skip(std::size_t n) = 0;
116 |
117 | /*
118 | * Moves the reader back by the minimum of n and the number of bytes already read in the reader.
119 | */
120 | virtual void rewind_bytes(std::size_t n) = 0;
121 |
122 | /*
123 | * Resets the number of bytes read to zero.
124 | */
125 | virtual void rewind() = 0;
126 |
127 | /*
128 | * Returns the number of bytes read.
129 | */
130 | virtual std::size_t num_bytes_read() = 0;
131 |
132 | /*
133 | * Returns the number of bytes in the reader.
134 | */
135 | virtual std::size_t get_size() = 0;
136 |
137 | /*
138 | * Returns a copy of the data backing the reader.
139 | */
140 | virtual std::vector get_data() = 0;
141 |
142 | unsigned char* get_c_data();
143 |
144 | virtual bool error() = 0;
145 | /*
146 | * Returns whether all bytes in the reader have been read.
147 | */
148 | virtual bool end_of_reader() = 0;
149 | };
150 |
151 | class MemoryReader : public Reader {
152 | public:
153 | MemoryReader(const std::vector& bytes);
154 | MemoryReader(const std::uint8_t* bytes, std::size_t size);
155 |
156 | ~MemoryReader() {}
157 |
158 | std::size_t read(std::uint8_t* to, std::size_t num_to_read) override;
159 | std::size_t read(std::vector& into, std::size_t num_to_read, std::size_t offset = 0) override;
160 | std::uint8_t read_byte() override;
161 | bool read_byte(std::uint8_t* to) override;
162 |
163 | void skip(std::size_t n) override;
164 | void rewind_bytes(std::size_t n) override;
165 | void rewind() override;
166 |
167 | std::size_t num_bytes_read() override;
168 | std::size_t get_size() override;
169 | std::vector get_data() override;
170 | bool error() override;
171 | bool end_of_reader() override;
172 |
173 | private:
174 | const std::vector data_;
175 | std::vector::const_iterator cbyte_; // The position in the data of the byte being read.
176 | };
177 |
178 | class FileReader : public Reader {
179 | public:
180 | FileReader(const std::string& file_path);
181 | ~FileReader();
182 |
183 | std::size_t read(std::uint8_t* to, std::size_t num_to_read) override;
184 | std::size_t read(std::vector& into, std::size_t num_to_read, std::size_t offset = 0) override;
185 | std::uint8_t read_byte() override;
186 | bool read_byte(std::uint8_t* to) override;
187 |
188 | void skip(std::size_t n) override;
189 | void rewind_bytes(std::size_t n) override;
190 | void rewind() override;
191 |
192 | std::size_t num_bytes_read() override;
193 | std::size_t get_size() override;
194 | std::vector get_data() override;
195 | bool error() override;
196 | bool end_of_reader() override;
197 |
198 | private:
199 | std::unique_ptr reader_;
200 | };
201 |
202 | class StreamReader : public Reader {
203 | public:
204 | StreamReader();
205 |
206 | ~StreamReader() {}
207 |
208 | std::size_t read(std::uint8_t* to, std::size_t num_to_read) override;
209 | std::size_t read(std::vector& into, std::size_t num_to_read, std::size_t offset = 0) override;
210 | std::uint8_t read_byte() override;
211 | bool read_byte(std::uint8_t* to) override;
212 |
213 | void skip(std::size_t n) override;
214 | void rewind_bytes(std::size_t n) override;
215 | void rewind() override;
216 |
217 | std::size_t num_bytes_read() override;
218 | std::size_t get_size() override;
219 | std::vector get_data() override;
220 | bool error() override;
221 | bool end_of_reader() override;
222 |
223 | private:
224 | std::unique_ptr reader_;
225 | };
226 |
227 | class Writer {
228 | public:
229 | Writer() {}
230 |
231 | virtual ~Writer() {}
232 |
233 | virtual std::size_t write(const std::uint8_t* from, std::size_t n) = 0;
234 | virtual std::size_t write(const std::vector& bytes) = 0;
235 | virtual std::size_t write(const std::array& bytes) = 0;
236 |
237 | virtual bool write_byte(std::uint8_t byte) = 0;
238 |
239 | virtual std::vector get_data() = 0;
240 | unsigned char* get_c_data();
241 |
242 | virtual void reset() = 0;
243 | virtual std::size_t num_bytes_written() = 0;
244 | virtual bool error() = 0;
245 | };
246 |
247 | class MemoryWriter : public Writer {
248 | public:
249 | MemoryWriter();
250 |
251 | ~MemoryWriter() {}
252 |
253 | std::size_t write(const std::uint8_t* from, std::size_t n) override;
254 | std::size_t write(const std::vector& bytes) override;
255 | std::size_t write(const std::array& bytes) override;
256 | bool write_byte(std::uint8_t byte) override;
257 |
258 | std::vector get_data() override;
259 |
260 | void reset() override;
261 | std::size_t num_bytes_written() override;
262 | bool error() override;
263 |
264 | private:
265 | std::vector data_;
266 | };
267 |
268 | class FileWriter : public Writer {
269 | public:
270 | FileWriter(const std::string& file_path);
271 | ~FileWriter();
272 |
273 | std::size_t write(const std::uint8_t* from, std::size_t n) override;
274 | std::size_t write(const std::vector& bytes) override;
275 | std::size_t write(const std::array& bytes) override;
276 | bool write_byte(std::uint8_t byte) override;
277 |
278 | std::vector get_data() override;
279 |
280 | void reset() override;
281 | std::size_t num_bytes_written() override;
282 | bool error() override;
283 |
284 | private:
285 | FILE* fptr_ = nullptr;
286 | std::vector file_buffer_; // Used to replace the default file buffer for reads/writes to improve performance.
287 | const std::string file_path_;
288 | };
289 |
290 | class StreamWriter : public Writer {
291 | public:
292 | StreamWriter();
293 | ~StreamWriter();
294 |
295 | std::size_t write(const std::uint8_t* from, std::size_t n) override;
296 | std::size_t write(const std::vector& bytes) override;
297 | std::size_t write(const std::array& bytes) override;
298 | bool write_byte(std::uint8_t byte) override;
299 |
300 | std::vector get_data() override;
301 |
302 | void reset() override;
303 | std::size_t num_bytes_written() override;
304 | bool error() override;
305 |
306 | private:
307 | std::unique_ptr writer_;
308 | };
309 |
310 | #endif
311 |
--------------------------------------------------------------------------------
/source/dct8x8.h:
--------------------------------------------------------------------------------
1 | #define DCT_RSC_FACTOR 8192
2 | #define DCT_RESCALE( v ) ( ( ( v > 0 ) ? ( v + (DCT_RSC_FACTOR/2) ) : ( v - (DCT_RSC_FACTOR/2) ) ) / DCT_RSC_FACTOR )
3 |
4 |
5 | // precalculated int values for 8x8 IDCT, multplied by 8192
6 | const int icos_idct_8x8[ 4096 ] =
7 | {
8 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
9 | 1420, 1970, 1856, 1670, 1420, 1116, 769, 392,
10 | 1338, 1856, 1748, 1573, 1338, 1051, 724, 369,
11 | 1204, 1670, 1573, 1416, 1204, 946, 652, 332,
12 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
13 | 805, 1116, 1051, 946, 805, 632, 435, 222,
14 | 554, 769, 724, 652, 554, 435, 300, 153,
15 | 283, 392, 369, 332, 283, 222, 153, 78,
16 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
17 | 1420, 1670, 769, -392, -1420, -1970, -1856, -1116,
18 | 1338, 1573, 724, -369, -1338, -1856, -1748, -1051,
19 | 1204, 1416, 652, -332, -1204, -1670, -1573, -946,
20 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
21 | 805, 946, 435, -222, -805, -1116, -1051, -632,
22 | 554, 652, 300, -153, -554, -769, -724, -435,
23 | 283, 332, 153, -78, -283, -392, -369, -222,
24 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
25 | 1420, 1116, -769, -1970, -1420, 392, 1856, 1670,
26 | 1338, 1051, -724, -1856, -1338, 369, 1748, 1573,
27 | 1204, 946, -652, -1670, -1204, 332, 1573, 1416,
28 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
29 | 805, 632, -435, -1116, -805, 222, 1051, 946,
30 | 554, 435, -300, -769, -554, 153, 724, 652,
31 | 283, 222, -153, -392, -283, 78, 369, 332,
32 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
33 | 1420, 392, -1856, -1116, 1420, 1670, -769, -1970,
34 | 1338, 369, -1748, -1051, 1338, 1573, -724, -1856,
35 | 1204, 332, -1573, -946, 1204, 1416, -652, -1670,
36 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
37 | 805, 222, -1051, -632, 805, 946, -435, -1116,
38 | 554, 153, -724, -435, 554, 652, -300, -769,
39 | 283, 78, -369, -222, 283, 332, -153, -392,
40 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
41 | 1420, -392, -1856, 1116, 1420, -1670, -769, 1970,
42 | 1338, -369, -1748, 1051, 1338, -1573, -724, 1856,
43 | 1204, -332, -1573, 946, 1204, -1416, -652, 1670,
44 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
45 | 805, -222, -1051, 632, 805, -946, -435, 1116,
46 | 554, -153, -724, 435, 554, -652, -300, 769,
47 | 283, -78, -369, 222, 283, -332, -153, 392,
48 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
49 | 1420, -1116, -769, 1970, -1420, -392, 1856, -1670,
50 | 1338, -1051, -724, 1856, -1338, -369, 1748, -1573,
51 | 1204, -946, -652, 1670, -1204, -332, 1573, -1416,
52 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
53 | 805, -632, -435, 1116, -805, -222, 1051, -946,
54 | 554, -435, -300, 769, -554, -153, 724, -652,
55 | 283, -222, -153, 392, -283, -78, 369, -332,
56 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
57 | 1420, -1670, 769, 392, -1420, 1970, -1856, 1116,
58 | 1338, -1573, 724, 369, -1338, 1856, -1748, 1051,
59 | 1204, -1416, 652, 332, -1204, 1670, -1573, 946,
60 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
61 | 805, -946, 435, 222, -805, 1116, -1051, 632,
62 | 554, -652, 300, 153, -554, 769, -724, 435,
63 | 283, -332, 153, 78, -283, 392, -369, 222,
64 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
65 | 1420, -1970, 1856, -1670, 1420, -1116, 769, -392,
66 | 1338, -1856, 1748, -1573, 1338, -1051, 724, -369,
67 | 1204, -1670, 1573, -1416, 1204, -946, 652, -332,
68 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
69 | 805, -1116, 1051, -946, 805, -632, 435, -222,
70 | 554, -769, 724, -652, 554, -435, 300, -153,
71 | 283, -392, 369, -332, 283, -222, 153, -78,
72 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
73 | 1204, 1670, 1573, 1416, 1204, 946, 652, 332,
74 | 554, 769, 724, 652, 554, 435, 300, 153,
75 | -283, -392, -369, -332, -283, -222, -153, -78,
76 | -1024, -1420, -1338, -1204, -1024, -805, -554, -283,
77 | -1420, -1970, -1856, -1670, -1420, -1116, -769, -392,
78 | -1338, -1856, -1748, -1573, -1338, -1051, -724, -369,
79 | -805, -1116, -1051, -946, -805, -632, -435, -222,
80 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
81 | 1204, 1416, 652, -332, -1204, -1670, -1573, -946,
82 | 554, 652, 300, -153, -554, -769, -724, -435,
83 | -283, -332, -153, 78, 283, 392, 369, 222,
84 | -1024, -1204, -554, 283, 1024, 1420, 1338, 805,
85 | -1420, -1670, -769, 392, 1420, 1970, 1856, 1116,
86 | -1338, -1573, -724, 369, 1338, 1856, 1748, 1051,
87 | -805, -946, -435, 222, 805, 1116, 1051, 632,
88 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
89 | 1204, 946, -652, -1670, -1204, 332, 1573, 1416,
90 | 554, 435, -300, -769, -554, 153, 724, 652,
91 | -283, -222, 153, 392, 283, -78, -369, -332,
92 | -1024, -805, 554, 1420, 1024, -283, -1338, -1204,
93 | -1420, -1116, 769, 1970, 1420, -392, -1856, -1670,
94 | -1338, -1051, 724, 1856, 1338, -369, -1748, -1573,
95 | -805, -632, 435, 1116, 805, -222, -1051, -946,
96 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
97 | 1204, 332, -1573, -946, 1204, 1416, -652, -1670,
98 | 554, 153, -724, -435, 554, 652, -300, -769,
99 | -283, -78, 369, 222, -283, -332, 153, 392,
100 | -1024, -283, 1338, 805, -1024, -1204, 554, 1420,
101 | -1420, -392, 1856, 1116, -1420, -1670, 769, 1970,
102 | -1338, -369, 1748, 1051, -1338, -1573, 724, 1856,
103 | -805, -222, 1051, 632, -805, -946, 435, 1116,
104 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
105 | 1204, -332, -1573, 946, 1204, -1416, -652, 1670,
106 | 554, -153, -724, 435, 554, -652, -300, 769,
107 | -283, 78, 369, -222, -283, 332, 153, -392,
108 | -1024, 283, 1338, -805, -1024, 1204, 554, -1420,
109 | -1420, 392, 1856, -1116, -1420, 1670, 769, -1970,
110 | -1338, 369, 1748, -1051, -1338, 1573, 724, -1856,
111 | -805, 222, 1051, -632, -805, 946, 435, -1116,
112 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
113 | 1204, -946, -652, 1670, -1204, -332, 1573, -1416,
114 | 554, -435, -300, 769, -554, -153, 724, -652,
115 | -283, 222, 153, -392, 283, 78, -369, 332,
116 | -1024, 805, 554, -1420, 1024, 283, -1338, 1204,
117 | -1420, 1116, 769, -1970, 1420, 392, -1856, 1670,
118 | -1338, 1051, 724, -1856, 1338, 369, -1748, 1573,
119 | -805, 632, 435, -1116, 805, 222, -1051, 946,
120 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
121 | 1204, -1416, 652, 332, -1204, 1670, -1573, 946,
122 | 554, -652, 300, 153, -554, 769, -724, 435,
123 | -283, 332, -153, -78, 283, -392, 369, -222,
124 | -1024, 1204, -554, -283, 1024, -1420, 1338, -805,
125 | -1420, 1670, -769, -392, 1420, -1970, 1856, -1116,
126 | -1338, 1573, -724, -369, 1338, -1856, 1748, -1051,
127 | -805, 946, -435, -222, 805, -1116, 1051, -632,
128 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
129 | 1204, -1670, 1573, -1416, 1204, -946, 652, -332,
130 | 554, -769, 724, -652, 554, -435, 300, -153,
131 | -283, 392, -369, 332, -283, 222, -153, 78,
132 | -1024, 1420, -1338, 1204, -1024, 805, -554, 283,
133 | -1420, 1970, -1856, 1670, -1420, 1116, -769, 392,
134 | -1338, 1856, -1748, 1573, -1338, 1051, -724, 369,
135 | -805, 1116, -1051, 946, -805, 632, -435, 222,
136 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
137 | 805, 1116, 1051, 946, 805, 632, 435, 222,
138 | -554, -769, -724, -652, -554, -435, -300, -153,
139 | -1420, -1970, -1856, -1670, -1420, -1116, -769, -392,
140 | -1024, -1420, -1338, -1204, -1024, -805, -554, -283,
141 | 283, 392, 369, 332, 283, 222, 153, 78,
142 | 1338, 1856, 1748, 1573, 1338, 1051, 724, 369,
143 | 1204, 1670, 1573, 1416, 1204, 946, 652, 332,
144 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
145 | 805, 946, 435, -222, -805, -1116, -1051, -632,
146 | -554, -652, -300, 153, 554, 769, 724, 435,
147 | -1420, -1670, -769, 392, 1420, 1970, 1856, 1116,
148 | -1024, -1204, -554, 283, 1024, 1420, 1338, 805,
149 | 283, 332, 153, -78, -283, -392, -369, -222,
150 | 1338, 1573, 724, -369, -1338, -1856, -1748, -1051,
151 | 1204, 1416, 652, -332, -1204, -1670, -1573, -946,
152 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
153 | 805, 632, -435, -1116, -805, 222, 1051, 946,
154 | -554, -435, 300, 769, 554, -153, -724, -652,
155 | -1420, -1116, 769, 1970, 1420, -392, -1856, -1670,
156 | -1024, -805, 554, 1420, 1024, -283, -1338, -1204,
157 | 283, 222, -153, -392, -283, 78, 369, 332,
158 | 1338, 1051, -724, -1856, -1338, 369, 1748, 1573,
159 | 1204, 946, -652, -1670, -1204, 332, 1573, 1416,
160 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
161 | 805, 222, -1051, -632, 805, 946, -435, -1116,
162 | -554, -153, 724, 435, -554, -652, 300, 769,
163 | -1420, -392, 1856, 1116, -1420, -1670, 769, 1970,
164 | -1024, -283, 1338, 805, -1024, -1204, 554, 1420,
165 | 283, 78, -369, -222, 283, 332, -153, -392,
166 | 1338, 369, -1748, -1051, 1338, 1573, -724, -1856,
167 | 1204, 332, -1573, -946, 1204, 1416, -652, -1670,
168 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
169 | 805, -222, -1051, 632, 805, -946, -435, 1116,
170 | -554, 153, 724, -435, -554, 652, 300, -769,
171 | -1420, 392, 1856, -1116, -1420, 1670, 769, -1970,
172 | -1024, 283, 1338, -805, -1024, 1204, 554, -1420,
173 | 283, -78, -369, 222, 283, -332, -153, 392,
174 | 1338, -369, -1748, 1051, 1338, -1573, -724, 1856,
175 | 1204, -332, -1573, 946, 1204, -1416, -652, 1670,
176 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
177 | 805, -632, -435, 1116, -805, -222, 1051, -946,
178 | -554, 435, 300, -769, 554, 153, -724, 652,
179 | -1420, 1116, 769, -1970, 1420, 392, -1856, 1670,
180 | -1024, 805, 554, -1420, 1024, 283, -1338, 1204,
181 | 283, -222, -153, 392, -283, -78, 369, -332,
182 | 1338, -1051, -724, 1856, -1338, -369, 1748, -1573,
183 | 1204, -946, -652, 1670, -1204, -332, 1573, -1416,
184 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
185 | 805, -946, 435, 222, -805, 1116, -1051, 632,
186 | -554, 652, -300, -153, 554, -769, 724, -435,
187 | -1420, 1670, -769, -392, 1420, -1970, 1856, -1116,
188 | -1024, 1204, -554, -283, 1024, -1420, 1338, -805,
189 | 283, -332, 153, 78, -283, 392, -369, 222,
190 | 1338, -1573, 724, 369, -1338, 1856, -1748, 1051,
191 | 1204, -1416, 652, 332, -1204, 1670, -1573, 946,
192 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
193 | 805, -1116, 1051, -946, 805, -632, 435, -222,
194 | -554, 769, -724, 652, -554, 435, -300, 153,
195 | -1420, 1970, -1856, 1670, -1420, 1116, -769, 392,
196 | -1024, 1420, -1338, 1204, -1024, 805, -554, 283,
197 | 283, -392, 369, -332, 283, -222, 153, -78,
198 | 1338, -1856, 1748, -1573, 1338, -1051, 724, -369,
199 | 1204, -1670, 1573, -1416, 1204, -946, 652, -332,
200 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
201 | 283, 392, 369, 332, 283, 222, 153, 78,
202 | -1338, -1856, -1748, -1573, -1338, -1051, -724, -369,
203 | -805, -1116, -1051, -946, -805, -632, -435, -222,
204 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
205 | 1204, 1670, 1573, 1416, 1204, 946, 652, 332,
206 | -554, -769, -724, -652, -554, -435, -300, -153,
207 | -1420, -1970, -1856, -1670, -1420, -1116, -769, -392,
208 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
209 | 283, 332, 153, -78, -283, -392, -369, -222,
210 | -1338, -1573, -724, 369, 1338, 1856, 1748, 1051,
211 | -805, -946, -435, 222, 805, 1116, 1051, 632,
212 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
213 | 1204, 1416, 652, -332, -1204, -1670, -1573, -946,
214 | -554, -652, -300, 153, 554, 769, 724, 435,
215 | -1420, -1670, -769, 392, 1420, 1970, 1856, 1116,
216 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
217 | 283, 222, -153, -392, -283, 78, 369, 332,
218 | -1338, -1051, 724, 1856, 1338, -369, -1748, -1573,
219 | -805, -632, 435, 1116, 805, -222, -1051, -946,
220 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
221 | 1204, 946, -652, -1670, -1204, 332, 1573, 1416,
222 | -554, -435, 300, 769, 554, -153, -724, -652,
223 | -1420, -1116, 769, 1970, 1420, -392, -1856, -1670,
224 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
225 | 283, 78, -369, -222, 283, 332, -153, -392,
226 | -1338, -369, 1748, 1051, -1338, -1573, 724, 1856,
227 | -805, -222, 1051, 632, -805, -946, 435, 1116,
228 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
229 | 1204, 332, -1573, -946, 1204, 1416, -652, -1670,
230 | -554, -153, 724, 435, -554, -652, 300, 769,
231 | -1420, -392, 1856, 1116, -1420, -1670, 769, 1970,
232 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
233 | 283, -78, -369, 222, 283, -332, -153, 392,
234 | -1338, 369, 1748, -1051, -1338, 1573, 724, -1856,
235 | -805, 222, 1051, -632, -805, 946, 435, -1116,
236 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
237 | 1204, -332, -1573, 946, 1204, -1416, -652, 1670,
238 | -554, 153, 724, -435, -554, 652, 300, -769,
239 | -1420, 392, 1856, -1116, -1420, 1670, 769, -1970,
240 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
241 | 283, -222, -153, 392, -283, -78, 369, -332,
242 | -1338, 1051, 724, -1856, 1338, 369, -1748, 1573,
243 | -805, 632, 435, -1116, 805, 222, -1051, 946,
244 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
245 | 1204, -946, -652, 1670, -1204, -332, 1573, -1416,
246 | -554, 435, 300, -769, 554, 153, -724, 652,
247 | -1420, 1116, 769, -1970, 1420, 392, -1856, 1670,
248 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
249 | 283, -332, 153, 78, -283, 392, -369, 222,
250 | -1338, 1573, -724, -369, 1338, -1856, 1748, -1051,
251 | -805, 946, -435, -222, 805, -1116, 1051, -632,
252 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
253 | 1204, -1416, 652, 332, -1204, 1670, -1573, 946,
254 | -554, 652, -300, -153, 554, -769, 724, -435,
255 | -1420, 1670, -769, -392, 1420, -1970, 1856, -1116,
256 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
257 | 283, -392, 369, -332, 283, -222, 153, -78,
258 | -1338, 1856, -1748, 1573, -1338, 1051, -724, 369,
259 | -805, 1116, -1051, 946, -805, 632, -435, 222,
260 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
261 | 1204, -1670, 1573, -1416, 1204, -946, 652, -332,
262 | -554, 769, -724, 652, -554, 435, -300, 153,
263 | -1420, 1970, -1856, 1670, -1420, 1116, -769, 392,
264 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
265 | -283, -392, -369, -332, -283, -222, -153, -78,
266 | -1338, -1856, -1748, -1573, -1338, -1051, -724, -369,
267 | 805, 1116, 1051, 946, 805, 632, 435, 222,
268 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
269 | -1204, -1670, -1573, -1416, -1204, -946, -652, -332,
270 | -554, -769, -724, -652, -554, -435, -300, -153,
271 | 1420, 1970, 1856, 1670, 1420, 1116, 769, 392,
272 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
273 | -283, -332, -153, 78, 283, 392, 369, 222,
274 | -1338, -1573, -724, 369, 1338, 1856, 1748, 1051,
275 | 805, 946, 435, -222, -805, -1116, -1051, -632,
276 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
277 | -1204, -1416, -652, 332, 1204, 1670, 1573, 946,
278 | -554, -652, -300, 153, 554, 769, 724, 435,
279 | 1420, 1670, 769, -392, -1420, -1970, -1856, -1116,
280 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
281 | -283, -222, 153, 392, 283, -78, -369, -332,
282 | -1338, -1051, 724, 1856, 1338, -369, -1748, -1573,
283 | 805, 632, -435, -1116, -805, 222, 1051, 946,
284 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
285 | -1204, -946, 652, 1670, 1204, -332, -1573, -1416,
286 | -554, -435, 300, 769, 554, -153, -724, -652,
287 | 1420, 1116, -769, -1970, -1420, 392, 1856, 1670,
288 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
289 | -283, -78, 369, 222, -283, -332, 153, 392,
290 | -1338, -369, 1748, 1051, -1338, -1573, 724, 1856,
291 | 805, 222, -1051, -632, 805, 946, -435, -1116,
292 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
293 | -1204, -332, 1573, 946, -1204, -1416, 652, 1670,
294 | -554, -153, 724, 435, -554, -652, 300, 769,
295 | 1420, 392, -1856, -1116, 1420, 1670, -769, -1970,
296 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
297 | -283, 78, 369, -222, -283, 332, 153, -392,
298 | -1338, 369, 1748, -1051, -1338, 1573, 724, -1856,
299 | 805, -222, -1051, 632, 805, -946, -435, 1116,
300 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
301 | -1204, 332, 1573, -946, -1204, 1416, 652, -1670,
302 | -554, 153, 724, -435, -554, 652, 300, -769,
303 | 1420, -392, -1856, 1116, 1420, -1670, -769, 1970,
304 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
305 | -283, 222, 153, -392, 283, 78, -369, 332,
306 | -1338, 1051, 724, -1856, 1338, 369, -1748, 1573,
307 | 805, -632, -435, 1116, -805, -222, 1051, -946,
308 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
309 | -1204, 946, 652, -1670, 1204, 332, -1573, 1416,
310 | -554, 435, 300, -769, 554, 153, -724, 652,
311 | 1420, -1116, -769, 1970, -1420, -392, 1856, -1670,
312 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
313 | -283, 332, -153, -78, 283, -392, 369, -222,
314 | -1338, 1573, -724, -369, 1338, -1856, 1748, -1051,
315 | 805, -946, 435, 222, -805, 1116, -1051, 632,
316 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
317 | -1204, 1416, -652, -332, 1204, -1670, 1573, -946,
318 | -554, 652, -300, -153, 554, -769, 724, -435,
319 | 1420, -1670, 769, 392, -1420, 1970, -1856, 1116,
320 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
321 | -283, 392, -369, 332, -283, 222, -153, 78,
322 | -1338, 1856, -1748, 1573, -1338, 1051, -724, 369,
323 | 805, -1116, 1051, -946, 805, -632, 435, -222,
324 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
325 | -1204, 1670, -1573, 1416, -1204, 946, -652, 332,
326 | -554, 769, -724, 652, -554, 435, -300, 153,
327 | 1420, -1970, 1856, -1670, 1420, -1116, 769, -392,
328 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
329 | -805, -1116, -1051, -946, -805, -632, -435, -222,
330 | -554, -769, -724, -652, -554, -435, -300, -153,
331 | 1420, 1970, 1856, 1670, 1420, 1116, 769, 392,
332 | -1024, -1420, -1338, -1204, -1024, -805, -554, -283,
333 | -283, -392, -369, -332, -283, -222, -153, -78,
334 | 1338, 1856, 1748, 1573, 1338, 1051, 724, 369,
335 | -1204, -1670, -1573, -1416, -1204, -946, -652, -332,
336 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
337 | -805, -946, -435, 222, 805, 1116, 1051, 632,
338 | -554, -652, -300, 153, 554, 769, 724, 435,
339 | 1420, 1670, 769, -392, -1420, -1970, -1856, -1116,
340 | -1024, -1204, -554, 283, 1024, 1420, 1338, 805,
341 | -283, -332, -153, 78, 283, 392, 369, 222,
342 | 1338, 1573, 724, -369, -1338, -1856, -1748, -1051,
343 | -1204, -1416, -652, 332, 1204, 1670, 1573, 946,
344 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
345 | -805, -632, 435, 1116, 805, -222, -1051, -946,
346 | -554, -435, 300, 769, 554, -153, -724, -652,
347 | 1420, 1116, -769, -1970, -1420, 392, 1856, 1670,
348 | -1024, -805, 554, 1420, 1024, -283, -1338, -1204,
349 | -283, -222, 153, 392, 283, -78, -369, -332,
350 | 1338, 1051, -724, -1856, -1338, 369, 1748, 1573,
351 | -1204, -946, 652, 1670, 1204, -332, -1573, -1416,
352 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
353 | -805, -222, 1051, 632, -805, -946, 435, 1116,
354 | -554, -153, 724, 435, -554, -652, 300, 769,
355 | 1420, 392, -1856, -1116, 1420, 1670, -769, -1970,
356 | -1024, -283, 1338, 805, -1024, -1204, 554, 1420,
357 | -283, -78, 369, 222, -283, -332, 153, 392,
358 | 1338, 369, -1748, -1051, 1338, 1573, -724, -1856,
359 | -1204, -332, 1573, 946, -1204, -1416, 652, 1670,
360 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
361 | -805, 222, 1051, -632, -805, 946, 435, -1116,
362 | -554, 153, 724, -435, -554, 652, 300, -769,
363 | 1420, -392, -1856, 1116, 1420, -1670, -769, 1970,
364 | -1024, 283, 1338, -805, -1024, 1204, 554, -1420,
365 | -283, 78, 369, -222, -283, 332, 153, -392,
366 | 1338, -369, -1748, 1051, 1338, -1573, -724, 1856,
367 | -1204, 332, 1573, -946, -1204, 1416, 652, -1670,
368 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
369 | -805, 632, 435, -1116, 805, 222, -1051, 946,
370 | -554, 435, 300, -769, 554, 153, -724, 652,
371 | 1420, -1116, -769, 1970, -1420, -392, 1856, -1670,
372 | -1024, 805, 554, -1420, 1024, 283, -1338, 1204,
373 | -283, 222, 153, -392, 283, 78, -369, 332,
374 | 1338, -1051, -724, 1856, -1338, -369, 1748, -1573,
375 | -1204, 946, 652, -1670, 1204, 332, -1573, 1416,
376 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
377 | -805, 946, -435, -222, 805, -1116, 1051, -632,
378 | -554, 652, -300, -153, 554, -769, 724, -435,
379 | 1420, -1670, 769, 392, -1420, 1970, -1856, 1116,
380 | -1024, 1204, -554, -283, 1024, -1420, 1338, -805,
381 | -283, 332, -153, -78, 283, -392, 369, -222,
382 | 1338, -1573, 724, 369, -1338, 1856, -1748, 1051,
383 | -1204, 1416, -652, -332, 1204, -1670, 1573, -946,
384 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
385 | -805, 1116, -1051, 946, -805, 632, -435, 222,
386 | -554, 769, -724, 652, -554, 435, -300, 153,
387 | 1420, -1970, 1856, -1670, 1420, -1116, 769, -392,
388 | -1024, 1420, -1338, 1204, -1024, 805, -554, 283,
389 | -283, 392, -369, 332, -283, 222, -153, 78,
390 | 1338, -1856, 1748, -1573, 1338, -1051, 724, -369,
391 | -1204, 1670, -1573, 1416, -1204, 946, -652, 332,
392 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
393 | -1204, -1670, -1573, -1416, -1204, -946, -652, -332,
394 | 554, 769, 724, 652, 554, 435, 300, 153,
395 | 283, 392, 369, 332, 283, 222, 153, 78,
396 | -1024, -1420, -1338, -1204, -1024, -805, -554, -283,
397 | 1420, 1970, 1856, 1670, 1420, 1116, 769, 392,
398 | -1338, -1856, -1748, -1573, -1338, -1051, -724, -369,
399 | 805, 1116, 1051, 946, 805, 632, 435, 222,
400 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
401 | -1204, -1416, -652, 332, 1204, 1670, 1573, 946,
402 | 554, 652, 300, -153, -554, -769, -724, -435,
403 | 283, 332, 153, -78, -283, -392, -369, -222,
404 | -1024, -1204, -554, 283, 1024, 1420, 1338, 805,
405 | 1420, 1670, 769, -392, -1420, -1970, -1856, -1116,
406 | -1338, -1573, -724, 369, 1338, 1856, 1748, 1051,
407 | 805, 946, 435, -222, -805, -1116, -1051, -632,
408 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
409 | -1204, -946, 652, 1670, 1204, -332, -1573, -1416,
410 | 554, 435, -300, -769, -554, 153, 724, 652,
411 | 283, 222, -153, -392, -283, 78, 369, 332,
412 | -1024, -805, 554, 1420, 1024, -283, -1338, -1204,
413 | 1420, 1116, -769, -1970, -1420, 392, 1856, 1670,
414 | -1338, -1051, 724, 1856, 1338, -369, -1748, -1573,
415 | 805, 632, -435, -1116, -805, 222, 1051, 946,
416 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
417 | -1204, -332, 1573, 946, -1204, -1416, 652, 1670,
418 | 554, 153, -724, -435, 554, 652, -300, -769,
419 | 283, 78, -369, -222, 283, 332, -153, -392,
420 | -1024, -283, 1338, 805, -1024, -1204, 554, 1420,
421 | 1420, 392, -1856, -1116, 1420, 1670, -769, -1970,
422 | -1338, -369, 1748, 1051, -1338, -1573, 724, 1856,
423 | 805, 222, -1051, -632, 805, 946, -435, -1116,
424 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
425 | -1204, 332, 1573, -946, -1204, 1416, 652, -1670,
426 | 554, -153, -724, 435, 554, -652, -300, 769,
427 | 283, -78, -369, 222, 283, -332, -153, 392,
428 | -1024, 283, 1338, -805, -1024, 1204, 554, -1420,
429 | 1420, -392, -1856, 1116, 1420, -1670, -769, 1970,
430 | -1338, 369, 1748, -1051, -1338, 1573, 724, -1856,
431 | 805, -222, -1051, 632, 805, -946, -435, 1116,
432 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
433 | -1204, 946, 652, -1670, 1204, 332, -1573, 1416,
434 | 554, -435, -300, 769, -554, -153, 724, -652,
435 | 283, -222, -153, 392, -283, -78, 369, -332,
436 | -1024, 805, 554, -1420, 1024, 283, -1338, 1204,
437 | 1420, -1116, -769, 1970, -1420, -392, 1856, -1670,
438 | -1338, 1051, 724, -1856, 1338, 369, -1748, 1573,
439 | 805, -632, -435, 1116, -805, -222, 1051, -946,
440 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
441 | -1204, 1416, -652, -332, 1204, -1670, 1573, -946,
442 | 554, -652, 300, 153, -554, 769, -724, 435,
443 | 283, -332, 153, 78, -283, 392, -369, 222,
444 | -1024, 1204, -554, -283, 1024, -1420, 1338, -805,
445 | 1420, -1670, 769, 392, -1420, 1970, -1856, 1116,
446 | -1338, 1573, -724, -369, 1338, -1856, 1748, -1051,
447 | 805, -946, 435, 222, -805, 1116, -1051, 632,
448 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
449 | -1204, 1670, -1573, 1416, -1204, 946, -652, 332,
450 | 554, -769, 724, -652, 554, -435, 300, -153,
451 | 283, -392, 369, -332, 283, -222, 153, -78,
452 | -1024, 1420, -1338, 1204, -1024, 805, -554, 283,
453 | 1420, -1970, 1856, -1670, 1420, -1116, 769, -392,
454 | -1338, 1856, -1748, 1573, -1338, 1051, -724, 369,
455 | 805, -1116, 1051, -946, 805, -632, 435, -222,
456 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
457 | -1420, -1970, -1856, -1670, -1420, -1116, -769, -392,
458 | 1338, 1856, 1748, 1573, 1338, 1051, 724, 369,
459 | -1204, -1670, -1573, -1416, -1204, -946, -652, -332,
460 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
461 | -805, -1116, -1051, -946, -805, -632, -435, -222,
462 | 554, 769, 724, 652, 554, 435, 300, 153,
463 | -283, -392, -369, -332, -283, -222, -153, -78,
464 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
465 | -1420, -1670, -769, 392, 1420, 1970, 1856, 1116,
466 | 1338, 1573, 724, -369, -1338, -1856, -1748, -1051,
467 | -1204, -1416, -652, 332, 1204, 1670, 1573, 946,
468 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
469 | -805, -946, -435, 222, 805, 1116, 1051, 632,
470 | 554, 652, 300, -153, -554, -769, -724, -435,
471 | -283, -332, -153, 78, 283, 392, 369, 222,
472 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
473 | -1420, -1116, 769, 1970, 1420, -392, -1856, -1670,
474 | 1338, 1051, -724, -1856, -1338, 369, 1748, 1573,
475 | -1204, -946, 652, 1670, 1204, -332, -1573, -1416,
476 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
477 | -805, -632, 435, 1116, 805, -222, -1051, -946,
478 | 554, 435, -300, -769, -554, 153, 724, 652,
479 | -283, -222, 153, 392, 283, -78, -369, -332,
480 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
481 | -1420, -392, 1856, 1116, -1420, -1670, 769, 1970,
482 | 1338, 369, -1748, -1051, 1338, 1573, -724, -1856,
483 | -1204, -332, 1573, 946, -1204, -1416, 652, 1670,
484 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
485 | -805, -222, 1051, 632, -805, -946, 435, 1116,
486 | 554, 153, -724, -435, 554, 652, -300, -769,
487 | -283, -78, 369, 222, -283, -332, 153, 392,
488 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
489 | -1420, 392, 1856, -1116, -1420, 1670, 769, -1970,
490 | 1338, -369, -1748, 1051, 1338, -1573, -724, 1856,
491 | -1204, 332, 1573, -946, -1204, 1416, 652, -1670,
492 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
493 | -805, 222, 1051, -632, -805, 946, 435, -1116,
494 | 554, -153, -724, 435, 554, -652, -300, 769,
495 | -283, 78, 369, -222, -283, 332, 153, -392,
496 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
497 | -1420, 1116, 769, -1970, 1420, 392, -1856, 1670,
498 | 1338, -1051, -724, 1856, -1338, -369, 1748, -1573,
499 | -1204, 946, 652, -1670, 1204, 332, -1573, 1416,
500 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
501 | -805, 632, 435, -1116, 805, 222, -1051, 946,
502 | 554, -435, -300, 769, -554, -153, 724, -652,
503 | -283, 222, 153, -392, 283, 78, -369, 332,
504 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
505 | -1420, 1670, -769, -392, 1420, -1970, 1856, -1116,
506 | 1338, -1573, 724, 369, -1338, 1856, -1748, 1051,
507 | -1204, 1416, -652, -332, 1204, -1670, 1573, -946,
508 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
509 | -805, 946, -435, -222, 805, -1116, 1051, -632,
510 | 554, -652, 300, 153, -554, 769, -724, 435,
511 | -283, 332, -153, -78, 283, -392, 369, -222,
512 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
513 | -1420, 1970, -1856, 1670, -1420, 1116, -769, 392,
514 | 1338, -1856, 1748, -1573, 1338, -1051, 724, -369,
515 | -1204, 1670, -1573, 1416, -1204, 946, -652, 332,
516 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
517 | -805, 1116, -1051, 946, -805, 632, -435, 222,
518 | 554, -769, 724, -652, 554, -435, 300, -153,
519 | -283, 392, -369, 332, -283, 222, -153, 78,
520 | };
521 |
522 | // precalculated int values for 8x8 FDCT, multplied by 8192
523 | const int icos_fdct_8x8[ 4096 ] =
524 | {
525 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
526 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
527 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
528 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
529 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
530 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
531 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
532 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
533 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
534 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
535 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
536 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
537 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
538 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
539 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
540 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
541 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
542 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
543 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
544 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
545 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
546 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
547 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
548 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
549 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
550 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
551 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
552 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
553 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
554 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
555 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
556 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
557 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
558 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
559 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
560 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
561 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
562 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
563 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
564 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
565 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
566 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
567 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
568 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
569 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
570 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
571 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
572 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
573 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
574 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
575 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
576 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
577 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
578 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
579 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
580 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
581 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
582 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
583 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
584 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
585 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
586 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
587 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
588 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
589 | 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420,
590 | 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
591 | 805, 805, 805, 805, 805, 805, 805, 805,
592 | 283, 283, 283, 283, 283, 283, 283, 283,
593 | -283, -283, -283, -283, -283, -283, -283, -283,
594 | -805, -805, -805, -805, -805, -805, -805, -805,
595 | -1204, -1204, -1204, -1204, -1204, -1204, -1204, -1204,
596 | -1420, -1420, -1420, -1420, -1420, -1420, -1420, -1420,
597 | 1970, 1670, 1116, 392, -392, -1116, -1670, -1970,
598 | 1670, 1416, 946, 332, -332, -946, -1416, -1670,
599 | 1116, 946, 632, 222, -222, -632, -946, -1116,
600 | 392, 332, 222, 78, -78, -222, -332, -392,
601 | -392, -332, -222, -78, 78, 222, 332, 392,
602 | -1116, -946, -632, -222, 222, 632, 946, 1116,
603 | -1670, -1416, -946, -332, 332, 946, 1416, 1670,
604 | -1970, -1670, -1116, -392, 392, 1116, 1670, 1970,
605 | 1856, 769, -769, -1856, -1856, -769, 769, 1856,
606 | 1573, 652, -652, -1573, -1573, -652, 652, 1573,
607 | 1051, 435, -435, -1051, -1051, -435, 435, 1051,
608 | 369, 153, -153, -369, -369, -153, 153, 369,
609 | -369, -153, 153, 369, 369, 153, -153, -369,
610 | -1051, -435, 435, 1051, 1051, 435, -435, -1051,
611 | -1573, -652, 652, 1573, 1573, 652, -652, -1573,
612 | -1856, -769, 769, 1856, 1856, 769, -769, -1856,
613 | 1670, -392, -1970, -1116, 1116, 1970, 392, -1670,
614 | 1416, -332, -1670, -946, 946, 1670, 332, -1416,
615 | 946, -222, -1116, -632, 632, 1116, 222, -946,
616 | 332, -78, -392, -222, 222, 392, 78, -332,
617 | -332, 78, 392, 222, -222, -392, -78, 332,
618 | -946, 222, 1116, 632, -632, -1116, -222, 946,
619 | -1416, 332, 1670, 946, -946, -1670, -332, 1416,
620 | -1670, 392, 1970, 1116, -1116, -1970, -392, 1670,
621 | 1420, -1420, -1420, 1420, 1420, -1420, -1420, 1420,
622 | 1204, -1204, -1204, 1204, 1204, -1204, -1204, 1204,
623 | 805, -805, -805, 805, 805, -805, -805, 805,
624 | 283, -283, -283, 283, 283, -283, -283, 283,
625 | -283, 283, 283, -283, -283, 283, 283, -283,
626 | -805, 805, 805, -805, -805, 805, 805, -805,
627 | -1204, 1204, 1204, -1204, -1204, 1204, 1204, -1204,
628 | -1420, 1420, 1420, -1420, -1420, 1420, 1420, -1420,
629 | 1116, -1970, 392, 1670, -1670, -392, 1970, -1116,
630 | 946, -1670, 332, 1416, -1416, -332, 1670, -946,
631 | 632, -1116, 222, 946, -946, -222, 1116, -632,
632 | 222, -392, 78, 332, -332, -78, 392, -222,
633 | -222, 392, -78, -332, 332, 78, -392, 222,
634 | -632, 1116, -222, -946, 946, 222, -1116, 632,
635 | -946, 1670, -332, -1416, 1416, 332, -1670, 946,
636 | -1116, 1970, -392, -1670, 1670, 392, -1970, 1116,
637 | 769, -1856, 1856, -769, -769, 1856, -1856, 769,
638 | 652, -1573, 1573, -652, -652, 1573, -1573, 652,
639 | 435, -1051, 1051, -435, -435, 1051, -1051, 435,
640 | 153, -369, 369, -153, -153, 369, -369, 153,
641 | -153, 369, -369, 153, 153, -369, 369, -153,
642 | -435, 1051, -1051, 435, 435, -1051, 1051, -435,
643 | -652, 1573, -1573, 652, 652, -1573, 1573, -652,
644 | -769, 1856, -1856, 769, 769, -1856, 1856, -769,
645 | 392, -1116, 1670, -1970, 1970, -1670, 1116, -392,
646 | 332, -946, 1416, -1670, 1670, -1416, 946, -332,
647 | 222, -632, 946, -1116, 1116, -946, 632, -222,
648 | 78, -222, 332, -392, 392, -332, 222, -78,
649 | -78, 222, -332, 392, -392, 332, -222, 78,
650 | -222, 632, -946, 1116, -1116, 946, -632, 222,
651 | -332, 946, -1416, 1670, -1670, 1416, -946, 332,
652 | -392, 1116, -1670, 1970, -1970, 1670, -1116, 392,
653 | 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338,
654 | 554, 554, 554, 554, 554, 554, 554, 554,
655 | -554, -554, -554, -554, -554, -554, -554, -554,
656 | -1338, -1338, -1338, -1338, -1338, -1338, -1338, -1338,
657 | -1338, -1338, -1338, -1338, -1338, -1338, -1338, -1338,
658 | -554, -554, -554, -554, -554, -554, -554, -554,
659 | 554, 554, 554, 554, 554, 554, 554, 554,
660 | 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338,
661 | 1856, 1573, 1051, 369, -369, -1051, -1573, -1856,
662 | 769, 652, 435, 153, -153, -435, -652, -769,
663 | -769, -652, -435, -153, 153, 435, 652, 769,
664 | -1856, -1573, -1051, -369, 369, 1051, 1573, 1856,
665 | -1856, -1573, -1051, -369, 369, 1051, 1573, 1856,
666 | -769, -652, -435, -153, 153, 435, 652, 769,
667 | 769, 652, 435, 153, -153, -435, -652, -769,
668 | 1856, 1573, 1051, 369, -369, -1051, -1573, -1856,
669 | 1748, 724, -724, -1748, -1748, -724, 724, 1748,
670 | 724, 300, -300, -724, -724, -300, 300, 724,
671 | -724, -300, 300, 724, 724, 300, -300, -724,
672 | -1748, -724, 724, 1748, 1748, 724, -724, -1748,
673 | -1748, -724, 724, 1748, 1748, 724, -724, -1748,
674 | -724, -300, 300, 724, 724, 300, -300, -724,
675 | 724, 300, -300, -724, -724, -300, 300, 724,
676 | 1748, 724, -724, -1748, -1748, -724, 724, 1748,
677 | 1573, -369, -1856, -1051, 1051, 1856, 369, -1573,
678 | 652, -153, -769, -435, 435, 769, 153, -652,
679 | -652, 153, 769, 435, -435, -769, -153, 652,
680 | -1573, 369, 1856, 1051, -1051, -1856, -369, 1573,
681 | -1573, 369, 1856, 1051, -1051, -1856, -369, 1573,
682 | -652, 153, 769, 435, -435, -769, -153, 652,
683 | 652, -153, -769, -435, 435, 769, 153, -652,
684 | 1573, -369, -1856, -1051, 1051, 1856, 369, -1573,
685 | 1338, -1338, -1338, 1338, 1338, -1338, -1338, 1338,
686 | 554, -554, -554, 554, 554, -554, -554, 554,
687 | -554, 554, 554, -554, -554, 554, 554, -554,
688 | -1338, 1338, 1338, -1338, -1338, 1338, 1338, -1338,
689 | -1338, 1338, 1338, -1338, -1338, 1338, 1338, -1338,
690 | -554, 554, 554, -554, -554, 554, 554, -554,
691 | 554, -554, -554, 554, 554, -554, -554, 554,
692 | 1338, -1338, -1338, 1338, 1338, -1338, -1338, 1338,
693 | 1051, -1856, 369, 1573, -1573, -369, 1856, -1051,
694 | 435, -769, 153, 652, -652, -153, 769, -435,
695 | -435, 769, -153, -652, 652, 153, -769, 435,
696 | -1051, 1856, -369, -1573, 1573, 369, -1856, 1051,
697 | -1051, 1856, -369, -1573, 1573, 369, -1856, 1051,
698 | -435, 769, -153, -652, 652, 153, -769, 435,
699 | 435, -769, 153, 652, -652, -153, 769, -435,
700 | 1051, -1856, 369, 1573, -1573, -369, 1856, -1051,
701 | 724, -1748, 1748, -724, -724, 1748, -1748, 724,
702 | 300, -724, 724, -300, -300, 724, -724, 300,
703 | -300, 724, -724, 300, 300, -724, 724, -300,
704 | -724, 1748, -1748, 724, 724, -1748, 1748, -724,
705 | -724, 1748, -1748, 724, 724, -1748, 1748, -724,
706 | -300, 724, -724, 300, 300, -724, 724, -300,
707 | 300, -724, 724, -300, -300, 724, -724, 300,
708 | 724, -1748, 1748, -724, -724, 1748, -1748, 724,
709 | 369, -1051, 1573, -1856, 1856, -1573, 1051, -369,
710 | 153, -435, 652, -769, 769, -652, 435, -153,
711 | -153, 435, -652, 769, -769, 652, -435, 153,
712 | -369, 1051, -1573, 1856, -1856, 1573, -1051, 369,
713 | -369, 1051, -1573, 1856, -1856, 1573, -1051, 369,
714 | -153, 435, -652, 769, -769, 652, -435, 153,
715 | 153, -435, 652, -769, 769, -652, 435, -153,
716 | 369, -1051, 1573, -1856, 1856, -1573, 1051, -369,
717 | 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
718 | -283, -283, -283, -283, -283, -283, -283, -283,
719 | -1420, -1420, -1420, -1420, -1420, -1420, -1420, -1420,
720 | -805, -805, -805, -805, -805, -805, -805, -805,
721 | 805, 805, 805, 805, 805, 805, 805, 805,
722 | 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420,
723 | 283, 283, 283, 283, 283, 283, 283, 283,
724 | -1204, -1204, -1204, -1204, -1204, -1204, -1204, -1204,
725 | 1670, 1416, 946, 332, -332, -946, -1416, -1670,
726 | -392, -332, -222, -78, 78, 222, 332, 392,
727 | -1970, -1670, -1116, -392, 392, 1116, 1670, 1970,
728 | -1116, -946, -632, -222, 222, 632, 946, 1116,
729 | 1116, 946, 632, 222, -222, -632, -946, -1116,
730 | 1970, 1670, 1116, 392, -392, -1116, -1670, -1970,
731 | 392, 332, 222, 78, -78, -222, -332, -392,
732 | -1670, -1416, -946, -332, 332, 946, 1416, 1670,
733 | 1573, 652, -652, -1573, -1573, -652, 652, 1573,
734 | -369, -153, 153, 369, 369, 153, -153, -369,
735 | -1856, -769, 769, 1856, 1856, 769, -769, -1856,
736 | -1051, -435, 435, 1051, 1051, 435, -435, -1051,
737 | 1051, 435, -435, -1051, -1051, -435, 435, 1051,
738 | 1856, 769, -769, -1856, -1856, -769, 769, 1856,
739 | 369, 153, -153, -369, -369, -153, 153, 369,
740 | -1573, -652, 652, 1573, 1573, 652, -652, -1573,
741 | 1416, -332, -1670, -946, 946, 1670, 332, -1416,
742 | -332, 78, 392, 222, -222, -392, -78, 332,
743 | -1670, 392, 1970, 1116, -1116, -1970, -392, 1670,
744 | -946, 222, 1116, 632, -632, -1116, -222, 946,
745 | 946, -222, -1116, -632, 632, 1116, 222, -946,
746 | 1670, -392, -1970, -1116, 1116, 1970, 392, -1670,
747 | 332, -78, -392, -222, 222, 392, 78, -332,
748 | -1416, 332, 1670, 946, -946, -1670, -332, 1416,
749 | 1204, -1204, -1204, 1204, 1204, -1204, -1204, 1204,
750 | -283, 283, 283, -283, -283, 283, 283, -283,
751 | -1420, 1420, 1420, -1420, -1420, 1420, 1420, -1420,
752 | -805, 805, 805, -805, -805, 805, 805, -805,
753 | 805, -805, -805, 805, 805, -805, -805, 805,
754 | 1420, -1420, -1420, 1420, 1420, -1420, -1420, 1420,
755 | 283, -283, -283, 283, 283, -283, -283, 283,
756 | -1204, 1204, 1204, -1204, -1204, 1204, 1204, -1204,
757 | 946, -1670, 332, 1416, -1416, -332, 1670, -946,
758 | -222, 392, -78, -332, 332, 78, -392, 222,
759 | -1116, 1970, -392, -1670, 1670, 392, -1970, 1116,
760 | -632, 1116, -222, -946, 946, 222, -1116, 632,
761 | 632, -1116, 222, 946, -946, -222, 1116, -632,
762 | 1116, -1970, 392, 1670, -1670, -392, 1970, -1116,
763 | 222, -392, 78, 332, -332, -78, 392, -222,
764 | -946, 1670, -332, -1416, 1416, 332, -1670, 946,
765 | 652, -1573, 1573, -652, -652, 1573, -1573, 652,
766 | -153, 369, -369, 153, 153, -369, 369, -153,
767 | -769, 1856, -1856, 769, 769, -1856, 1856, -769,
768 | -435, 1051, -1051, 435, 435, -1051, 1051, -435,
769 | 435, -1051, 1051, -435, -435, 1051, -1051, 435,
770 | 769, -1856, 1856, -769, -769, 1856, -1856, 769,
771 | 153, -369, 369, -153, -153, 369, -369, 153,
772 | -652, 1573, -1573, 652, 652, -1573, 1573, -652,
773 | 332, -946, 1416, -1670, 1670, -1416, 946, -332,
774 | -78, 222, -332, 392, -392, 332, -222, 78,
775 | -392, 1116, -1670, 1970, -1970, 1670, -1116, 392,
776 | -222, 632, -946, 1116, -1116, 946, -632, 222,
777 | 222, -632, 946, -1116, 1116, -946, 632, -222,
778 | 392, -1116, 1670, -1970, 1970, -1670, 1116, -392,
779 | 78, -222, 332, -392, 392, -332, 222, -78,
780 | -332, 946, -1416, 1670, -1670, 1416, -946, 332,
781 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
782 | -1024, -1024, -1024, -1024, -1024, -1024, -1024, -1024,
783 | -1024, -1024, -1024, -1024, -1024, -1024, -1024, -1024,
784 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
785 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
786 | -1024, -1024, -1024, -1024, -1024, -1024, -1024, -1024,
787 | -1024, -1024, -1024, -1024, -1024, -1024, -1024, -1024,
788 | 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
789 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
790 | -1420, -1204, -805, -283, 283, 805, 1204, 1420,
791 | -1420, -1204, -805, -283, 283, 805, 1204, 1420,
792 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
793 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
794 | -1420, -1204, -805, -283, 283, 805, 1204, 1420,
795 | -1420, -1204, -805, -283, 283, 805, 1204, 1420,
796 | 1420, 1204, 805, 283, -283, -805, -1204, -1420,
797 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
798 | -1338, -554, 554, 1338, 1338, 554, -554, -1338,
799 | -1338, -554, 554, 1338, 1338, 554, -554, -1338,
800 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
801 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
802 | -1338, -554, 554, 1338, 1338, 554, -554, -1338,
803 | -1338, -554, 554, 1338, 1338, 554, -554, -1338,
804 | 1338, 554, -554, -1338, -1338, -554, 554, 1338,
805 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
806 | -1204, 283, 1420, 805, -805, -1420, -283, 1204,
807 | -1204, 283, 1420, 805, -805, -1420, -283, 1204,
808 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
809 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
810 | -1204, 283, 1420, 805, -805, -1420, -283, 1204,
811 | -1204, 283, 1420, 805, -805, -1420, -283, 1204,
812 | 1204, -283, -1420, -805, 805, 1420, 283, -1204,
813 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
814 | -1024, 1024, 1024, -1024, -1024, 1024, 1024, -1024,
815 | -1024, 1024, 1024, -1024, -1024, 1024, 1024, -1024,
816 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
817 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
818 | -1024, 1024, 1024, -1024, -1024, 1024, 1024, -1024,
819 | -1024, 1024, 1024, -1024, -1024, 1024, 1024, -1024,
820 | 1024, -1024, -1024, 1024, 1024, -1024, -1024, 1024,
821 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
822 | -805, 1420, -283, -1204, 1204, 283, -1420, 805,
823 | -805, 1420, -283, -1204, 1204, 283, -1420, 805,
824 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
825 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
826 | -805, 1420, -283, -1204, 1204, 283, -1420, 805,
827 | -805, 1420, -283, -1204, 1204, 283, -1420, 805,
828 | 805, -1420, 283, 1204, -1204, -283, 1420, -805,
829 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
830 | -554, 1338, -1338, 554, 554, -1338, 1338, -554,
831 | -554, 1338, -1338, 554, 554, -1338, 1338, -554,
832 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
833 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
834 | -554, 1338, -1338, 554, 554, -1338, 1338, -554,
835 | -554, 1338, -1338, 554, 554, -1338, 1338, -554,
836 | 554, -1338, 1338, -554, -554, 1338, -1338, 554,
837 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
838 | -283, 805, -1204, 1420, -1420, 1204, -805, 283,
839 | -283, 805, -1204, 1420, -1420, 1204, -805, 283,
840 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
841 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
842 | -283, 805, -1204, 1420, -1420, 1204, -805, 283,
843 | -283, 805, -1204, 1420, -1420, 1204, -805, 283,
844 | 283, -805, 1204, -1420, 1420, -1204, 805, -283,
845 | 805, 805, 805, 805, 805, 805, 805, 805,
846 | -1420, -1420, -1420, -1420, -1420, -1420, -1420, -1420,
847 | 283, 283, 283, 283, 283, 283, 283, 283,
848 | 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
849 | -1204, -1204, -1204, -1204, -1204, -1204, -1204, -1204,
850 | -283, -283, -283, -283, -283, -283, -283, -283,
851 | 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420,
852 | -805, -805, -805, -805, -805, -805, -805, -805,
853 | 1116, 946, 632, 222, -222, -632, -946, -1116,
854 | -1970, -1670, -1116, -392, 392, 1116, 1670, 1970,
855 | 392, 332, 222, 78, -78, -222, -332, -392,
856 | 1670, 1416, 946, 332, -332, -946, -1416, -1670,
857 | -1670, -1416, -946, -332, 332, 946, 1416, 1670,
858 | -392, -332, -222, -78, 78, 222, 332, 392,
859 | 1970, 1670, 1116, 392, -392, -1116, -1670, -1970,
860 | -1116, -946, -632, -222, 222, 632, 946, 1116,
861 | 1051, 435, -435, -1051, -1051, -435, 435, 1051,
862 | -1856, -769, 769, 1856, 1856, 769, -769, -1856,
863 | 369, 153, -153, -369, -369, -153, 153, 369,
864 | 1573, 652, -652, -1573, -1573, -652, 652, 1573,
865 | -1573, -652, 652, 1573, 1573, 652, -652, -1573,
866 | -369, -153, 153, 369, 369, 153, -153, -369,
867 | 1856, 769, -769, -1856, -1856, -769, 769, 1856,
868 | -1051, -435, 435, 1051, 1051, 435, -435, -1051,
869 | 946, -222, -1116, -632, 632, 1116, 222, -946,
870 | -1670, 392, 1970, 1116, -1116, -1970, -392, 1670,
871 | 332, -78, -392, -222, 222, 392, 78, -332,
872 | 1416, -332, -1670, -946, 946, 1670, 332, -1416,
873 | -1416, 332, 1670, 946, -946, -1670, -332, 1416,
874 | -332, 78, 392, 222, -222, -392, -78, 332,
875 | 1670, -392, -1970, -1116, 1116, 1970, 392, -1670,
876 | -946, 222, 1116, 632, -632, -1116, -222, 946,
877 | 805, -805, -805, 805, 805, -805, -805, 805,
878 | -1420, 1420, 1420, -1420, -1420, 1420, 1420, -1420,
879 | 283, -283, -283, 283, 283, -283, -283, 283,
880 | 1204, -1204, -1204, 1204, 1204, -1204, -1204, 1204,
881 | -1204, 1204, 1204, -1204, -1204, 1204, 1204, -1204,
882 | -283, 283, 283, -283, -283, 283, 283, -283,
883 | 1420, -1420, -1420, 1420, 1420, -1420, -1420, 1420,
884 | -805, 805, 805, -805, -805, 805, 805, -805,
885 | 632, -1116, 222, 946, -946, -222, 1116, -632,
886 | -1116, 1970, -392, -1670, 1670, 392, -1970, 1116,
887 | 222, -392, 78, 332, -332, -78, 392, -222,
888 | 946, -1670, 332, 1416, -1416, -332, 1670, -946,
889 | -946, 1670, -332, -1416, 1416, 332, -1670, 946,
890 | -222, 392, -78, -332, 332, 78, -392, 222,
891 | 1116, -1970, 392, 1670, -1670, -392, 1970, -1116,
892 | -632, 1116, -222, -946, 946, 222, -1116, 632,
893 | 435, -1051, 1051, -435, -435, 1051, -1051, 435,
894 | -769, 1856, -1856, 769, 769, -1856, 1856, -769,
895 | 153, -369, 369, -153, -153, 369, -369, 153,
896 | 652, -1573, 1573, -652, -652, 1573, -1573, 652,
897 | -652, 1573, -1573, 652, 652, -1573, 1573, -652,
898 | -153, 369, -369, 153, 153, -369, 369, -153,
899 | 769, -1856, 1856, -769, -769, 1856, -1856, 769,
900 | -435, 1051, -1051, 435, 435, -1051, 1051, -435,
901 | 222, -632, 946, -1116, 1116, -946, 632, -222,
902 | -392, 1116, -1670, 1970, -1970, 1670, -1116, 392,
903 | 78, -222, 332, -392, 392, -332, 222, -78,
904 | 332, -946, 1416, -1670, 1670, -1416, 946, -332,
905 | -332, 946, -1416, 1670, -1670, 1416, -946, 332,
906 | -78, 222, -332, 392, -392, 332, -222, 78,
907 | 392, -1116, 1670, -1970, 1970, -1670, 1116, -392,
908 | -222, 632, -946, 1116, -1116, 946, -632, 222,
909 | 554, 554, 554, 554, 554, 554, 554, 554,
910 | -1338, -1338, -1338, -1338, -1338, -1338, -1338, -1338,
911 | 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338,
912 | -554, -554, -554, -554, -554, -554, -554, -554,
913 | -554, -554, -554, -554, -554, -554, -554, -554,
914 | 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338,
915 | -1338, -1338, -1338, -1338, -1338, -1338, -1338, -1338,
916 | 554, 554, 554, 554, 554, 554, 554, 554,
917 | 769, 652, 435, 153, -153, -435, -652, -769,
918 | -1856, -1573, -1051, -369, 369, 1051, 1573, 1856,
919 | 1856, 1573, 1051, 369, -369, -1051, -1573, -1856,
920 | -769, -652, -435, -153, 153, 435, 652, 769,
921 | -769, -652, -435, -153, 153, 435, 652, 769,
922 | 1856, 1573, 1051, 369, -369, -1051, -1573, -1856,
923 | -1856, -1573, -1051, -369, 369, 1051, 1573, 1856,
924 | 769, 652, 435, 153, -153, -435, -652, -769,
925 | 724, 300, -300, -724, -724, -300, 300, 724,
926 | -1748, -724, 724, 1748, 1748, 724, -724, -1748,
927 | 1748, 724, -724, -1748, -1748, -724, 724, 1748,
928 | -724, -300, 300, 724, 724, 300, -300, -724,
929 | -724, -300, 300, 724, 724, 300, -300, -724,
930 | 1748, 724, -724, -1748, -1748, -724, 724, 1748,
931 | -1748, -724, 724, 1748, 1748, 724, -724, -1748,
932 | 724, 300, -300, -724, -724, -300, 300, 724,
933 | 652, -153, -769, -435, 435, 769, 153, -652,
934 | -1573, 369, 1856, 1051, -1051, -1856, -369, 1573,
935 | 1573, -369, -1856, -1051, 1051, 1856, 369, -1573,
936 | -652, 153, 769, 435, -435, -769, -153, 652,
937 | -652, 153, 769, 435, -435, -769, -153, 652,
938 | 1573, -369, -1856, -1051, 1051, 1856, 369, -1573,
939 | -1573, 369, 1856, 1051, -1051, -1856, -369, 1573,
940 | 652, -153, -769, -435, 435, 769, 153, -652,
941 | 554, -554, -554, 554, 554, -554, -554, 554,
942 | -1338, 1338, 1338, -1338, -1338, 1338, 1338, -1338,
943 | 1338, -1338, -1338, 1338, 1338, -1338, -1338, 1338,
944 | -554, 554, 554, -554, -554, 554, 554, -554,
945 | -554, 554, 554, -554, -554, 554, 554, -554,
946 | 1338, -1338, -1338, 1338, 1338, -1338, -1338, 1338,
947 | -1338, 1338, 1338, -1338, -1338, 1338, 1338, -1338,
948 | 554, -554, -554, 554, 554, -554, -554, 554,
949 | 435, -769, 153, 652, -652, -153, 769, -435,
950 | -1051, 1856, -369, -1573, 1573, 369, -1856, 1051,
951 | 1051, -1856, 369, 1573, -1573, -369, 1856, -1051,
952 | -435, 769, -153, -652, 652, 153, -769, 435,
953 | -435, 769, -153, -652, 652, 153, -769, 435,
954 | 1051, -1856, 369, 1573, -1573, -369, 1856, -1051,
955 | -1051, 1856, -369, -1573, 1573, 369, -1856, 1051,
956 | 435, -769, 153, 652, -652, -153, 769, -435,
957 | 300, -724, 724, -300, -300, 724, -724, 300,
958 | -724, 1748, -1748, 724, 724, -1748, 1748, -724,
959 | 724, -1748, 1748, -724, -724, 1748, -1748, 724,
960 | -300, 724, -724, 300, 300, -724, 724, -300,
961 | -300, 724, -724, 300, 300, -724, 724, -300,
962 | 724, -1748, 1748, -724, -724, 1748, -1748, 724,
963 | -724, 1748, -1748, 724, 724, -1748, 1748, -724,
964 | 300, -724, 724, -300, -300, 724, -724, 300,
965 | 153, -435, 652, -769, 769, -652, 435, -153,
966 | -369, 1051, -1573, 1856, -1856, 1573, -1051, 369,
967 | 369, -1051, 1573, -1856, 1856, -1573, 1051, -369,
968 | -153, 435, -652, 769, -769, 652, -435, 153,
969 | -153, 435, -652, 769, -769, 652, -435, 153,
970 | 369, -1051, 1573, -1856, 1856, -1573, 1051, -369,
971 | -369, 1051, -1573, 1856, -1856, 1573, -1051, 369,
972 | 153, -435, 652, -769, 769, -652, 435, -153,
973 | 283, 283, 283, 283, 283, 283, 283, 283,
974 | -805, -805, -805, -805, -805, -805, -805, -805,
975 | 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
976 | -1420, -1420, -1420, -1420, -1420, -1420, -1420, -1420,
977 | 1420, 1420, 1420, 1420, 1420, 1420, 1420, 1420,
978 | -1204, -1204, -1204, -1204, -1204, -1204, -1204, -1204,
979 | 805, 805, 805, 805, 805, 805, 805, 805,
980 | -283, -283, -283, -283, -283, -283, -283, -283,
981 | 392, 332, 222, 78, -78, -222, -332, -392,
982 | -1116, -946, -632, -222, 222, 632, 946, 1116,
983 | 1670, 1416, 946, 332, -332, -946, -1416, -1670,
984 | -1970, -1670, -1116, -392, 392, 1116, 1670, 1970,
985 | 1970, 1670, 1116, 392, -392, -1116, -1670, -1970,
986 | -1670, -1416, -946, -332, 332, 946, 1416, 1670,
987 | 1116, 946, 632, 222, -222, -632, -946, -1116,
988 | -392, -332, -222, -78, 78, 222, 332, 392,
989 | 369, 153, -153, -369, -369, -153, 153, 369,
990 | -1051, -435, 435, 1051, 1051, 435, -435, -1051,
991 | 1573, 652, -652, -1573, -1573, -652, 652, 1573,
992 | -1856, -769, 769, 1856, 1856, 769, -769, -1856,
993 | 1856, 769, -769, -1856, -1856, -769, 769, 1856,
994 | -1573, -652, 652, 1573, 1573, 652, -652, -1573,
995 | 1051, 435, -435, -1051, -1051, -435, 435, 1051,
996 | -369, -153, 153, 369, 369, 153, -153, -369,
997 | 332, -78, -392, -222, 222, 392, 78, -332,
998 | -946, 222, 1116, 632, -632, -1116, -222, 946,
999 | 1416, -332, -1670, -946, 946, 1670, 332, -1416,
1000 | -1670, 392, 1970, 1116, -1116, -1970, -392, 1670,
1001 | 1670, -392, -1970, -1116, 1116, 1970, 392, -1670,
1002 | -1416, 332, 1670, 946, -946, -1670, -332, 1416,
1003 | 946, -222, -1116, -632, 632, 1116, 222, -946,
1004 | -332, 78, 392, 222, -222, -392, -78, 332,
1005 | 283, -283, -283, 283, 283, -283, -283, 283,
1006 | -805, 805, 805, -805, -805, 805, 805, -805,
1007 | 1204, -1204, -1204, 1204, 1204, -1204, -1204, 1204,
1008 | -1420, 1420, 1420, -1420, -1420, 1420, 1420, -1420,
1009 | 1420, -1420, -1420, 1420, 1420, -1420, -1420, 1420,
1010 | -1204, 1204, 1204, -1204, -1204, 1204, 1204, -1204,
1011 | 805, -805, -805, 805, 805, -805, -805, 805,
1012 | -283, 283, 283, -283, -283, 283, 283, -283,
1013 | 222, -392, 78, 332, -332, -78, 392, -222,
1014 | -632, 1116, -222, -946, 946, 222, -1116, 632,
1015 | 946, -1670, 332, 1416, -1416, -332, 1670, -946,
1016 | -1116, 1970, -392, -1670, 1670, 392, -1970, 1116,
1017 | 1116, -1970, 392, 1670, -1670, -392, 1970, -1116,
1018 | -946, 1670, -332, -1416, 1416, 332, -1670, 946,
1019 | 632, -1116, 222, 946, -946, -222, 1116, -632,
1020 | -222, 392, -78, -332, 332, 78, -392, 222,
1021 | 153, -369, 369, -153, -153, 369, -369, 153,
1022 | -435, 1051, -1051, 435, 435, -1051, 1051, -435,
1023 | 652, -1573, 1573, -652, -652, 1573, -1573, 652,
1024 | -769, 1856, -1856, 769, 769, -1856, 1856, -769,
1025 | 769, -1856, 1856, -769, -769, 1856, -1856, 769,
1026 | -652, 1573, -1573, 652, 652, -1573, 1573, -652,
1027 | 435, -1051, 1051, -435, -435, 1051, -1051, 435,
1028 | -153, 369, -369, 153, 153, -369, 369, -153,
1029 | 78, -222, 332, -392, 392, -332, 222, -78,
1030 | -222, 632, -946, 1116, -1116, 946, -632, 222,
1031 | 332, -946, 1416, -1670, 1670, -1416, 946, -332,
1032 | -392, 1116, -1670, 1970, -1970, 1670, -1116, 392,
1033 | 392, -1116, 1670, -1970, 1970, -1670, 1116, -392,
1034 | -332, 946, -1416, 1670, -1670, 1416, -946, 332,
1035 | 222, -632, 946, -1116, 1116, -946, 632, -222,
1036 | -78, 222, -332, 392, -392, 332, -222, 78,
1037 | };
1038 |
1039 | // precalculated int base values for 8x8 DCT, multplied by 8192
1040 | const int icos_base_8x8[ 64 ] =
1041 | {
1042 | 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
1043 | 11363, 9633, 6436, 2260, -2260, -6436, -9633, -11363,
1044 | 10703, 4433, -4433, -10703, -10703, -4433, 4433, 10703,
1045 | 9633, -2260, -11363, -6436, 6436, 11363, 2260, -9633,
1046 | 8192, -8192, -8192, 8192, 8192, -8192, -8192, 8192,
1047 | 6436, -11363, 2260, 9633, -9633, -2260, 11363, -6436,
1048 | 4433, -10703, 10703, -4433, -4433, 10703, -10703, 4433,
1049 | 2260, -6436, 9633, -11363, 11363, -9633, 6436, -2260,
1050 | };
1051 |
1052 | // precalculated int values for 1x8 IDCT, multplied by 8192
1053 | const int icos_idct_1x8[ 64 ] =
1054 | {
1055 | 1024, 1420, 1338, 1204, 1024, 805, 554, 283,
1056 | 1024, 1204, 554, -283, -1024, -1420, -1338, -805,
1057 | 1024, 805, -554, -1420, -1024, 283, 1338, 1204,
1058 | 1024, 283, -1338, -805, 1024, 1204, -554, -1420,
1059 | 1024, -283, -1338, 805, 1024, -1204, -554, 1420,
1060 | 1024, -805, -554, 1420, -1024, -283, 1338, -1204,
1061 | 1024, -1204, 554, 283, -1024, 1420, -1338, 805,
1062 | 1024, -1420, 1338, -1204, 1024, -805, 554, -283,
1063 | };
1064 |
1065 | // precalculated int values for 1x8 FDCT, multplied by 8192
1066 | const int icos_fdct_1x8[ 64 ] =
1067 | {
1068 | 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
1069 | 11363, 9633, 6436, 2260, -2260, -6436, -9633, -11363,
1070 | 10703, 4433, -4433, -10703, -10703, -4433, 4433, 10703,
1071 | 9633, -2260, -11363, -6436, 6436, 11363, 2260, -9633,
1072 | 8192, -8192, -8192, 8192, 8192, -8192, -8192, 8192,
1073 | 6436, -11363, 2260, 9633, -9633, -2260, 11363, -6436,
1074 | 4433, -10703, 10703, -4433, -4433, 10703, -10703, 4433,
1075 | 2260, -6436, 9633, -11363, 11363, -9633, 6436, -2260,
1076 | };
1077 |
1078 |
1079 | // dct functions follow, you need to rescale the results using DCT_RESCALE
1080 |
1081 | /* -----------------------------------------------
1082 | inverse 8x8 DCT transform
1083 | ----------------------------------------------- */
1084 | inline int idct_2d_fst_8x8( signed short* F, int ix, int iy )
1085 | {
1086 | int idct;
1087 | int ixy;
1088 | int i;
1089 |
1090 |
1091 | // calculate start index
1092 | ixy = ( ( iy * 8 ) + ix ) * 64;
1093 |
1094 | // begin transform
1095 | idct = 0;
1096 | for ( i = 0; i < 64; i++ )
1097 | idct += F[ i ] * icos_idct_8x8[ ixy++ ];
1098 |
1099 |
1100 | return idct;
1101 | }
1102 |
1103 | /* -----------------------------------------------
1104 | forward 8x8 DCT transform
1105 | ----------------------------------------------- */
1106 | inline int fdct_2d_fst_8x8( unsigned char* f, int iu, int iv )
1107 | {
1108 | int fdct;
1109 | int iuv;
1110 | int i;
1111 |
1112 |
1113 | // calculate start index
1114 | iuv = ( ( iv * 8 ) + iu ) * 64;
1115 |
1116 | // begin transform
1117 | fdct = 0;
1118 | for ( i = 0; i < 64; i++ )
1119 | fdct += f[ i ] * icos_fdct_8x8[ iuv++ ];
1120 |
1121 |
1122 | return fdct;
1123 | }
1124 |
1125 | /* -----------------------------------------------
1126 | inverse 1D-8 DCT transform
1127 | ----------------------------------------------- */
1128 | inline int idct_1d_fst_8( signed short* F, int ix )
1129 | {
1130 | int idct;
1131 | int i;
1132 |
1133 |
1134 | // calculate start index
1135 | ix *= 8;
1136 |
1137 | // begin transform
1138 | idct = 0;
1139 | for ( i = 0; i < 8; i++ )
1140 | idct += F[ i ] * icos_idct_1x8[ ix++ ];
1141 |
1142 |
1143 | return idct;
1144 | }
1145 |
1146 | /* -----------------------------------------------
1147 | forward 1D-8 DCT transform
1148 | ----------------------------------------------- */
1149 | inline int fdct_1d_fst_8( unsigned char* f, int iu )
1150 | {
1151 | int fdct;
1152 | int i;
1153 |
1154 |
1155 | // calculate start index
1156 | iu *= 8;
1157 |
1158 | // begin transform
1159 | fdct = 0;
1160 | for ( i = 0; i < 8; i++ )
1161 | fdct += f[ i ] * icos_fdct_1x8[ iu++ ];
1162 |
1163 |
1164 | return fdct;
1165 | }
1166 |
1167 |
--------------------------------------------------------------------------------
/source/file_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/packjpg/packJPG/93a7dfbe1fb9aa2aee763cc5b8a16c14b2f66c8c/source/file_icon.ico
--------------------------------------------------------------------------------
/source/icons.rc:
--------------------------------------------------------------------------------
1 | app ICON app_icon.ico
2 | ICONS1 ICON file_icon.ico
--------------------------------------------------------------------------------
/source/icons.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/packjpg/packJPG/93a7dfbe1fb9aa2aee763cc5b8a16c14b2f66c8c/source/icons.res
--------------------------------------------------------------------------------
/source/packjpg.spec:
--------------------------------------------------------------------------------
1 | Name: packjpg
2 | Version: 2.5j
3 | Release: 1%{?dist}
4 | Summary: Lossless JPEG re-compression
5 | URL: http://www.elektronik.htw-aalen.de/packjpg/
6 | License: LGPL
7 | Group: Applications/File
8 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
9 | Source0: %{name}-%{version}.tar.xz
10 | Patch0: %{name}-build-fix.patch
11 |
12 | %description
13 | packJPG is a compression program specially designed for further
14 | compression of JPEG images without causing any further loss. Typically
15 | it reduces the file size of a JPEG file by 20%.
16 |
17 | %prep
18 | %setup -q
19 | %patch0 -p1
20 |
21 |
22 | %build
23 | cd source
24 | CFLAGS="%{optflags}" LDFLAGS="%{?__global_ldflags}" make -f Makefile_linux %{?_smp_mflags}
25 |
26 |
27 | %install
28 | rm -rf %{buildroot}
29 | install -D -m755 source/%{name} %{buildroot}%{_bindir}/%{name}
30 |
31 |
32 | %clean
33 | rm -rf %{buildroot}
34 |
35 |
36 | %files
37 | %defattr(-,root,root)
38 | %{_bindir}/%{name}
39 |
40 |
41 | %changelog
42 | * Fri Jul 18 2014 Bryan Stillwell - 2.5j-1
43 | - Initial packaging
44 |
--------------------------------------------------------------------------------
/source/packjpgdll.h:
--------------------------------------------------------------------------------
1 | // packJPGdll.h - function import declarations for the packJPG DLL
2 | #define IMPORT __declspec( dllimport )
3 |
4 | /* -----------------------------------------------
5 | function declarations: library only functions
6 | ----------------------------------------------- */
7 |
8 | IMPORT bool pjglib_convert_stream2stream( char* msg );
9 | IMPORT bool pjglib_convert_file2file( char* in, char* out, char* msg );
10 | IMPORT bool pjglib_convert_stream2mem( unsigned char** out_file, unsigned int* out_size, char* msg );
11 | IMPORT void pjglib_init_streams( void* in_src, int in_type, int in_size, void* out_dest, int out_type );
12 | IMPORT const char* pjglib_version_info( void );
13 | IMPORT const char* pjglib_short_name( void );
14 |
15 | /* a short reminder about input/output stream types
16 | for the pjglib_init_streams() function
17 |
18 | if input is file
19 | ----------------
20 | in_scr -> name of input file
21 | in_type -> 0
22 | in_size -> ignore
23 |
24 | if input is memory
25 | ------------------
26 | in_scr -> array containg data
27 | in_type -> 1
28 | in_size -> size of data array
29 |
30 | if input is *FILE (f.e. stdin)
31 | ------------------------------
32 | in_src -> stream pointer
33 | in_type -> 2
34 | in_size -> ignore
35 |
36 | vice versa for output streams! */
37 |
--------------------------------------------------------------------------------
/source/packjpglib.h:
--------------------------------------------------------------------------------
1 | // packJPGlib.h - function declarations for the packJPG library
2 | #if defined BUILD_DLL
3 | #define EXPORT __declspec( dllexport )
4 | #else
5 | #define EXPORT extern
6 | #endif
7 |
8 | /* -----------------------------------------------
9 | function declarations: library only functions
10 | ----------------------------------------------- */
11 |
12 | EXPORT bool pjglib_convert_stream2stream( char* msg );
13 | EXPORT bool pjglib_convert_file2file( char* in, char* out, char* msg );
14 | EXPORT bool pjglib_convert_stream2mem( unsigned char** out_file, unsigned int* out_size, char* msg );
15 | EXPORT void pjglib_init_streams( void* in_src, int in_type, int in_size, void* out_dest, int out_type );
16 | EXPORT const char* pjglib_version_info( void );
17 | EXPORT const char* pjglib_short_name( void );
18 |
19 | /* a short reminder about input/output stream types
20 | for the pjglib_init_streams() function
21 |
22 | if input is file
23 | ----------------
24 | in_scr -> name of input file
25 | in_type -> 0
26 | in_size -> ignore
27 |
28 | if input is memory
29 | ------------------
30 | in_scr -> array containg data
31 | in_type -> 1
32 | in_size -> size of data array
33 |
34 | if input is *FILE (f.e. stdin)
35 | ------------------------------
36 | in_src -> stream pointer
37 | in_type -> 2
38 | in_size -> ignore
39 |
40 | vice versa for output streams! */
41 |
--------------------------------------------------------------------------------