├── .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 | --------------------------------------------------------------------------------